import 'dart:async'; import 'dart:io'; import 'package:device_info_plus/device_info_plus.dart'; import 'performance_test.dart'; // Make sure this path is correct /// Analyzes various device hardware and software aspects to generate a compatibility score. /// This class provides a standardized output for the UI to consume easily. class DeviceAnalyzer { final DeviceInfoPlugin _deviceInfo = DeviceInfoPlugin(); /// Reads the total RAM from the system's meminfo file. /// Returns the value in Megabytes (MB). Future _readTotalRamMB() async { try { final file = File('/proc/meminfo'); if (!await file.exists()) return 0.0; final lines = await file.readAsLines(); for (var line in lines) { if (line.startsWith('MemTotal')) { // Extracts the numeric value from the line. final kb = int.tryParse(RegExp(r'\d+').stringMatch(line) ?? '0') ?? 0; return kb / 1024.0; // Convert from Kilobytes to Megabytes } } } catch (e) { print('❌ Error reading total RAM: $e'); } return 0.0; } /// Reads the current RAM usage percentage from the system's meminfo file. Future _readUsedRamPercent() async { try { final file = File('/proc/meminfo'); if (!await file.exists()) return 0.0; final lines = await file.readAsLines(); int? total, available; for (var line in lines) { if (line.startsWith('MemTotal')) { total = int.tryParse(RegExp(r'\d+').stringMatch(line) ?? ''); } else if (line.startsWith('MemAvailable')) { available = int.tryParse(RegExp(r'\d+').stringMatch(line) ?? ''); } } if (total != null && available != null && total > 0) { final used = total - available; return (used / total) * 100.0; } } catch (e) { print('❌ Error reading used RAM: $e'); } return 0.0; } /// The main analysis function that runs all checks. Future> analyzeDevice() async { List> details = []; if (!Platform.isAndroid) { return { 'score': 0, 'details': [ { 'label': 'النظام غير مدعوم', 'status': false, 'achieved_score': 0, 'max_score': 100 } ] }; } final info = await _deviceInfo.androidInfo; final data = info.data; final features = List.from(data['systemFeatures'] ?? []); // 1. Android Version (Max: 10 points) final version = int.tryParse(info.version.release?.split('.').first ?? '0') ?? 0; final int androidScore = version >= 9 ? 10 : 0; details.add({ 'label': 'إصدار أندرويد ${info.version.release}', 'status': androidScore > 0, 'achieved_score': androidScore, 'max_score': 10, }); // 2. Total RAM (Max: 10 points) final totalRam = await _readTotalRamMB(); int ramScore; if (totalRam >= 8000) { ramScore = 10; } else if (totalRam >= 4000) { ramScore = 5; } else if (totalRam >= 3000) { ramScore = 3; } else { ramScore = 0; } details.add({ 'label': 'إجمالي الرام ${totalRam.toStringAsFixed(0)} ميجابايت', 'status': ramScore >= 5, 'achieved_score': ramScore, 'max_score': 10, }); // 3. CPU Cores (Max: 10 points) final cores = Platform.numberOfProcessors; int coreScore = cores >= 6 ? 10 : (cores >= 4 ? 5 : 0); details.add({ 'label': 'أنوية المعالج ($cores)', 'status': coreScore >= 5, 'achieved_score': coreScore, 'max_score': 10, }); // 4. Free Storage (Max: 5 points) final freeBytes = data['freeDiskSize'] ?? 0; final freeGB = freeBytes / (1024 * 1024 * 1024); int storeScore = freeGB >= 5 ? 5 : (freeGB >= 2 ? 3 : 0); details.add({ 'label': 'المساحة الحرة ${freeGB.toStringAsFixed(1)} جيجابايت', 'status': storeScore >= 3, 'achieved_score': storeScore, 'max_score': 5, }); // 5. GPS + Gyroscope Sensors (Max: 10 points) bool okSensors = features.contains('android.hardware.location.gps') && features.contains('android.hardware.sensor.gyroscope'); final int sensorScore = okSensors ? 10 : 0; details.add({ 'label': 'حساسات GPS و Gyroscope', 'status': okSensors, 'achieved_score': sensorScore, 'max_score': 10, }); // 6. Storage Write Speed (Max: 20 points) final writeSpeed = await PerformanceTester.testStorageWriteSpeed(); int writeScore; if (writeSpeed >= 30) { writeScore = 20; } else if (writeSpeed >= 15) { writeScore = 15; } else if (writeSpeed >= 5) { writeScore = 10; } else { writeScore = 5; } details.add({ 'label': 'سرعة الكتابة (${writeSpeed.toStringAsFixed(1)} MB/s)', 'status': writeScore >= 10, 'achieved_score': writeScore, 'max_score': 20, }); // 7. CPU Compute Speed (Max: 20 points) final cpuTime = await PerformanceTester.testCPUSpeed(); int cpuScore; if (cpuTime <= 1.0) { cpuScore = 20; } else if (cpuTime <= 2.5) { cpuScore = 15; } else if (cpuTime <= 4.0) { cpuScore = 10; } else { cpuScore = 5; } details.add({ 'label': 'سرعة المعالجة (${cpuTime.toStringAsFixed(2)} ثانية)', 'status': cpuScore >= 10, 'achieved_score': cpuScore, 'max_score': 20, }); // 8. Memory Pressure (Max: 15 points) final usedPercent = await _readUsedRamPercent(); int memScore; if (usedPercent <= 60) { memScore = 15; } else if (usedPercent <= 80) { memScore = 10; } else if (usedPercent <= 90) { memScore = 5; } else { memScore = 0; } details.add({ 'label': 'استخدام الرام الحالي (${usedPercent.toStringAsFixed(0)}%)', 'status': memScore >= 10, 'achieved_score': memScore, 'max_score': 15, }); // Calculate the final total score by summing up the achieved scores. final totalScore = details.fold( 0, (sum, item) => sum + (item['achieved_score'] as int)); return { 'score': totalScore.clamp(0, 100), 'details': details, }; } }