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 652ef527d4325294c8e9c69eb4ea4877ad501e25..763c50332da6d0ff26bf6ee5f683281c1900b95f 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.briar.BriarCoreEagerSingletons; import org.briarproject.briar.BriarCoreModule; import org.briarproject.briar.android.reporting.BriarReportSender; import org.briarproject.briar.api.android.AndroidNotificationManager; +import org.briarproject.briar.api.android.DozeWatchdog; import org.briarproject.briar.api.android.ScreenFilterMonitor; import org.briarproject.briar.api.blog.BlogManager; import org.briarproject.briar.api.blog.BlogPostFactory; @@ -140,6 +141,8 @@ public interface AndroidComponent TestDataCreator testDataCreator(); + DozeWatchdog dozeWatchdog(); + @IoExecutor Executor ioExecutor(); 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 725a690475b0249b1b2456cbd6f425fcecfde02f..c0e06897655f5c442ed6473a00814ad2e8673533 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 @@ -15,6 +15,7 @@ import org.briarproject.bramble.api.reporting.DevConfig; import org.briarproject.bramble.api.ui.UiCallback; import org.briarproject.bramble.util.StringUtils; import org.briarproject.briar.api.android.AndroidNotificationManager; +import org.briarproject.briar.api.android.DozeWatchdog; import org.briarproject.briar.api.android.ReferenceManager; import org.briarproject.briar.api.android.ScreenFilterMonitor; @@ -40,6 +41,8 @@ public class AppModule { AndroidNotificationManager androidNotificationManager; @Inject NetworkUsageLogger networkUsageLogger; + @Inject + DozeWatchdog dozeWatchdog; } private final Application application; @@ -183,4 +186,12 @@ public class AppModule { lifecycleManager.registerService(networkUsageLogger); return networkUsageLogger; } + + @Provides + @Singleton + DozeWatchdog provideDozeWatchdog(LifecycleManager lifecycleManager) { + DozeWatchdogImpl dozeWatchdog = new DozeWatchdogImpl(application); + lifecycleManager.registerService(dozeWatchdog); + return dozeWatchdog; + } } 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 2ac0c3e3e60166d5e6de8da51e0cef53ce0d7773..0e6bb7c399b79d68f0bc942164f8d0b4013b6125 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 @@ -3,16 +3,12 @@ package org.briarproject.briar.android; 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.Build; import android.os.IBinder; -import android.os.PowerManager; -import android.support.annotation.Nullable; import android.support.v4.app.NotificationCompat; import android.support.v4.content.ContextCompat; @@ -32,15 +28,12 @@ import javax.inject.Inject; import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; 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.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED; 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.VISIBILITY_SECRET; import static java.util.logging.Level.WARNING; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.ALREADY_RUNNING; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SUCCESS; -import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting; public class BriarService extends Service { @@ -52,8 +45,6 @@ public class BriarService extends Service { private final AtomicBoolean created = new AtomicBoolean(false); private final Binder binder = new BriarBinder(); - @Nullable - private BriarBroadcastReceiver receiver = null; @Inject protected DatabaseConfig databaseConfig; @@ -62,7 +53,7 @@ public class BriarService extends Service { protected volatile LifecycleManager lifecycleManager; @Inject protected volatile AndroidExecutor androidExecutor; - private volatile boolean started = false, hasDozed = false; + private volatile boolean started = false; @Override public void onCreate() { @@ -93,7 +84,7 @@ public class BriarService extends Service { Intent i = new Intent(this, NavDrawerActivity.class); i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP); b.setContentIntent(PendingIntent.getActivity(this, 0, i, 0)); - if (SDK_INT >= 21) { + if (Build.VERSION.SDK_INT >= 21) { b.setCategory(CATEGORY_SERVICE); b.setVisibility(VISIBILITY_SECRET); } @@ -118,7 +109,6 @@ public class BriarService extends Service { } } }.start(); - registerBroadcastReceiver(); } private void showStartupFailureNotification(StartResult result) { @@ -163,7 +153,6 @@ public class BriarService extends Service { public void onDestroy() { super.onDestroy(); LOG.info("Destroyed"); - if (receiver != null) unregisterReceiver(receiver); stopForeground(true); // Stop the services in a background thread new Thread() { @@ -181,21 +170,6 @@ public class BriarService extends Service { // FIXME: Work out what to do about it } - private void registerBroadcastReceiver() { - if (SDK_INT < 23) return; - IntentFilter filter = new IntentFilter(ACTION_DEVICE_IDLE_MODE_CHANGED); - receiver = new BriarBroadcastReceiver(); - registerReceiver(receiver, filter); - } - - public boolean hasDozed() { - return hasDozed; - } - - public void resetDozeFlag() { - hasDozed = false; - } - /** * Waits for all services to start before returning. */ @@ -251,15 +225,4 @@ public class BriarService extends Service { return binder; } } - - public class BriarBroadcastReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - if (SDK_INT < 23 || !needsDozeWhitelisting(getApplicationContext())) - return; - PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE); - if (pm.isDeviceIdleMode()) hasDozed = true; - } - } - } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/DozeWatchdogImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/DozeWatchdogImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..9b104ca0f805727b84dbc15e0f271d673fb4e8be --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/DozeWatchdogImpl.java @@ -0,0 +1,56 @@ +package org.briarproject.briar.android; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.PowerManager; + +import org.briarproject.bramble.api.lifecycle.Service; +import org.briarproject.bramble.api.lifecycle.ServiceException; +import org.briarproject.briar.api.android.DozeWatchdog; + +import java.util.concurrent.atomic.AtomicBoolean; + +import static android.content.Context.POWER_SERVICE; +import static android.os.Build.VERSION.SDK_INT; +import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED; + +class DozeWatchdogImpl implements DozeWatchdog, Service { + + private final Context appContext; + private final AtomicBoolean dozed = new AtomicBoolean(false); + private final BroadcastReceiver receiver = new DozeBroadcastReceiver(); + + DozeWatchdogImpl(Context appContext) { + this.appContext = appContext; + } + + @Override + public boolean getAndResetDozeFlag() { + return dozed.getAndSet(false); + } + + @Override + public void startService() throws ServiceException { + if (SDK_INT < 23) return; + IntentFilter filter = new IntentFilter(ACTION_DEVICE_IDLE_MODE_CHANGED); + appContext.registerReceiver(receiver, filter); + } + + @Override + public void stopService() throws ServiceException { + appContext.unregisterReceiver(receiver); + } + + private class DozeBroadcastReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + if (SDK_INT < 23) return; + PowerManager pm = + (PowerManager) appContext.getSystemService(POWER_SERVICE); + if (pm.isDeviceIdleMode()) dozed.set(true); + } + } +} 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 64cc194f3e179eac48cb9cbb3ea298ed89789a7a..d00730f2448db7b361072965692d5a51ae09178d 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 @@ -2,7 +2,6 @@ package org.briarproject.briar.android.activity; import android.annotation.SuppressLint; import android.content.Intent; -import android.os.Build; import android.support.v7.app.ActionBar; import android.support.v7.app.AlertDialog; import android.support.v7.widget.Toolbar; @@ -28,6 +27,7 @@ import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK; 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 org.briarproject.briar.android.activity.RequestCodes.REQUEST_DOZE_WHITELISTING; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PASSWORD; import static org.briarproject.briar.android.util.UiUtils.getDozeWhitelistingIntent; @@ -64,7 +64,7 @@ public abstract class BriarActivity extends BaseActivity { if (!briarController.hasEncryptionKey() && !isFinishing()) { Intent i = new Intent(this, PasswordActivity.class); startActivityForResult(i, REQUEST_PASSWORD); - } else { + } else if (SDK_INT >= 23) { briarController.hasDozed(new UiResultHandler<Boolean>(this) { @Override public void onResultUi(Boolean result) { @@ -78,7 +78,7 @@ public abstract class BriarActivity extends BaseActivity { } public void setSceneTransitionAnimation() { - if (Build.VERSION.SDK_INT < 21) return; + if (SDK_INT < 21) return; Transition slide = new Slide(Gravity.RIGHT); slide.excludeTarget(android.R.id.statusBarBackground, true); slide.excludeTarget(android.R.id.navigationBarBackground, true); @@ -160,7 +160,7 @@ public abstract class BriarActivity extends BaseActivity { } private void finishAndExit() { - if (Build.VERSION.SDK_INT >= 21) finishAndRemoveTask(); + if (SDK_INT >= 21) finishAndRemoveTask(); else supportFinishAfterTransition(); LOG.info("Exiting"); System.exit(0); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/BriarControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/BriarControllerImpl.java index 9ecd35e915d67542dffb2c94e169b27a4476c6d2..a8d90dd0cc98a9162e9a1eaed234e53e404ad5c1 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/controller/BriarControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/BriarControllerImpl.java @@ -4,8 +4,6 @@ import android.app.Activity; import android.content.Intent; import android.os.IBinder; import android.support.annotation.CallSuper; -import android.support.annotation.Nullable; -import android.support.annotation.WorkerThread; import org.briarproject.bramble.api.db.DatabaseConfig; import org.briarproject.bramble.api.db.DatabaseExecutor; @@ -15,6 +13,7 @@ import org.briarproject.bramble.api.settings.SettingsManager; import org.briarproject.briar.android.BriarService; import org.briarproject.briar.android.BriarService.BriarServiceConnection; import org.briarproject.briar.android.controller.handler.ResultHandler; +import org.briarproject.briar.api.android.DozeWatchdog; import java.util.concurrent.Executor; import java.util.logging.Logger; @@ -37,22 +36,22 @@ public class BriarControllerImpl implements BriarController { @DatabaseExecutor private final Executor databaseExecutor; private final SettingsManager settingsManager; + private final DozeWatchdog dozeWatchdog; private final Activity activity; private boolean bound = false; - @Nullable - private volatile BriarService service; - @Inject BriarControllerImpl(BriarServiceConnection serviceConnection, DatabaseConfig databaseConfig, @DatabaseExecutor Executor databaseExecutor, - SettingsManager settingsManager, Activity activity) { + SettingsManager settingsManager, DozeWatchdog dozeWatchdog, + Activity activity) { this.serviceConnection = serviceConnection; this.databaseConfig = databaseConfig; this.databaseExecutor = databaseExecutor; this.settingsManager = settingsManager; + this.dozeWatchdog = dozeWatchdog; this.activity = activity; } @@ -81,15 +80,6 @@ public class BriarControllerImpl implements BriarController { activity.startService(new Intent(activity, BriarService.class)); bound = activity.bindService(new Intent(activity, BriarService.class), serviceConnection, 0); - if (!bound) throw new IllegalStateException(); - - new Thread(() -> { - try { - service = getBriarService(); - } catch (InterruptedException e) { - LOG.warning("Interrupted while waiting for service"); - } - }).start(); } @Override @@ -99,13 +89,11 @@ public class BriarControllerImpl implements BriarController { @Override public void hasDozed(ResultHandler<Boolean> handler) { - BriarService briarService = service; - if (briarService == null || !briarService.hasDozed() || - !needsDozeWhitelisting(activity)) { + if (!dozeWatchdog.getAndResetDozeFlag() + || !needsDozeWhitelisting(activity)) { handler.onResult(false); return; } - if (briarService.hasDozed()) briarService.resetDozeFlag(); databaseExecutor.execute(() -> { try { Settings settings = @@ -137,11 +125,12 @@ public class BriarControllerImpl implements BriarController { public void signOut(ResultHandler<Void> eventHandler) { new Thread() { @Override - @SuppressWarnings("ConstantConditions") public void run() { try { - if (service == null) service = getBriarService(); // Wait for the service to finish starting up + IBinder binder = serviceConnection.waitForBinder(); + BriarService service = + ((BriarService.BriarBinder) binder).getService(); service.waitForStartup(); // Shut down the service and wait for it to shut down LOG.info("Shutting down service"); @@ -155,12 +144,6 @@ public class BriarControllerImpl implements BriarController { }.start(); } - @WorkerThread - private BriarService getBriarService() throws InterruptedException { - IBinder binder = serviceConnection.waitForBinder(); - return ((BriarService.BriarBinder) binder).getService(); - } - private void unbindService() { if (bound) activity.unbindService(serviceConnection); } diff --git a/briar-android/src/main/java/org/briarproject/briar/api/android/DozeWatchdog.java b/briar-android/src/main/java/org/briarproject/briar/api/android/DozeWatchdog.java new file mode 100644 index 0000000000000000000000000000000000000000..9b37aebff0af6407657c693f471f64a8f28189e0 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/api/android/DozeWatchdog.java @@ -0,0 +1,6 @@ +package org.briarproject.briar.api.android; + +public interface DozeWatchdog { + + boolean getAndResetDozeFlag(); +}