geiger_api_connector 0.4.11 geiger_api_connector: ^0.4.11 copied to clipboard
A connector to GEIGER APIs
import 'dart:async';
import 'dart:developer';
import 'dart:io';
import 'dart:math' as math;
import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:flutter/material.dart';
import 'package:geiger_api_connector/multi_language_value.dart';
import 'package:uuid/uuid.dart';
import 'package:geiger_api_connector/geiger_api_connector.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
if (Platform.isWindows) {
doWhenWindowReady(() {
final win = appWindow;
const initialSize = Size(417, 732);
win.minSize = initialSize;
win.size = initialSize;
win.alignment = Alignment.center;
win.title = "Custom window with Flutter";
win.show();
});
}
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
MyHomePageState createState() => MyHomePageState();
}
const String montimagePluginId = 'my-plugin-id-00';
const String montimagePluginName = "Testing Plugin";
class MyHomePageState extends State<MyHomePage> {
List<Message> events = [];
String userData = '';
String deviceData = '';
bool isInProcessing = false;
bool isMasterStarted = false;
bool isExternalPluginStarted = false;
String? masterOutput;
String? pluginOutput;
GeigerApiConnector masterApiConnector = GeigerApiConnector(
pluginId: GeigerApi.masterId, pluginName: montimagePluginName);
GeigerApiConnector pluginApiConnector = GeigerApiConnector(
pluginId: montimagePluginId, pluginName: montimagePluginName);
SensorDataModel userNodeDataModel = SensorDataModel(
sensorId: 'user-sensor-data-flag-0',
name: 'MI Cyberrange (Test)',
description: [
MultilingualValues(
language: "en", value: "MI Cyberrange sensor data in English"),
MultilingualValues(
language: "fr", value: "MI Cyberrange sensor data en francais")
],
minValue: '0',
maxValue: '100',
valueType: 'double',
flag: '0',
urgency: "high",
threatsImpact:
'1f3eff0a-1817-4ede-aef7-8c836aecc1c1,High;1f3eff0a-1817-4ede-aef7-8c836aecc1c3,Medium;f1836c07-0bf8-49ab-831a-61026c7ce0d3,High',
);
SensorDataModel deviceNodeDataModel = SensorDataModel(
sensorId: 'device-sensor-data',
name: 'MSEC (Test)',
description: [
MultilingualValues(language: "en", value: "MSEC sensor data in English"),
MultilingualValues(language: "fr", value: "MSEC sensor data en francais")
],
minValue: '0',
maxValue: '5',
valueType: 'double',
flag: '1',
urgency: "high",
threatsImpact:
'f7742d4c-2cfa-4c61-874e-fb8c38ef7d14,High;7cf1c9a8-fe8d-4ff7-be51-25e401537e11,Medium;f1836c07-0bf8-49ab-831a-61026c7ce0d3,Medium;f1836c07-0bf8-49ab-831a-61026c7ce0d1,Medium;1f3eff0a-1817-4ede-aef7-8c836aecc1c1,Low',
);
String deviceRecommendationId = const Uuid().v4();
RecommendationNodeModel deviceRecommendation = RecommendationNodeModel(
sensorId: 'device-sensor-data',
short: [MultilingualValues(language: "en", value: "recommendation 01")],
long: [
MultilingualValues(
language: "en",
value: "This is a long description of recommendation 01")
],
action: 'geiger://my-recommendation/01',
relatedThreatsWeights:
'1f3eff0a-1817-4ede-aef7-8c836aecc1c1,High;1f3eff0a-1817-4ede-aef7-8c836aecc1c3,Medium;f1836c07-0bf8-49ab-831a-61026c7ce0d3,High',
costs: 'False',
recommendationType: 'device',
os: '[android,iphone]',
);
String userRecommendationId = const Uuid().v4();
RecommendationNodeModel userRecommendation = RecommendationNodeModel(
sensorId: 'user-sensor-data',
short: [MultilingualValues(language: "en", value: "recommendation 02")],
long: [
MultilingualValues(
language: "en",
value: "This is a long description of recommendation 02"),
MultilingualValues(
language: "fr",
value: "C'est la long description de recommendation 02")
],
action: 'geiger://my-recommendation/02',
relatedThreatsWeights:
'f7742d4c-2cfa-4c61-874e-fb8c38ef7d14,High;7cf1c9a8-fe8d-4ff7-be51-25e401537e11,Medium;f1836c07-0bf8-49ab-831a-61026c7ce0d3,Medium;f1836c07-0bf8-49ab-831a-61026c7ce0d1,Medium;1f3eff0a-1817-4ede-aef7-8c836aecc1c1,Low',
costs: 'False',
recommendationType: 'device',
os: '[android,iphone]',
);
// String masterExecutor = 'cybergeigertoolbox.geiger_toolbox;'
// 'cybergeigertoolbox.geiger_toolbox.MainActivity;'
// 'TODO';
String masterExecutor = 'cybergeigertoolbox.geiger_toolbox;'
'cybergeigertoolbox.geiger_toolbox.MainActivity;'
'TODO';
String pluginExecutor = 'com.montimage.master;'
'com.montimage.master.MainActivity;'
'TODO';
Future<bool> initMasterPlugin() async {
final bool initGeigerAPI = await masterApiConnector.connectToGeigerAPI(
masterExecutor: masterExecutor);
if (initGeigerAPI == false) return false;
final bool ret = await masterApiConnector.connectToLocalStorage();
if (ret == false) return false;
final bool regPluginListener =
await masterApiConnector.registerPluginListener();
final bool regStorageListener =
await masterApiConnector.registerStorageListener(searchPath: ':Device');
isMasterStarted = true;
return regPluginListener && regStorageListener;
}
Future<bool> initExternalPlugin() async {
final bool initGeigerAPI = await pluginApiConnector.connectToGeigerAPI(
masterExecutor: masterExecutor, pluginExecutor: pluginExecutor);
if (initGeigerAPI == false) return false;
bool ret = await pluginApiConnector.connectToLocalStorage();
if (ret == false) return false;
// Prepare some data roots
// Prepare Devices data metrics node
// ret = await pluginApiConnector.prepareRoot(
// [
// 'Devices',
// pluginApiConnector.currentDeviceId!,
// montimagePluginId,
// 'data',
// 'metrics'
// ],
// );
// if (ret == false) return false;
// Prepare a recommendation node
// ret = await pluginApiConnector.prepareRoot(
// [
// 'Devices',
// pluginApiConnector.currentDeviceId!,
// montimagePluginId,
// 'data',
// 'recommendations'
// ],
// );
// Prepare Users data metrics node
// ret = await pluginApiConnector.prepareRoot(
// [
// 'Users',
// pluginApiConnector.currentUserId!,
// montimagePluginId,
// 'data',
// 'metrics'
// ],
// );
// if (ret == false) return false;
ret = await pluginApiConnector.prepareRoot(
[
'Chatbot',
'sensors',
montimagePluginId,
],
);
if (ret == false) return false;
// write the plugin information
ret = await pluginApiConnector
.updatePluginInfo(montimagePluginId, 'Montimage', [
MultilingualValues(language: "en", value: "Awesome Plugin"),
MultilingualValues(language: "fr", value: "Application Fantasitque")
]);
// Prepare some data nodes
ret = await pluginApiConnector.addDeviceSensorNode(deviceNodeDataModel);
if (ret == false) return false;
ret = await pluginApiConnector.addUserSensorNode(userNodeDataModel);
if (ret == false) return false;
// Prepare for plugin event handler
pluginApiConnector.addPluginEventhandler(MessageType.scanPressed,
(Message msg) async {
await pluginApiConnector.sendDeviceSensorData(
deviceNodeDataModel.sensorId,
math.Random().nextBool().toString(),
);
await pluginApiConnector.sendUserSensorData(
userNodeDataModel.sensorId,
math.Random().nextInt(100).toString(),
);
});
final bool regPluginListener =
await pluginApiConnector.registerPluginListener();
// Prepare for storage event handler
final bool regStorageListener = await pluginApiConnector
.registerStorageListener(searchPath: ':Chatbot:sensors');
isExternalPluginStarted = true;
return regPluginListener && regStorageListener;
}
_showSnackBar(String message) {
SnackBar snackBar = SnackBar(
content: Text(message),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: const TabBar(
tabs: [
Tab(
icon: Icon(
Icons.center_focus_strong_outlined,
),
text: 'GeigerToolbox',
),
Tab(
icon: Icon(Icons.extension_rounded),
text: 'External Plugin',
),
],
),
),
body: isInProcessing == true
? const Center(
child: CircularProgressIndicator(
backgroundColor: Colors.orange,
),
)
: TabBarView(
children: [
_viewBackendView(),
_viewExternalPluginView(),
],
),
),
);
}
_viewBackendView() {
return Container(
margin: const EdgeInsets.all(20),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
const SizedBox(height: 5),
const Text(
'GeigerToolbox',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
color: Colors.orange),
),
Text(
'(geiger_api_connector: ${GeigerApiConnector.version})',
style: const TextStyle(fontStyle: FontStyle.italic),
),
!isMasterStarted
? Column(children: [
ElevatedButton(
onPressed: () async {
setState(() {
isInProcessing = true;
});
final bool masterPlugin = await initMasterPlugin();
if (masterPlugin == false) {
_showSnackBar('Failed to start Master Plugin');
} else {
_showSnackBar('The Master Plugin has been started');
}
setState(() {
isInProcessing = false;
});
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.orange,
minimumSize: const Size.fromHeight(40),
),
child: const Text('Start Master Plugin'),
),
const Text('The Master Plugin is not intialized yet!'),
])
: Column(
children: [
const Text(
'Backend is running...',
style: TextStyle(
fontSize: 14,
fontStyle: FontStyle.italic,
color: Colors.green),
),
const SizedBox(height: 5),
ElevatedButton(
onPressed: () async {
setState(() {
isInProcessing = true;
});
final bool sentScanPressed = await masterApiConnector
.sendPluginEventType(MessageType.scanPressed);
if (sentScanPressed == false) {
_showSnackBar('Failed to send SCAN_PRESSED event');
} else {
_showSnackBar('A SCAN_PRESSED event has been sent');
}
setState(() {
isInProcessing = false;
});
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.orange,
minimumSize: const Size.fromHeight(40),
),
child: const Text('Send SCAN_PRESSED'),
),
const SizedBox(height: 5),
ElevatedButton(
onPressed: () async {
final String storageStr =
await masterApiConnector.dumpLocalStorage(':');
setState(() {
masterOutput = storageStr;
});
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.orange,
minimumSize: const Size.fromHeight(40),
),
child: const Text('Dump Storage'),
),
const SizedBox(
height: 5,
),
ElevatedButton(
onPressed: () {
final String allEventStr =
masterApiConnector.showAllPluginEvents();
setState(() {
masterOutput = allEventStr;
});
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.orange,
minimumSize: const Size.fromHeight(40),
),
child: const Text('Show all plugin events'),
),
const SizedBox(
height: 5,
),
ElevatedButton(
onPressed: () {
final String allStorageStr =
masterApiConnector.showAllStorageEvents();
setState(() {
masterOutput = allStorageStr;
});
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.orange,
minimumSize: const Size.fromHeight(40),
),
child: const Text('Show all storage events'),
),
const SizedBox(
height: 5,
),
ElevatedButton(
onPressed: () async {
final String? geigerValue =
await masterApiConnector.readDeviceSensorData(
montimagePluginId,
deviceNodeDataModel.sensorId,
'GEIGERvalue');
final String? valueDescription =
await masterApiConnector.readDeviceSensorData(
montimagePluginId,
deviceNodeDataModel.sensorId,
'description');
final String? dataUrgency =
await masterApiConnector.readDeviceSensorData(
montimagePluginId,
deviceNodeDataModel.sensorId,
'urgency');
setState(() {
deviceData =
'$geigerValue -$dataUrgency - $valueDescription';
masterOutput = 'Device sensors data: $deviceData';
});
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.orange,
minimumSize: const Size.fromHeight(40),
),
child: Text(
'Show the received device sensor data ($deviceData)'),
),
const SizedBox(
height: 5,
),
ElevatedButton(
onPressed: () async {
final String? geigerValue =
await masterApiConnector.readUserSensorData(
montimagePluginId,
userNodeDataModel.sensorId,
'GEIGERvalue');
final String? valueDescription =
await masterApiConnector.readUserSensorData(
montimagePluginId,
userNodeDataModel.sensorId,
'description');
final String? dataUrgency =
await masterApiConnector.readUserSensorData(
montimagePluginId,
userNodeDataModel.sensorId,
'urgency');
setState(() {
userData =
'$geigerValue - $dataUrgency - $valueDescription';
masterOutput = 'User sensors data: $userData';
});
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.orange,
minimumSize: const Size.fromHeight(40),
),
child: Text(
'Show the received users sensor data ($userData)'),
),
const Divider(),
const SizedBox(height: 5),
Text(masterOutput != null ? masterOutput! : '<output>'),
],
),
],
),
),
);
}
_viewExternalPluginView() {
return Container(
margin: const EdgeInsets.all(20),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
const SizedBox(height: 5),
const Text(
'External Plugin',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
color: Colors.blue),
),
!isExternalPluginStarted
? Column(
children: [
ElevatedButton(
onPressed: () async {
setState(() {
isInProcessing = true;
});
final bool externalPlugin =
await initExternalPlugin();
if (externalPlugin == false) {
_showSnackBar('Failed to start External Plugin');
} else {
_showSnackBar(
'The External Plugin has been started');
}
setState(() {
isInProcessing = false;
});
},
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(40),
),
child: const Text('Start an External Plugin'),
),
const Text('The external plugin is not initialzed yet!'),
],
)
: Column(
children: [
const Text(
'Plugin $montimagePluginId is running...',
style: TextStyle(
fontSize: 14,
fontStyle: FontStyle.italic,
color: Colors.green),
),
const SizedBox(height: 5),
ElevatedButton(
onPressed: () async {
setState(() {
isInProcessing = true;
});
for (var i = 5; i >= 0; i--) {
final bool dataSent =
await pluginApiConnector.sendDeviceSensorData(
deviceNodeDataModel.sensorId, '$i',
description: [
MultilingualValues(
language: "en",
value:
"The geigerValue is $i/5 - flag = 1")
],
urgency: 'high');
if (dataSent == false) {
_showSnackBar(
'Failed to send a device sensor data');
} else {
_showSnackBar(
'A device sensor data has been sent');
}
}
setState(() {
isInProcessing = false;
});
},
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(40),
),
child: const Text('Send a device data'),
),
const SizedBox(height: 5),
ElevatedButton(
onPressed: () async {
setState(() {
isInProcessing = true;
});
final bool dataSent =
await pluginApiConnector.sendDeviceSensorData(
deviceNodeDataModel.sensorId,
"-200",
description: [
MultilingualValues(
language: "en", value: "The score is too low")
],
urgency: 'high',
);
if (dataSent == false) {
_showSnackBar(
'Failed to send a device sensor data');
} else {
_showSnackBar('A device sensor data has been sent');
}
setState(() {
isInProcessing = false;
});
},
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(40),
),
child: const Text('Send an invalid device data'),
),
const SizedBox(height: 5),
ElevatedButton(
onPressed: () async {
setState(() {
isInProcessing = true;
});
for (var i = 10; i >= 0; i--) {
final bool dataSent =
await pluginApiConnector.sendUserSensorData(
userNodeDataModel.sensorId, "${i * 10}",
description: [
MultilingualValues(
language: "en",
value:
"The geigerValue is ${i * 10}/100 - flag = 0")
],
urgency: 'medium');
if (dataSent == false) {
_showSnackBar(
'Failed to send a user sensor data');
} else {
_showSnackBar('A user sensor data has been sent');
}
}
setState(() {
isInProcessing = false;
});
},
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(40),
),
child: const Text('Send a user data'),
),
const SizedBox(height: 5),
// ElevatedButton(
// onPressed: () async {
// // trigger/send a SCAN_COMPLETED event
// setState(() {
// isInProcessing = true;
// });
// final bool sentData = await pluginApiConnector
// .sendPluginEventType(MessageType.scanCompleted);
// if (sentData == false) {
// _showSnackBar(
// 'Failed to send SCAN_COMPLETED event');
// } else {
// _showSnackBar(
// 'The SCAN_COMPLETED event has been sent');
// }
// setState(() {
// isInProcessing = false;
// });
// },
// style: ElevatedButton.styleFrom(
// minimumSize: const Size.fromHeight(40),
// ),
// child: const Text('Send SCAN_COMPLETED event'),
// ),
// const SizedBox(height: 5),
// ElevatedButton(
// onPressed: () async {
// // trigger/send a SCAN_COMPLETED event
// setState(() {
// isInProcessing = true;
// });
// final String payload = '''{
// "title":"A message from MI Cyberrange",
// "message":"You should do more anti-phishing email testing",
// "timestamp": ${DateTime.now().millisecondsSinceEpoch}
// }''';
// final bool sentData = await pluginApiConnector
// .sendPluginEventWithPayload(
// MessageType.customEvent, payload);
// if (sentData == false) {
// _showSnackBar(
// 'Failed to send a message with payload');
// } else {
// _showSnackBar(
// 'A message with payload has been sent');
// }
// setState(() {
// isInProcessing = false;
// });
// },
// style: ElevatedButton.styleFrom(
// minimumSize: const Size.fromHeight(40),
// ),
// child: const Text(
// 'Send a custom event with payload (json encoded string)'),
// ),
// const SizedBox(height: 5),
// ElevatedButton(
// onPressed: () async {
// // trigger/send a SCAN_COMPLETED event
// setState(() {
// isInProcessing = true;
// });
// bool chatbotNode = await pluginApiConnector.isNodeExist(
// ':Chatbot:sensors:$montimagePluginId:my-sensor-data');
// log('Chatbot node check ($montimagePluginId): $chatbotNode');
// setState(() {
// isInProcessing = false;
// });
// },
// style: ElevatedButton.styleFrom(
// minimumSize: const Size.fromHeight(40),
// ),
// child: const Text('Check the chatbot node'),
// ),
// const SizedBox(height: 5),
// ElevatedButton(
// onPressed: () async {
// // trigger/send a STORAGE_EVENT event
// setState(() {
// isInProcessing = true;
// });
// final bool sentData =
// await pluginApiConnector.sendDataNode(
// 'my-sensor-data',
// ':Chatbot:sensors:$montimagePluginId',
// [
// 'category',
// 'description',
// 'fileFullPath',
// 'isApplication',
// 'isDeviceAdminThreat',
// 'objectName',
// 'virusName'
// ],
// [
// 'Malware',
// 'critical threat detected',
// 'fileFullPath/applications/glume.apk',
// 'true',
// 'true',
// 'hijack.org',
// 'hijack'
// ],
// null);
// if (sentData == false) {
// _showSnackBar('Failed to send data to Chatbot');
// } else {
// _showSnackBar('Data has been sent to Chatbot');
// }
// setState(() {
// isInProcessing = false;
// });
// },
// style: ElevatedButton.styleFrom(
// minimumSize: const Size.fromHeight(40),
// ),
// child: const Text('Send a threat info to Chatbot'),
// ),
// const SizedBox(
// height: 5,
// ),
ElevatedButton(
onPressed: () async {
// trigger/send a STORAGE_EVENT event
setState(() {
isInProcessing = true;
});
final bool sentData =
await pluginApiConnector.sendRecommendation(
"Devices",
deviceRecommendation,
);
if (sentData == false) {
_showSnackBar(
'Failed to send a device recommendation');
} else {
_showSnackBar(
'A Device recommendation has been sent');
}
setState(() {
isInProcessing = false;
});
},
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(40),
),
child: const Text('Send the device recommendation'),
),
const SizedBox(
height: 5,
),
ElevatedButton(
onPressed: () async {
// trigger/send a STORAGE_EVENT event
setState(() {
isInProcessing = true;
});
final bool recom =
await pluginApiConnector.isRecommendationExist(
"Devices",
deviceRecommendation.sensorId,
);
log('Device recommendation of sensor node ${deviceRecommendation.sensorId}): $recom');
setState(() {
isInProcessing = false;
});
},
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(40),
),
child: const Text('Check the device recommendation'),
),
const SizedBox(
height: 5,
),
ElevatedButton(
onPressed: () async {
// trigger/send a STORAGE_EVENT event
setState(() {
isInProcessing = true;
});
final bool sentData =
await pluginApiConnector.resolveRecommendation(
'Devices',
deviceRecommendation.sensorId,
'0');
if (sentData == false) {
_showSnackBar(
'Failed to resolve a device recommendation');
} else {
_showSnackBar(
'A Device recommendation has been resolved');
}
setState(() {
isInProcessing = false;
});
},
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(40),
),
child: const Text('Resolve the device recommendation'),
),
const SizedBox(
height: 5,
),
ElevatedButton(
onPressed: () async {
// trigger/send a STORAGE_EVENT event
setState(() {
isInProcessing = true;
});
final bool sentData =
await pluginApiConnector.sendRecommendation(
"Users",
userRecommendation,
);
if (sentData == false) {
_showSnackBar(
'Failed to send a user recommendation');
} else {
_showSnackBar(
'A user recommendation has been sent');
}
setState(() {
isInProcessing = false;
});
},
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(40),
),
child: const Text('Send a user recommendation'),
),
const SizedBox(
height: 5,
),
ElevatedButton(
onPressed: () async {
// trigger/send a STORAGE_EVENT event
setState(() {
isInProcessing = true;
});
final bool recom =
await pluginApiConnector.isRecommendationExist(
"Users",
userRecommendation.sensorId,
);
log('User recommendation of sensor node ${userRecommendation.sensorId}): $recom');
setState(() {
isInProcessing = false;
});
},
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(40),
),
child: const Text('Check the user recommendation'),
),
const SizedBox(
height: 5,
),
ElevatedButton(
onPressed: () async {
// trigger/send a STORAGE_EVENT event
setState(() {
isInProcessing = true;
});
final bool sentData =
await pluginApiConnector.resolveRecommendation(
'Users', userRecommendation.sensorId, '1');
if (sentData == false) {
_showSnackBar(
'Failed to resolve a device recommendation');
} else {
_showSnackBar(
'A Device recommendation has been resolved');
}
setState(() {
isInProcessing = false;
});
},
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(40),
),
child: const Text('Resolve the user recommendation'),
),
const SizedBox(
height: 5,
),
ElevatedButton(
onPressed: () {
pluginApiConnector.sendDataNode(
'cffb567a-3d64-4204-a637-1da234ed25b0',
':Global:Recommendations',
['RecommendationType'],
['device'],
);
},
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(40),
),
child: const Text('Change a global recommendation'),
),
const SizedBox(
height: 5,
),
ElevatedButton(
onPressed: () {
final String allEventStr =
pluginApiConnector.showAllPluginEvents();
setState(() {
pluginOutput = allEventStr;
});
},
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(40),
),
child: const Text('Show all plugin events'),
),
const SizedBox(
height: 5,
),
ElevatedButton(
onPressed: () {
final String allStorageStr =
pluginApiConnector.showAllStorageEvents();
setState(() {
pluginOutput = allStorageStr;
});
},
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(40),
),
child: const Text('Show all storage events'),
),
const SizedBox(height: 5),
ElevatedButton(
onPressed: () {
pluginApiConnector.sendPluginEventType(
MessageType.returningControl);
},
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(40),
),
child: const Text('Back to the GeigerToolbox'),
),
const SizedBox(height: 5),
ElevatedButton(
onPressed: () async {
await pluginApiConnector.close();
setState(() {
isExternalPluginStarted = false;
});
},
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(40),
),
child: const Text('Disconnect'),
),
const Divider(),
const SizedBox(height: 5),
Text(pluginOutput != null ? pluginOutput! : '<output>'),
],
),
],
),
),
);
}
}