Added setting for biometric inactivity period

pull/157/head
M66B 6 years ago
parent be2f1a2aa7
commit f9729cdca4

@ -1901,7 +1901,8 @@ for a list of privacy friendly email providers with advantages and disadvantages
If your device has a biometric sensor, for example a fingerprint sensor, you can enable/disable biometric authentication in the navigation (hamburger) menu of the setup screen. If your device has a biometric sensor, for example a fingerprint sensor, you can enable/disable biometric authentication in the navigation (hamburger) menu of the setup screen.
When enabled FairEmail will require biometric authentication after a period of inactivity or after the screen has been turned off while FairEmail was running. When enabled FairEmail will require biometric authentication after a period of inactivity or after the screen has been turned off while FairEmail was running.
Activity is navigation within FairEmail, for example opening a conversation thread. The inactivity period length is the same as the screen timeout. Activity is navigation within FairEmail, for example opening a conversation thread.
The inactivity period duration can be configured in the miscellaneous settings.
When biometric authentication is enabled new message notifications will not show any content and FairEmail won't be visible on the Android recents screen. When biometric authentication is enabled new message notifications will not show any content and FairEmail won't be visible on the Android recents screen.
Biometric authentication is meant to prevent others from seeing your messages only. Biometric authentication is meant to prevent others from seeing your messages only.

@ -31,8 +31,10 @@ import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button; import android.widget.Button;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@ -51,6 +53,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
private SwitchCompat swSubscriptions; private SwitchCompat swSubscriptions;
private TextView tvSubscriptionPro; private TextView tvSubscriptionPro;
private SwitchCompat swSubscribedOnly; private SwitchCompat swSubscribedOnly;
private Spinner spBiometricsTimeout;
private SwitchCompat swEnglish; private SwitchCompat swEnglish;
private SwitchCompat swWatchdog; private SwitchCompat swWatchdog;
private SwitchCompat swUpdates; private SwitchCompat swUpdates;
@ -66,7 +69,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
private Group grpDebug; private Group grpDebug;
private final static String[] RESET_OPTIONS = new String[]{ private final static String[] RESET_OPTIONS = new String[]{
"badge", "subscriptions", "subscribed_only", "english", "watchdog", "updates", "crash_reports", "debug" "badge", "subscriptions", "subscribed_only", "biometrics_timeout", "english", "watchdog", "updates", "crash_reports", "debug"
}; };
private final static String[] RESET_QUESTIONS = new String[]{ private final static String[] RESET_QUESTIONS = new String[]{
@ -87,6 +90,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
swSubscriptions = view.findViewById(R.id.swSubscriptions); swSubscriptions = view.findViewById(R.id.swSubscriptions);
tvSubscriptionPro = view.findViewById(R.id.tvSubscriptionPro); tvSubscriptionPro = view.findViewById(R.id.tvSubscriptionPro);
swSubscribedOnly = view.findViewById(R.id.swSubscribedOnly); swSubscribedOnly = view.findViewById(R.id.swSubscribedOnly);
spBiometricsTimeout = view.findViewById(R.id.spBiometricsTimeout);
swEnglish = view.findViewById(R.id.swEnglish); swEnglish = view.findViewById(R.id.swEnglish);
swWatchdog = view.findViewById(R.id.swWatchdog); swWatchdog = view.findViewById(R.id.swWatchdog);
swUpdates = view.findViewById(R.id.swUpdates); swUpdates = view.findViewById(R.id.swUpdates);
@ -132,6 +136,19 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
} }
}); });
spBiometricsTimeout.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
int[] values = getResources().getIntArray(R.array.biometricsTimeoutValues);
prefs.edit().putInt("biometrics_timeout", values[position]).apply();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
prefs.edit().remove("biometrics_timeout").apply();
}
});
swEnglish.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { swEnglish.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
@ -274,6 +291,14 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
swSubscriptions.setEnabled(pro); swSubscriptions.setEnabled(pro);
swSubscribedOnly.setChecked(prefs.getBoolean("subscribed_only", false)); swSubscribedOnly.setChecked(prefs.getBoolean("subscribed_only", false));
int biometrics_timeout = prefs.getInt("biometrics_timeout", 2);
int[] biometricTimeoutValues = getResources().getIntArray(R.array.biometricsTimeoutValues);
for (int pos = 0; pos < biometricTimeoutValues.length; pos++)
if (biometricTimeoutValues[pos] == biometrics_timeout) {
spBiometricsTimeout.setSelection(pos);
break;
}
swEnglish.setChecked(prefs.getBoolean("english", false)); swEnglish.setChecked(prefs.getBoolean("english", false));
swWatchdog.setChecked(prefs.getBoolean("watchdog", true)); swWatchdog.setChecked(prefs.getBoolean("watchdog", true));
swUpdates.setChecked(prefs.getBoolean("updates", true)); swUpdates.setChecked(prefs.getBoolean("updates", true));

@ -21,7 +21,6 @@ package eu.faircode.email;
import android.app.Dialog; import android.app.Dialog;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
@ -37,7 +36,6 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Parcel; import android.os.Parcel;
import android.provider.Settings;
import android.text.Spannable; import android.text.Spannable;
import android.text.Spanned; import android.text.Spanned;
import android.text.format.DateUtils; import android.text.format.DateUtils;
@ -663,17 +661,14 @@ public class Helper {
static boolean shouldAuthenticate(Context context) { static boolean shouldAuthenticate(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean biometrics = prefs.getBoolean("biometrics", false); boolean biometrics = prefs.getBoolean("biometrics", false);
long biometrics_timeout = prefs.getInt("biometrics_timeout", 2) * 60 * 1000L;
if (biometrics) { if (biometrics) {
ContentResolver resolver = context.getContentResolver();
int screen_timeout = Settings.System.getInt(resolver, Settings.System.SCREEN_OFF_TIMEOUT, -1);
Log.i("Screen timeout=" + screen_timeout);
long now = new Date().getTime(); long now = new Date().getTime();
long last_authentication = prefs.getLong("last_authentication", 0); long last_authentication = prefs.getLong("last_authentication", 0);
Log.i("Authentication valid until=" + new Date(last_authentication + screen_timeout)); Log.i("Authentication valid until=" + new Date(last_authentication + biometrics_timeout));
if (last_authentication + screen_timeout < now) if (last_authentication + biometrics_timeout < now)
return true; return true;
prefs.edit().putLong("last_authentication", now).apply(); prefs.edit().putLong("last_authentication", now).apply();

@ -85,6 +85,28 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swSubscribedOnly" /> app:layout_constraintTop_toBottomOf="@id/swSubscribedOnly" />
<TextView
android:id="@+id/tvBiometricsTimeout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginEnd="48dp"
android:text="@string/title_advanced_biometrics_timeout"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Small"
android:textColor="?android:attr/textColorPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvSubscribedOnlyHint" />
<Spinner
android:id="@+id/spBiometricsTimeout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:entries="@array/biometricsTimeoutNames"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvBiometricsTimeout" />
<androidx.appcompat.widget.SwitchCompat <androidx.appcompat.widget.SwitchCompat
android:id="@+id/swEnglish" android:id="@+id/swEnglish"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -92,7 +114,7 @@
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:text="@string/title_advanced_english" android:text="@string/title_advanced_english"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvSubscribedOnlyHint" app:layout_constraintTop_toBottomOf="@id/spBiometricsTimeout"
app:switchPadding="12dp" /> app:switchPadding="12dp" />
<TextView <TextView

@ -248,6 +248,7 @@
<string name="title_advanced_badge">Show launcher icon with number of new messages</string> <string name="title_advanced_badge">Show launcher icon with number of new messages</string>
<string name="title_advanced_subscriptions">Manage folder subscriptions</string> <string name="title_advanced_subscriptions">Manage folder subscriptions</string>
<string name="title_advanced_sync_subscribed">Synchronize subscribed folders only</string> <string name="title_advanced_sync_subscribed">Synchronize subscribed folders only</string>
<string name="title_advanced_biometrics_timeout">Biometric authentication timeout</string>
<string name="title_advanced_english">Force English language</string> <string name="title_advanced_english">Force English language</string>
<string name="title_advanced_watchdog">Periodically check if FairEmail is still active</string> <string name="title_advanced_watchdog">Periodically check if FairEmail is still active</string>
<string name="title_advanced_updates">Check for updates</string> <string name="title_advanced_updates">Check for updates</string>
@ -851,6 +852,22 @@
<item>Bcc</item> <item>Bcc</item>
</string-array> </string-array>
<integer-array name="biometricsTimeoutValues" translatable="false">
<item>1</item>
<item>2</item>
<item>5</item>
<item>10</item>
<item>20</item>
</integer-array>
<string-array name="biometricsTimeoutNames">
<item>One minute</item>
<item>2 minutes</item>
<item>5 minutes</item>
<item>10 minutes</item>
<item>20 minutes</item>
</string-array>
<array name="colorPicker"> <array name="colorPicker">
<item>@color/red</item> <item>@color/red</item>
<item>@color/pink</item> <item>@color/pink</item>

Loading…
Cancel
Save