ios_device_monitor 0.1.1 copy "ios_device_monitor: ^0.1.1" to clipboard
ios_device_monitor: ^0.1.1 copied to clipboard

PlatformiOS

Comprehensive iOS device monitoring plugin with CPU, GPU, thermal, uptime, and advanced CPU usage tracking.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
import 'package:ios_device_monitor/ios_device_monitor.dart';
import 'package:ios_device_monitor/models/models.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'iOS Device Monitor',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        useMaterial3: true,
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.blue,
          brightness: Brightness.light,
        ),
        cardTheme: CardThemeData(
          elevation: 2,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(16),
          ),
        ),
      ),
      darkTheme: ThemeData(
        useMaterial3: true,
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.blue,
          brightness: Brightness.dark,
        ),
        cardTheme: CardThemeData(
          elevation: 2,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(16),
          ),
        ),
      ),
      home: const DeviceMonitorScreen(),
    );
  }
}

class DeviceMonitorScreen extends StatefulWidget {
  const DeviceMonitorScreen({super.key});

  @override
  State<DeviceMonitorScreen> createState() => _DeviceMonitorScreenState();
}

class _DeviceMonitorScreenState extends State<DeviceMonitorScreen> {
  CpuInfo? _cpuInfo;
  GpuInfo? _gpuInfo;
  ThermalState? _thermalState;
  SystemUptime? _systemUptime;
  AdvancedCpuUsage? _advancedCpuUsage;

  bool _isLoading = false;
  String? _errorMessage;

  Timer? _refreshTimer;

  @override
  void initState() {
    super.initState();
    _loadAllData();
  }

  @override
  void dispose() {
    _refreshTimer?.cancel();
    super.dispose();
  }

  Future<void> _loadAllData() async {
    if (_isLoading) return;

    setState(() {
      _isLoading = true;
      _errorMessage = null;
    });

    try {
      final results = await Future.wait([
        IosDeviceMonitor.getCpuInfo(),
        IosDeviceMonitor.getGpuInfo(),
        IosDeviceMonitor.getThermalState(),
        IosDeviceMonitor.getSystemUptime(),
        IosDeviceMonitor.getAdvancedCpuUsage(),
      ]);

      setState(() {
        _cpuInfo = results[0] as CpuInfo;
        _gpuInfo = results[1] as GpuInfo;
        _thermalState = results[2] as ThermalState;
        _systemUptime = results[3] as SystemUptime;
        _advancedCpuUsage = results[4] as AdvancedCpuUsage;
        _isLoading = false;
      });
    } on PlatformException catch (e) {
      setState(() {
        _errorMessage = 'Platform Error: ${e.message}';
        _isLoading = false;
      });
    } catch (e) {
      setState(() {
        _errorMessage = 'Error: $e';
        _isLoading = false;
      });
    }
  }

  Future<void> _refreshCpuUsage() async {
    try {
      final cpuUsage = await IosDeviceMonitor.getAdvancedCpuUsage();
      setState(() {
        _advancedCpuUsage = cpuUsage;
      });
    } catch (e) {
      debugPrint('Failed to refresh CPU usage: $e');
    }
  }

  void _toggleAutoRefresh() {
    setState(() {
      if (_refreshTimer != null) {
        _refreshTimer?.cancel();
        _refreshTimer = null;
      } else {
        _refreshTimer = Timer.periodic(
          const Duration(seconds: 2),
          (_) => _refreshCpuUsage(),
        );
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    final colorScheme = Theme.of(context).colorScheme;

    return Scaffold(
      floatingActionButton: FloatingActionButton(onPressed: () {
        debugPrint('cpu');
        debugPrint(_cpuInfo?.architecture.toString());
        debugPrint(_cpuInfo?.coreCount.toString());
        debugPrint(_cpuInfo?.coreCountDescription.toString());
        debugPrint('\n\n\ngpu');
        debugPrint(_gpuInfo?.maxThreadsPerThreadgroup.toString());
        debugPrint(_gpuInfo?.name.toString());
        debugPrint(_gpuInfo?.recommendedMaxWorkingSetSize.toString());
        debugPrint(_gpuInfo?.registryID.toString());
        debugPrint(_gpuInfo?.supportedFeatures.toString());
        debugPrint(_gpuInfo?.supportsFamily.toString());
        debugPrint('\n\n\ntemperature');
        debugPrint(_thermalState?.description.toString());
        debugPrint(_thermalState?.isCritical.toString());
        debugPrint(_thermalState?.isThrottling.toString());
        debugPrint(_thermalState?.isWarning.toString());
        debugPrint(_thermalState?.level.toString());
        debugPrint(_thermalState?.state.toString());
        debugPrint(_thermalState?.statusMessage.toString());
        debugPrint(_thermalState?.thermalLevel.toString());
        debugPrint('\n\n\nsystemup time');
        debugPrint(_systemUptime?.bootDate.toString());
        debugPrint(_systemUptime?.bootDateFormatted.toString());
        debugPrint(_systemUptime?.bootTime.toString());
        debugPrint(_systemUptime?.hasBeenRunningForADay.toString());
        debugPrint(_systemUptime?.hasBeenRunningForAWeek.toString());
        debugPrint(_systemUptime?.shortUptimeDescription.toString());
        debugPrint(_systemUptime?.uptime.toString());
        debugPrint(_systemUptime?.uptimeDays.toString());
        debugPrint(_systemUptime?.uptimeFormatted.toString());
        debugPrint(_systemUptime?.uptimeHours.toString());
        debugPrint('\n\n\nadvanced');
        debugPrint(_advancedCpuUsage?.activeThreadCount.toString());
        debugPrint(_advancedCpuUsage?.averageCoreUsage.toString());
        debugPrint(_advancedCpuUsage?.coreCount.toString());
        debugPrint(_advancedCpuUsage?.detailedCoreUsages.toString());
        debugPrint(_advancedCpuUsage?.isHighUsage.toString());
        debugPrint(_advancedCpuUsage?.isLowUsage.toString());
        debugPrint(_advancedCpuUsage?.isMediumUsage.toString());
        debugPrint(_advancedCpuUsage?.systemTime.toString());
        debugPrint(_advancedCpuUsage?.threadDetails.toString());
        debugPrint(_advancedCpuUsage?.timestamp.toString());
        debugPrint(_advancedCpuUsage?.timestampDate.toString());
        debugPrint(_advancedCpuUsage?.timestampFormatted.toString());
        debugPrint(_advancedCpuUsage?.totalThreadCount.toString());
        debugPrint(_advancedCpuUsage?.totalTime.toString());
        debugPrint(_advancedCpuUsage?.usage.toString());
        debugPrint(_advancedCpuUsage?.usageLevel.toString());
        debugPrint(_advancedCpuUsage?.usagePercentageString.toString());
        debugPrint(_advancedCpuUsage?.userTime.toString());
      }),
      appBar: AppBar(
        title: const Text('iOS Device Monitor'),
        centerTitle: true,
        elevation: 0,
        backgroundColor: colorScheme.surface,
        foregroundColor: colorScheme.onSurface,
        actions: [
          IconButton(
            icon: Icon(_refreshTimer != null ? Icons.pause : Icons.play_arrow),
            tooltip: _refreshTimer != null
                ? 'Stop Auto-Refresh'
                : 'Start Auto-Refresh',
            onPressed: _advancedCpuUsage != null ? _toggleAutoRefresh : null,
          ),
        ],
      ),
      body: RefreshIndicator(
        onRefresh: _loadAllData,
        child: _buildBody(context, colorScheme),
      ),
    );
  }

  Widget _buildBody(BuildContext context, ColorScheme colorScheme) {
    if (_isLoading && _cpuInfo == null) {
      return Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            CircularProgressIndicator(
              color: colorScheme.primary,
            ),
            const SizedBox(height: 16),
            Text(
              'Loading device information...',
              style: TextStyle(
                color: colorScheme.onSurface.withValues(alpha: 0.7),
              ),
            ),
          ],
        ),
      );
    }

    if (_errorMessage != null && _cpuInfo == null) {
      return Center(
        child: Padding(
          padding: const EdgeInsets.all(24.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Icon(
                Icons.error_outline,
                size: 64,
                color: colorScheme.error,
              ),
              const SizedBox(height: 16),
              Text(
                'Failed to Load Data',
                style: Theme.of(context).textTheme.headlineSmall?.copyWith(
                      color: colorScheme.error,
                    ),
              ),
              const SizedBox(height: 8),
              Text(
                _errorMessage!,
                textAlign: TextAlign.center,
                style: TextStyle(
                  color: colorScheme.onSurface.withValues(alpha: 0.7),
                ),
              ),
              const SizedBox(height: 24),
              FilledButton.icon(
                onPressed: _loadAllData,
                icon: const Icon(Icons.refresh),
                label: const Text('Retry'),
              ),
            ],
          ),
        ),
      );
    }

    return ListView(
      padding: const EdgeInsets.all(16.0),
      children: [
        _buildCpuInfoSection(colorScheme),
        const SizedBox(height: 16),
        _buildGpuInfoSection(colorScheme),
        const SizedBox(height: 16),
        _buildThermalStateSection(colorScheme),
        const SizedBox(height: 16),
        _buildSystemUptimeSection(colorScheme),
        const SizedBox(height: 16),
        _buildAdvancedCpuUsageSection(colorScheme),
        const SizedBox(height: 16),
        Center(
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Text(
              'Pull down to refresh all data',
              style: TextStyle(
                color: colorScheme.onSurface.withValues(alpha: 0.5),
                fontSize: 12,
              ),
            ),
          ),
        ),
      ],
    );
  }

  Widget _buildCpuInfoSection(ColorScheme colorScheme) {
    if (_cpuInfo == null) return const SizedBox.shrink();

    return Card(
      child: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                Icon(
                  Icons.memory,
                  color: colorScheme.primary,
                  size: 28,
                ),
                const SizedBox(width: 12),
                Text(
                  'CPU Information',
                  style: Theme.of(context).textTheme.titleLarge?.copyWith(
                        fontWeight: FontWeight.bold,
                      ),
                ),
              ],
            ),
            const Divider(height: 24),
            _buildInfoRow(
              'Architecture',
              _cpuInfo!.architecture ?? 'Unknown',
              Icons.architecture,
              colorScheme,
            ),
            _buildInfoRow(
              'Core Count',
              _formatCoreCount(_cpuInfo!.coreCountDescription),
              Icons.grid_view,
              colorScheme,
            ),
            if (_cpuInfo!.architecture?.toLowerCase().contains('arm64') ??
                false)
              Padding(
                padding: const EdgeInsets.only(top: 12.0),
                child: Container(
                  padding:
                      const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
                  decoration: BoxDecoration(
                    color: colorScheme.primaryContainer,
                    borderRadius: BorderRadius.circular(8),
                  ),
                  child: Row(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Icon(
                        Icons.apple,
                        size: 16,
                        color: colorScheme.onPrimaryContainer,
                      ),
                      const SizedBox(width: 6),
                      Text(
                        'Apple Silicon',
                        style: TextStyle(
                          color: colorScheme.onPrimaryContainer,
                          fontWeight: FontWeight.w600,
                          fontSize: 12,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
          ],
        ),
      ),
    );
  }

  Widget _buildGpuInfoSection(ColorScheme colorScheme) {
    if (_gpuInfo == null) return const SizedBox.shrink();

    return Card(
      child: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                Icon(
                  Icons.videogame_asset,
                  color: colorScheme.secondary,
                  size: 28,
                ),
                const SizedBox(width: 12),
                Text(
                  'GPU Information',
                  style: Theme.of(context).textTheme.titleLarge?.copyWith(
                        fontWeight: FontWeight.bold,
                      ),
                ),
              ],
            ),
            const Divider(height: 24),
            _buildInfoRow(
              'GPU Name',
              _gpuInfo!.name,
              Icons.label,
              colorScheme,
            ),
            if (_formatBytes(_gpuInfo!.recommendedMaxWorkingSetSize) != null)
              _buildInfoRow(
                'Max Working Set',
                _formatBytes(_gpuInfo!.registryID)!,
                Icons.storage,
                colorScheme,
              ),
            if (_gpuInfo!.registryID != null)
              _buildInfoRow(
                'Registry ID',
                '${_gpuInfo!.registryID}',
                Icons.fingerprint,
                colorScheme,
              ),
            if (_gpuInfo!.maxThreadsPerThreadgroup != null)
              _buildInfoRow(
                'Max Threads/Group',
                '${_gpuInfo!.maxThreadsPerThreadgroup!.width}×'
                    '${_gpuInfo!.maxThreadsPerThreadgroup!.height}×'
                    '${_gpuInfo!.maxThreadsPerThreadgroup!.depth}',
                Icons.apps,
                colorScheme,
              ),
            if (_gpuInfo!.supportedFeatures.isNotEmpty) ...[
              const SizedBox(height: 12),
              Text(
                'Metal GPU Families',
                style: Theme.of(context).textTheme.labelLarge?.copyWith(
                      color: colorScheme.onSurface.withValues(alpha: 0.7),
                    ),
              ),
              const SizedBox(height: 8),
              Wrap(
                spacing: 8,
                runSpacing: 8,
                children: _gpuInfo!.supportedFeatures.map((feature) {
                  return Chip(
                    label: Text(
                      feature,
                      style: TextStyle(
                        fontSize: 11,
                        color: colorScheme.onSecondaryContainer,
                      ),
                    ),
                    backgroundColor: colorScheme.secondaryContainer,
                    padding: EdgeInsets.zero,
                    visualDensity: VisualDensity.compact,
                  );
                }).toList(),
              ),
            ],
          ],
        ),
      ),
    );
  }

  Widget _buildThermalStateSection(ColorScheme colorScheme) {
    if (_thermalState == null) return const SizedBox.shrink();

    Color thermalColor;
    IconData thermalIcon;

    if (_thermalState!.isCritical) {
      thermalColor = Colors.red;
      thermalIcon = Icons.whatshot;
    } else if (_thermalState!.isWarning) {
      thermalColor = Colors.orange;
      thermalIcon = Icons.warning_amber;
    } else {
      thermalColor = Colors.green;
      thermalIcon = Icons.check_circle;
    }

    return Card(
      child: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                Icon(
                  Icons.thermostat,
                  color: colorScheme.tertiary,
                  size: 28,
                ),
                const SizedBox(width: 12),
                Text(
                  'Thermal State',
                  style: Theme.of(context).textTheme.titleLarge?.copyWith(
                        fontWeight: FontWeight.bold,
                      ),
                ),
              ],
            ),
            const Divider(height: 24),
            Container(
              padding: const EdgeInsets.all(16),
              decoration: BoxDecoration(
                color: thermalColor.withValues(alpha: 0.1),
                borderRadius: BorderRadius.circular(12),
                border: Border.all(
                  color: thermalColor.withValues(alpha: 0.3),
                  width: 2,
                ),
              ),
              child: Row(
                children: [
                  Icon(
                    thermalIcon,
                    color: thermalColor,
                    size: 48,
                  ),
                  const SizedBox(width: 16),
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          _thermalState!.statusMessage ?? _thermalState!.state,
                          style: Theme.of(context)
                              .textTheme
                              .headlineSmall
                              ?.copyWith(
                                color: thermalColor,
                                fontWeight: FontWeight.bold,
                              ),
                        ),
                        const SizedBox(height: 4),
                        Text(
                          _thermalState!.description ??
                              'No description available',
                          style: TextStyle(
                            color: colorScheme.onSurface.withValues(alpha: 0.7),
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
            const SizedBox(height: 16),
            _buildInfoRow(
              'Thermal State',
              _thermalState!.state,
              Icons.info_outline,
              colorScheme,
            ),
            _buildInfoRow(
              'Level',
              '${_thermalState!.level}',
              Icons.layers,
              colorScheme,
            ),
            _buildInfoRow(
              'Throttling',
              _thermalState!.isThrottling ? 'Yes' : 'No',
              _thermalState!.isThrottling
                  ? Icons.speed
                  : Icons.check_circle_outline,
              colorScheme,
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildSystemUptimeSection(ColorScheme colorScheme) {
    if (_systemUptime == null) return const SizedBox.shrink();

    return Card(
      child: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                Icon(
                  Icons.access_time,
                  color: colorScheme.primary,
                  size: 28,
                ),
                const SizedBox(width: 12),
                Text(
                  'System Uptime',
                  style: Theme.of(context).textTheme.titleLarge?.copyWith(
                        fontWeight: FontWeight.bold,
                      ),
                ),
              ],
            ),
            const Divider(height: 24),
            Container(
              padding: const EdgeInsets.all(16),
              decoration: BoxDecoration(
                color: colorScheme.primaryContainer.withValues(alpha: 0.3),
                borderRadius: BorderRadius.circular(12),
              ),
              child: Row(
                children: [
                  Icon(
                    Icons.timer,
                    color: colorScheme.primary,
                    size: 48,
                  ),
                  const SizedBox(width: 16),
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          _systemUptime!.uptimeFormatted,
                          style: Theme.of(context)
                              .textTheme
                              .headlineSmall
                              ?.copyWith(
                                color: colorScheme.onSurface,
                                fontWeight: FontWeight.bold,
                              ),
                        ),
                        const SizedBox(height: 4),
                        Text(
                          _systemUptime!.shortUptimeDescription,
                          style: TextStyle(
                            color: colorScheme.onSurface.withValues(alpha: 0.7),
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
            const SizedBox(height: 16),
            _buildInfoRow(
              'Boot Date',
              _systemUptime!.bootDateFormatted,
              Icons.calendar_today,
              colorScheme,
            ),
            _buildInfoRow(
              'Uptime (seconds)',
              '${_systemUptime!.uptime.toStringAsFixed(0)}s',
              Icons.hourglass_bottom,
              colorScheme,
            ),
            _buildInfoRow(
              'Uptime (hours)',
              '${_systemUptime!.uptimeHours.toStringAsFixed(2)}h',
              Icons.schedule,
              colorScheme,
            ),
            _buildInfoRow(
              'Uptime (days)',
              '${_systemUptime!.uptimeDays.toStringAsFixed(2)} days',
              Icons.event,
              colorScheme,
            ),
            if (_systemUptime!.hasBeenRunningForAWeek)
              Padding(
                padding: const EdgeInsets.only(top: 12.0),
                child: Container(
                  padding:
                      const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
                  decoration: BoxDecoration(
                    color: Colors.amber.withValues(alpha: 0.2),
                    borderRadius: BorderRadius.circular(8),
                    border: Border.all(
                      color: Colors.amber,
                      width: 1,
                    ),
                  ),
                  child: Row(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      const Icon(
                        Icons.battery_alert,
                        size: 16,
                        color: Colors.amber,
                      ),
                      const SizedBox(width: 6),
                      Text(
                        'Consider restarting your device',
                        style: TextStyle(
                          color: colorScheme.onSurface,
                          fontWeight: FontWeight.w600,
                          fontSize: 12,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
          ],
        ),
      ),
    );
  }

  Widget _buildAdvancedCpuUsageSection(ColorScheme colorScheme) {
    if (_advancedCpuUsage == null) return const SizedBox.shrink();

    return Card(
      child: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                Icon(
                  Icons.show_chart,
                  color: colorScheme.secondary,
                  size: 28,
                ),
                const SizedBox(width: 12),
                Expanded(
                  child: Text(
                    'Advanced CPU Usage',
                    style: Theme.of(context).textTheme.titleLarge?.copyWith(
                          fontWeight: FontWeight.bold,
                        ),
                  ),
                ),
                if (_refreshTimer != null)
                  Container(
                    padding:
                        const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
                    decoration: BoxDecoration(
                      color: Colors.green.withValues(alpha: 0.2),
                      borderRadius: BorderRadius.circular(4),
                    ),
                    child: const Row(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Icon(Icons.refresh, size: 14, color: Colors.green),
                        SizedBox(width: 4),
                        Text(
                          'Live',
                          style: TextStyle(
                            color: Colors.green,
                            fontSize: 11,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ],
                    ),
                  ),
              ],
            ),
            const Divider(height: 24),
            Container(
              padding: const EdgeInsets.all(16),
              decoration: BoxDecoration(
                gradient: LinearGradient(
                  colors: [
                    colorScheme.secondaryContainer.withValues(alpha: 0.5),
                    colorScheme.secondaryContainer.withValues(alpha: 0.2),
                  ],
                  begin: Alignment.topLeft,
                  end: Alignment.bottomRight,
                ),
                borderRadius: BorderRadius.circular(12),
              ),
              child: Column(
                children: [
                  Text(
                    _advancedCpuUsage!.usagePercentageString,
                    style: Theme.of(context).textTheme.displayMedium?.copyWith(
                          color: colorScheme.onSurface,
                          fontWeight: FontWeight.bold,
                        ),
                  ),
                  const SizedBox(height: 8),
                  Text(
                    _advancedCpuUsage!.usageLevel,
                    style: Theme.of(context).textTheme.titleMedium?.copyWith(
                          color: colorScheme.onSurface.withValues(alpha: 0.7),
                        ),
                  ),
                  const SizedBox(height: 16),
                  LinearProgressIndicator(
                    value: _advancedCpuUsage!.usage / 100,
                    minHeight: 8,
                    borderRadius: BorderRadius.circular(4),
                    backgroundColor:
                        colorScheme.onSurface.withValues(alpha: 0.1),
                  ),
                ],
              ),
            ),
            const SizedBox(height: 16),
            _buildInfoRow(
              'User Time',
              '${_advancedCpuUsage!.userTime.toStringAsFixed(2)}s',
              Icons.person,
              colorScheme,
            ),
            _buildInfoRow(
              'System Time',
              '${_advancedCpuUsage!.systemTime.toStringAsFixed(2)}s',
              Icons.settings,
              colorScheme,
            ),
            _buildInfoRow(
              'Active Threads',
              '${_advancedCpuUsage!.activeThreadCount} / ${_advancedCpuUsage!.totalThreadCount}',
              Icons.account_tree,
              colorScheme,
            ),
            _buildInfoRow(
              'Core Count',
              '${_advancedCpuUsage!.coreCount}',
              Icons.grid_view,
              colorScheme,
            ),
            if (_advancedCpuUsage!.detailedCoreUsages.isNotEmpty) ...[
              const SizedBox(height: 16),
              Text(
                'Per-Core Usage',
                style: Theme.of(context).textTheme.titleMedium?.copyWith(
                      fontWeight: FontWeight.bold,
                    ),
              ),
              const SizedBox(height: 12),
              ..._advancedCpuUsage!.detailedCoreUsages.map((core) {
                return Padding(
                  padding: const EdgeInsets.only(bottom: 12.0),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          Text(
                            'Core ${core.coreIndex}',
                            style: TextStyle(
                              fontWeight: FontWeight.w600,
                              color: colorScheme.onSurface,
                            ),
                          ),
                          Text(
                            core.usageString,
                            style: TextStyle(
                              fontWeight: FontWeight.bold,
                              color: colorScheme.primary,
                            ),
                          ),
                        ],
                      ),
                      const SizedBox(height: 6),
                      LinearProgressIndicator(
                        value: core.usage / 100,
                        minHeight: 6,
                        borderRadius: BorderRadius.circular(3),
                        backgroundColor:
                            colorScheme.onSurface.withValues(alpha: 0.1),
                        color: _getCoreColor(core.usage, colorScheme),
                      ),
                    ],
                  ),
                );
              }),
            ],
            if (_advancedCpuUsage!.threadDetails
                .where((t) => t.isActive && t.cpuUsage > 0)
                .isNotEmpty) ...[
              const SizedBox(height: 16),
              Text(
                'Active Threads (${_advancedCpuUsage!.threadDetails.where((t) => t.isActive && t.cpuUsage > 0).length})',
                style: Theme.of(context).textTheme.titleMedium?.copyWith(
                      fontWeight: FontWeight.bold,
                    ),
              ),
              const SizedBox(height: 12),
              Container(
                constraints: const BoxConstraints(maxHeight: 300),
                child: ListView.builder(
                  shrinkWrap: true,
                  physics: const NeverScrollableScrollPhysics(),
                  itemCount: _advancedCpuUsage!.threadDetails
                              .where((t) => t.isActive && t.cpuUsage > 0)
                              .length >
                          10
                      ? 10
                      : _advancedCpuUsage!.threadDetails
                          .where((t) => t.isActive && t.cpuUsage > 0)
                          .length,
                  itemBuilder: (context, index) {
                    final activeThreads = _advancedCpuUsage!.threadDetails
                        .where((t) => t.isActive && t.cpuUsage > 0)
                        .toList();
                    final thread = activeThreads[index];
                    return Container(
                      margin: const EdgeInsets.only(bottom: 8),
                      padding: const EdgeInsets.all(12),
                      decoration: BoxDecoration(
                        color: colorScheme.surfaceContainerHighest,
                        borderRadius: BorderRadius.circular(8),
                      ),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Expanded(
                                child: Text(
                                  thread.displayName,
                                  style: const TextStyle(
                                    fontWeight: FontWeight.w600,
                                    fontSize: 13,
                                  ),
                                  maxLines: 1,
                                  overflow: TextOverflow.ellipsis,
                                ),
                              ),
                              Text(
                                thread.cpuUsageString,
                                style: TextStyle(
                                  fontWeight: FontWeight.bold,
                                  color: colorScheme.primary,
                                  fontSize: 13,
                                ),
                              ),
                            ],
                          ),
                        ],
                      ),
                    );
                  },
                ),
              ),
              if (_advancedCpuUsage!.threadDetails
                      .where((t) => t.isActive && t.cpuUsage > 0)
                      .length >
                  10)
                Padding(
                  padding: const EdgeInsets.only(top: 8.0),
                  child: Text(
                    'Showing 10 of ${_advancedCpuUsage!.threadDetails.where((t) => t.isActive && t.cpuUsage > 0).length} active threads',
                    style: TextStyle(
                      fontSize: 12,
                      color: colorScheme.onSurface.withValues(alpha: 0.5),
                      fontStyle: FontStyle.italic,
                    ),
                  ),
                ),
            ],
            const SizedBox(height: 16),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Icon(
                  Icons.access_time,
                  size: 14,
                  color: colorScheme.onSurface.withValues(alpha: 0.5),
                ),
                const SizedBox(width: 6),
                Text(
                  'Last updated: ${_formatTimestamp(_advancedCpuUsage!.timestamp)}',
                  style: TextStyle(
                    fontSize: 12,
                    color: colorScheme.onSurface.withValues(alpha: 0.5),
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildInfoRow(
    String label,
    String value,
    IconData icon,
    ColorScheme colorScheme,
  ) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 12.0),
      child: Row(
        children: [
          Icon(
            icon,
            size: 20,
            color: colorScheme.onSurface.withValues(alpha: 0.6),
          ),
          const SizedBox(width: 12),
          Expanded(
            child: Text(
              label,
              style: TextStyle(
                color: colorScheme.onSurface.withValues(alpha: 0.7),
                fontWeight: FontWeight.w500,
              ),
            ),
          ),
          const SizedBox(width: 12),
          Flexible(
            child: Text(
              value,
              textAlign: TextAlign.end,
              style: TextStyle(
                color: colorScheme.onSurface,
                fontWeight: FontWeight.w600,
              ),
            ),
          ),
        ],
      ),
    );
  }

  Color _getCoreColor(double usage, ColorScheme colorScheme) {
    if (usage > 80) return Colors.red;
    if (usage > 50) return Colors.orange;
    if (usage > 25) return colorScheme.primary;
    return Colors.green;
  }

  String _formatTimestamp(double timestamp) {
    final date =
        DateTime.fromMillisecondsSinceEpoch((timestamp * 1000).toInt());
    return '${date.hour.toString().padLeft(2, '0')}:'
        '${date.minute.toString().padLeft(2, '0')}:'
        '${date.second.toString().padLeft(2, '0')}';
  }

  String _formatCoreCount(Map<String, int?> cores) {
    final physical = cores['physical'];
    final logical = cores['logical'];
    final total = cores['total'];
    if (physical != null && logical != null) {
      return '$physical Physical, $logical Logical';
    }
    return '${total ?? 0} Cores';
  }

  String? _formatBytes(int? bytes) {
    if (bytes == null) return null;
    if (bytes >= 1024 * 1024 * 1024) {
      return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(2)} GB';
    } else if (bytes >= 1024 * 1024) {
      return '${(bytes / (1024 * 1024)).toStringAsFixed(2)} MB';
    }
    return '$bytes B';
  }
}
0
likes
145
points
14
downloads

Publisher

unverified uploader

Weekly Downloads

Comprehensive iOS device monitoring plugin with CPU, GPU, thermal, uptime, and advanced CPU usage tracking.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on ios_device_monitor

Packages that implement ios_device_monitor