core_controller.dart 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'package:get/get.dart';
  4. import '../../pigeons/core_api.g.dart';
  5. import '../../utils/haptic_feedback_manager.dart';
  6. import '../../utils/log/logger.dart';
  7. import '../constants/enums.dart';
  8. import '../data/models/vpn_message.dart';
  9. class CoreController extends GetxService {
  10. final TAG = 'CoreController';
  11. final _state = ConnectionState.disconnected.obs;
  12. ConnectionState get state => _state.value;
  13. set state(ConnectionState value) => _state.value = value;
  14. final _timer = "00:00:00".obs;
  15. String get timer => _timer.value;
  16. set timer(String value) => _timer.value = value;
  17. // 事件流订阅
  18. StreamSubscription<String>? _eventSubscription;
  19. @override
  20. void onInit() {
  21. super.onInit();
  22. _initCheckConnect();
  23. _startListeningToEvents();
  24. }
  25. @override
  26. void onClose() {
  27. super.onClose();
  28. // 取消事件流订阅
  29. _eventSubscription?.cancel();
  30. _eventSubscription = null;
  31. }
  32. void _initCheckConnect() {
  33. CoreApi().isConnected().then((value) {
  34. if (value == true) {
  35. state = ConnectionState.connected;
  36. CoreApi().reconnect();
  37. } else {
  38. state = ConnectionState.disconnected;
  39. }
  40. });
  41. }
  42. void handleConnection() {
  43. if (state == ConnectionState.disconnected) {
  44. // 开始连接 - 轻微震动
  45. state = ConnectionState.connecting;
  46. HapticFeedbackManager.connectionStart();
  47. CoreApi().connect();
  48. } else {
  49. // 断开连接
  50. state = ConnectionState.disconnecting;
  51. CoreApi().disconnect();
  52. }
  53. }
  54. /// 开始监听来自 Android 的事件
  55. void _startListeningToEvents() {
  56. _eventSubscription = onEventChange().listen(
  57. _handleEventChange,
  58. onError: (error) {
  59. log(TAG, '事件流错误: $error');
  60. },
  61. );
  62. }
  63. // 处理从原生端接收到的消息
  64. void _handleEventChange(String message) {
  65. try {
  66. final Map<String, dynamic> json = jsonDecode(message);
  67. final String type = json['type'] ?? '';
  68. switch (type) {
  69. case 'vpn_status':
  70. _handleVpnStatus(VpnStatusMessage.fromJson(json));
  71. break;
  72. case 'timer_update':
  73. _handleTimerUpdate(TimerUpdateMessage.fromJson(json));
  74. break;
  75. default:
  76. log(TAG, '未知消息类型: $type');
  77. }
  78. } catch (e) {
  79. log(TAG, '解析消息失败: $e');
  80. }
  81. }
  82. void _handleVpnStatus(VpnStatusMessage message) {
  83. log(TAG, 'VPN状态变化: status=${message.status}, message=${message.message}');
  84. // 根据状态码处理不同的VPN状态
  85. switch (message.status) {
  86. case 0:
  87. // disconnected
  88. _onVpnDisconnected();
  89. break;
  90. case 1:
  91. // connecting
  92. _onVpnConnecting();
  93. break;
  94. case 2:
  95. // connected
  96. _onVpnConnected();
  97. break;
  98. case 3:
  99. // error
  100. _onVpnError(message.message);
  101. break;
  102. case 4:
  103. // disconnecting
  104. _onVpnDisconnecting();
  105. break;
  106. case 403:
  107. // permission denied
  108. _onVpnPermissionDenied();
  109. break;
  110. default:
  111. log(TAG, '未知VPN状态: ${message.status}');
  112. }
  113. }
  114. void _handleTimerUpdate(TimerUpdateMessage message) {
  115. log(
  116. TAG,
  117. '计时更新: time=${message.currentTime}, mode=${message.mode}, running=${message.isRunning}, paused=${message.isPaused}',
  118. );
  119. timer = _formatTime(message.currentTime);
  120. // 处理计时更新
  121. if (message.isRunning) {
  122. if (message.isPaused) {
  123. _onTimerPaused(message.currentTime, message.mode);
  124. } else {
  125. _onTimerRunning(message.currentTime, message.mode);
  126. }
  127. } else {
  128. _onTimerStopped();
  129. }
  130. }
  131. // VPN状态处理方法
  132. void _onVpnDisconnected() {
  133. log(TAG, 'VPN已断开连接');
  134. // 更新UI状态
  135. state = ConnectionState.disconnected;
  136. timer = "00:00:00";
  137. HapticFeedbackManager.connectionDisconnected();
  138. }
  139. void _onVpnConnecting() {
  140. log(TAG, 'VPN正在连接');
  141. // 显示连接中状态
  142. state = ConnectionState.connecting;
  143. }
  144. void _onVpnConnected() {
  145. log(TAG, 'VPN已连接');
  146. // 显示已连接状态
  147. state = ConnectionState.connected;
  148. HapticFeedbackManager.connectionSuccess();
  149. }
  150. void _onVpnError(String errorMessage) {
  151. log(TAG, 'VPN连接错误: $errorMessage');
  152. // 显示错误信息
  153. state = ConnectionState.disconnected;
  154. HapticFeedbackManager.connectionDisconnected();
  155. // 可以显示错误提示
  156. Get.snackbar('连接失败', '无法建立连接,请重试');
  157. }
  158. void _onVpnDisconnecting() {
  159. log(TAG, 'VPN正在断开连接');
  160. // 显示断开连接状态
  161. state = ConnectionState.disconnecting;
  162. }
  163. void _onVpnPermissionDenied() {
  164. log(TAG, 'VPN权限拒绝');
  165. // 显示权限拒绝状态
  166. state = ConnectionState.disconnected;
  167. HapticFeedbackManager.connectionDisconnected();
  168. // 可以显示错误提示
  169. Get.snackbar('权限拒绝', '无法建立连接,请重试');
  170. }
  171. // 计时器状态处理方法
  172. void _onTimerRunning(int currentTime, int mode) {
  173. log(
  174. TAG,
  175. '计时器运行中: ${_formatTime(currentTime)}, 模式: ${mode == 0 ? "普通计时" : "倒计时"}',
  176. );
  177. }
  178. void _onTimerPaused(int currentTime, int mode) {
  179. log(
  180. TAG,
  181. '计时器已暂停: ${_formatTime(currentTime)}, 模式: ${mode == 0 ? "普通计时" : "倒计时"}',
  182. );
  183. }
  184. void _onTimerStopped() {
  185. log(TAG, '计时器已停止');
  186. }
  187. // 格式化时间显示
  188. String _formatTime(int timeMs) {
  189. final totalSeconds = (timeMs / 1000).abs().round();
  190. final days = totalSeconds ~/ 86400; // 86400 = 24 * 3600
  191. final hours = (totalSeconds % 86400) ~/ 3600;
  192. final minutes = (totalSeconds % 3600) ~/ 60;
  193. final seconds = totalSeconds % 60;
  194. if (days > 0) {
  195. return '$days days ${hours.toString().padLeft(2, '0')}:${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
  196. } else if (hours > 0) {
  197. return '${hours.toString().padLeft(2, '0')}:${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
  198. } else {
  199. return '00:${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
  200. }
  201. }
  202. }