mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-17 05:09:53 +01:00
Merge branch '1190-shutdown-from-background' into 'maintenance-0.16'
Backport: Shut down cleanly when phone is shutting down or memory is low See merge request akwizgran/briar!754
This commit is contained in:
@@ -374,7 +374,12 @@
|
|||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="org.briarproject.briar.android.panic.ExitActivity"
|
android:name="org.briarproject.briar.android.logout.ExitActivity"
|
||||||
|
android:theme="@android:style/Theme.NoDisplay">
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".android.logout.HideUiActivity"
|
||||||
android:theme="@android:style/Theme.NoDisplay">
|
android:theme="@android:style/Theme.NoDisplay">
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,11 @@ import android.app.NotificationChannel;
|
|||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
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.lifecycle.LifecycleManager.StartResult;
|
||||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
|
import org.briarproject.briar.android.logout.HideUiActivity;
|
||||||
import org.briarproject.briar.android.navdrawer.NavDrawerActivity;
|
import org.briarproject.briar.android.navdrawer.NavDrawerActivity;
|
||||||
|
import org.briarproject.briar.android.splash.SplashScreenActivity;
|
||||||
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
|
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
|
||||||
import static android.app.NotificationManager.IMPORTANCE_NONE;
|
import static android.app.NotificationManager.IMPORTANCE_NONE;
|
||||||
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
|
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_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_NEW_TASK;
|
||||||
|
import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
|
||||||
import static android.os.Build.VERSION.SDK_INT;
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
import static android.support.v4.app.NotificationCompat.CATEGORY_SERVICE;
|
import static android.support.v4.app.NotificationCompat.CATEGORY_SERVICE;
|
||||||
import static android.support.v4.app.NotificationCompat.PRIORITY_MIN;
|
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 AtomicBoolean created = new AtomicBoolean(false);
|
||||||
private final Binder binder = new BriarBinder();
|
private final Binder binder = new BriarBinder();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private BroadcastReceiver receiver = null;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected DatabaseConfig databaseConfig;
|
protected DatabaseConfig databaseConfig;
|
||||||
// Fields that are accessed from background threads must be volatile
|
// Fields that are accessed from background threads must be volatile
|
||||||
@@ -143,6 +156,19 @@ public class BriarService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.start();
|
}.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) {
|
private void showStartupFailureNotification(StartResult result) {
|
||||||
@@ -187,6 +213,7 @@ public class BriarService extends Service {
|
|||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
LOG.info("Destroyed");
|
LOG.info("Destroyed");
|
||||||
stopForeground(true);
|
stopForeground(true);
|
||||||
|
if (receiver != null) unregisterReceiver(receiver);
|
||||||
// Stop the services in a background thread
|
// Stop the services in a background thread
|
||||||
new Thread() {
|
new Thread() {
|
||||||
@Override
|
@Override
|
||||||
@@ -200,7 +227,48 @@ public class BriarService extends Service {
|
|||||||
public void onLowMemory() {
|
public void onLowMemory() {
|
||||||
super.onLowMemory();
|
super.onLowMemory();
|
||||||
LOG.warning("Memory is low");
|
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());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import org.briarproject.briar.android.controller.BriarController;
|
|||||||
import org.briarproject.briar.android.controller.DbController;
|
import org.briarproject.briar.android.controller.DbController;
|
||||||
import org.briarproject.briar.android.controller.handler.UiResultHandler;
|
import org.briarproject.briar.android.controller.handler.UiResultHandler;
|
||||||
import org.briarproject.briar.android.login.PasswordActivity;
|
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;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.briar.android.panic;
|
package org.briarproject.briar.android.logout;
|
||||||
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.briar.android.fragment;
|
package org.briarproject.briar.android.logout;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -7,7 +7,9 @@ import android.view.ViewGroup;
|
|||||||
|
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class SignOutFragment extends BaseFragment {
|
public class SignOutFragment extends BaseFragment {
|
||||||
@@ -15,7 +17,7 @@ public class SignOutFragment extends BaseFragment {
|
|||||||
public static final String TAG = SignOutFragment.class.getName();
|
public static final String TAG = SignOutFragment.class.getName();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater,
|
public View onCreateView(@Nonnull LayoutInflater inflater,
|
||||||
@Nullable ViewGroup container,
|
@Nullable ViewGroup container,
|
||||||
@Nullable Bundle savedInstanceState) {
|
@Nullable Bundle savedInstanceState) {
|
||||||
return inflater.inflate(R.layout.fragment_sign_out, container, false);
|
return inflater.inflate(R.layout.fragment_sign_out, container, false);
|
||||||
@@ -37,7 +37,7 @@ import org.briarproject.briar.android.controller.handler.UiResultHandler;
|
|||||||
import org.briarproject.briar.android.forum.ForumListFragment;
|
import org.briarproject.briar.android.forum.ForumListFragment;
|
||||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
|
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.navdrawer.NavDrawerController.ExpiryWarning;
|
||||||
import org.briarproject.briar.android.privategroup.list.GroupListFragment;
|
import org.briarproject.briar.android.privategroup.list.GroupListFragment;
|
||||||
import org.briarproject.briar.android.settings.SettingsActivity;
|
import org.briarproject.briar.android.settings.SettingsActivity;
|
||||||
|
|||||||
@@ -415,4 +415,7 @@
|
|||||||
<string name="qr_code">QR code</string>
|
<string name="qr_code">QR code</string>
|
||||||
<string name="show_qr_code_fullscreen">Show QR code fullscreen</string>
|
<string name="show_qr_code_fullscreen">Show QR code fullscreen</string>
|
||||||
|
|
||||||
|
<!-- Low Memory Notification -->
|
||||||
|
<string name="low_memory_shutdown_notification_title">Signed out of Briar</string>
|
||||||
|
<string name="low_memory_shutdown_notification_text">Signed out due to lack of memory.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user