add NFC Discovery Sound toggle

This commit is contained in:
Adam Velebil 2023-01-03 13:10:03 +01:00
parent a613963113
commit 499108bc77
No known key found for this signature in database
GPG Key ID: AC6D6B9D715FC084
6 changed files with 90 additions and 10 deletions

View File

@ -18,21 +18,31 @@ package com.yubico.authenticator
import android.content.Context
import android.content.SharedPreferences
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import com.yubico.authenticator.logging.Log
class AppPreferences(context: Context) {
companion object {
const val PREFS_FILE = "FlutterSharedPreferences"
const val PREF_NFC_OPEN_APP = "flutter.prefNfcOpenApp"
const val PREF_NFC_BYPASS_TOUCH = "flutter.prefNfcBypassTouch"
const val PREF_NFC_PLAY_DISCOVERY_SOUND = "flutter.prefNfcPlayDiscoverySound"
const val PREF_NFC_COPY_OTP = "flutter.prefNfcCopyOtp"
const val PREF_USB_OPEN_APP = "flutter.prefUsbOpenApp"
const val PREF_CLIP_KBD_LAYOUT = "flutter.prefClipKbdLayout"
const val DEFAULT_CLIP_KBD_LAYOUT = "US"
const val TAG = "AppPreferences"
}
private val prefs: SharedPreferences =
context.getSharedPreferences(PREFS_FILE, Context.MODE_PRIVATE)
context.getSharedPreferences(PREFS_FILE, Context.MODE_PRIVATE).also {
Log.d(TAG, "Current app preferences:")
it.all.map { preference ->
Log.d(TAG, "${preference.key}: ${preference.value}")
}
}
val openAppOnNfcTap: Boolean
get() = prefs.getBoolean(PREF_NFC_OPEN_APP, true)
@ -40,6 +50,9 @@ class AppPreferences(context: Context) {
val bypassTouchOnNfcTap: Boolean
get() = prefs.getBoolean(PREF_NFC_BYPASS_TOUCH, false)
val playNfcDiscoverySound: Boolean
get() = prefs.getBoolean(PREF_NFC_PLAY_DISCOVERY_SOUND, true)
val copyOtpOnNfcTap: Boolean
get() = prefs.getBoolean(PREF_NFC_COPY_OTP, false)
@ -51,4 +64,14 @@ class AppPreferences(context: Context) {
val openAppOnUsb: Boolean
get() = prefs.getBoolean(PREF_USB_OPEN_APP, false)
fun registerListener(listener: OnSharedPreferenceChangeListener) {
Log.d(TAG, "registering change listener")
prefs.registerOnSharedPreferenceChangeListener(listener)
}
fun unregisterListener(listener: OnSharedPreferenceChangeListener) {
prefs.unregisterOnSharedPreferenceChangeListener(listener)
Log.d(TAG, "unregistered change listener")
}
}

View File

@ -17,6 +17,7 @@
package com.yubico.authenticator
import android.content.*
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import android.content.pm.PackageManager
import android.hardware.camera2.CameraManager
import android.hardware.usb.UsbDevice
@ -102,7 +103,11 @@ class MainActivity : FlutterFragmentActivity() {
private fun startNfcDiscovery() =
try {
Log.d(TAG, "Starting nfc discovery")
yubikit.startNfcDiscovery(nfcConfiguration, this, ::processYubiKey)
yubikit.startNfcDiscovery(
nfcConfiguration.disableNfcDiscoverySound(!appPreferences.playNfcDiscoverySound),
this,
::processYubiKey
)
hasNfc = true
} catch (e: NfcNotAvailable) {
hasNfc = false
@ -158,6 +163,9 @@ class MainActivity : FlutterFragmentActivity() {
}
override fun onPause() {
appPreferences.unregisterListener(sharedPreferencesListener)
stopNfcDiscovery()
if (!appPreferences.openAppOnUsb) {
enableAliasMainActivityComponent(false)
@ -221,6 +229,8 @@ class MainActivity : FlutterFragmentActivity() {
}
}
}
appPreferences.registerListener(sharedPreferencesListener)
}
private fun processYubiKey(device: YubiKeyDevice) {
@ -304,6 +314,13 @@ class MainActivity : FlutterFragmentActivity() {
}
}
private val sharedPreferencesListener = OnSharedPreferenceChangeListener { _, key ->
if ( AppPreferences.PREF_NFC_PLAY_DISCOVERY_SOUND == key) {
stopNfcDiscovery()
startNfcDiscovery()
}
}
inner class AppMethodChannel(messenger: BinaryMessenger) {
private val methodChannel = MethodChannel(messenger, "app.methods")

View File

@ -23,6 +23,7 @@ const betaDialogView = Key('$_prefix.beta_dialog');
const nfcTapSetting = Key('$_prefix.nfc_tap');
const nfcKeyboardLayoutSetting = Key('$_prefix.nfc_keyboard_layout');
const nfcBypassTouchSetting = Key('$_prefix.nfc_bypass_touch');
const nfcPlayDiscoverySoundSetting = Key('$_prefix.nfc_play_discovery_sound');
const usbOpenApp = Key('$_prefix.usb_open_app');
const themeModeSetting = Key('$_prefix.theme_mode');

View File

@ -18,6 +18,7 @@
const betaDialogPrefName = 'prefBetaDialogShouldBeShown';
const prefNfcOpenApp = 'prefNfcOpenApp';
const prefNfcBypassTouch = 'prefNfcBypassTouch';
const prefNfcPlayDiscoverySound = 'prefNfcPlayDiscoverySound';
const prefNfcCopyOtp = 'prefNfcCopyOtp';
const prefClipKbdLayout = 'prefClipKbdLayout';
const prefUsbOpenApp = 'prefUsbOpenApp';

View File

@ -105,6 +105,7 @@ class _AndroidSettingsPageState extends ConsumerState<AndroidSettingsPage> {
final clipKbdLayout =
prefs.getString(prefClipKbdLayout) ?? _defaultClipKbdLayout;
final nfcBypassTouch = prefs.getBool(prefNfcBypassTouch) ?? false;
final nfcPlayDiscoverySound = prefs.getBool(prefNfcPlayDiscoverySound) ?? true;
final usbOpenApp = prefs.getBool(prefUsbOpenApp) ?? false;
final themeMode = ref.watch(themeModeProvider);
@ -131,8 +132,9 @@ class _AndroidSettingsPageState extends ConsumerState<AndroidSettingsPage> {
key: keys.nfcTapSetting,
onTap: () async {
final newTapAction = await _selectTapAction(context, tapAction);
newTapAction.save(prefs);
setState(() {});
setState(() {
newTapAction.save(prefs);
});
},
),
ListTile(
@ -143,8 +145,9 @@ class _AndroidSettingsPageState extends ConsumerState<AndroidSettingsPage> {
onTap: () async {
var newValue = await _selectKbdLayout(context, clipKbdLayout);
if (newValue != clipKbdLayout) {
await prefs.setString(prefClipKbdLayout, newValue);
setState(() {});
setState(() {
prefs.setString(prefClipKbdLayout, newValue);
});
}
},
),
@ -158,8 +161,18 @@ class _AndroidSettingsPageState extends ConsumerState<AndroidSettingsPage> {
value: nfcBypassTouch,
key: keys.nfcBypassTouchSetting,
onChanged: (value) {
prefs.setBool(prefNfcBypassTouch, value);
setState(() {});
setState(() {
prefs.setBool(prefNfcBypassTouch, value);
});
}),
SwitchListTile(
title: const Text('Play sound on tap'),
value: nfcPlayDiscoverySound,
key: keys.nfcPlayDiscoverySoundSetting,
onChanged: (value) {
setState(() {
prefs.setBool(prefNfcPlayDiscoverySound, value);
});
}),
const ListTitle('USB options'),
SwitchListTile(
@ -171,8 +184,9 @@ class _AndroidSettingsPageState extends ConsumerState<AndroidSettingsPage> {
value: usbOpenApp,
key: keys.usbOpenApp,
onChanged: (value) {
prefs.setBool(prefUsbOpenApp, value);
setState(() {});
setState(() {
prefs.setBool(prefUsbOpenApp, value);
});
}),
const ListTitle('Appearance'),
ListTile(

View File

@ -103,10 +103,16 @@ extension _WidgetTesterHelper on WidgetTester {
}
Future<void> tapOpenAppOnUsb() async {
await ensureVisible(find.byKey(keys.usbOpenApp));
await tap(find.byKey(keys.usbOpenApp));
await pumpAndSettle();
}
Future<void> tapPlayNfcDiscoverySounds() async {
await tap(find.byKey(keys.nfcPlayDiscoverySoundSetting));
await pumpAndSettle();
}
ListTile themeModeListTile() =>
find.byKey(keys.themeModeSetting).evaluate().single.widget as ListTile;
@ -313,4 +319,22 @@ void main() {
await tester.tapOpenAppOnUsb();
expect(sharedPrefs.getBool(prefUsbOpenApp), equals(false));
});
testWidgets('Play NFC Discovery sound', (WidgetTester tester) async {
SharedPreferences.setMockInitialValues({prefNfcPlayDiscoverySound: true});
SharedPreferences sharedPrefs = await SharedPreferences.getInstance();
await tester.pumpWidget(androidWidget(
sharedPrefs: sharedPrefs,
child: widget,
));
// change to false
await tester.tapPlayNfcDiscoverySounds();
expect(sharedPrefs.getBool(prefNfcPlayDiscoverySound), equals(false));
// change to true
await tester.tapPlayNfcDiscoverySounds();
expect(sharedPrefs.getBool(prefNfcPlayDiscoverySound), equals(true));
});
}