diff --git a/briar-android/src/main/AndroidManifest.xml b/briar-android/src/main/AndroidManifest.xml index f105d57e9706e53679d3ba75d2c8baed390c9497..9ae75930b6de1e5bae61576f8a385967029f75ad 100644 --- a/briar-android/src/main/AndroidManifest.xml +++ b/briar-android/src/main/AndroidManifest.xml @@ -26,10 +26,11 @@ android:theme="@style/BriarTheme"> <receiver - android:name="org.briarproject.briar.android.BootReceiver" + android:name="org.briarproject.briar.android.login.SignInReminderReceiver" android:exported="false"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> + <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/> </intent-filter> </receiver> diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java index 778a6f2b95c6454adaf4ddad3d174eb5239f13cb..087aa5ea0cd7d6a2f6b76eb9c9b3a82d92e269fc 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java @@ -26,6 +26,7 @@ import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.Clock; import org.briarproject.briar.BriarCoreEagerSingletons; import org.briarproject.briar.BriarCoreModule; +import org.briarproject.briar.android.login.SignInReminderReceiver; import org.briarproject.briar.android.reporting.BriarReportSender; import org.briarproject.briar.api.android.AndroidNotificationManager; import org.briarproject.briar.api.android.DozeWatchdog; @@ -150,7 +151,7 @@ public interface AndroidComponent @IoExecutor Executor ioExecutor(); - void inject(BootReceiver briarService); + void inject(SignInReminderReceiver briarService); void inject(BriarService briarService); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java index 5a2ad896c626dbf0e26d282e9d730f117115090a..2296a8bafffb48d0e8c315e3460846b9b3d3bef8 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java @@ -162,6 +162,7 @@ public class AppModule { @Provides SharedPreferences provideSharedPreferences(Application app) { + // FIXME unify this with getDefaultSharedPreferences() return app.getSharedPreferences("db", MODE_PRIVATE); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/BriarApplication.java b/briar-android/src/main/java/org/briarproject/briar/android/BriarApplication.java index e537bd86d6fe804e9aa55a2811a9c8eb5522fa2f..6ab1c9ee01e318068441254f829702a060221c08 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/BriarApplication.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/BriarApplication.java @@ -1,5 +1,7 @@ package org.briarproject.briar.android; +import android.content.SharedPreferences; + import java.util.Collection; import java.util.logging.LogRecord; @@ -12,4 +14,6 @@ public interface BriarApplication { Collection<LogRecord> getRecentLogRecords(); AndroidComponent getApplicationComponent(); + + SharedPreferences getDefaultSharedPreferences(); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/BriarApplicationImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/BriarApplicationImpl.java index 0b2f034660a83ef46fb3d7b0922da1acd45d2eda..08fc14b5daabbb6e415562b945b3e2ae5ee11b46 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/BriarApplicationImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/BriarApplicationImpl.java @@ -77,11 +77,12 @@ public class BriarApplicationImpl extends Application private final CachingLogHandler logHandler = new CachingLogHandler(); private AndroidComponent applicationComponent; + private volatile SharedPreferences prefs; @Override protected void attachBaseContext(Context base) { - SharedPreferences prefs = - PreferenceManager.getDefaultSharedPreferences(base); + if (prefs == null) + prefs = PreferenceManager.getDefaultSharedPreferences(base); // Loading the language needs to be done here. Localizer.initialize(prefs); super.attachBaseContext( @@ -156,4 +157,9 @@ public class BriarApplicationImpl extends Application public AndroidComponent getApplicationComponent() { return applicationComponent; } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return prefs; + } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/BootReceiver.java b/briar-android/src/main/java/org/briarproject/briar/android/login/SignInReminderReceiver.java similarity index 63% rename from briar-android/src/main/java/org/briarproject/briar/android/BootReceiver.java rename to briar-android/src/main/java/org/briarproject/briar/android/login/SignInReminderReceiver.java index cf4e0ab13eb058412c7730e997982de41c6c327d..cf1edaae668db3a49a938478a3e7633066e3e79e 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/BootReceiver.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/login/SignInReminderReceiver.java @@ -1,4 +1,4 @@ -package org.briarproject.briar.android; +package org.briarproject.briar.android.login; import android.app.NotificationChannel; import android.app.NotificationManager; @@ -6,11 +6,14 @@ import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.support.v4.app.NotificationCompat; import android.support.v4.content.ContextCompat; import org.briarproject.bramble.api.db.DatabaseConfig; import org.briarproject.briar.R; +import org.briarproject.briar.android.AndroidComponent; +import org.briarproject.briar.android.BriarApplication; import org.briarproject.briar.android.navdrawer.NavDrawerActivity; import javax.inject.Inject; @@ -18,16 +21,20 @@ import javax.inject.Inject; import static android.app.NotificationManager.IMPORTANCE_LOW; import static android.content.Context.NOTIFICATION_SERVICE; import static android.content.Intent.ACTION_BOOT_COMPLETED; +import static android.content.Intent.ACTION_MY_PACKAGE_REPLACED; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.os.Build.VERSION.SDK_INT; import static android.support.v4.app.NotificationCompat.PRIORITY_LOW; import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET; import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_SIGN_IN_REMINDER; +import static org.briarproject.briar.android.settings.SettingsFragment.NOTIFY_SIGN_IN; import static org.briarproject.briar.api.android.AndroidNotificationManager.REMINDER_CHANNEL_ID; import static org.briarproject.briar.api.android.AndroidNotificationManager.REMINDER_NOTIFICATION_ID; -public class BootReceiver extends BroadcastReceiver { +public class SignInReminderReceiver extends BroadcastReceiver { + + public static final String DISMISS_REMINDER = "dismissReminder"; @Inject DatabaseConfig databaseConfig; @@ -36,16 +43,22 @@ public class BootReceiver extends BroadcastReceiver { public void onReceive(Context ctx, Intent intent) { if (!FEATURE_FLAG_SIGN_IN_REMINDER) return; - AndroidComponent applicationComponent = - ((BriarApplication) ctx.getApplicationContext()) - .getApplicationComponent(); + BriarApplication app = (BriarApplication) ctx.getApplicationContext(); + AndroidComponent applicationComponent = app.getApplicationComponent(); applicationComponent.inject(this); String action = intent.getAction(); - if (action != null && action.equals(ACTION_BOOT_COMPLETED)) { + if (action == null) return; + if (action.equals(ACTION_BOOT_COMPLETED) || + action.equals(ACTION_MY_PACKAGE_REPLACED)) { if (databaseConfig.databaseExists()) { - showSignInNotification(ctx); + SharedPreferences prefs = app.getDefaultSharedPreferences(); + if (prefs.getBoolean(NOTIFY_SIGN_IN, true)) { + showSignInNotification(ctx); + } } + } else if (action.equals(DISMISS_REMINDER)) { + dismissReminder(ctx); } } @@ -65,7 +78,7 @@ public class BootReceiver extends BroadcastReceiver { NotificationCompat.Builder b = new NotificationCompat.Builder(ctx, REMINDER_CHANNEL_ID); - b.setSmallIcon(R.drawable.notification_reminder); + b.setSmallIcon(R.drawable.ic_signout); b.setColor(ContextCompat.getColor(ctx, R.color.briar_primary)); b.setContentTitle(ctx.getText(R.string.reminder_notification_title)); b.setContentText(ctx.getText(R.string.reminder_notification_text)); @@ -73,6 +86,14 @@ public class BootReceiver extends BroadcastReceiver { b.setWhen(0); // Don't show the time b.setPriority(PRIORITY_LOW); + // Add a 'Dismiss' action + String actionTitle = + ctx.getString(R.string.reminder_notification_dismiss); + Intent i1 = new Intent(ctx, SignInReminderReceiver.class); + i1.setAction(DISMISS_REMINDER); + PendingIntent actionIntent = PendingIntent.getBroadcast(ctx, 0, i1, 0); + b.addAction(0, actionTitle, actionIntent); + Intent i = new Intent(ctx, NavDrawerActivity.class); i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP); b.setContentIntent(PendingIntent.getActivity(ctx, 0, i, 0)); @@ -80,4 +101,11 @@ public class BootReceiver extends BroadcastReceiver { nm.notify(REMINDER_NOTIFICATION_ID, b.build()); } + private void dismissReminder(Context ctx) { + NotificationManager nm = (NotificationManager) + ctx.getSystemService(NOTIFICATION_SERVICE); + if (nm == null) return; + nm.cancel(REMINDER_NOTIFICATION_ID); + } + } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java index 17c50fca0f464946818c0c86aec39c0b394748b7..955680ff521ed9c2fea89b5712993444f5beedb6 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java @@ -71,6 +71,7 @@ import static org.briarproject.bramble.util.LogUtils.logDuration; import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.now; import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_DARK_THEME; +import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_SIGN_IN_REMINDER; import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_RINGTONE; import static org.briarproject.briar.android.navdrawer.NavDrawerActivity.INTENT_SIGN_OUT; @@ -97,6 +98,7 @@ public class SettingsFragment extends PreferenceFragmentCompat public static final String BT_NAMESPACE = BluetoothConstants.ID.getString(); public static final String TOR_NAMESPACE = TorConstants.ID.getString(); public static final String LANGUAGE = "pref_key_language"; + public static final String NOTIFY_SIGN_IN = "pref_key_notify_sign_in"; private static final Logger LOG = Logger.getLogger(SettingsFragment.class.getName()); @@ -143,6 +145,8 @@ public class SettingsFragment extends PreferenceFragmentCompat (ListPreference) findPreference("pref_key_theme"); enableBluetooth = (ListPreference) findPreference("pref_key_bluetooth"); torNetwork = (ListPreference) findPreference("pref_key_tor_network"); + CheckBoxPreference notifySignIn = + (CheckBoxPreference) findPreference(NOTIFY_SIGN_IN); notifyPrivateMessages = (CheckBoxPreference) findPreference( "pref_key_notify_private_messages"); notifyGroupMessages = (CheckBoxPreference) findPreference( @@ -199,6 +203,7 @@ public class SettingsFragment extends PreferenceFragmentCompat ); } else { theme.setVisible(FEATURE_FLAG_DARK_THEME); + notifySignIn.setVisible(FEATURE_FLAG_SIGN_IN_REMINDER); findPreference("pref_key_explode").setVisible(false); findPreference("pref_key_test_data").setVisible(false); @@ -346,7 +351,9 @@ public class SettingsFragment extends PreferenceFragmentCompat } private void setSettingsEnabled(boolean enabled) { - // theme not needed here, because handled by SharedPreferences + // preferences not needed here, because handled by SharedPreferences: + // - pref_key_theme + // - pref_key_notify_sign_in enableBluetooth.setEnabled(enabled); torNetwork.setEnabled(enabled); notifyPrivateMessages.setEnabled(enabled); diff --git a/briar-android/src/main/res/drawable/ic_signout.xml b/briar-android/src/main/res/drawable/ic_signout.xml new file mode 100644 index 0000000000000000000000000000000000000000..2dd789085a157058356d72ca8701da0aaaaaeb57 --- /dev/null +++ b/briar-android/src/main/res/drawable/ic_signout.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportHeight="24" + android:viewportWidth="24"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M17,17.25V14H10V10H17V6.75L22.25,12L17,17.25M13,2A2,2 0 0,1 15,4V8H13V4H4V20H13V16H15V20A2,2 0 0,1 13,22H4A2,2 0 0,1 2,20V4A2,2 0 0,1 4,2H13Z"/> +</vector> \ No newline at end of file diff --git a/briar-android/src/main/res/drawable/ic_signout_black_24dp.xml b/briar-android/src/main/res/drawable/ic_signout_black_24dp.xml deleted file mode 100644 index 05569dbdf34c6d668d7f8f2a4d4c120fcf988c2d..0000000000000000000000000000000000000000 --- a/briar-android/src/main/res/drawable/ic_signout_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportHeight="24.0" - android:viewportWidth="24.0"> - <path - android:fillColor="#FF000000" - android:pathData="M13,8.2l-1,-1 -4,4 -4,-4 -1,1 4,4 -4,4 1,1 4,-4 4,4 1,-1 -4,-4 4,-4zM19,1H9c-1.1,0 -2,0.9 -2,2v3h2V4h10v16H9v-2H7v3c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3c0,-1.1 -0.9,-2 -2,-2z"/> -</vector> diff --git a/briar-android/src/main/res/drawable/notification_reminder.xml b/briar-android/src/main/res/drawable/notification_reminder.xml deleted file mode 100644 index 1defd7d3d3583a62e15eac36d7e8066b389903da..0000000000000000000000000000000000000000 --- a/briar-android/src/main/res/drawable/notification_reminder.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportHeight="24" - android:viewportWidth="24"> - <path - android:fillColor="#ffffff" - android:pathData="M 12 0 A 12 12 0 0 0 4.875 2.3613281 L 6.9316406 4.4160156 C 7.0875805 3.8805807 7.5639651 3.4765625 8.1464844 3.4765625 L 8.7480469 3.4765625 C 9.4535014 3.4765625 10.035156 4.0582174 10.035156 4.7636719 L 10.035156 6.4003906 L 8.9140625 6.4003906 L 9.4238281 6.9101562 L 13.404297 6.9101562 L 13.404297 10.085938 L 12.601562 10.085938 L 13.914062 11.398438 L 13.914062 4.7636719 C 13.914062 4.0582174 14.495717 3.4765625 15.201172 3.4765625 L 15.802734 3.4765625 C 16.515461 3.4765625 17.089844 4.0582174 17.089844 4.7636719 L 17.089844 13.455078 L 15.96875 13.455078 L 16.478516 13.964844 L 19.236328 13.964844 C 19.941782 13.964844 20.516165 14.546498 20.523438 15.251953 L 20.523438 15.853516 C 20.523438 16.436036 20.119418 16.91242 19.583984 17.068359 L 21.638672 19.125 A 12 12 0 0 0 24 12 A 12 12 0 0 0 12 0 z M 1.2617188 1.3632812 L 0 2.6269531 L 2.3125 4.9472656 A 12 12 0 0 0 0 12 A 12 12 0 0 0 12 24 A 12 12 0 0 0 19.027344 21.707031 L 21.314453 24 L 22.576172 22.734375 L 2.7519531 2.8554688 L 1.9863281 2.0898438 L 1.2617188 1.3632812 z M 17.599609 6.9101562 L 19.236328 6.9101562 C 19.941782 6.9101562 20.516165 7.4918111 20.523438 8.1972656 L 20.523438 8.7988281 C 20.523438 9.511555 19.941782 10.085937 19.236328 10.085938 L 17.599609 10.085938 L 17.599609 6.9101562 z M 4.359375 6.9980469 L 7.4394531 10.085938 L 4.7128906 10.085938 C 4.0001632 10.085938 3.4257813 9.504282 3.4257812 8.7988281 L 3.4257812 8.1972656 C 3.4257812 7.6133228 3.8294199 7.1540656 4.359375 6.9980469 z M 6.859375 10.595703 L 7.9472656 10.595703 L 10.035156 12.689453 L 10.035156 19.287109 C 10.035156 19.992562 9.4535014 20.574219 8.7480469 20.574219 L 8.1464844 20.574219 C 7.4337573 20.574219 6.859375 19.992563 6.859375 19.287109 L 6.859375 10.595703 z M 4.7128906 13.964844 L 6.3496094 13.964844 L 6.3496094 17.140625 L 4.7128906 17.140625 C 4.0001632 17.140625 3.4257813 16.558971 3.4257812 15.853516 L 3.4257812 15.251953 C 3.4257812 14.539226 4.007436 13.964844 4.7128906 13.964844 z M 10.544922 13.964844 L 11.306641 13.964844 L 14.474609 17.140625 L 10.544922 17.140625 L 10.544922 13.964844 z M 13.914062 17.650391 L 14.982422 17.650391 L 16.992188 19.666016 C 16.827053 20.182975 16.371277 20.574219 15.802734 20.574219 L 15.201172 20.574219 C 14.495717 20.574219 13.914063 19.992563 13.914062 19.287109 L 13.914062 17.650391 z"/> -</vector> \ No newline at end of file diff --git a/briar-android/src/main/res/menu/navigation_drawer.xml b/briar-android/src/main/res/menu/navigation_drawer.xml index 9c98a51871f1a27c85dc638f60d476e625d99df8..befb4faa2f50ddd0b9c48d13b4740f58bb8dd6e5 100644 --- a/briar-android/src/main/res/menu/navigation_drawer.xml +++ b/briar-android/src/main/res/menu/navigation_drawer.xml @@ -28,7 +28,7 @@ android:title="@string/settings_button"/> <item android:id="@+id/nav_btn_signout" - android:icon="@drawable/ic_signout_black_24dp" + android:icon="@drawable/ic_signout" android:title="@string/sign_out_button"/> </group> diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index 194856e898b19f95da1dc1402b499f1623f28fd9..06a09ddce823d4463d6cdaba9e12a12216e86e2d 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -69,8 +69,9 @@ <!-- Notifications --> <string name="reminder_notification_title">Signed out of Briar</string> - <string name="reminder_notification_text">Tap to sign back in or swipe to dismiss.</string> + <string name="reminder_notification_text">Tap to sign back in.</string> <string name="reminder_notification_channel_title">Briar Sign-in Reminder</string> + <string name="reminder_notification_dismiss">Dismiss</string> <string name="ongoing_notification_title">Signed into Briar</string> <string name="ongoing_notification_text">Touch to open Briar.</string> <plurals name="private_message_notification_text"> @@ -373,6 +374,8 @@ <!-- Settings Notifications --> <string name="notification_settings_title">Notifications</string> + <string name="notify_sign_in_title">Remind me to sign in</string> + <string name="notify_sign_in_summary">Show a reminder when the phone starts or the app has been updated</string> <string name="notify_private_messages_setting_title">Private messages</string> <string name="notify_private_messages_setting_summary">Show alerts for private messages</string> <string name="notify_private_messages_setting_summary_26">Configure alerts for private messages</string> diff --git a/briar-android/src/main/res/xml/settings.xml b/briar-android/src/main/res/xml/settings.xml index c74c7e3c3ec69ab980320ec5ce5a0ceacbb8ac1e..c81fbb2ad497c3493f7e3766678f3b4aeef7dfdd 100644 --- a/briar-android/src/main/res/xml/settings.xml +++ b/briar-android/src/main/res/xml/settings.xml @@ -81,6 +81,12 @@ android:layout="@layout/preferences_category" android:title="@string/notification_settings_title"> + <CheckBoxPreference + android:defaultValue="true" + android:key="pref_key_notify_sign_in" + android:summary="@string/notify_sign_in_summary" + android:title="@string/notify_sign_in_title"/> + <CheckBoxPreference android:defaultValue="true" android:key="pref_key_notify_private_messages" diff --git a/briar-android/src/test/java/org/briarproject/briar/android/TestBriarApplication.java b/briar-android/src/test/java/org/briarproject/briar/android/TestBriarApplication.java index ae086abf3385fde2ede3dd979a0e73cf79525edc..024c62b141b5c1cef76c413dd564ec962763e230 100644 --- a/briar-android/src/test/java/org/briarproject/briar/android/TestBriarApplication.java +++ b/briar-android/src/test/java/org/briarproject/briar/android/TestBriarApplication.java @@ -23,13 +23,14 @@ public class TestBriarApplication extends Application Logger.getLogger(TestBriarApplication.class.getName()); private AndroidComponent applicationComponent; + private volatile SharedPreferences prefs; @Override public void onCreate() { super.onCreate(); LOG.info("Created"); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + prefs = PreferenceManager.getDefaultSharedPreferences(this); Localizer.initialize(prefs); applicationComponent = DaggerAndroidComponent.builder() .appModule(new AppModule(this)) @@ -51,4 +52,9 @@ public class TestBriarApplication extends Application public AndroidComponent getApplicationComponent() { return applicationComponent; } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return prefs; + } }