Skip to content

Commit 720cb77

Browse files
ovironclaude
andcommitted
style: format Phase E files and satisfy detekt/DCM lint
CI lint gates that flutter analyze does not cover: dart format the new library/ + picker + test files, drop the now-unused kLibLabels const (check-unused-code), and extract AarInstaller.verify so install stays within detekt's ThrowsCount limit. No behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent ffce9d0 commit 720cb77

8 files changed

Lines changed: 94 additions & 58 deletions

File tree

android/app/src/main/kotlin/com/follow/clash/AarInstaller.kt

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,7 @@ object AarInstaller {
3131
requiredSo: List<String>,
3232
dirName: String,
3333
): File {
34-
val sha = sha256(aar)
35-
if (!sha.equals(expectedSha256, ignoreCase = true)) {
36-
throw InstallException("SHA-256 mismatch: expected $expectedSha256, got $sha")
37-
}
38-
if (!verifyDetached(context, aar, asc)) {
39-
throw InstallException("GPG signature verification failed")
40-
}
34+
verify(context, aar, asc, expectedSha256)
4135
val libsRoot = File(context.filesDir, "libs").apply { mkdirs() }
4236
val tmp = File(libsRoot, "$dirName.tmp")
4337
if (tmp.exists()) tmp.deleteRecursively()
@@ -58,6 +52,16 @@ object AarInstaller {
5852
return dest
5953
}
6054

55+
private fun verify(context: Context, aar: File, asc: File, expectedSha256: String) {
56+
val sha = sha256(aar)
57+
if (!sha.equals(expectedSha256, ignoreCase = true)) {
58+
throw InstallException("SHA-256 mismatch: expected $expectedSha256, got $sha")
59+
}
60+
if (!verifyDetached(context, aar, asc)) {
61+
throw InstallException("GPG signature verification failed")
62+
}
63+
}
64+
6165
private fun sha256(f: File): String {
6266
val md = MessageDigest.getInstance("SHA-256")
6367
f.inputStream().use { ins ->

lib/library/library_plugin.dart

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ class LibraryPlugin {
3939
await _channel.invokeListMethod<dynamic>(LibraryMethod.listInstalled) ??
4040
const [];
4141
return list
42-
.map((e) => InstalledLibrary.fromMap((e as Map).cast<String, dynamic>()))
42+
.map(
43+
(e) => InstalledLibrary.fromMap((e as Map).cast<String, dynamic>()),
44+
)
4345
.toList();
4446
}
4547

@@ -60,19 +62,22 @@ class LibraryPlugin {
6062
required String label,
6163
required String version,
6264
}) async {
63-
final dir = await _channel.invokeMethod<String>(LibraryMethod.installFromAar, {
64-
'aarPath': aarPath,
65-
'ascPath': ascPath,
66-
'sha256': sha256,
67-
'label': label,
68-
'version': version,
69-
});
65+
final dir = await _channel
66+
.invokeMethod<String>(LibraryMethod.installFromAar, {
67+
'aarPath': aarPath,
68+
'ascPath': ascPath,
69+
'sha256': sha256,
70+
'label': label,
71+
'version': version,
72+
});
7073
if (dir == null) throw StateError('installFromAar returned null');
7174
return dir;
7275
}
7376

74-
Future<void> setActive(String label, String dir) =>
75-
_channel.invokeMethod(LibraryMethod.setActive, {'label': label, 'dir': dir});
77+
Future<void> setActive(String label, String dir) => _channel.invokeMethod(
78+
LibraryMethod.setActive,
79+
{'label': label, 'dir': dir},
80+
);
7681

7782
Future<void> clearActive(String label) =>
7883
_channel.invokeMethod(LibraryMethod.clearActive, {'label': label});

lib/library/model.dart

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
const kLibMihomo = 'mihomo';
22
const kLibByedpi = 'byedpi';
33

4-
const kLibLabels = [kLibMihomo, kLibByedpi];
5-
6-
String repoFor(String label) =>
7-
label == kLibMihomo ? 'oviron/libmihomo-android' : 'oviron/libbyedpi-android';
4+
String repoFor(String label) => label == kLibMihomo
5+
? 'oviron/libmihomo-android'
6+
: 'oviron/libbyedpi-android';
87

98
// A wrapper release as advertised by its metadata.json GitHub release asset.
109
class LibraryRelease {
@@ -31,7 +30,9 @@ class LibraryRelease {
3130
});
3231

3332
bool compatibleWith({required int? expectedAbi, required String deviceAbi}) =>
34-
expectedAbi != null && bridgeAbi == expectedAbi && abis.contains(deviceAbi);
33+
expectedAbi != null &&
34+
bridgeAbi == expectedAbi &&
35+
abis.contains(deviceAbi);
3536
}
3637

3738
class InstalledLibrary {

lib/library/providers.dart

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ class LibraryController extends Notifier<void> {
5151
ref.invalidate(installedLibrariesProvider);
5252
}
5353

54-
Future<void> switchTo(InstalledLibrary lib, {required bool wasRunning}) async {
54+
Future<void> switchTo(
55+
InstalledLibrary lib, {
56+
required bool wasRunning,
57+
}) async {
5558
await applyLibrarySelection(
5659
label: lib.label,
5760
dir: lib.dir,
@@ -63,7 +66,11 @@ class LibraryController extends Notifier<void> {
6366
}
6467

6568
Future<void> resetToBundled(String label, {required bool wasRunning}) async {
66-
await applyLibrarySelection(label: label, dir: null, wasRunning: wasRunning);
69+
await applyLibrarySelection(
70+
label: label,
71+
dir: null,
72+
wasRunning: wasRunning,
73+
);
6774
ref.invalidate(activeLibraryDirsProvider);
6875
}
6976

lib/library/releases_client.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ class ReleasesClient {
4848
meta['browser_download_url'] as String,
4949
options: Options(responseType: ResponseType.plain),
5050
);
51-
final m = (jsonDecode(metaRes.data ?? '{}') as Map).cast<String, dynamic>();
51+
final m = (jsonDecode(metaRes.data ?? '{}') as Map)
52+
.cast<String, dynamic>();
5253
final core = (m['core'] as Map?)?.cast<String, dynamic>() ?? const {};
5354
final tag = r['tag_name'] as String;
5455

lib/views/setting/library_version.dart

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ class LibraryVersionView extends ConsumerWidget {
1919
Widget build(BuildContext context, WidgetRef ref) {
2020
// Single source of truth for byedpi presence: the build flavor flag, never
2121
// native reflection. A non-byedpi build shows zero byedpi here, period.
22-
final labels = [
23-
kLibMihomo,
24-
if (kByeDpiEnabled) kLibByedpi,
25-
];
22+
final labels = [kLibMihomo, if (kByeDpiEnabled) kLibByedpi];
2623
return BaseScaffold(
2724
title: Intl.message('Library version', name: 'libraryVersion'),
2825
actions: [
@@ -38,9 +35,7 @@ class LibraryVersionView extends ConsumerWidget {
3835
],
3936
body: ListView(
4037
padding: const EdgeInsets.only(bottom: 24),
41-
children: [
42-
for (final label in labels) _CoreSection(label: label),
43-
],
38+
children: [for (final label in labels) _CoreSection(label: label)],
4439
),
4540
);
4641
}
@@ -65,7 +60,9 @@ class _CoreSectionState extends ConsumerState<_CoreSection> {
6560
await action();
6661
} catch (e) {
6762
if (mounted) {
68-
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('$e')));
63+
ScaffoldMessenger.of(
64+
context,
65+
).showSnackBar(SnackBar(content: Text('$e')));
6966
}
7067
} finally {
7168
if (mounted) setState(() => _busy.remove(key));
@@ -90,7 +87,8 @@ class _CoreSectionState extends ConsumerState<_CoreSection> {
9087
final label = widget.label;
9188
final expected = ref.watch(libraryExpectedAbiProvider).value ?? const {};
9289
final deviceAbi = ref.watch(libraryDeviceAbiProvider).value ?? '';
93-
final active = (ref.watch(activeLibraryDirsProvider).value ?? const {})[label];
90+
final active =
91+
(ref.watch(activeLibraryDirsProvider).value ?? const {})[label];
9492
final installed = (ref.watch(installedLibrariesProvider).value ?? const [])
9593
.where((e) => e.label == label)
9694
.toList();
@@ -153,7 +151,9 @@ class _CoreSectionState extends ConsumerState<_CoreSection> {
153151
),
154152
error: (e, _) => ListTile(
155153
leading: const Icon(Icons.error_outline),
156-
title: Text(Intl.message('Failed to load releases', name: 'libLoadError')),
154+
title: Text(
155+
Intl.message('Failed to load releases', name: 'libLoadError'),
156+
),
157157
subtitle: Text('$e'),
158158
),
159159
data: (releases) => Column(
@@ -203,7 +203,8 @@ class _CoreSectionState extends ConsumerState<_CoreSection> {
203203
tooltip: Intl.message('Delete', name: 'libDelete'),
204204
onPressed: _busy.isNotEmpty
205205
? null
206-
: () => _guard('del-${lib.version}', () => controller.delete(lib)),
206+
: () =>
207+
_guard('del-${lib.version}', () => controller.delete(lib)),
207208
),
208209
],
209210
);

test/byedpi/strategies_asset_test.dart

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,16 @@ void main() {
1717
expect(list.map((e) => e.id).toSet().length, list.length); // unique ids
1818

1919
for (final s in list) {
20-
expect(s.args.contains('"'), isFalse, reason: '${s.id} has a literal quote');
21-
expect(s.args.contains('{sni}'), isFalse, reason: '${s.id} has an unresolved {sni}');
20+
expect(
21+
s.args.contains('"'),
22+
isFalse,
23+
reason: '${s.id} has a literal quote',
24+
);
25+
expect(
26+
s.args.contains('{sni}'),
27+
isFalse,
28+
reason: '${s.id} has an unresolved {sni}',
29+
);
2230
}
2331
});
2432
}

test/library/model_test.dart

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
import 'package:fl_clash/library/model.dart';
22
import 'package:flutter_test/flutter_test.dart';
33

4-
LibraryRelease _rel({required int abi, List<String> abis = const ['arm64-v8a']}) =>
5-
LibraryRelease(
6-
label: kLibMihomo,
7-
version: '0.1.4',
8-
coreName: 'mihomo',
9-
coreVersion: 'v1.19.26',
10-
bridgeAbi: abi,
11-
abis: abis,
12-
aarUrl: 'https://example/a.aar',
13-
ascUrl: 'https://example/a.aar.asc',
14-
sha256: 'deadbeef',
15-
);
4+
LibraryRelease _rel({
5+
required int abi,
6+
List<String> abis = const ['arm64-v8a'],
7+
}) => LibraryRelease(
8+
label: kLibMihomo,
9+
version: '0.1.4',
10+
coreName: 'mihomo',
11+
coreVersion: 'v1.19.26',
12+
bridgeAbi: abi,
13+
abis: abis,
14+
aarUrl: 'https://example/a.aar',
15+
ascUrl: 'https://example/a.aar.asc',
16+
sha256: 'deadbeef',
17+
);
1618

1719
void main() {
1820
group('LibraryRelease.compatibleWith', () {
@@ -32,18 +34,25 @@ void main() {
3234

3335
test('device abi absent from release abis is incompatible', () {
3436
expect(
35-
_rel(abi: 1, abis: const ['x86_64'])
36-
.compatibleWith(expectedAbi: 1, deviceAbi: 'arm64-v8a'),
37+
_rel(
38+
abi: 1,
39+
abis: const ['x86_64'],
40+
).compatibleWith(expectedAbi: 1, deviceAbi: 'arm64-v8a'),
3741
isFalse,
3842
);
3943
});
4044

41-
test('null expectedAbi (e.g. byedpi absent in classic) is incompatible', () {
42-
expect(
43-
_rel(abi: 1).compatibleWith(expectedAbi: null, deviceAbi: 'arm64-v8a'),
44-
isFalse,
45-
);
46-
});
45+
test(
46+
'null expectedAbi (e.g. byedpi absent in classic) is incompatible',
47+
() {
48+
expect(
49+
_rel(
50+
abi: 1,
51+
).compatibleWith(expectedAbi: null, deviceAbi: 'arm64-v8a'),
52+
isFalse,
53+
);
54+
},
55+
);
4756
});
4857

4958
group('InstalledLibrary.fromMap', () {

0 commit comments

Comments
 (0)