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..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
@@ -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;
@@ -17,19 +20,26 @@ 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 org.briarproject.briar.android.splash.SplashScreenActivity;
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;
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;
@@ -61,6 +71,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
@@ -143,6 +156,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) {
@@ -187,6 +213,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
@@ -200,7 +227,48 @@ public class BriarService extends Service {
public void onLowMemory() {
super.onLowMemory();
LOG.warning("Memory is low");
- // FIXME: Work out what to do about it
+ shutdownFromBackground();
+ showLowMemoryShutdownNotification();
+ }
+
+ 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();
+ }
+
+ 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());
+ });
}
/**
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;
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.