Skip to content

Commit 8c49ef5

Browse files
[cronet_http] Upgrade jni and jnigen to 0.14.2 (#1793)
1 parent ca07b4c commit 8c49ef5

File tree

8 files changed

+3148
-2245
lines changed

8 files changed

+3148
-2245
lines changed

pkgs/cronet_http/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Add a new `CronetStreamedResponse` class that provides additional information
44
about the HTTP response.
55
* Fix a Flutter warning by upgrading to Kotlin 1.18.10.
6+
* Upgrade `package:jni` and `package:jnigen` to 0.14.2.
67

78
## 1.3.4
89

pkgs/cronet_http/android/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ android {
3131
compileSdkVersion 31
3232

3333
compileOptions {
34-
sourceCompatibility JavaVersion.VERSION_1_8
35-
targetCompatibility JavaVersion.VERSION_1_8
34+
sourceCompatibility JavaVersion.VERSION_11
35+
targetCompatibility JavaVersion.VERSION_11
3636
}
3737

3838
kotlinOptions {
39-
jvmTarget = '1.8'
39+
jvmTarget = '11'
4040
}
4141

4242
sourceSets {

pkgs/cronet_http/android/src/main/kotlin/io/flutter/plugins/cronet_http/UrlRequestCallbackProxy.kt

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,58 +19,69 @@ import org.chromium.net.UrlRequest
1919
import org.chromium.net.UrlResponseInfo
2020
import java.nio.ByteBuffer
2121

22+
// Due to a bug (https://github.com/dart-lang/native/issues/2421) where JNIgen
23+
// does not synchronize the nullabilities across the class hierarchy and the
24+
// fact that UrlRequest.Callback is a Java class with no nullability
25+
// annotations, generating both `UrlRequestCallbackProxy` and
26+
// `UrlRequest.Callback` together with different nullabilities causes the
27+
// super method to have a looser type for parameters which is a Dart compilation
28+
// error.
29+
// That is why all of the parameters of this class are defined as nullable to
30+
// match `UrlRequest.Callback` while in reality only `onFailed`'s `info`
31+
// parameter is nullable as specified in the cronet source code:
32+
// https://source.chromium.org/chromium/chromium/src/+/main:components/cronet/android/api/src/org/chromium/net/UrlRequest.java;l=232
2233

2334
class UrlRequestCallbackProxy(val callback: UrlRequestCallbackInterface) : UrlRequest.Callback() {
2435
public interface UrlRequestCallbackInterface {
2536
fun onRedirectReceived(
26-
request: UrlRequest,
27-
info: UrlResponseInfo,
28-
newLocationUrl: String
37+
request: UrlRequest?,
38+
info: UrlResponseInfo?,
39+
newLocationUrl: String?
2940
)
3041

31-
fun onResponseStarted(request: UrlRequest?, info: UrlResponseInfo)
42+
fun onResponseStarted(request: UrlRequest?, info: UrlResponseInfo?)
3243
fun onReadCompleted(
33-
request: UrlRequest,
34-
info: UrlResponseInfo,
35-
byteBuffer: ByteBuffer
44+
request: UrlRequest?,
45+
info: UrlResponseInfo?,
46+
byteBuffer: ByteBuffer?
3647
)
3748

38-
fun onSucceeded(request: UrlRequest, info: UrlResponseInfo?)
49+
fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?)
3950
fun onFailed(
40-
request: UrlRequest,
51+
request: UrlRequest?,
4152
info: UrlResponseInfo?,
42-
error: CronetException
53+
error: CronetException?
4354
)
4455
}
4556

4657
override fun onRedirectReceived(
47-
request: UrlRequest,
48-
info: UrlResponseInfo,
49-
newLocationUrl: String
58+
request: UrlRequest?,
59+
info: UrlResponseInfo?,
60+
newLocationUrl: String?
5061
) {
5162
callback.onRedirectReceived(request, info, newLocationUrl);
5263
}
5364

54-
override fun onResponseStarted(request: UrlRequest?, info: UrlResponseInfo) {
65+
override fun onResponseStarted(request: UrlRequest?, info: UrlResponseInfo?) {
5566
callback.onResponseStarted(request, info);
5667
}
5768

5869
override fun onReadCompleted(
59-
request: UrlRequest,
60-
info: UrlResponseInfo,
61-
byteBuffer: ByteBuffer
70+
request: UrlRequest?,
71+
info: UrlResponseInfo?,
72+
byteBuffer: ByteBuffer?
6273
) {
6374
callback.onReadCompleted(request, info, byteBuffer);
6475
}
6576

66-
override fun onSucceeded(request: UrlRequest, info: UrlResponseInfo?) {
77+
override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) {
6778
callback.onSucceeded(request, info);
6879
}
6980

7081
override fun onFailed(
71-
request: UrlRequest,
82+
request: UrlRequest?,
7283
info: UrlResponseInfo?,
73-
error: CronetException
84+
error: CronetException?
7485
) {
7586
callback.onFailed(request, info, error);
7687
}

pkgs/cronet_http/example/android/app/build.gradle

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ android {
2828
namespace 'io.flutter.cronet_http_example'
2929

3030
compileOptions {
31-
sourceCompatibility JavaVersion.VERSION_1_8
32-
targetCompatibility JavaVersion.VERSION_1_8
31+
sourceCompatibility JavaVersion.VERSION_11
32+
targetCompatibility JavaVersion.VERSION_11
3333
}
3434

3535
kotlinOptions {
36-
jvmTarget = '1.8'
36+
jvmTarget = '11'
3737
}
3838

3939
sourceSets {
@@ -66,9 +66,6 @@ flutter {
6666
}
6767

6868
dependencies {
69-
// TODO(#1112): org.jetbrains.kotlin:kotlin-bom artifact purpose is to align kotlin stdlib and related code versions.
70-
// This should be removed when https://github.com/flutter/flutter/issues/125062 is fixed.
71-
implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))
7269
// ""com.google.android.gms:play-services-cronet" is only present so that
7370
// `jnigen` will work. Applications should not include this line.
7471
// The version should be synced with `pkgs/cronet_http/android/build.gradle`.

pkgs/cronet_http/example/android/build.gradle

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
allprojects {
2+
repositories {
3+
google()
4+
mavenCentral()
5+
gradlePluginPortal()
6+
}
7+
}
8+
19
rootProject.buildDir = '../build'
210
subprojects {
311
project.buildDir = "${rootProject.buildDir}/${project.name}"

pkgs/cronet_http/lib/src/cronet_client.dart

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ class CronetStreamedResponse extends _StreamedResponseWithUrl {
3939
///
4040
/// It will be the empty string or `'unknown'` if no protocol was negotiated,
4141
/// the protocol is not known, or when using plain HTTP or HTTPS.
42-
String get negotiatedProtocol =>
43-
_responseInfo.getNegotiatedProtocol().toDartString(releaseOriginal: true);
42+
String get negotiatedProtocol => _responseInfo
43+
.getNegotiatedProtocol()!
44+
.toDartString(releaseOriginal: true);
4445

4546
/// The minimum count of bytes received from the network to process this
4647
/// request.
@@ -124,7 +125,7 @@ class CronetEngine {
124125
bool? enableQuic,
125126
String? storagePath,
126127
String? userAgent}) {
127-
final builder = jb.CronetEngine_Builder(
128+
final builder = jb.CronetEngine$Builder(
128129
JObject.fromReference(Jni.getCachedApplicationContext()));
129130

130131
try {
@@ -159,7 +160,7 @@ class CronetEngine {
159160
builder.setUserAgent(userAgent.toJString());
160161
}
161162

162-
return CronetEngine._(builder.build());
163+
return CronetEngine._(builder.build()!);
163164
} on JniException catch (e) {
164165
// TODO: Decode this exception in a better way when
165166
// https://github.com/dart-lang/jnigen/issues/239 is fixed.
@@ -182,12 +183,12 @@ class CronetEngine {
182183
}
183184

184185
Map<String, String> _cronetToClientHeaders(
185-
JMap<JString, JList<JString>> cronetHeaders) =>
186+
JMap<JString?, JList<JString?>?> cronetHeaders) =>
186187
cronetHeaders.map((key, value) => MapEntry(
187-
key.toDartString(releaseOriginal: true).toLowerCase(),
188-
value.join(',')));
188+
key!.toDartString(releaseOriginal: true).toLowerCase(),
189+
value!.join(',')));
189190

190-
jb.UrlRequestCallbackProxy_UrlRequestCallbackInterface _urlRequestCallbacks(
191+
jb.UrlRequestCallbackProxy$UrlRequestCallbackInterface _urlRequestCallbacks(
191192
BaseRequest request,
192193
Completer<CronetStreamedResponse> responseCompleter,
193194
HttpClientRequestProfile? profile) {
@@ -198,21 +199,24 @@ jb.UrlRequestCallbackProxy_UrlRequestCallbackInterface _urlRequestCallbacks(
198199

199200
// The order of callbacks generated by Cronet is documented here:
200201
// https://developer.android.com/guide/topics/connectivity/cronet/lifecycle
201-
return jb.UrlRequestCallbackProxy_UrlRequestCallbackInterface.implement(
202-
jb.$UrlRequestCallbackProxy_UrlRequestCallbackInterface(
202+
return jb.UrlRequestCallbackProxy$UrlRequestCallbackInterface.implement(
203+
// All of the variables in the interface are non-nullable with the
204+
// exception of onFailed's UrlResponseInfo as specified in:
205+
// https://source.chromium.org/chromium/chromium/src/+/main:components/cronet/android/api/src/org/chromium/net/UrlRequest.java;l=232
206+
jb.$UrlRequestCallbackProxy$UrlRequestCallbackInterface(
203207
onResponseStarted: (urlRequest, responseInfo) {
204208
responseStream = StreamController(onCancel: () {
205209
// The user did `response.stream.cancel()`. We can just pretend that
206210
// the response completed normally.
207211
if (done) return;
208212
done = true;
209-
urlRequest.cancel();
213+
urlRequest!.cancel();
210214
responseStream!.sink.close();
211215
jByteBuffer?.release();
212216
profile?.responseData.close();
213217
});
214218
final responseHeaders =
215-
_cronetToClientHeaders(responseInfo.getAllHeaders());
219+
_cronetToClientHeaders(responseInfo!.getAllHeaders()!);
216220
int? contentLength;
217221

218222
switch (responseHeaders['content-length']) {
@@ -222,7 +226,7 @@ jb.UrlRequestCallbackProxy_UrlRequestCallbackInterface _urlRequestCallbacks(
222226
'Invalid content-length header [$contentLengthHeader].',
223227
request.url,
224228
));
225-
urlRequest.cancel();
229+
urlRequest?.cancel();
226230
return;
227231
case final contentLengthHeader?:
228232
contentLength = int.parse(contentLengthHeader);
@@ -232,10 +236,10 @@ jb.UrlRequestCallbackProxy_UrlRequestCallbackInterface _urlRequestCallbacks(
232236
responseInfo.getHttpStatusCode(),
233237
responseInfo: responseInfo,
234238
url: Uri.parse(
235-
responseInfo.getUrl().toDartString(releaseOriginal: true)),
239+
responseInfo.getUrl()!.toDartString(releaseOriginal: true)),
236240
contentLength: contentLength,
237241
reasonPhrase: responseInfo
238-
.getHttpStatusText()
242+
.getHttpStatusText()!
239243
.toDartString(releaseOriginal: true),
240244
request: request,
241245
isRedirect: false,
@@ -247,39 +251,40 @@ jb.UrlRequestCallbackProxy_UrlRequestCallbackInterface _urlRequestCallbacks(
247251
?..contentLength = contentLength
248252
..headersCommaValues = responseHeaders
249253
..isRedirect = false
250-
..reasonPhrase =
251-
responseInfo.getHttpStatusText().toDartString(releaseOriginal: true)
254+
..reasonPhrase = responseInfo
255+
.getHttpStatusText()!
256+
.toDartString(releaseOriginal: true)
252257
..startTime = DateTime.now()
253258
..statusCode = responseInfo.getHttpStatusCode();
254259
jByteBuffer = JByteBuffer.allocateDirect(_bufferSize);
255-
urlRequest.read(jByteBuffer!);
260+
urlRequest?.read(jByteBuffer!);
256261
},
257262
onRedirectReceived: (urlRequest, responseInfo, newLocationUrl) {
258263
if (done) return;
259264
final responseHeaders =
260-
_cronetToClientHeaders(responseInfo.getAllHeaders());
265+
_cronetToClientHeaders(responseInfo!.getAllHeaders()!);
261266

262267
if (!request.followRedirects) {
263-
urlRequest.cancel();
268+
urlRequest!.cancel();
264269
responseCompleter.complete(CronetStreamedResponse._(
265270
const Stream.empty(), // Cronet provides no body for redirects.
266271
responseInfo.getHttpStatusCode(),
267272
responseInfo: responseInfo,
268273
url: Uri.parse(
269-
responseInfo.getUrl().toDartString(releaseOriginal: true)),
274+
responseInfo.getUrl()!.toDartString(releaseOriginal: true)),
270275
contentLength: 0,
271276
reasonPhrase: responseInfo
272-
.getHttpStatusText()
277+
.getHttpStatusText()!
273278
.toDartString(releaseOriginal: true),
274279
request: request,
275280
isRedirect: true,
276-
headers: _cronetToClientHeaders(responseInfo.getAllHeaders())));
281+
headers: _cronetToClientHeaders(responseInfo.getAllHeaders()!)));
277282

278283
profile?.responseData
279284
?..headersCommaValues = responseHeaders
280285
..isRedirect = true
281286
..reasonPhrase = responseInfo
282-
.getHttpStatusText()
287+
.getHttpStatusText()!
283288
.toDartString(releaseOriginal: true)
284289
..startTime = DateTime.now()
285290
..statusCode = responseInfo.getHttpStatusCode();
@@ -294,23 +299,23 @@ jb.UrlRequestCallbackProxy_UrlRequestCallbackInterface _urlRequestCallbacks(
294299
// does not seem to have a way to get the method so we'd have to
295300
// calculate it according to the rules in RFC-7231.
296301
method: 'GET',
297-
location: newLocationUrl.toDartString(releaseOriginal: true)));
298-
urlRequest.followRedirect();
302+
location: newLocationUrl!.toDartString(releaseOriginal: true)));
303+
urlRequest!.followRedirect();
299304
} else {
300-
urlRequest.cancel();
305+
urlRequest!.cancel();
301306
responseCompleter.completeError(
302307
ClientException('Redirect limit exceeded', request.url));
303308
}
304309
},
305310
onReadCompleted: (urlRequest, responseInfo, byteBuffer) {
306311
if (done) return;
307-
byteBuffer.flip();
312+
byteBuffer!.flip();
308313
final data = jByteBuffer!.asUint8List().sublist(0, byteBuffer.remaining);
309314
responseStream!.add(data);
310315
profile?.responseData.bodySink.add(data);
311316

312317
byteBuffer.clear();
313-
urlRequest.read(byteBuffer);
318+
urlRequest!.read(byteBuffer);
314319
},
315320
onSucceeded: (urlRequest, responseInfo) {
316321
if (done) return;
@@ -319,7 +324,7 @@ jb.UrlRequestCallbackProxy_UrlRequestCallbackInterface _urlRequestCallbacks(
319324
jByteBuffer?.release();
320325
profile?.responseData.close();
321326
},
322-
onFailed: (urlRequest, responseInfo, cronetException) {
327+
onFailed: (urlRequest, responseInfo /* can be null */, cronetException) {
323328
if (done) return;
324329
done = true;
325330
final error = ClientException(
@@ -442,7 +447,8 @@ class CronetClient extends BaseClient {
442447
jb.UrlRequestCallbackProxy(
443448
_urlRequestCallbacks(request, responseCompleter, profile)),
444449
_executor,
445-
)..setHttpMethod(request.method.toJString());
450+
)!
451+
..setHttpMethod(request.method.toJString());
446452

447453
var headers = request.headers;
448454
if (body.isNotEmpty &&
@@ -471,7 +477,7 @@ class CronetClient extends BaseClient {
471477
builder.setUploadDataProvider(
472478
jb.UploadDataProviders.create$2(data), _executor);
473479
}
474-
builder.build().start();
480+
builder.build()!.start();
475481
return responseCompleter.future;
476482
}
477483
}

0 commit comments

Comments
 (0)