mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-12-23 10:11:52 +03:00
implemented getLogs on Android
This commit is contained in:
parent
87ad07fe7c
commit
89d632390a
@ -5,8 +5,13 @@ import io.flutter.plugin.common.MethodChannel
|
|||||||
|
|
||||||
class FlutterLog(messenger: BinaryMessenger) {
|
class FlutterLog(messenger: BinaryMessenger) {
|
||||||
|
|
||||||
|
private val _buffer = arrayListOf<String>()
|
||||||
private var _channel = MethodChannel(messenger, "android.log.redirect")
|
private var _channel = MethodChannel(messenger, "android.log.redirect")
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val MAX_BUFFER_SIZE = 1000
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
_channel.setMethodCallHandler { call, result ->
|
_channel.setMethodCallHandler { call, result ->
|
||||||
|
|
||||||
@ -21,7 +26,7 @@ class FlutterLog(messenger: BinaryMessenger) {
|
|||||||
if (level == null) {
|
if (level == null) {
|
||||||
loggerError("Invalid level for message from [$loggerName]: $levelValue")
|
loggerError("Invalid level for message from [$loggerName]: $levelValue")
|
||||||
} else if (loggerName != null && message != null) {
|
} else if (loggerName != null && message != null) {
|
||||||
Log.log(level, loggerName, message, error)
|
log(level, loggerName, message, error)
|
||||||
result.success(null)
|
result.success(null)
|
||||||
} else {
|
} else {
|
||||||
result.error("-1", "Invalid log parameters", null)
|
result.error("-1", "Invalid log parameters", null)
|
||||||
@ -35,6 +40,13 @@ class FlutterLog(messenger: BinaryMessenger) {
|
|||||||
} else {
|
} else {
|
||||||
loggerError("Invalid log level requested: $levelArgValue")
|
loggerError("Invalid log level requested: $levelArgValue")
|
||||||
}
|
}
|
||||||
|
result.success(null)
|
||||||
|
}
|
||||||
|
"getLogs" -> {
|
||||||
|
result.success(_buffer)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
result.notImplemented()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,6 +56,14 @@ class FlutterLog(messenger: BinaryMessenger) {
|
|||||||
Log.LogLevel.values().firstOrNull { it.name == argValue?.uppercase() }
|
Log.LogLevel.values().firstOrNull { it.name == argValue?.uppercase() }
|
||||||
|
|
||||||
private fun loggerError(message: String) {
|
private fun loggerError(message: String) {
|
||||||
Log.e("FlutterLog", message, null)
|
log(Log.LogLevel.ERROR,"FlutterLog", message, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun log(level: Log.LogLevel, loggerName: String, message: String, error: String?) {
|
||||||
|
if (_buffer.size > MAX_BUFFER_SIZE) {
|
||||||
|
_buffer.removeAt(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
_buffer.addAll(Log.log(level, loggerName, message, error))
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -47,12 +47,16 @@ object Log {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun log(level: LogLevel, loggerName: String, message: String, error: String?) {
|
fun log(level: LogLevel, loggerName: String, message: String, error: String?) : List<String> {
|
||||||
if (level < this.level) {
|
if (level < this.level) {
|
||||||
return
|
return listOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
val logMessage = "[$loggerName] ${level.name}: $message"
|
val lines = mutableListOf<String>()
|
||||||
|
|
||||||
|
val logMessage = "[$loggerName] ${level.name}: $message".also {
|
||||||
|
lines.add(it)
|
||||||
|
}
|
||||||
|
|
||||||
when (level) {
|
when (level) {
|
||||||
LogLevel.TRAFFIC -> Log.v(TAG, logMessage)
|
LogLevel.TRAFFIC -> Log.v(TAG, logMessage)
|
||||||
@ -63,8 +67,12 @@ object Log {
|
|||||||
}
|
}
|
||||||
|
|
||||||
error?.let {
|
error?.let {
|
||||||
Log.e(TAG, "[$loggerName] ${level.name}: $error")
|
Log.e(TAG, "[$loggerName] ${level.name}: $error".also {
|
||||||
|
lines.add(it)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return lines
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
|
@ -83,9 +83,8 @@ class LoggingPanel extends ConsumerWidget {
|
|||||||
child: const Text('Copy log'),
|
child: const Text('Copy log'),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
_log.info('Copying log to clipboard...');
|
_log.info('Copying log to clipboard...');
|
||||||
final logs =
|
final logs = await ref.read(logLevelProvider.notifier).getLogs();
|
||||||
ref.read(logLevelProvider.notifier).getLogs().join('\n');
|
await Clipboard.setData(ClipboardData(text: logs.join('\n')));
|
||||||
await Clipboard.setData(ClipboardData(text: logs));
|
|
||||||
showMessage(context, 'Log copied to clipboard');
|
showMessage(context, 'Log copied to clipboard');
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -23,8 +23,6 @@ import 'qr_scanner/qr_scanner_provider.dart';
|
|||||||
import 'state.dart';
|
import 'state.dart';
|
||||||
import 'views/tap_request_dialog.dart';
|
import 'views/tap_request_dialog.dart';
|
||||||
|
|
||||||
final androidLogger = AndroidLogger();
|
|
||||||
|
|
||||||
Future<Widget> initialize() async {
|
Future<Widget> initialize() async {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
Logger.root.level = Levels.DEBUG;
|
Logger.root.level = Levels.DEBUG;
|
||||||
@ -36,6 +34,7 @@ Future<Widget> initialize() async {
|
|||||||
Application.oath,
|
Application.oath,
|
||||||
]),
|
]),
|
||||||
prefProvider.overrideWithValue(await SharedPreferences.getInstance()),
|
prefProvider.overrideWithValue(await SharedPreferences.getInstance()),
|
||||||
|
logLevelProvider.overrideWithProvider(androidLogProvider),
|
||||||
attachedDevicesProvider
|
attachedDevicesProvider
|
||||||
.overrideWithProvider(androidAttachedDevicesProvider),
|
.overrideWithProvider(androidAttachedDevicesProvider),
|
||||||
currentDeviceDataProvider.overrideWithProvider(androidDeviceDataProvider),
|
currentDeviceDataProvider.overrideWithProvider(androidDeviceDataProvider),
|
||||||
@ -56,14 +55,6 @@ Future<Widget> initialize() async {
|
|||||||
// activates window state provider
|
// activates window state provider
|
||||||
ref.read(androidWindowStateProvider);
|
ref.read(androidWindowStateProvider);
|
||||||
|
|
||||||
ref.listen(logLevelProvider, (oldLevel, newLevel) {
|
|
||||||
if (oldLevel != newLevel && newLevel is Level) {
|
|
||||||
androidLogger.setLogLevel(newLevel);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
androidLogger.setLogLevel(Logger.root.level);
|
|
||||||
|
|
||||||
/// initializes global handler for dialogs
|
/// initializes global handler for dialogs
|
||||||
FDialogApi.setup(FDialogApiImpl(ref.watch(withContextProvider)));
|
FDialogApi.setup(FDialogApiImpl(ref.watch(withContextProvider)));
|
||||||
return const MainPage();
|
return const MainPage();
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
|
import 'package:yubico_authenticator/app/logging.dart';
|
||||||
|
|
||||||
final _log = Logger('android.logger');
|
final _log = Logger('android.logger');
|
||||||
|
|
||||||
class AndroidLogger {
|
final androidLogProvider =
|
||||||
|
StateNotifierProvider<LogLevelNotifier, Level>((ref) => AndroidLogger());
|
||||||
|
|
||||||
|
class AndroidLogger extends LogLevelNotifier {
|
||||||
final MethodChannel _channel = const MethodChannel('android.log.redirect');
|
final MethodChannel _channel = const MethodChannel('android.log.redirect');
|
||||||
|
|
||||||
AndroidLogger() {
|
AndroidLogger() : super() {
|
||||||
Logger.root.onRecord.listen((record) {
|
Logger.root.onRecord.listen((record) {
|
||||||
if (record.level >= Logger.root.level) {
|
if (record.level >= Logger.root.level) {
|
||||||
log(record);
|
log(record);
|
||||||
@ -15,12 +20,21 @@ class AndroidLogger {
|
|||||||
_log.info('Logging initialized, outputting to Android/logcat');
|
_log.info('Logging initialized, outputting to Android/logcat');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void setLogLevel(Level level) {
|
void setLogLevel(Level level) {
|
||||||
|
super.setLogLevel(level);
|
||||||
_channel.invokeMethod('setLevel', {
|
_channel.invokeMethod('setLevel', {
|
||||||
'level': level.name,
|
'level': level.name,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<String>> getLogs() async {
|
||||||
|
_log.debug('Getting logs...');
|
||||||
|
var buffer = await _channel.invokeMethod('getLogs', {});
|
||||||
|
return List.unmodifiable(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
void log(LogRecord record) {
|
void log(LogRecord record) {
|
||||||
_channel.invokeMethod('log', {
|
_channel.invokeMethod('log', {
|
||||||
'loggerName': record.loggerName,
|
'loggerName': record.loggerName,
|
||||||
|
@ -60,7 +60,7 @@ class LogLevelNotifier extends StateNotifier<Level> {
|
|||||||
Logger.root.level = level;
|
Logger.root.level = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> getLogs() {
|
Future<List<String>> getLogs() async {
|
||||||
return List.unmodifiable(_buffer);
|
return List.unmodifiable(_buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user