diff --git a/briar-android/build.gradle b/briar-android/build.gradle
index edfe7ba99..b5e256f8e 100644
--- a/briar-android/build.gradle
+++ b/briar-android/build.gradle
@@ -40,9 +40,9 @@ dependencies {
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
- testImplementation 'org.robolectric:robolectric:3.5.1'
- testImplementation 'org.robolectric:shadows-support-v4:3.0'
- testImplementation 'org.mockito:mockito-core:2.8.9'
+ testImplementation 'org.robolectric:robolectric:3.8'
+ testImplementation 'org.robolectric:shadows-support-v4:3.3.2'
+ testImplementation 'org.mockito:mockito-core:2.13.0'
testImplementation 'junit:junit:4.12'
testImplementation "org.jmock:jmock:2.8.2"
testImplementation "org.jmock:jmock-junit4:2.8.2"
@@ -165,8 +165,8 @@ dependencyVerification {
'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
'nekohtml:nekohtml:1.9.6.2:nekohtml-1.9.6.2.jar:fdff6cfa9ed9cc911c842a5d2395f209ec621ef1239d46810e9e495809d3ae09',
'nekohtml:xercesMinimal:1.9.6.2:xercesMinimal-1.9.6.2.jar:95b8b357d19f63797dd7d67622fd3f18374d64acbc6584faba1c7759a31e8438',
- 'net.bytebuddy:byte-buddy-agent:1.6.14:byte-buddy-agent-1.6.14.jar:c141a2d6809c3eeff4a43d25992826abccebdd4b793af3e7a5f346e88ae73a33',
- 'net.bytebuddy:byte-buddy:1.6.14:byte-buddy-1.6.14.jar:917758b3c651e278a15a029ba1d42dbf802d8b0e1fe2aa4b81c5750c64f461c1',
+ 'net.bytebuddy:byte-buddy-agent:1.7.9:byte-buddy-agent-1.7.9.jar:ac1a993befb528c3271a83a9ad9c42d363d399e9deb26e0470e3c4962066c550',
+ 'net.bytebuddy:byte-buddy:1.7.9:byte-buddy-1.7.9.jar:2ea2ada12b790d16ac7f6e6c065cb55cbcdb6ba519355f5958851159cad3b16a',
'net.sf.jopt-simple:jopt-simple:4.9:jopt-simple-4.9.jar:26c5856e954b5f864db76f13b86919b59c6eecf9fd930b96baa8884626baf2f5',
'net.sf.kxml:kxml2:2.3.0:kxml2-2.3.0.jar:f264dd9f79a1fde10ce5ecc53221eff24be4c9331c830b7d52f2f08a7b633de2',
'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d',
@@ -215,8 +215,8 @@ dependencyVerification {
'org.jmock:jmock-testjar:2.8.2:jmock-testjar-2.8.2.jar:8900860f72c474e027cf97fe78dcbf154a1aa7fc62b6845c5fb4e4f3c7bc8760',
'org.jmock:jmock:2.8.2:jmock-2.8.2.jar:6c73cb4a2e6dbfb61fd99c9a768539c170ab6568e57846bd60dbf19596b65b16',
'org.jvnet.staxex:stax-ex:1.7.7:stax-ex-1.7.7.jar:a31ff7d77163c0deb09e7fee59ad35ae44c2cee2cc8552a116ccd1583d813fb4',
- 'org.mockito:mockito-core:2.8.9:mockito-core-2.8.9.jar:a2bb9b8b40d81bb02ccb84259524c0f4911f73c6577bfc7ddd940b8fc729b6e6',
- 'org.objenesis:objenesis:2.5:objenesis-2.5.jar:293328e1b0d31ed30bb89fca542b6c52fac00989bb0e62eb9d98d630c4dd6b7c',
+ 'org.mockito:mockito-core:2.13.0:mockito-core-2.13.0.jar:92a746b37cf8c5730a5e7b35fd7d8cd72700089435ff92ee03ed8384d4eb3377',
+ 'org.objenesis:objenesis:2.6:objenesis-2.6.jar:5e168368fbc250af3c79aa5fef0c3467a2d64e5a7bd74005f25d8399aeb0708d',
'org.ow2.asm:asm-analysis:5.1:asm-analysis-5.1.jar:a34658f5c5de4b573eef21131cc32cc25f7b66407944f312b28ec2e56abb1fa9',
'org.ow2.asm:asm-commons:5.0.1:asm-commons-5.0.1.jar:fb1cb7fa27d892712ced8fbf8d027eb5052ecd3999dba1ba47824357accb40e7',
'org.ow2.asm:asm-commons:5.1:asm-commons-5.1.jar:97b3786e1f55e74bddf8ad102bf50e33bbcbc1f6b7fd7b36f0bbbb25cd4981be',
@@ -225,15 +225,15 @@ dependencyVerification {
'org.ow2.asm:asm-util:5.1:asm-util-5.1.jar:ee032c39ae5e3cd099148fbba9a2124f9ed613e5cb93e03ee0fa8808ce364040',
'org.ow2.asm:asm:5.0.4:asm-5.0.4.jar:896618ed8ae62702521a78bc7be42b7c491a08e6920a15f89a3ecdec31e9a220',
'org.ow2.asm:asm:5.1:asm-5.1.jar:d2da399a9967c69f0a21739256fa79d284222c223082cacadc17372244764b54',
- 'org.robolectric:annotations:3.5.1:annotations-3.5.1.jar:14db0f7d2299c5400ff7764bb37b4fa80306582d8965fdf6999091723e2384ce',
- 'org.robolectric:junit:3.5.1:junit-3.5.1.jar:b2e81b7d5a22755f2ea76aa9bbbd4359d61c4cb9577193ccfbb8f97378ed293b',
- 'org.robolectric:resources:3.5.1:resources-3.5.1.jar:22a5564590c8bfd8df7efb2b0c7d9942b46a0beb59ba38899d59c1270f293b1c',
- 'org.robolectric:robolectric:3.5.1:robolectric-3.5.1.jar:603cf898f93b854f18021fab452aca3fe482368eeb2e720988ae82212ebcf4b6',
- 'org.robolectric:sandbox:3.5.1:sandbox-3.5.1.jar:beff8c3c1e840e0f7f78aadef170f347bae349f098babfc176765f499a4bcbb5',
- 'org.robolectric:shadowapi:3.5.1:shadowapi-3.5.1.jar:6d574f9ae0922791eb8f06979f0010997d4b862c7aec96d485ae797ddfc13278',
- 'org.robolectric:shadows-framework:3.5.1:shadows-framework-3.5.1.jar:597b54cc1a494799d783921c6ac04352f33e94fca8e00f299d4ca192db79e3fc',
- 'org.robolectric:shadows-support-v4:3.0:shadows-support-v4-3.0.jar:66bcc3257b037d72998e860d67b1bc58215b7eeac8ad860fcc3e613332d88619',
- 'org.robolectric:utils:3.5.1:utils-3.5.1.jar:d7d77326867e6d903156ebb18c244819b26aebe3aa82a1c57081081a0b6c4f63',
+ 'org.robolectric:annotations:3.8:annotations-3.8.jar:8eab08facfe2a8cd22f6a09f4378f012a5985c0d4f4ad4e203e00f75b5568458',
+ 'org.robolectric:junit:3.8:junit-3.8.jar:042575dbc95dc82ec046d13438ccda578917ce786d2f464cba0eb18da1f412cb',
+ 'org.robolectric:resources:3.8:resources-3.8.jar:6d11e6d39df8eda837c52319cf8d6bef424df45be6f29b3a731707832eb6ffc1',
+ 'org.robolectric:robolectric:3.8:robolectric-3.8.jar:34908fc858e6e4113be2cf97fe55d3ffa4462bf7183d466542582ca1898ce60a',
+ 'org.robolectric:sandbox:3.8:sandbox-3.8.jar:cc257dc75c5af9e62a43572ac89dff4d8520427307cf973e6b663c88fb000720',
+ 'org.robolectric:shadowapi:3.8:shadowapi-3.8.jar:28bc24cb5c4b4030852cebebfd5f12536d03088892cb3c8b1d1379297087aca8',
+ 'org.robolectric:shadows-framework:3.8:shadows-framework-3.8.jar:83548db7249edf1af87e1a1f4d8f4eec3e85d6220161da601e6f6398476911b2',
+ 'org.robolectric:shadows-support-v4:3.3.2:shadows-support-v4-3.3.2.jar:6f689264738266e70fe08db7c04b7b5a75155994f4e3f7f311960d90486bf005',
+ 'org.robolectric:utils:3.8:utils-3.8.jar:e945d04d40e37554e02d4be1bc3abf9bede45375c843aa36d10ccb6b63edbf34',
'tools.fastlane:screengrab:1.1.0:screengrab-1.1.0.aar:03ce3868ee8a0082d14e7a1de0999f91531c0cc794392688beb08ee9bc4495fd',
'uk.co.samuelwall:material-tap-target-prompt:2.8.0:material-tap-target-prompt-2.8.0.aar:ac70770c05bbc4675a1d5712c0e53d46ee4fa961b74947589fce50d8003065ec',
'xmlpull:xmlpull:1.1.3.1:xmlpull-1.1.3.1.jar:34e08ee62116071cbb69c0ed70d15a7a5b208d62798c59f2120bb8929324cb63',
diff --git a/briar-android/src/main/AndroidManifest.xml b/briar-android/src/main/AndroidManifest.xml
index 33899a202..82d4b83cf 100644
--- a/briar-android/src/main/AndroidManifest.xml
+++ b/briar-android/src/main/AndroidManifest.xml
@@ -402,5 +402,11 @@
android:theme="@android:style/Theme.NoDisplay">
+
+
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 75b25b099..e531f295c 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
@@ -28,6 +28,7 @@ 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;
+import org.briarproject.briar.api.android.LockManager;
import org.briarproject.briar.api.android.ScreenFilterMonitor;
import org.briarproject.briar.api.blog.BlogManager;
import org.briarproject.briar.api.blog.BlogPostFactory;
@@ -146,6 +147,8 @@ public interface AndroidComponent
AccountManager accountManager();
+ LockManager lockManager();
+
void inject(SignInReminderReceiver briarService);
void inject(BriarService briarService);
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java
index d3ee12a94..d88368f7c 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java
@@ -2,6 +2,7 @@ package org.briarproject.briar.android;
import android.annotation.TargetApi;
import android.app.Application;
+import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -12,7 +13,6 @@ import android.support.annotation.StringRes;
import android.support.annotation.UiThread;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
-import android.support.v4.content.ContextCompat;
import org.briarproject.bramble.api.Multiset;
import org.briarproject.bramble.api.contact.ContactId;
@@ -65,7 +65,6 @@ import javax.inject.Inject;
import static android.app.Notification.DEFAULT_LIGHTS;
import static android.app.Notification.DEFAULT_SOUND;
import static android.app.Notification.DEFAULT_VIBRATE;
-import static android.app.Notification.VISIBILITY_SECRET;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.content.Context.NOTIFICATION_SERVICE;
@@ -73,8 +72,12 @@ 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.CATEGORY_MESSAGE;
+import static android.support.v4.app.NotificationCompat.CATEGORY_SERVICE;
import static android.support.v4.app.NotificationCompat.CATEGORY_SOCIAL;
import static android.support.v4.app.NotificationCompat.PRIORITY_LOW;
+import static android.support.v4.app.NotificationCompat.PRIORITY_MIN;
+import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET;
+import static android.support.v4.content.ContextCompat.getColor;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.android.activity.BriarActivity.GROUP_ID;
@@ -173,8 +176,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
nc.setLockscreenVisibility(VISIBILITY_SECRET);
nc.enableVibration(true);
nc.enableLights(true);
- nc.setLightColor(
- ContextCompat.getColor(appContext, R.color.briar_green_light));
+ nc.setLightColor(getColor(appContext, R.color.briar_green_light));
notificationManager.createNotificationChannel(nc);
}
@@ -271,6 +273,47 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
});
}
+ @UiThread
+ @Override
+ public Notification getForegroundNotification() {
+ return getForegroundNotification(false);
+ }
+
+ @UiThread
+ private Notification getForegroundNotification(boolean locked) {
+ int title = locked ? R.string.lock_is_locked :
+ R.string.ongoing_notification_title;
+ int text = locked ? R.string.lock_tap_to_unlock :
+ R.string.ongoing_notification_text;
+ int icon = locked ? R.drawable.startup_lock :
+ R.drawable.notification_ongoing;
+ // Ongoing foreground notification that shows BriarService is running
+ NotificationCompat.Builder b =
+ new NotificationCompat.Builder(appContext, ONGOING_CHANNEL_ID);
+ b.setSmallIcon(icon);
+ b.setColor(getColor(appContext, R.color.briar_primary));
+ b.setContentTitle(appContext.getText(title));
+ b.setContentText(appContext.getText(text));
+ b.setWhen(0); // Don't show the time
+ b.setOngoing(true);
+ Intent i = new Intent(appContext, NavDrawerActivity.class);
+ i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP);
+ b.setContentIntent(PendingIntent.getActivity(appContext, 0, i, 0));
+ if (SDK_INT >= 21) {
+ b.setCategory(CATEGORY_SERVICE);
+ b.setVisibility(VISIBILITY_SECRET);
+ }
+ b.setPriority(PRIORITY_MIN);
+ return b.build();
+ }
+
+ @UiThread
+ @Override
+ public void updateForegroundNotification(boolean locked) {
+ Notification n = getForegroundNotification(locked);
+ notificationManager.notify(ONGOING_NOTIFICATION_ID, n);
+ }
+
private void showContactNotification(ContactId c) {
androidExecutor.runOnUiThread(() -> {
if (blockContacts) return;
@@ -636,7 +679,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
NotificationCompat.Builder b =
new NotificationCompat.Builder(appContext, REMINDER_CHANNEL_ID);
b.setSmallIcon(R.drawable.ic_signout);
- b.setColor(ContextCompat.getColor(appContext, R.color.briar_primary));
+ b.setColor(getColor(appContext, R.color.briar_primary));
b.setContentTitle(
appContext.getText(R.string.reminder_notification_title));
b.setContentText(
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 9f4ba2d14..3c3512281 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
@@ -29,8 +29,10 @@ import org.briarproject.bramble.plugin.tor.AndroidTorPluginFactory;
import org.briarproject.bramble.plugin.tor.CircumventionProvider;
import org.briarproject.bramble.util.AndroidUtils;
import org.briarproject.bramble.util.StringUtils;
+import org.briarproject.briar.android.account.LockManagerImpl;
import org.briarproject.briar.api.android.AndroidNotificationManager;
import org.briarproject.briar.api.android.DozeWatchdog;
+import org.briarproject.briar.api.android.LockManager;
import org.briarproject.briar.api.android.ScreenFilterMonitor;
import java.io.File;
@@ -200,4 +202,13 @@ public class AppModule {
return dozeWatchdog;
}
+ @Provides
+ @Singleton
+ LockManager provideLockManager(LifecycleManager lifecycleManager,
+ EventBus eventBus, LockManagerImpl lockManager) {
+ lifecycleManager.registerService(lockManager);
+ eventBus.addListener(lockManager);
+ return lockManager;
+ }
+
}
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 022fa3195..7aa0371fe 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
@@ -2,6 +2,7 @@ package org.briarproject.briar.android;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
+import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -15,7 +16,6 @@ import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
-import android.support.v4.content.ContextCompat;
import org.briarproject.bramble.api.account.AccountManager;
import org.briarproject.bramble.api.crypto.SecretKey;
@@ -25,6 +25,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.api.android.AndroidNotificationManager;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -44,8 +45,6 @@ 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;
import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
@@ -74,6 +73,8 @@ public class BriarService extends Service {
@Nullable
private BroadcastReceiver receiver = null;
+ @Inject
+ AndroidNotificationManager notificationManager;
@Inject
AccountManager accountManager;
@@ -121,24 +122,9 @@ public class BriarService extends Service {
failureChannel.setLockscreenVisibility(VISIBILITY_SECRET);
nm.createNotificationChannel(failureChannel);
}
- // Show an ongoing notification that the service is running
- NotificationCompat.Builder b =
- new NotificationCompat.Builder(this, ONGOING_CHANNEL_ID);
- b.setSmallIcon(R.drawable.notification_ongoing);
- b.setColor(ContextCompat.getColor(this, R.color.briar_primary));
- b.setContentTitle(getText(R.string.ongoing_notification_title));
- b.setContentText(getText(R.string.ongoing_notification_text));
- b.setWhen(0); // Don't show the time
- b.setOngoing(true);
- 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) {
- b.setCategory(CATEGORY_SERVICE);
- b.setVisibility(VISIBILITY_SECRET);
- }
- b.setPriority(PRIORITY_MIN);
- startForeground(ONGOING_NOTIFICATION_ID, b.build());
+ Notification foregroundNotification =
+ notificationManager.getForegroundNotification();
+ startForeground(ONGOING_NOTIFICATION_ID, foregroundNotification);
// Start the services in a background thread
new Thread(() -> {
StartResult result = lifecycleManager.startServices(dbKey);
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/TestingConstants.java b/briar-android/src/main/java/org/briarproject/briar/android/TestingConstants.java
index ea67d50ec..bbcab474b 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/TestingConstants.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/TestingConstants.java
@@ -40,4 +40,9 @@ public interface TestingConstants {
* Feature flag for enabling the sign-in reminder in release builds.
*/
boolean FEATURE_FLAG_SIGN_IN_REMINDER = IS_DEBUG_BUILD;
+
+ /**
+ * Feature flag for enabling the PIN lock in release builds.
+ */
+ boolean FEATURE_FLAG_PIN_LOCK = IS_DEBUG_BUILD;
}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/LockManagerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/account/LockManagerImpl.java
new file mode 100644
index 000000000..562ea9588
--- /dev/null
+++ b/briar-android/src/main/java/org/briarproject/briar/android/account/LockManagerImpl.java
@@ -0,0 +1,132 @@
+package org.briarproject.briar.android.account;
+
+import android.app.Application;
+import android.arch.lifecycle.LiveData;
+import android.arch.lifecycle.MutableLiveData;
+import android.content.Context;
+import android.support.annotation.UiThread;
+
+import org.briarproject.bramble.api.db.DatabaseExecutor;
+import org.briarproject.bramble.api.db.DbException;
+import org.briarproject.bramble.api.event.Event;
+import org.briarproject.bramble.api.event.EventListener;
+import org.briarproject.bramble.api.lifecycle.Service;
+import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
+import org.briarproject.bramble.api.settings.Settings;
+import org.briarproject.bramble.api.settings.SettingsManager;
+import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent;
+import org.briarproject.briar.api.android.AndroidNotificationManager;
+import org.briarproject.briar.api.android.LockManager;
+
+import java.util.concurrent.Executor;
+import java.util.logging.Logger;
+
+import javax.annotation.concurrent.ThreadSafe;
+import javax.inject.Inject;
+
+import static java.util.logging.Level.WARNING;
+import static org.briarproject.bramble.util.LogUtils.logException;
+import static org.briarproject.briar.android.settings.SettingsFragment.PREF_SCREEN_LOCK;
+import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE;
+import static org.briarproject.briar.android.util.UiUtils.hasScreenLock;
+
+@ThreadSafe
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
+public class LockManagerImpl implements LockManager, Service, EventListener {
+
+ private static final Logger LOG =
+ Logger.getLogger(LockManagerImpl.class.getName());
+
+ private final Context appContext;
+ private final SettingsManager settingsManager;
+ private final AndroidNotificationManager notificationManager;
+ @DatabaseExecutor
+ private final Executor dbExecutor;
+
+ private volatile boolean locked = false;
+ private volatile boolean lockableSetting = false;
+ private final MutableLiveData lockable = new MutableLiveData<>();
+
+ @Inject
+ public LockManagerImpl(Application app, SettingsManager settingsManager,
+ AndroidNotificationManager notificationManager,
+ @DatabaseExecutor Executor dbExecutor) {
+ this.appContext = app.getApplicationContext();
+ this.settingsManager = settingsManager;
+ this.notificationManager = notificationManager;
+ this.dbExecutor = dbExecutor;
+
+ // setting this in the constructor makes #getValue() @NonNull
+ this.lockable.setValue(false);
+ }
+
+ @Override
+ public void startService() {
+ // only load the setting here, because database isn't open before
+ loadLockableSetting();
+ }
+
+ @Override
+ public void stopService() {
+ }
+
+ @Override
+ public LiveData isLockable() {
+ return lockable;
+ }
+
+ @UiThread
+ @Override
+ public void checkIfLockable() {
+ boolean oldValue = lockable.getValue();
+ boolean newValue = hasScreenLock(appContext) && lockableSetting;
+ if (oldValue != newValue) {
+ this.lockable.setValue(newValue);
+ }
+ }
+
+ @Override
+ public boolean isLocked() {
+ if (locked && !hasScreenLock(appContext)) {
+ lockable.postValue(false);
+ locked = false;
+ }
+ return locked;
+ }
+
+ @Override
+ public void setLocked(boolean locked) {
+ this.locked = locked;
+ notificationManager.updateForegroundNotification(locked);
+ }
+
+ @Override
+ public void eventOccurred(Event event) {
+ if (event instanceof SettingsUpdatedEvent) {
+ SettingsUpdatedEvent e = (SettingsUpdatedEvent) event;
+ String namespace = e.getNamespace();
+ if (namespace.equals(SETTINGS_NAMESPACE)) {
+ loadLockableSetting();
+ }
+ }
+ }
+
+ private void loadLockableSetting() {
+ dbExecutor.execute(() -> {
+ try {
+ Settings settings =
+ settingsManager.getSettings(SETTINGS_NAMESPACE);
+ lockableSetting = settings.getBoolean(PREF_SCREEN_LOCK, false);
+ boolean newValue = hasScreenLock(appContext) && lockableSetting;
+ lockable.postValue(newValue);
+ } catch (DbException e) {
+ logException(LOG, WARNING, e);
+ lockableSetting = false;
+ lockable.postValue(false);
+ }
+ });
+ }
+
+}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java
index 1d92a31f3..8a8abb9f8 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java
@@ -37,6 +37,7 @@ import org.briarproject.briar.android.login.OpenDatabaseActivity;
import org.briarproject.briar.android.login.PasswordActivity;
import org.briarproject.briar.android.login.PasswordFragment;
import org.briarproject.briar.android.login.SetupActivity;
+import org.briarproject.briar.android.login.UnlockActivity;
import org.briarproject.briar.android.navdrawer.NavDrawerActivity;
import org.briarproject.briar.android.panic.PanicPreferencesActivity;
import org.briarproject.briar.android.panic.PanicResponderActivity;
@@ -163,6 +164,8 @@ public interface ActivityComponent {
void inject(StartupFailureActivity activity);
+ void inject(UnlockActivity activity);
+
// Fragments
void inject(AuthorNameFragment fragment);
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 cf71839f9..77c6b4132 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,9 @@ 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.login.UnlockActivity;
import org.briarproject.briar.android.logout.ExitActivity;
+import org.briarproject.briar.api.android.LockManager;
import java.util.logging.Logger;
@@ -30,6 +32,7 @@ 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.activity.RequestCodes.REQUEST_UNLOCK;
import static org.briarproject.briar.android.util.UiUtils.getDozeWhitelistingIntent;
import static org.briarproject.briar.android.util.UiUtils.isSamsung7;
@@ -44,26 +47,43 @@ public abstract class BriarActivity extends BaseActivity {
@Inject
BriarController briarController;
-
@Deprecated
@Inject
DbController dbController;
+ @Inject
+ protected LockManager lockManager;
@Override
protected void onActivityResult(int request, int result, Intent data) {
super.onActivityResult(request, result, data);
- if (request == REQUEST_PASSWORD) {
- if (result == RESULT_OK) briarController.startAndBindService();
- else supportFinishAfterTransition();
+ if (request == REQUEST_PASSWORD && result == RESULT_OK) {
+ // PasswordActivity finishes when password was entered correctly.
+ // When back button is pressed there, it will bring itself back,
+ // so that we never arrive here with a result that is not OK.
+ briarController.startAndBindService();
+ } else if (request == REQUEST_UNLOCK && result != RESULT_OK) {
+ // We arrive here, if the user presses 'back'
+ // in the Keyguard unlock screen, because UnlockActivity finishes.
+ // If we don't finish here, isFinishing will be false in onResume()
+ // and we launch a new UnlockActivity causing a loop.
+ supportFinishAfterTransition();
+ // If the result is OK, we don't need to do anything here
+ // and can resume normally.
}
}
@Override
- public void onStart() {
- super.onStart();
- if (!briarController.accountSignedIn() && !isFinishing()) {
+ public void onResume() {
+ super.onResume();
+ if (!briarController.accountSignedIn()) {
Intent i = new Intent(this, PasswordActivity.class);
startActivityForResult(i, REQUEST_PASSWORD);
+ } else if (lockManager.isLocked() && !isFinishing()) {
+ // Also check that the activity isn't finishing already.
+ // This is possible if finishing in onActivityResult().
+ // Failure to do this check would cause an UnlockActivity loop.
+ Intent i = new Intent(this, UnlockActivity.class);
+ startActivityForResult(i, REQUEST_UNLOCK);
} else if (SDK_INT >= 23) {
briarController.hasDozed(new UiResultHandler(this) {
@Override
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/RequestCodes.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/RequestCodes.java
index 4b8caa3d2..f3d72d17c 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/activity/RequestCodes.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/RequestCodes.java
@@ -12,5 +12,7 @@ public interface RequestCodes {
int REQUEST_PERMISSION_CAMERA = 8;
int REQUEST_DOZE_WHITELISTING = 9;
int REQUEST_ENABLE_BLUETOOTH = 10;
+ int REQUEST_UNLOCK = 11;
+ int REQUEST_KEYGUARD_UNLOCK = 12;
}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordActivity.java
index 5326cf3db..629d0fc97 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordActivity.java
@@ -23,8 +23,6 @@ import org.briarproject.briar.api.android.AndroidNotificationManager;
import javax.inject.Inject;
-import static android.content.Intent.ACTION_MAIN;
-import static android.content.Intent.CATEGORY_HOME;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.view.View.INVISIBLE;
@@ -109,10 +107,9 @@ public class PasswordActivity extends BaseActivity {
@Override
public void onBackPressed() {
- // Show the home screen rather than another password prompt
- Intent intent = new Intent(ACTION_MAIN);
- intent.addCategory(CATEGORY_HOME);
- startActivity(intent);
+ // Move task and activity to the background instead of showing another
+ // password prompt. onActivityResult() won't be called in BriarActivity
+ moveTaskToBack(true);
}
private void deleteAccount() {
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/login/UnlockActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/login/UnlockActivity.java
new file mode 100644
index 000000000..49286c21f
--- /dev/null
+++ b/briar-android/src/main/java/org/briarproject/briar/android/login/UnlockActivity.java
@@ -0,0 +1,123 @@
+package org.briarproject.briar.android.login;
+
+import android.app.KeyguardManager;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.annotation.RequiresApi;
+import android.widget.Button;
+
+import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
+import org.briarproject.briar.R;
+import org.briarproject.briar.android.activity.ActivityComponent;
+import org.briarproject.briar.android.activity.BaseActivity;
+import org.briarproject.briar.api.android.LockManager;
+
+import java.util.logging.Logger;
+
+import javax.inject.Inject;
+
+import static android.os.Build.VERSION.SDK_INT;
+import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_KEYGUARD_UNLOCK;
+
+@RequiresApi(21)
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
+public class UnlockActivity extends BaseActivity {
+
+ private static final Logger LOG =
+ Logger.getLogger(UnlockActivity.class.getName());
+ private static final String KEYGUARD_SHOWN = "keyguardShown";
+
+ @Inject
+ LockManager lockManager;
+
+ private boolean keyguardShown = false;
+
+ @Override
+ public void injectActivity(ActivityComponent component) {
+ component.inject(this);
+ }
+
+ public void onCreate(@Nullable Bundle state) {
+ super.onCreate(state);
+ overridePendingTransition(0, 0);
+ setContentView(R.layout.activity_unlock);
+
+ Button button = findViewById(R.id.unlock);
+ button.setOnClickListener(view -> requestKeyguardUnlock());
+
+ keyguardShown = state != null && state.getBoolean(KEYGUARD_SHOWN);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ // Saving whether we've shown the keyguard already is necessary
+ // for Android 6 when this activity gets destroyed.
+ //
+ // This will not help Android 5.
+ // There the system will show the keyguard once again.
+ // So if this activity was destroyed, the user needs to enter PIN twice.
+ outState.putBoolean(KEYGUARD_SHOWN, keyguardShown);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode,
+ Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == REQUEST_KEYGUARD_UNLOCK) {
+ if (resultCode == RESULT_OK) unlock();
+ else {
+ finish();
+ overridePendingTransition(0, 0);
+ }
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ // Show keyguard after onActivityResult() as been called.
+ // Check if app is still locked, lockable
+ // and not finishing (which is possible if recreated)
+ if (!keyguardShown && lockManager.isLocked() && !isFinishing()) {
+ requestKeyguardUnlock();
+ } else if (!lockManager.isLocked()) {
+ setResult(RESULT_OK);
+ finish();
+ }
+ }
+
+ @Override
+ public void onBackPressed() {
+ moveTaskToBack(true);
+ }
+
+ private void requestKeyguardUnlock() {
+ KeyguardManager keyguardManager =
+ (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
+ if (keyguardManager == null) throw new AssertionError();
+ Intent intent = keyguardManager.createConfirmDeviceCredentialIntent(
+ SDK_INT < 23 ? getString(R.string.lock_unlock_verbose) :
+ getString(R.string.lock_unlock), null);
+ if (intent == null) {
+ // the user must have removed the screen lock since locked
+ LOG.warning("Unlocking without keyguard");
+ unlock();
+ } else {
+ keyguardShown = true;
+ startActivityForResult(intent, REQUEST_KEYGUARD_UNLOCK);
+ overridePendingTransition(0, 0);
+ }
+ }
+
+ private void unlock() {
+ lockManager.setLocked(false);
+ setResult(RESULT_OK);
+ finish();
+ overridePendingTransition(0, 0);
+ }
+
+}
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 e7800f1db..9b7727ff9 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
@@ -7,6 +7,7 @@ import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.design.widget.NavigationView.OnNavigationItemSelectedListener;
+import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.ContextCompat;
@@ -136,6 +137,8 @@ public class NavDrawerActivity extends BriarActivity implements
initializeTransports(getLayoutInflater());
transportsView.setAdapter(transportsAdapter);
+ lockManager.isLockable().observe(this, this::setLockVisible);
+
if (lifecycleManager.getLifecycleState().isAfter(RUNNING)) {
showSignOutFragment();
} else if (state == null) {
@@ -152,6 +155,7 @@ public class NavDrawerActivity extends BriarActivity implements
public void onStart() {
super.onStart();
updateTransports();
+ lockManager.checkIfLockable();
controller.showExpiryWarning(new UiResultHandler(this) {
@Override
public void onResultUi(ExpiryWarning expiry) {
@@ -213,9 +217,15 @@ public class NavDrawerActivity extends BriarActivity implements
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
drawerLayout.closeDrawer(START);
clearBackStack();
- loadFragment(item.getItemId());
- // Don't display the Settings item as checked
- return item.getItemId() != R.id.nav_btn_settings;
+ if (item.getItemId() == R.id.nav_btn_lock) {
+ lockManager.setLocked(true);
+ ActivityCompat.finishAfterTransition(this);
+ return false;
+ } else {
+ loadFragment(item.getItemId());
+ // Don't display the Settings item as checked
+ return item.getItemId() != R.id.nav_btn_settings;
+ }
}
@Override
@@ -301,6 +311,11 @@ public class NavDrawerActivity extends BriarActivity implements
// Do nothing for now
}
+ private void setLockVisible(boolean visible) {
+ MenuItem item = navigation.getMenu().findItem(R.id.nav_btn_lock);
+ if (item != null) item.setVisible(visible);
+ }
+
@SuppressWarnings("ConstantConditions")
private void showExpiryWarning(ExpiryWarning expiry) {
int daysUntilExpiry = getDaysUntilExpiry();
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 6d5105f1e..1f52854f3 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
@@ -82,10 +82,12 @@ import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.bramble.util.StringUtils.join;
import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_DARK_THEME;
+import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_PIN_LOCK;
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;
+import static org.briarproject.briar.android.util.UiUtils.hasScreenLock;
import static org.briarproject.briar.api.android.AndroidNotificationManager.BLOG_CHANNEL_ID;
import static org.briarproject.briar.api.android.AndroidNotificationManager.CONTACT_CHANNEL_ID;
import static org.briarproject.briar.api.android.AndroidNotificationManager.FORUM_CHANNEL_ID;
@@ -109,6 +111,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 PREF_SCREEN_LOCK = "pref_key_lock";
public static final String NOTIFY_SIGN_IN = "pref_key_notify_sign_in";
public static final String TOR_LOCATION = "pref_key_tor_location";
@@ -120,13 +123,13 @@ public class SettingsFragment extends PreferenceFragmentCompat
private ListPreference enableBluetooth;
private ListPreference torNetwork;
private SwitchPreference torBlocked;
+ private SwitchPreference screenLock;
private SwitchPreference notifyPrivateMessages;
private SwitchPreference notifyGroupMessages;
private SwitchPreference notifyForumPosts;
private SwitchPreference notifyBlogPosts;
private SwitchPreference notifyVibration;
private SwitchPreference notifyLockscreen;
-
private Preference notifySound;
// Fields that are accessed from background threads must be volatile
@@ -162,6 +165,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
setBlockedCountries();
SwitchPreference notifySignIn =
(SwitchPreference) findPreference(NOTIFY_SIGN_IN);
+ screenLock = (SwitchPreference) findPreference(PREF_SCREEN_LOCK);
notifyPrivateMessages = (SwitchPreference) findPreference(
"pref_key_notify_private_messages");
notifyGroupMessages = (SwitchPreference) findPreference(
@@ -176,8 +180,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
"pref_key_notify_lock_screen");
notifySound = findPreference("pref_key_notify_sound");
- setSettingsEnabled(false);
-
language.setOnPreferenceChangeListener(this);
theme.setOnPreferenceChangeListener((preference, newValue) -> {
if (getActivity() != null) {
@@ -200,6 +202,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
enableBluetooth.setOnPreferenceChangeListener(this);
torNetwork.setOnPreferenceChangeListener(this);
torBlocked.setOnPreferenceChangeListener(this);
+ screenLock.setOnPreferenceChangeListener(this);
if (SDK_INT >= 21) {
notifyLockscreen.setVisible(true);
notifyLockscreen.setOnPreferenceChangeListener(this);
@@ -220,6 +223,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
} else {
theme.setVisible(FEATURE_FLAG_DARK_THEME);
notifySignIn.setVisible(FEATURE_FLAG_SIGN_IN_REMINDER);
+ screenLock.setVisible(FEATURE_FLAG_PIN_LOCK);
findPreference("pref_key_explode").setVisible(false);
findPreference("pref_key_test_data").setVisible(false);
@@ -229,7 +233,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
testing.setVisible(false);
}
- loadSettings();
}
@Override
@@ -246,6 +249,8 @@ public class SettingsFragment extends PreferenceFragmentCompat
public void onStart() {
super.onStart();
eventBus.addListener(this);
+ setSettingsEnabled(false);
+ loadSettings();
}
@Override
@@ -354,6 +359,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
enableBluetooth.setValue(Boolean.toString(btSetting));
torNetwork.setValue(Integer.toString(torNetworkSetting));
torBlocked.setChecked(torBlockedSetting);
+ displayScreenLockSetting();
if (SDK_INT < 26) {
notifyPrivateMessages.setChecked(settings.getBoolean(
@@ -411,9 +417,12 @@ public class SettingsFragment extends PreferenceFragmentCompat
// preferences not needed here, because handled by SharedPreferences:
// - pref_key_theme
// - pref_key_notify_sign_in
+ // preferences partly needed here, because they have their own logic
+ // - pref_key_lock (screenLock -> displayScreenLockSetting())
enableBluetooth.setEnabled(enabled);
torNetwork.setEnabled(enabled);
torBlocked.setEnabled(enabled);
+ if (!enabled) screenLock.setEnabled(false);
notifyPrivateMessages.setEnabled(enabled);
notifyGroupMessages.setEnabled(enabled);
notifyForumPosts.setEnabled(enabled);
@@ -423,6 +432,23 @@ public class SettingsFragment extends PreferenceFragmentCompat
notifySound.setEnabled(enabled);
}
+ private void displayScreenLockSetting() {
+ if (SDK_INT < 21) {
+ screenLock.setVisible(false);
+ } else {
+ if (getActivity() != null && hasScreenLock(getActivity())) {
+ screenLock.setEnabled(true);
+ screenLock.setChecked(
+ settings.getBoolean(PREF_SCREEN_LOCK, false));
+ screenLock.setSummary(R.string.pref_lock_summary);
+ } else {
+ screenLock.setEnabled(false);
+ screenLock.setChecked(false);
+ screenLock.setSummary(R.string.pref_lock_disabled_summary);
+ }
+ }
+ }
+
@TargetApi(26)
private void setupNotificationPreference(SwitchPreference pref,
String channelId, @StringRes int summary) {
@@ -478,6 +504,10 @@ public class SettingsFragment extends PreferenceFragmentCompat
} else if (preference == torBlocked) {
boolean torBlockedSetting = (Boolean) newValue;
storeTorBlockedSetting(torBlockedSetting);
+ } else if (preference == screenLock) {
+ Settings s = new Settings();
+ s.putBoolean(PREF_SCREEN_LOCK, (Boolean) newValue);
+ storeSettings(s);
} else if (preference == notifyPrivateMessages) {
Settings s = new Settings();
s.putBoolean(PREF_NOTIFY_PRIVATE, (Boolean) newValue);
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/splash/SplashScreenActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/splash/SplashScreenActivity.java
index e878d2376..cf890f89e 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/splash/SplashScreenActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/splash/SplashScreenActivity.java
@@ -14,6 +14,8 @@ import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.activity.BaseActivity;
import org.briarproject.briar.android.login.OpenDatabaseActivity;
import org.briarproject.briar.android.login.SetupActivity;
+import org.briarproject.briar.android.navdrawer.NavDrawerActivity;
+import org.briarproject.briar.api.android.LockManager;
import java.util.logging.Logger;
@@ -29,6 +31,8 @@ public class SplashScreenActivity extends BaseActivity {
@Inject
protected AccountManager accountManager;
@Inject
+ protected LockManager lockManager;
+ @Inject
protected AndroidExecutor androidExecutor;
@Override
@@ -44,7 +48,16 @@ public class SplashScreenActivity extends BaseActivity {
setContentView(R.layout.splash);
if (accountManager.hasDatabaseKey()) {
- startActivity(new Intent(this, OpenDatabaseActivity.class));
+ Intent i;
+ if (lockManager.isLocked()) {
+ // The database needs to be opened for the app to be locked.
+ // Start main activity right away. It will open UnlockActivity.
+ // Otherwise, we would end up with two screen unlock inputs.
+ i = new Intent(this, NavDrawerActivity.class);
+ } else {
+ i = new Intent(this, OpenDatabaseActivity.class);
+ }
+ startActivity(i);
finish();
} else {
new Handler().postDelayed(() -> {
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java
index ee30d8d37..60c6db311 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java
@@ -2,6 +2,7 @@ package org.briarproject.briar.android.util;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
+import android.app.KeyguardManager;
import android.content.Context;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
@@ -36,6 +37,7 @@ import org.briarproject.briar.android.widget.LinkDialogFragment;
import javax.annotation.Nullable;
+import static android.content.Context.KEYGUARD_SERVICE;
import static android.content.Context.POWER_SERVICE;
import static android.content.Intent.CATEGORY_DEFAULT;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
@@ -229,4 +231,15 @@ public class UiUtils {
return ContextCompat.getColor(ctx, color);
}
+ public static boolean hasScreenLock(Context ctx) {
+ if (SDK_INT < 21) return false;
+ KeyguardManager keyguardManager =
+ (KeyguardManager) ctx.getSystemService(KEYGUARD_SERVICE);
+ if (keyguardManager == null) return false;
+ // check if there's a lock mechanism we can use
+ // first one is true if SIM card is locked, so use second if available
+ return (SDK_INT < 23 && keyguardManager.isKeyguardSecure()) ||
+ (SDK_INT >= 23 && keyguardManager.isDeviceSecure());
+ }
+
}
diff --git a/briar-android/src/main/java/org/briarproject/briar/api/android/AndroidNotificationManager.java b/briar-android/src/main/java/org/briarproject/briar/api/android/AndroidNotificationManager.java
index 5de4b066f..fdca9f595 100644
--- a/briar-android/src/main/java/org/briarproject/briar/api/android/AndroidNotificationManager.java
+++ b/briar-android/src/main/java/org/briarproject/briar/api/android/AndroidNotificationManager.java
@@ -1,5 +1,7 @@
package org.briarproject.briar.api.android;
+import android.app.Notification;
+
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.sync.GroupId;
@@ -52,6 +54,10 @@ public interface AndroidNotificationManager {
// Actions for pending intents
String ACTION_DISMISS_REMINDER = "dismissReminder";
+ Notification getForegroundNotification();
+
+ void updateForegroundNotification(boolean locked);
+
void clearContactNotification(ContactId c);
void clearAllContactNotifications();
diff --git a/briar-android/src/main/java/org/briarproject/briar/api/android/LockManager.java b/briar-android/src/main/java/org/briarproject/briar/api/android/LockManager.java
new file mode 100644
index 000000000..968d4e522
--- /dev/null
+++ b/briar-android/src/main/java/org/briarproject/briar/api/android/LockManager.java
@@ -0,0 +1,33 @@
+package org.briarproject.briar.api.android;
+
+import android.arch.lifecycle.LiveData;
+import android.support.annotation.UiThread;
+
+public interface LockManager {
+
+ /**
+ * Returns an observable LiveData to indicate whether the app can be locked.
+ */
+ LiveData isLockable();
+
+ /**
+ * Updates the LiveData returned by {@link #isLockable()}.
+ * It checks whether a device screen lock is available and
+ * whether the app setting is checked.
+ */
+ @UiThread
+ void checkIfLockable();
+
+ /**
+ * Returns true if app is currently locked, false otherwise.
+ * If the device's screen lock was removed while the app was locked,
+ * calling this will unlock the app automatically.
+ */
+ boolean isLocked();
+
+ /**
+ * Locks the app if true is passed, otherwise unlocks the app.
+ */
+ void setLocked(boolean locked);
+
+}
diff --git a/briar-android/src/main/res/layout/activity_unlock.xml b/briar-android/src/main/res/layout/activity_unlock.xml
new file mode 100644
index 000000000..48413a198
--- /dev/null
+++ b/briar-android/src/main/res/layout/activity_unlock.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
\ 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 befb4faa2..6f3606d0f 100644
--- a/briar-android/src/main/res/menu/navigation_drawer.xml
+++ b/briar-android/src/main/res/menu/navigation_drawer.xml
@@ -26,6 +26,11 @@
android:id="@+id/nav_btn_settings"
android:icon="@drawable/ic_settings_black_24dp"
android:title="@string/settings_button"/>
+
- Seguridá
Configuración del Botón d\'espantu
Botón d\'espantu
- Colar
+ Colar
Desinstalar Briar
Avisos
diff --git a/briar-android/src/main/res/values-bg/strings.xml b/briar-android/src/main/res/values-bg/strings.xml
index 75da4e717..339f00f2b 100644
--- a/briar-android/src/main/res/values-bg/strings.xml
+++ b/briar-android/src/main/res/values-bg/strings.xml
@@ -271,8 +271,8 @@
Няма
Потвърждение на паник приложение
Сигурни ли сте, че искате да позволите на %1$s да задейства унищожителни действия на паник бутон?
- Отписване
- Отписване от Briar, ако паник бутонът е натиснат
+ Отписване
+ Отписване от Briar, ако паник бутонът е натиснат
Изтриване на профил
Изтриване на Briar профила, ако паник бутонът е натиснат. Внимание: Изтрива завинаги вашия профил, контакти и съобщения
Деинсталиране на Briar
diff --git a/briar-android/src/main/res/values-br/strings.xml b/briar-android/src/main/res/values-br/strings.xml
index 482a4408c..25de4a52e 100644
--- a/briar-android/src/main/res/values-br/strings.xml
+++ b/briar-android/src/main/res/values-br/strings.xml
@@ -164,7 +164,7 @@
Cheñch ar ger-tremen
Kadarnaat ar ger-tremen nevez
Hini ebet
- Digevreañ
+ Digevreañ
Hini ebet
diff --git a/briar-android/src/main/res/values-ca/strings.xml b/briar-android/src/main/res/values-ca/strings.xml
index 2470bddd5..ba13119f2 100644
--- a/briar-android/src/main/res/values-ca/strings.xml
+++ b/briar-android/src/main/res/values-ca/strings.xml
@@ -343,8 +343,8 @@
Cap
Confirmeu l\'aplicació de pànic
Segur que voleu permetre que %1$s desencadeni accions destructives a conseqüència del botó de pànic?
- Tanca la sessió
- Tanca la sessió de Briar si es prem un botó de pànic
+ Tanca la sessió
+ Tanca la sessió de Briar si es prem un botó de pànic
Esborreu el compte
Suprimeix el compte de Briar si es prem el botó de pànic. Atenció: En aquest cas, s\'eliminarien permanentment les vostres identitats, contactes i missatges
Desinstal·leu Briar
diff --git a/briar-android/src/main/res/values-cs/strings.xml b/briar-android/src/main/res/values-cs/strings.xml
index 1ae001c6f..16bcaf2a7 100644
--- a/briar-android/src/main/res/values-cs/strings.xml
+++ b/briar-android/src/main/res/values-cs/strings.xml
@@ -346,8 +346,8 @@
Žádný
Potvrdit aplikaci Paniky
Jste si jisti, že chcete povolit %1$s spustit akci zneškodnění pomocí tlačítka paniky?
- Odhlásit se
- Odhlásit se z Briar, pokud je stisknuto tlačítko paniky
+ Odhlásit se
+ Odhlásit se z Briar, pokud je stisknuto tlačítko paniky
Odstranit účet
Vymazat váš Briar účet pokud je stlačeno tlačítko paniky. Upozornění: Toto trvale vymaže vaši identitu, kontakty a zprávy
Odinstalovat Briar
diff --git a/briar-android/src/main/res/values-de/strings.xml b/briar-android/src/main/res/values-de/strings.xml
index 427effe32..df2052310 100644
--- a/briar-android/src/main/res/values-de/strings.xml
+++ b/briar-android/src/main/res/values-de/strings.xml
@@ -333,8 +333,8 @@
Keine
Bestätige Panik-App
Bist du sicher, dass du %1$s erlauben willst, Panik-Button-Ereignisse auszulösen? Dies kann zum Löschen von Daten führen.
- Abmelden
- Von Briar abmelden, wenn ein Panik-Button aktiviert wird
+ Abmelden
+ Von Briar abmelden, wenn ein Panik-Button aktiviert wird
Konto löschen
Briar-Konto löschen, wenn der Panik-Button gedrückt wird. Achtung: Es werden alle Identitäten, Kontakte und Nachrichten unwiderruflich gelöscht.
Briar deinstallieren
diff --git a/briar-android/src/main/res/values-es/strings.xml b/briar-android/src/main/res/values-es/strings.xml
index b38f1052d..4d11571de 100644
--- a/briar-android/src/main/res/values-es/strings.xml
+++ b/briar-android/src/main/res/values-es/strings.xml
@@ -327,8 +327,8 @@
Ninguna
Confirmar aplicación de pánico
¿Seguro que quieres permitir que %1$s lance acciones destructivas de botón de pánico?
- Cerrar sesión
- Cerrar la sesión de Briar si se pulsa un botón de pánico
+ Cerrar sesión
+ Cerrar la sesión de Briar si se pulsa un botón de pánico
Eliminar cuenta
Eliminar tu cuenta de Briar si se pulsa un botón de pánico. Advertencia: esto eliminará permanentemente tus identidades, contactos y mensajes
Desinstalar Briar
diff --git a/briar-android/src/main/res/values-eu/strings.xml b/briar-android/src/main/res/values-eu/strings.xml
index ef3079cae..e8d5f47bd 100644
--- a/briar-android/src/main/res/values-eu/strings.xml
+++ b/briar-android/src/main/res/values-eu/strings.xml
@@ -343,8 +343,8 @@
Bat ere ez
Berretsi larrialdi-aplikazioa
Ziur %1$s baimendu nahi duzula larrialdi botoiaren ekintza suntsitzaileak burutzea?
- Amaitu saioa
- Amaitu saioa larrialdi botoia zapaltzen bada
+ Amaitu saioa
+ Amaitu saioa larrialdi botoia zapaltzen bada
Ezabatu kontua
Ezabatu kontua Briar larrialdi botoia zapaltzen bada. Kontuz: Honek behin betiko ezabatuko ditu zure identitateak, kontaktuak eta mezuak
Desinstalatu Briar
diff --git a/briar-android/src/main/res/values-fa/strings.xml b/briar-android/src/main/res/values-fa/strings.xml
index 383a06f7d..10c315a94 100644
--- a/briar-android/src/main/res/values-fa/strings.xml
+++ b/briar-android/src/main/res/values-fa/strings.xml
@@ -382,8 +382,8 @@
هیچکدام
تایید برنامه هراس
آیا مطمئن هستید که میخواهید به %1$s اجازه دهید تا باعث عملیات مخرب دکمه هراس بشود؟
- خروج
- در صورت کلیک بر روی کلید هراس از برایر خارج شو
+ خروج
+ در صورت کلیک بر روی کلید هراس از برایر خارج شو
حذف حساب کاربری
پاک کردن حساب کاربری برایر شما در صورتی که دکمه هراس فشار داده شود. اخطار: این باعث پاک شدن دائمی تمام هویت ها، مخاطبان و پیام های شما خواهد شد
پاک کردن برایر
diff --git a/briar-android/src/main/res/values-fi/strings.xml b/briar-android/src/main/res/values-fi/strings.xml
index 5b161f888..2d98404f5 100644
--- a/briar-android/src/main/res/values-fi/strings.xml
+++ b/briar-android/src/main/res/values-fi/strings.xml
@@ -343,8 +343,8 @@
Ei mitään
Vahvista paniikkisovellus
Oletko varma, että haluat myöntää ohjelmalle %1$s luvan laukaista tuhoa aiheuttavia paniikkinapin toimintoja?
- Kirjaudu ulos
- Kirjaudu ulos Briarista jos paniikkinappia on painettu
+ Kirjaudu ulos
+ Kirjaudu ulos Briarista jos paniikkinappia on painettu
Poista tili
Poista Briar tilisi jos paniikkinappia on painettu. Varoitus: Tämä tulee pysyvästi poistamaan sinun tunnukset, yhteystiedot ja viestit
Poista Briarin asennus
diff --git a/briar-android/src/main/res/values-fr/strings.xml b/briar-android/src/main/res/values-fr/strings.xml
index 01f8ab291..c1cae7458 100644
--- a/briar-android/src/main/res/values-fr/strings.xml
+++ b/briar-android/src/main/res/values-fr/strings.xml
@@ -343,8 +343,8 @@
Aucune
Confirmer l’application d’urgence
Voulez-vous vraiment autoriser %1$s à déclencher les actions destructrices du bouton d’urgence ?
- Déconnexion
- Se déconnecter de Briar lorsqu’on appuie sur un bouton d’urgence
+ Déconnexion
+ Se déconnecter de Briar lorsqu’on appuie sur un bouton d’urgence
Supprimer le compte
Supprimer votre compte Briar lorsqu’on appuie sur un bouton d’urgence. Attention : cela supprimera définitivement vos identités, contacts et messages
Désinstaller Briar
diff --git a/briar-android/src/main/res/values-gl/strings.xml b/briar-android/src/main/res/values-gl/strings.xml
index 7d7e338f3..9b3a6273d 100644
--- a/briar-android/src/main/res/values-gl/strings.xml
+++ b/briar-android/src/main/res/values-gl/strings.xml
@@ -341,8 +341,8 @@
Ningún
Confirme a App do pánico
Está segura de querer permitir a %1$s activar accións destrutivas do botón do pánico?
- Finalizar sesión
- Desconecte de Briar si o botón do pánico se preme
+ Finalizar sesión
+ Desconecte de Briar si o botón do pánico se preme
Eliminar conta
Elimina a súa conta en Briar si se preme o botón do pánico. Coidado: Esto eliminará permanentemente as súas identidade, contactos e mensaxes
Desinstalar Briar
diff --git a/briar-android/src/main/res/values-he/strings.xml b/briar-android/src/main/res/values-he/strings.xml
index b66d106c5..d7bf70bd1 100644
--- a/briar-android/src/main/res/values-he/strings.xml
+++ b/briar-android/src/main/res/values-he/strings.xml
@@ -239,7 +239,7 @@
אבטחה
סיסמא חדשה
כלום
- יציאה
+ יציאה
מחק חשבון
הודעות מערכת
diff --git a/briar-android/src/main/res/values-hi/strings.xml b/briar-android/src/main/res/values-hi/strings.xml
index 54cb1b0db..26ad56548 100644
--- a/briar-android/src/main/res/values-hi/strings.xml
+++ b/briar-android/src/main/res/values-hi/strings.xml
@@ -327,8 +327,8 @@
कुछ भी नहीं
आतंक ऐप की पुष्टि करें
क्या आप निश्चित हैं कि आप%1$s को विनाशकारी आतंक बटन क्रियाओं को ट्रिगर करने की अनुमति देना चाहते हैं?
- साइन आउट
- यदि कोई आतंक बटन दबाया जाता है तो बियर से साइन आउट करें
+ साइन आउट
+ यदि कोई आतंक बटन दबाया जाता है तो बियर से साइन आउट करें
खाता हटा दो
यदि आपका आतंक बटन दबाया गया हो तो अपने ब्रियर खाते को हटा दें। सावधानी: यह आपकी पहचान, संपर्क और संदेश को स्थायी रूप से हटा देगा
बरिअर की स्थापना रद्द करें
diff --git a/briar-android/src/main/res/values-it/strings.xml b/briar-android/src/main/res/values-it/strings.xml
index fce549280..3d4d06b4c 100644
--- a/briar-android/src/main/res/values-it/strings.xml
+++ b/briar-android/src/main/res/values-it/strings.xml
@@ -343,8 +343,8 @@
Nessuno
Conferma App Panico
Sei sicuro di voler consentire %1$s di attivare le azioni distruttive del pulsante panico?
- Esci
- Uscire da Briar se viene premuto un pulsante di panico
+ Esci
+ Uscire da Briar se viene premuto un pulsante di panico
Elimina Account
Cancella il tuo account Briar se un panic button è premuto. Attenzione: ciò cancellerà permanentemente le tue identità, contatti e messaggi
Disinstalla Briar
diff --git a/briar-android/src/main/res/values-ja/strings.xml b/briar-android/src/main/res/values-ja/strings.xml
index ac467e713..2514e51e9 100644
--- a/briar-android/src/main/res/values-ja/strings.xml
+++ b/briar-android/src/main/res/values-ja/strings.xml
@@ -114,7 +114,7 @@
パスワードの変更
新しいパスワードの確認
なし
- サインアウト
+ サインアウト
アカウントを削除
通知
diff --git a/briar-android/src/main/res/values-nb/strings.xml b/briar-android/src/main/res/values-nb/strings.xml
index 700819d26..dd09db1e4 100644
--- a/briar-android/src/main/res/values-nb/strings.xml
+++ b/briar-android/src/main/res/values-nb/strings.xml
@@ -296,8 +296,8 @@
Inget
Bekreft panikk-knapp-program
Er du sikker på at du vil tillate %1$s å utløse destruktive panikk-knapp-handlinger?
- Logg ut
- Logg ut av Briar hvis panikk-knappen trykkes
+ Logg ut
+ Logg ut av Briar hvis panikk-knappen trykkes
Slett konto
Slett Briar-kontoen din hvis panikk-knappen trykkes. Advarsel: Dette vil slette dine identiteter, kontakter og meldinger for godt.
Avinstaller Briar
diff --git a/briar-android/src/main/res/values-nl/strings.xml b/briar-android/src/main/res/values-nl/strings.xml
index 1125337a7..7e1551e8e 100644
--- a/briar-android/src/main/res/values-nl/strings.xml
+++ b/briar-android/src/main/res/values-nl/strings.xml
@@ -343,8 +343,8 @@
Geen
Bevestig paniekapp
Weet je zeker dat je wil toestaan dat %1$s destructieve paniekknopacties mag veroorzaken?
- Log uit
- Log uit op Briar als de paniekknop wordt ingedrukt.
+ Log uit
+ Log uit op Briar als de paniekknop wordt ingedrukt.
Verwijder account
Verwijder je Briar-account als een paniekknop wordt ingedrukt. Let op: Dit zal permanent je identiteit, contacten en berichten verwijderen.
Deïnstalleer Briar
diff --git a/briar-android/src/main/res/values-oc/strings.xml b/briar-android/src/main/res/values-oc/strings.xml
index 6f1766e7a..4b40026c3 100644
--- a/briar-android/src/main/res/values-oc/strings.xml
+++ b/briar-android/src/main/res/values-oc/strings.xml
@@ -309,8 +309,8 @@ Volètz suprimir vòstre compte e ne crear un nòu ?\n
Cap
Confirmar l’aplicacion Urgéncia
Sètz segur de voler autorizar %1$s a aviar las accions de destruccion del boton Urgéncia ?
- Se desconnectar
- Se desconnectar de Briar en apiejant lo boton Urgéncia ?
+ Se desconnectar
+ Se desconnectar de Briar en apiejant lo boton Urgéncia ?
Suprimir lo compte
Suprimir vòstre compte en apiejant lo boton Urgéncia. Mèfi, aquò escafarà per totjorn vòstra identitat, vòstres contactes e messatges.
Desinstallar Briar
diff --git a/briar-android/src/main/res/values-pl/strings.xml b/briar-android/src/main/res/values-pl/strings.xml
index 92cf15a2c..51853e213 100644
--- a/briar-android/src/main/res/values-pl/strings.xml
+++ b/briar-android/src/main/res/values-pl/strings.xml
@@ -361,8 +361,8 @@
Brak
Potwierdź Awaryjną Aplikację
Czy na pewno chcesz pozwolić %1$s aby działała jako przycisk wyjścia awaryjnego?
- Wyloguj się
- Wyloguj się z Briar jeśli przycisk zostanie wciśnięty
+ Wyloguj się
+ Wyloguj się z Briar jeśli przycisk zostanie wciśnięty
Skasuj Konto
Skasuj Twoje konto Briar jeśli przycisk wyjścia awaryjnego zostanie wciśnięty. Ostrzeżenie: Ta akcja usunie permanentnie Twoje konto, kontakty i wiadomości
Odinstaluj Briar
diff --git a/briar-android/src/main/res/values-pt-rBR/strings.xml b/briar-android/src/main/res/values-pt-rBR/strings.xml
index 812615bb4..7e89a075a 100644
--- a/briar-android/src/main/res/values-pt-rBR/strings.xml
+++ b/briar-android/src/main/res/values-pt-rBR/strings.xml
@@ -332,8 +332,8 @@
Nenhum
Confirmar aplicativo de pânico
Você tem certeza que quer permitir que %1$s ative ações destrutivas do botão de pânico?
- Desconectar
- Desconectar do Briar se o botão de pânico for apertado
+ Desconectar
+ Desconectar do Briar se o botão de pânico for apertado
Apagar conta
Apagar sua conta do Briar se o botão de pânico for apertado. Atenção: isso irá apagar permanentemente suas identidades, contatos e mensagens
Desinstalar o Briar
diff --git a/briar-android/src/main/res/values-ro/strings.xml b/briar-android/src/main/res/values-ro/strings.xml
index c2aae2a1b..fac76c4a8 100644
--- a/briar-android/src/main/res/values-ro/strings.xml
+++ b/briar-android/src/main/res/values-ro/strings.xml
@@ -354,8 +354,8 @@
Nici una
Confirmare aplicație de panică
Sigur doriți să permiteți %1$s să declanșeze acțiuni destructive pentru butonul de panică?
- Ieșire
- Ieși din Briar dacă un buton de panică este apăsat
+ Ieșire
+ Ieși din Briar dacă un buton de panică este apăsat
Șterge cont
Ștergeți contul Briar dacă este apăsat buton de panică. Atenție: aceasta va șterge definitiv identitatea, contactele și mesajele dvs.
Dezinstalare Briar
diff --git a/briar-android/src/main/res/values-ru/strings.xml b/briar-android/src/main/res/values-ru/strings.xml
index e62219035..a0fb21065 100644
--- a/briar-android/src/main/res/values-ru/strings.xml
+++ b/briar-android/src/main/res/values-ru/strings.xml
@@ -363,8 +363,8 @@
Нет
Подтвердить приложение тревожной кнопки
Вы уверены, что хотите разрешить %1$s запускать действия тревожной кнопки?
- Выйти
- Выйти из Briar, если нажата тревожная кнопка
+ Выйти
+ Выйти из Briar, если нажата тревожная кнопка
Удалить аккаунт
Удалить вашу учетную запись Briar при нажатии тревожной кнопки. Внимание: это необратимо удалит ваши идентификаторы, контакты и сообщения
Удалить Briar
diff --git a/briar-android/src/main/res/values-sq/strings.xml b/briar-android/src/main/res/values-sq/strings.xml
index e2e905963..9bead86c3 100644
--- a/briar-android/src/main/res/values-sq/strings.xml
+++ b/briar-android/src/main/res/values-sq/strings.xml
@@ -343,8 +343,8 @@
Asnjë
Ripohoni Aplikacion Paniku
Jeni i sigurt se doni të lejohet %1$s të prodhojë veprime shkatërruese butoni paniku?
- Dilni
- Dil nga Briar-i nëse shtypet një buton paniku
+ Dilni
+ Dil nga Briar-i nëse shtypet një buton paniku
Fshi Llogarinë
Fshijeni llogarinë tuaj Briar, nëse shtypet një buton paniku. Kujdes: Kjo do të shkaktojë fshirjen e identiteteve, kontakteve dhe mesazheve tuaj
Çinstalo Briar-in
diff --git a/briar-android/src/main/res/values-sr/strings.xml b/briar-android/src/main/res/values-sr/strings.xml
index 0dcd6cba8..7e93c1b8b 100644
--- a/briar-android/src/main/res/values-sr/strings.xml
+++ b/briar-android/src/main/res/values-sr/strings.xml
@@ -237,8 +237,8 @@
Ništa
Potvrdi Panic App
Jeste li sigurni da želite da dozvolite %1$s da pokrene destruktivne akcije panik dugmeta?
- Izlogujte se
- Izloguj se iz Briar-a ako je pritisnuto panik dugme
+ Izlogujte se
+ Izloguj se iz Briar-a ako je pritisnuto panik dugme
Izbriši račun
Izbriši Briar račun ako je panik dugme pritisnuto. Pažnja: Ovo će permanentno izbrisati vaše identitete, kontakte i poruke
Deinstaliraj Briar
diff --git a/briar-android/src/main/res/values-sv/strings.xml b/briar-android/src/main/res/values-sv/strings.xml
index 2463668ad..49ef2ba62 100644
--- a/briar-android/src/main/res/values-sv/strings.xml
+++ b/briar-android/src/main/res/values-sv/strings.xml
@@ -129,8 +129,8 @@
Nytt lösenord
Bekräfta nytt lösenord
Ingen
- Logga ut
- Logga ut från Briar om panikknappen tryckts
+ Logga ut
+ Logga ut från Briar om panikknappen tryckts
Radera kontot
Avinstallera Briar
diff --git a/briar-android/src/main/res/values-tr/strings.xml b/briar-android/src/main/res/values-tr/strings.xml
index e93212819..295fd1d5d 100644
--- a/briar-android/src/main/res/values-tr/strings.xml
+++ b/briar-android/src/main/res/values-tr/strings.xml
@@ -264,8 +264,8 @@
Yok
Panik Uygulaması Doğrulama
%1$s kişisinin yıkıcı panik düğmesi eylemlerini tetiklemesine izin vermek istediğinizden emin misiniz?
- Çıkış Yap
- Panik Butonuna basıldığında Briar\'dan çıkış yap
+ Çıkış Yap
+ Panik Butonuna basıldığında Briar\'dan çıkış yap
Hesabı Sil
Bir panik düğmesine basıldığında Briar hesabınızı silin. Dikkat: Bu, kimliklerinizi, kayıtlarınızı ve iletilerinizi kalıcı olarak silecektir.
Briar\'ı Kaldır
diff --git a/briar-android/src/main/res/values-zh-rCN/strings.xml b/briar-android/src/main/res/values-zh-rCN/strings.xml
index d1d43e92d..7dfa06f4a 100644
--- a/briar-android/src/main/res/values-zh-rCN/strings.xml
+++ b/briar-android/src/main/res/values-zh-rCN/strings.xml
@@ -333,8 +333,8 @@
无
确认应急应用
是否允许 %1$s 触发破坏性应急开关反应?
- 登出
- 触发应急开关时登出 Briar
+ 登出
+ 触发应急开关时登出 Briar
删除账号
触发应急开关时删除您的账号。注意:您的身份、联系人和消息将会永久遗失。
卸载 Briar
diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml
index 8456ceda1..45c9ce6e7 100644
--- a/briar-android/src/main/res/values/strings.xml
+++ b/briar-android/src/main/res/values/strings.xml
@@ -62,6 +62,7 @@
Private Groups
Forums
Blogs
+ Lock App
Settings
Sign Out
@@ -356,6 +357,9 @@
Security
+ Screen Lock
+ Use the device\'s screen lock to protect Briar while signed in
+ Set up a screen lock for your device to protect Briar while signed in
Change password
Current password
New password
@@ -370,8 +374,8 @@
None
Confirm Panic App
Are you sure that you want to allow %1$s to trigger destructive panic button actions?
- Sign Out
- Sign out of Briar if a panic button is pressed
+ Sign Out
+ Sign out of Briar if a panic button is pressed
Delete Account
Delete your Briar account if a panic button is pressed. Caution: This will permanently delete your identities, contacts and messages
Uninstall Briar
@@ -444,4 +448,11 @@
Camera permission was not granted
QR code
Show QR code fullscreen
+
+
+ Unlock Briar
+ Enter your device PIN, pattern or password to unlock Briar
+ Briar is locked
+ Tap to unlock
+
diff --git a/briar-android/src/main/res/xml/panic_preferences.xml b/briar-android/src/main/res/xml/panic_preferences.xml
index c02c8e008..d823e6f0f 100644
--- a/briar-android/src/main/res/xml/panic_preferences.xml
+++ b/briar-android/src/main/res/xml/panic_preferences.xml
@@ -12,8 +12,8 @@
android:defaultValue="true"
android:enabled="false"
android:key="pref_key_lock"
- android:summary="@string/lock_setting_summary"
- android:title="@string/lock_setting_title"/>
+ android:summary="@string/panic_setting_signout_summary"
+ android:title="@string/panic_setting_signout_title"/>
+
+