From 1038a3532b1603e8b96d5f7a8d54b16eec8f4c96 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Wed, 21 Mar 2018 14:31:12 +0000 Subject: [PATCH 1/3] Shut down cleanly when memory is low. --- briar-android/src/main/AndroidManifest.xml | 7 ++++- .../briar/android/BriarService.java | 28 ++++++++++++++++++- .../briar/android/activity/BriarActivity.java | 2 +- .../{panic => logout}/ExitActivity.java | 2 +- .../briar/android/logout/HideUiActivity.java | 20 +++++++++++++ .../{fragment => logout}/SignOutFragment.java | 6 ++-- .../android/navdrawer/NavDrawerActivity.java | 2 +- 7 files changed, 60 insertions(+), 7 deletions(-) rename briar-android/src/main/java/org/briarproject/briar/android/{panic => logout}/ExitActivity.java (92%) create mode 100644 briar-android/src/main/java/org/briarproject/briar/android/logout/HideUiActivity.java rename briar-android/src/main/java/org/briarproject/briar/android/{fragment => logout}/SignOutFragment.java (77%) diff --git a/briar-android/src/main/AndroidManifest.xml b/briar-android/src/main/AndroidManifest.xml index 102de1290..cc195722b 100644 --- a/briar-android/src/main/AndroidManifest.xml +++ b/briar-android/src/main/AndroidManifest.xml @@ -374,7 +374,12 @@ + + + diff --git a/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java b/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java index 28551dfa6..d4fdaffc1 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java @@ -17,6 +17,7 @@ import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult; import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.briar.R; +import org.briarproject.briar.android.logout.HideUiActivity; import org.briarproject.briar.android.navdrawer.NavDrawerActivity; import java.util.concurrent.CountDownLatch; @@ -28,8 +29,11 @@ import javax.inject.Inject; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static android.app.NotificationManager.IMPORTANCE_NONE; import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; +import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; +import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; +import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION; import static android.os.Build.VERSION.SDK_INT; import static android.support.v4.app.NotificationCompat.CATEGORY_SERVICE; import static android.support.v4.app.NotificationCompat.PRIORITY_MIN; @@ -200,7 +204,29 @@ public class BriarService extends Service { public void onLowMemory() { super.onLowMemory(); LOG.warning("Memory is low"); - // FIXME: Work out what to do about it + shutdownFromBackground(); + } + + private void shutdownFromBackground() { + // Stop the service + stopSelf(); + // Hide the UI + Intent i = new Intent(this, HideUiActivity.class); + i.addFlags(FLAG_ACTIVITY_NEW_TASK + | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS + | FLAG_ACTIVITY_NO_ANIMATION + | FLAG_ACTIVITY_CLEAR_TASK); + startActivity(i); + // Wait for shutdown to complete, then exit + new Thread(() -> { + try { + if (started) lifecycleManager.waitForShutdown(); + } catch (InterruptedException e) { + LOG.info("Interrupted while waiting for shutdown"); + } + LOG.info("Exiting"); + System.exit(0); + }).start(); } /** diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java index 499696182..d557e717f 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java @@ -16,7 +16,7 @@ import org.briarproject.briar.android.controller.BriarController; import org.briarproject.briar.android.controller.DbController; import org.briarproject.briar.android.controller.handler.UiResultHandler; import org.briarproject.briar.android.login.PasswordActivity; -import org.briarproject.briar.android.panic.ExitActivity; +import org.briarproject.briar.android.logout.ExitActivity; import java.util.logging.Logger; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/panic/ExitActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/logout/ExitActivity.java similarity index 92% rename from briar-android/src/main/java/org/briarproject/briar/android/panic/ExitActivity.java rename to briar-android/src/main/java/org/briarproject/briar/android/logout/ExitActivity.java index bd027c39c..78c0a57e9 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/panic/ExitActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/logout/ExitActivity.java @@ -1,4 +1,4 @@ -package org.briarproject.briar.android.panic; +package org.briarproject.briar.android.logout; import android.os.Build; import android.os.Bundle; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/logout/HideUiActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/logout/HideUiActivity.java new file mode 100644 index 000000000..3064993f7 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/logout/HideUiActivity.java @@ -0,0 +1,20 @@ +package org.briarproject.briar.android.logout; + +import android.os.Bundle; + +import org.briarproject.briar.android.activity.ActivityComponent; +import org.briarproject.briar.android.activity.BaseActivity; + +public class HideUiActivity extends BaseActivity { + + @Override + public void onCreate(Bundle state) { + super.onCreate(state); + finish(); + } + + @Override + public void injectActivity(ActivityComponent component) { + + } +} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/fragment/SignOutFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/logout/SignOutFragment.java similarity index 77% rename from briar-android/src/main/java/org/briarproject/briar/android/fragment/SignOutFragment.java rename to briar-android/src/main/java/org/briarproject/briar/android/logout/SignOutFragment.java index 6d122c6df..a0bc31684 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/fragment/SignOutFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/logout/SignOutFragment.java @@ -1,4 +1,4 @@ -package org.briarproject.briar.android.fragment; +package org.briarproject.briar.android.logout; import android.os.Bundle; import android.view.LayoutInflater; @@ -7,7 +7,9 @@ import android.view.ViewGroup; import org.briarproject.briar.R; import org.briarproject.briar.android.activity.ActivityComponent; +import org.briarproject.briar.android.fragment.BaseFragment; +import javax.annotation.Nonnull; import javax.annotation.Nullable; public class SignOutFragment extends BaseFragment { @@ -15,7 +17,7 @@ public class SignOutFragment extends BaseFragment { public static final String TAG = SignOutFragment.class.getName(); @Override - public View onCreateView(LayoutInflater inflater, + public View onCreateView(@Nonnull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_sign_out, container, false); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java index a42a1071c..af09db700 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java @@ -37,7 +37,7 @@ import org.briarproject.briar.android.controller.handler.UiResultHandler; import org.briarproject.briar.android.forum.ForumListFragment; import org.briarproject.briar.android.fragment.BaseFragment; import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener; -import org.briarproject.briar.android.fragment.SignOutFragment; +import org.briarproject.briar.android.logout.SignOutFragment; import org.briarproject.briar.android.navdrawer.NavDrawerController.ExpiryWarning; import org.briarproject.briar.android.privategroup.list.GroupListFragment; import org.briarproject.briar.android.settings.SettingsActivity; From 347868684cf65221a81319dee9b324822f7082e4 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Wed, 21 Mar 2018 14:42:30 +0000 Subject: [PATCH 2/3] Shut down cleanly when device shuts down. --- .../briar/android/BriarService.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java b/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java index d4fdaffc1..46a01180e 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java @@ -4,8 +4,11 @@ import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; +import android.content.BroadcastReceiver; import android.content.ComponentName; +import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.ServiceConnection; import android.os.Binder; import android.os.IBinder; @@ -24,11 +27,13 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Logger; +import javax.annotation.Nullable; import javax.inject.Inject; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static android.app.NotificationManager.IMPORTANCE_NONE; import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; +import static android.content.Intent.ACTION_SHUTDOWN; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; @@ -65,6 +70,9 @@ public class BriarService extends Service { private final AtomicBoolean created = new AtomicBoolean(false); private final Binder binder = new BriarBinder(); + @Nullable + private BroadcastReceiver receiver = null; + @Inject protected DatabaseConfig databaseConfig; // Fields that are accessed from background threads must be volatile @@ -147,6 +155,19 @@ public class BriarService extends Service { } } }.start(); + // Register for device shutdown broadcasts + receiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + LOG.info("Device is shutting down"); + shutdownFromBackground(); + } + }; + IntentFilter filter = new IntentFilter(); + filter.addAction(ACTION_SHUTDOWN); + filter.addAction("android.intent.action.QUICKBOOT_POWEROFF"); + filter.addAction("com.htc.intent.action.QUICKBOOT_POWEROFF"); + registerReceiver(receiver, filter); } private void showStartupFailureNotification(StartResult result) { @@ -191,6 +212,7 @@ public class BriarService extends Service { super.onDestroy(); LOG.info("Destroyed"); stopForeground(true); + if (receiver != null) unregisterReceiver(receiver); // Stop the services in a background thread new Thread() { @Override From 41d3bd4f19ed176ae11ad4aa4d3d40f34f092436 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Thu, 29 Mar 2018 11:45:03 +0100 Subject: [PATCH 3/3] Show notification for low memory shutdown. --- .../briar/android/BriarService.java | 20 +++++++++++++++++++ briar-android/src/main/res/values/strings.xml | 3 +++ 2 files changed, 23 insertions(+) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java b/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java index 46a01180e..4d8ad78c4 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java @@ -22,6 +22,7 @@ import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.briar.R; import org.briarproject.briar.android.logout.HideUiActivity; import org.briarproject.briar.android.navdrawer.NavDrawerActivity; +import org.briarproject.briar.android.splash.SplashScreenActivity; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; @@ -227,6 +228,7 @@ public class BriarService extends Service { super.onLowMemory(); LOG.warning("Memory is low"); shutdownFromBackground(); + showLowMemoryShutdownNotification(); } private void shutdownFromBackground() { @@ -251,6 +253,24 @@ public class BriarService extends Service { }).start(); } + private void showLowMemoryShutdownNotification() { + androidExecutor.runOnUiThread(() -> { + NotificationCompat.Builder b = new NotificationCompat.Builder( + BriarService.this, FAILURE_CHANNEL_ID); + b.setSmallIcon(android.R.drawable.stat_notify_error); + b.setContentTitle(getText( + R.string.low_memory_shutdown_notification_title)); + b.setContentText(getText( + R.string.low_memory_shutdown_notification_text)); + Intent i = new Intent(this, SplashScreenActivity.class); + b.setContentIntent(PendingIntent.getActivity(this, 0, i, 0)); + b.setAutoCancel(true); + Object o = getSystemService(NOTIFICATION_SERVICE); + NotificationManager nm = (NotificationManager) o; + nm.notify(FAILURE_NOTIFICATION_ID, b.build()); + }); + } + /** * Waits for all services to start before returning. */ diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index 1842654de..a4b0b554d 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -415,4 +415,7 @@ QR code Show QR code fullscreen + + Signed out of Briar + Signed out due to lack of memory.