device_security 1.0.0
device_security: ^1.0.0 copied to clipboard
Flutter plugin for device security detection: root/jailbreak, emulator, hooking framework, and virtual camera detection with confidence scoring.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:device_security/device_security.dart';
void main() => runApp(const SecurityDemoApp());
class SecurityDemoApp extends StatelessWidget {
const SecurityDemoApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Device Security Check',
theme: ThemeData(
colorSchemeSeed: Colors.indigo,
useMaterial3: true,
),
home: const SecurityCheckPage(),
);
}
}
class SecurityCheckPage extends StatefulWidget {
const SecurityCheckPage({super.key});
@override
State<SecurityCheckPage> createState() => _SecurityCheckPageState();
}
class _SecurityCheckPageState extends State<SecurityCheckPage> {
SecurityResult? _result;
bool _loading = false;
Future<void> _runCheck() async {
setState(() => _loading = true);
final result = await DeviceSecurityChecker.check();
setState(() {
_result = result;
_loading = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Device Security')),
body: _loading
? const Center(child: CircularProgressIndicator())
: _result == null
? Center(
child: ElevatedButton(
onPressed: _runCheck,
child: const Text('Run Security Check'),
),
)
: _buildResult(),
floatingActionButton: _result != null
? FloatingActionButton(
onPressed: _runCheck,
child: const Icon(Icons.refresh),
)
: null,
);
}
Widget _buildResult() {
final r = _result!;
return ListView(
padding: const EdgeInsets.all(16),
children: [
_overallCard(r),
const SizedBox(height: 12),
_detailCard('Root / Jailbreak', r.rootJailbreak),
_detailCard('Emulator', r.emulator),
_detailCard('Hooking Framework', r.hookingFramework),
_detailCard('Virtual Camera', r.virtualCamera),
],
);
}
Widget _overallCard(SecurityResult r) {
final color = switch (r.riskLevel) {
RiskLevel.safe => Colors.green,
RiskLevel.low => Colors.lightGreen,
RiskLevel.medium => Colors.orange,
RiskLevel.high => Colors.deepOrange,
RiskLevel.critical => Colors.red,
};
return Card(
color: color.withOpacity(0.1),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Text(
r.riskLevel.name.toUpperCase(),
style: TextStyle(
fontSize: 28, fontWeight: FontWeight.bold, color: color),
),
const SizedBox(height: 8),
Text(
'Overall Risk Score: ${r.overallRiskScore.toStringAsFixed(2)}',
style: const TextStyle(fontSize: 16),
),
const SizedBox(height: 4),
Text(
r.isSafeForLiveness
? 'Environment is safe for liveness verification'
: 'Environment is NOT safe for liveness verification',
style: TextStyle(color: r.isSafeForLiveness ? Colors.green : Colors.red),
),
],
),
),
);
}
Widget _detailCard(String title, DetectionDetail d) {
return Card(
child: ExpansionTile(
leading: Icon(
d.detected ? Icons.warning_amber_rounded : Icons.check_circle,
color: d.detected ? Colors.red : Colors.green,
),
title: Text(title),
subtitle: Text(
'Confidence: ${d.confidence.toStringAsFixed(2)} — ${d.detected ? "DETECTED" : "Clean"}'),
children: d.reasons.isEmpty
? [const ListTile(title: Text('No issues found'))]
: d.reasons.map((r) => ListTile(title: Text(r))).toList(),
),
);
}
}