Adjust android process
This commit is contained in:
@@ -5,19 +5,45 @@ import 'package:fl_clash/enum/enum.dart';
|
||||
import 'package:fl_clash/plugins/app.dart';
|
||||
import 'package:fl_clash/providers/providers.dart';
|
||||
import 'package:fl_clash/state.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:wifi_ssid/wifi_ssid_manager.dart';
|
||||
|
||||
enum LocationPermissionFollowUp { none, showDeniedMessage, openSettings }
|
||||
|
||||
LocationPermissionFollowUp getLocationPermissionFollowUp(
|
||||
WifiSsidPermission permission,
|
||||
) {
|
||||
return switch (permission) {
|
||||
WifiSsidPermission.granted => LocationPermissionFollowUp.none,
|
||||
WifiSsidPermission.denied => LocationPermissionFollowUp.showDeniedMessage,
|
||||
WifiSsidPermission.permanentlyDenied =>
|
||||
LocationPermissionFollowUp.openSettings,
|
||||
};
|
||||
}
|
||||
|
||||
class Permissions {
|
||||
static Permissions? _instance;
|
||||
|
||||
Permissions._internal();
|
||||
Permissions._internal({bool Function()? supportsLocationPermissions})
|
||||
: _supportsLocationPermissions =
|
||||
supportsLocationPermissions ??
|
||||
(() => system.isAndroid || system.isMacOS);
|
||||
|
||||
factory Permissions() {
|
||||
_instance ??= Permissions._internal();
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
@visibleForTesting
|
||||
factory Permissions.test({required bool supportsLocationPermissions}) {
|
||||
return Permissions._internal(
|
||||
supportsLocationPermissions: () => supportsLocationPermissions,
|
||||
);
|
||||
}
|
||||
|
||||
final bool Function() _supportsLocationPermissions;
|
||||
|
||||
bool _isRequestingLocation = false;
|
||||
bool needWaitingBatteryOptimizationSettings = false;
|
||||
|
||||
@@ -53,7 +79,7 @@ class Permissions {
|
||||
}
|
||||
|
||||
Future<void> checkLocationPermissions() async {
|
||||
if (!(system.isAndroid || system.isMacOS)) {
|
||||
if (!_supportsLocationPermissions()) {
|
||||
return;
|
||||
}
|
||||
final res = await WifiSsidManager.instance.checkPermission();
|
||||
@@ -74,7 +100,7 @@ class Permissions {
|
||||
final res = await WifiSsidManager.instance.requestPermission();
|
||||
globalState.container.read(locationPermissionsProvider.notifier).value =
|
||||
res;
|
||||
if (res != WifiSsidPermission.granted) {
|
||||
if (res == WifiSsidPermission.granted) {
|
||||
final ssid = await WifiSsidManager.instance.getSsid();
|
||||
globalState.container.read(currentSSIDProvider.notifier).value = ssid;
|
||||
}
|
||||
|
||||
@@ -53,14 +53,6 @@ class _AndroidContainerState extends ConsumerState<AndroidManager>
|
||||
super.onServiceEvent(event);
|
||||
}
|
||||
|
||||
@override
|
||||
void onServiceCrash(String message) {
|
||||
coreEventManager.sendEvent(
|
||||
CoreEvent(type: CoreEventType.crash, data: message),
|
||||
);
|
||||
super.onServiceCrash(message);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return widget.child;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:fl_clash/common/app_localizations.dart';
|
||||
import 'package:fl_clash/core/controller.dart';
|
||||
import 'package:fl_clash/enum/enum.dart';
|
||||
import 'package:fl_clash/plugins/app.dart';
|
||||
import 'package:fl_clash/plugins/tile.dart';
|
||||
import 'package:fl_clash/providers/providers.dart';
|
||||
@@ -25,10 +25,10 @@ class _TileContainerState extends ConsumerState<TileManager> with TileListener {
|
||||
|
||||
@override
|
||||
Future<void> onStart() async {
|
||||
if (isStart && coreController.isCompleted) {
|
||||
if (isStart && ref.read(coreStatusProvider) == CoreStatus.connected) {
|
||||
return;
|
||||
}
|
||||
ref.read(setupActionProvider.notifier).updateStatus(true);
|
||||
ref.read(setupActionProvider.notifier).setRunning(true);
|
||||
app?.tip(currentAppLocalizations.startVpn);
|
||||
super.onStart();
|
||||
}
|
||||
@@ -38,7 +38,7 @@ class _TileContainerState extends ConsumerState<TileManager> with TileListener {
|
||||
if (!isStart) {
|
||||
return;
|
||||
}
|
||||
ref.read(setupActionProvider.notifier).updateStatus(false);
|
||||
ref.read(setupActionProvider.notifier).setRunning(false);
|
||||
app?.tip(currentAppLocalizations.stopVpn);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ class _VpnContainerState extends ConsumerState<VpnManager> {
|
||||
actionText: currentAppLocalizations.restart,
|
||||
action: () async {
|
||||
final setupAction = ref.read(setupActionProvider.notifier);
|
||||
await setupAction.handleStop();
|
||||
await setupAction.updateStatus(true);
|
||||
await setupAction.setRunning(false);
|
||||
await setupAction.setRunning(true);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
@@ -102,6 +102,17 @@ class App {
|
||||
if (!Platform.isAndroid) return false;
|
||||
return methodChannel.invokeMethod<bool>('openAppSettings');
|
||||
}
|
||||
|
||||
Future<bool> didCrashOnPreviousExecution() async {
|
||||
try {
|
||||
return await methodChannel.invokeMethod<bool>(
|
||||
'didCrashOnPreviousExecution',
|
||||
) ??
|
||||
false;
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final app = system.isAndroid ? App() : null;
|
||||
|
||||
+22
-15
@@ -3,14 +3,15 @@ import 'dart:convert';
|
||||
import 'dart:isolate';
|
||||
|
||||
import 'package:fl_clash/common/common.dart';
|
||||
import 'package:fl_clash/core/event.dart';
|
||||
import 'package:fl_clash/core/method.dart';
|
||||
import 'package:fl_clash/enum/enum.dart';
|
||||
import 'package:fl_clash/models/models.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
abstract mixin class ServiceListener {
|
||||
void onServiceEvent(CoreEvent event) {}
|
||||
|
||||
void onServiceCrash(String message) {}
|
||||
}
|
||||
|
||||
class Service {
|
||||
@@ -32,15 +33,21 @@ class Service {
|
||||
switch (call.method) {
|
||||
case 'event':
|
||||
final data = call.arguments as String? ?? '';
|
||||
final result = ActionResult.fromJson(json.decode(data));
|
||||
for (final listener in _listeners) {
|
||||
listener.onServiceEvent(CoreEvent.fromJson(result.data));
|
||||
}
|
||||
break;
|
||||
case 'crash':
|
||||
final message = call.arguments as String? ?? '';
|
||||
for (final listener in _listeners) {
|
||||
listener.onServiceCrash(message);
|
||||
final methodCall = CoreMethodCall.fromJson(
|
||||
Map<String, Object?>.from(json.decode(data) as Map),
|
||||
);
|
||||
for (final event in coreEventsFromData(methodCall.arguments)) {
|
||||
for (final listener in _listeners) {
|
||||
try {
|
||||
listener.onServiceEvent(event);
|
||||
} catch (error) {
|
||||
commonPrint.log(
|
||||
'Unable to dispatch Android Core event '
|
||||
'${event.type.name}: $error',
|
||||
logLevel: LogLevel.error,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -49,16 +56,16 @@ class Service {
|
||||
});
|
||||
}
|
||||
|
||||
Future<ActionResult?> invokeAction(Action action) async {
|
||||
Future<CoreMethodResponse?> invokeMethod(CoreMethodCall call) async {
|
||||
final data = await methodChannel.invokeMethod<String>(
|
||||
'invokeAction',
|
||||
json.encode(action),
|
||||
'invokeMethod',
|
||||
json.encode(call),
|
||||
);
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
final dataJson = await data.commonToJSON<dynamic>();
|
||||
return ActionResult.fromJson(dataJson);
|
||||
return CoreMethodResponse.fromJson(dataJson);
|
||||
}
|
||||
|
||||
Future<bool> start() async {
|
||||
|
||||
Reference in New Issue
Block a user