diff --git a/briar-android/build.gradle b/briar-android/build.gradle
index bb4988e825110c3dd3de940a1a6a73311c485924..ef9427921fe63c69a84009ffda49f91078a66808 100644
--- a/briar-android/build.gradle
+++ b/briar-android/build.gradle
@@ -75,8 +75,8 @@ def getStdout = { command, defaultValue ->
}
android {
- compileSdkVersion 27
- buildToolsVersion '27.0.3'
+ compileSdkVersion 28
+ buildToolsVersion '28.0.2'
defaultConfig {
minSdkVersion 15
diff --git a/briar-android/src/main/AndroidManifest.xml b/briar-android/src/main/AndroidManifest.xml
index 82d4b83cfca31940105b2a64a3b4b57544bba5b8..79eb8b41a5dd723babfa06d22499a193d1e3865f 100644
--- a/briar-android/src/main/AndroidManifest.xml
+++ b/briar-android/src/main/AndroidManifest.xml
@@ -17,6 +17,7 @@
+
requestKeyguardUnlock());
-
+ if (!hasUsableFingerprint(this)) {
+ getWindow().setBackgroundDrawable(null);
+ findViewById(R.id.image).setVisibility(INVISIBLE);
+ }
keyguardShown = state != null && state.getBoolean(KEYGUARD_SHOWN);
}
@@ -83,18 +94,79 @@ public class UnlockActivity extends BaseActivity {
// Check if app is still locked, lockable
// and not finishing (which is possible if recreated)
if (!keyguardShown && lockManager.isLocked() && !isFinishing()) {
- requestKeyguardUnlock();
+ requestUnlock();
} else if (!lockManager.isLocked()) {
setResult(RESULT_OK);
finish();
}
}
+ private void requestUnlock() {
+ if (SDK_INT >= 28 && hasUsableFingerprint(this)) {
+ requestFingerprintUnlock();
+ } else {
+ requestKeyguardUnlock();
+ }
+ }
+
@Override
public void onBackPressed() {
moveTaskToBack(true);
}
+ @RequiresApi(api = 28)
+ private void requestFingerprintUnlock() {
+ BiometricPrompt biometricPrompt = new Builder(this)
+ .setTitle(getString(R.string.lock_unlock))
+ .setDescription(
+ getString(R.string.lock_unlock_fingerprint_description))
+ .setNegativeButton(getString(R.string.lock_unlock_password),
+ getMainExecutor(),
+ (dialog, which) -> requestKeyguardUnlock())
+ .build();
+ CancellationSignal signal = new CancellationSignal();
+ AuthenticationCallback callback = new AuthenticationCallback() {
+ @Override
+ public void onAuthenticationError(int errorCode,
+ @Nullable CharSequence errString) {
+ // when back button is pressed while fingerprint dialog shows
+ if (errorCode == BIOMETRIC_ERROR_CANCELED ||
+ errorCode == BIOMETRIC_ERROR_USER_CANCELED) {
+ finish();
+ }
+ // e.g. 5 failed attempts
+ else {
+ if (hasKeyguardLock(UnlockActivity.this)) {
+ requestKeyguardUnlock();
+ } else {
+ // normally fingerprints require a screen lock, but
+ // who knows if that's true for all devices out there
+ if (errString != null) {
+ Toast.makeText(UnlockActivity.this, errString,
+ Toast.LENGTH_LONG).show();
+ }
+ finish();
+ }
+ }
+ }
+
+ @Override
+ public void onAuthenticationHelp(int helpCode,
+ @Nullable CharSequence helpString) {
+ }
+
+ @Override
+ public void onAuthenticationSucceeded(AuthenticationResult result) {
+ unlock();
+ }
+
+ @Override
+ public void onAuthenticationFailed() {
+ }
+ };
+ biometricPrompt.authenticate(signal, getMainExecutor(), callback);
+ }
+
private void requestKeyguardUnlock() {
KeyguardManager keyguardManager =
(KeyguardManager) getSystemService(KEYGUARD_SERVICE);
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 7fb316a622e387df0c0b837f2a2ee857f96196ce..4cb49aac5d7a00752ef32e646fd0c32d8f10504f 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
@@ -14,6 +14,7 @@ import android.support.annotation.ColorRes;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
+import android.support.v4.hardware.fingerprint.FingerprintManagerCompat;
import android.support.v7.app.AlertDialog;
import android.text.Html;
import android.text.Spannable;
@@ -261,6 +262,10 @@ public class UiUtils {
}
public static boolean hasScreenLock(Context ctx) {
+ return hasKeyguardLock(ctx) || hasUsableFingerprint(ctx);
+ }
+
+ public static boolean hasKeyguardLock(Context ctx) {
if (SDK_INT < 21) return false;
KeyguardManager keyguardManager =
(KeyguardManager) ctx.getSystemService(KEYGUARD_SERVICE);
@@ -271,6 +276,12 @@ public class UiUtils {
(SDK_INT >= 23 && keyguardManager.isDeviceSecure());
}
+ public static boolean hasUsableFingerprint(Context ctx) {
+ if (SDK_INT < 28) return false;
+ FingerprintManagerCompat fm = FingerprintManagerCompat.from(ctx);
+ return fm.hasEnrolledFingerprints() && fm.isHardwareDetected();
+ }
+
public static void triggerFeedback(AndroidExecutor androidExecutor) {
androidExecutor.runOnBackgroundThread(
() -> ACRA.getErrorReporter()
diff --git a/briar-android/src/main/res/layout/activity_unlock.xml b/briar-android/src/main/res/layout/activity_unlock.xml
index 48413a19820d5251e01c1418ffd54fb48aedcb09..83c8d594b103d7bfd9d57dc849240888a07e9f19 100644
--- a/briar-android/src/main/res/layout/activity_unlock.xml
+++ b/briar-android/src/main/res/layout/activity_unlock.xml
@@ -14,36 +14,11 @@
android:layout_height="150dp"
android:layout_margin="@dimen/margin_large"
android:src="@drawable/splash_screen"
- app:layout_constraintBottom_toTopOf="@+id/is_locked"
+ app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintVertical_chainStyle="spread"
+ app:layout_constraintVertical_bias="0.1"
app:tint="?attr/colorControlNormal"/>
-
-
-
-
\ No newline at end of file
diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml
index bdc04d7926923e84b0577bdc1b982e347dbfe1dc..722a2f50d1903ab75a89271ff9e36e967e755b5b 100644
--- a/briar-android/src/main/res/values/strings.xml
+++ b/briar-android/src/main/res/values/strings.xml
@@ -475,6 +475,8 @@
Unlock Briar
Enter your device PIN, pattern or password to unlock Briar
+ Touch your fingerprint sensor with the registered finger to continue
+ Use Password
Briar is locked
Tap to unlock