Skip to content

Commit c13a3f8

Browse files
authored
✨ Add Cronet embedded tool (#853)
1 parent f4b365e commit c13a3f8

File tree

4 files changed

+119
-0
lines changed

4 files changed

+119
-0
lines changed

pkgs/cronet_http/README_EMBEDDED.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
An Android Flutter plugin that provides access to the
2+
[Cronet](https://developer.android.com/guide/topics/connectivity/cronet/reference/org/chromium/net/package-summary)
3+
HTTP client.
4+
5+
This package is identical to [`package:cronet_http`](https://pub.dev/packages/cronet_http)
6+
except that it embeds
7+
[Cronet](https://developer.android.com/guide/topics/connectivity/cronet/reference/org/chromium/net/package-summary)
8+
rather than using the version included with
9+
[Google Play Services](https://developers.google.com/android/guides/overview).
10+
This increases the uncompressed size of the application by approximately 8MB.
11+
12+
See more details about cronet_http at: https://pub.dev/packages/cronet_http.

pkgs/cronet_http/pubspec.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ dependencies:
1616
dev_dependencies:
1717
lints: ^1.0.0
1818
pigeon: ^3.2.3
19+
xml: ^6.1.0
20+
yaml_edit: ^2.0.3
1921

2022
flutter:
2123
plugin:
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// The cronet_http directory is used to produce two packages:
6+
/// - `cronet_http`, which uses the Google Play Services version of Cronet.
7+
/// - `cronet_http_embedded`, which embeds Cronet.
8+
///
9+
/// The default configuration of this code is to use the
10+
/// Google Play Services version of Cronet.
11+
///
12+
/// The script transforms the configuration into one that embeds Cronet by:
13+
/// 1. Modifying the Gradle build file to reference the embedded Cronet.
14+
/// 2. Modifying the *name* and *description* in `pubspec.yaml`.
15+
/// 3. Replacing `README.md` with `README_EMBEDDED.md`.
16+
///
17+
/// After running this script, `flutter pub publish`
18+
/// can be run to update package:cronet_http_embedded.
19+
///
20+
/// NOTE: This script modifies the above files in place.
21+
22+
import 'dart:io';
23+
24+
import 'package:http/http.dart' as http;
25+
import 'package:xml/xml.dart';
26+
import 'package:yaml_edit/yaml_edit.dart';
27+
28+
late final Directory _packageDirectory;
29+
30+
const _gmsDependencyName = 'com.google.android.gms:play-services-cronet';
31+
const _embeddedDependencyName = 'org.chromium.net:cronet-embedded';
32+
const _packageName = 'cronet_http_embedded';
33+
const _packageDescription = 'An Android Flutter plugin that '
34+
'provides access to the Cronet HTTP client. '
35+
'Identical to package:cronet_http except that it embeds Cronet '
36+
'rather than relying on Google Play Services.';
37+
final _cronetVersionUri = Uri.https(
38+
'dl.google.com',
39+
'android/maven2/org/chromium/net/group-index.xml',
40+
);
41+
42+
void main() async {
43+
if (Directory.current.path.endsWith('tool')) {
44+
_packageDirectory = Directory.current.parent;
45+
} else {
46+
_packageDirectory = Directory.current;
47+
}
48+
49+
final latestVersion = await _getLatestCronetVersion();
50+
updateCronetDependency(latestVersion);
51+
updatePubSpec();
52+
updateReadme();
53+
}
54+
55+
Future<String> _getLatestCronetVersion() async {
56+
final response = await http.get(_cronetVersionUri);
57+
final parsedXml = XmlDocument.parse(response.body);
58+
final embeddedNode = parsedXml.children
59+
.singleWhere((e) => e is XmlElement)
60+
.children
61+
.singleWhere((e) => e is XmlElement && e.name.local == 'cronet-embedded');
62+
final stableVersionReg = RegExp(r'^\d+.\d+.\d+$');
63+
final versions = embeddedNode.attributes
64+
.singleWhere((e) => e.name.local == 'versions')
65+
.value
66+
.split(',')
67+
.where((e) => stableVersionReg.stringMatch(e) == e);
68+
return versions.last;
69+
}
70+
71+
/// Update android/build.gradle
72+
void updateCronetDependency(String latestVersion) {
73+
final fBuildGradle = File('${_packageDirectory.path}/android/build.gradle');
74+
final gradleContent = fBuildGradle.readAsStringSync();
75+
final implementationRegExp = RegExp(
76+
'^\\s*implementation [\'"]'
77+
'$_gmsDependencyName'
78+
':\\d+.\\d+.\\d+[\'"]',
79+
multiLine: true,
80+
);
81+
final newImplementation = '$_embeddedDependencyName:$latestVersion';
82+
print('Patching $newImplementation');
83+
final newGradleContent = gradleContent.replaceAll(
84+
implementationRegExp,
85+
' implementation $newImplementation',
86+
);
87+
fBuildGradle.writeAsStringSync(newGradleContent);
88+
}
89+
90+
/// Update pubspec.yaml
91+
void updatePubSpec() {
92+
final fPubspec = File('${_packageDirectory.path}/pubspec.yaml');
93+
final yamlEditor = YamlEditor(fPubspec.readAsStringSync())
94+
..update(['name'], _packageName)
95+
..update(['description'], _packageDescription);
96+
fPubspec.writeAsStringSync(yamlEditor.toString());
97+
}
98+
99+
/// Move README_EMBEDDED.md to replace README.md
100+
void updateReadme() {
101+
File('${_packageDirectory.path}/README.md').deleteSync();
102+
File('${_packageDirectory.path}/README_EMBEDDED.md')
103+
.renameSync('${_packageDirectory.path}/README.md');
104+
}

pkgs/cronet_http/run_pigeon.sh renamed to pkgs/cronet_http/tool/run_pigeon.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/bin/sh
22

33
# Generate the platform messages used by cronet_http.
4+
cd ../
45

56
flutter pub run pigeon \
67
--input pigeons/messages.dart \

0 commit comments

Comments
 (0)