Skip to content

Commit 0929348

Browse files
committed
Added v4 implementation of AndroidWebViewCookieManager
This PR adds the Android implementation of the new v4 PlatformWebViewCookieManager interface. This commit should be a complete implementation including the required tests.
1 parent 287af0f commit 0929348

File tree

7 files changed

+234
-2
lines changed

7 files changed

+234
-2
lines changed

packages/webview_flutter/webview_flutter_android/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.9.0
2+
3+
* Adds Android implementation of the new webview_flutter_platform_interface (v4).
4+
15
## 2.8.8
26

37
* Minor fixes for new analysis options.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/foundation.dart';
6+
import 'package:webview_flutter_platform_interface/v4/webview_flutter_platform_interface.dart';
7+
8+
import '../android_webview.dart';
9+
import 'types/android_webview_cookie_manager_creation_params.dart';
10+
11+
/// Handles all cookie operations for the Android platform.
12+
class AndroidWebViewCookieManager extends PlatformWebViewCookieManager {
13+
/// Creates a new [AndroidWebViewCookieManager].
14+
AndroidWebViewCookieManager(AndroidWebViewCookieManagerCreationParams params)
15+
: this.fromNativeApi(
16+
params,
17+
cookieManager: CookieManager.instance,
18+
);
19+
20+
/// Creates a new [AndroidWebViewCookieManager] using the Android native [CookieManager] implementation.
21+
///
22+
/// This constructor is only used for testing. An instance should be obtained
23+
/// with the default [AndroidWebViewCookieManager] constructor.
24+
@visibleForTesting
25+
AndroidWebViewCookieManager.fromNativeApi(
26+
AndroidWebViewCookieManagerCreationParams params, {
27+
required CookieManager cookieManager,
28+
}) : _cookieManager = cookieManager,
29+
super.implementation(params);
30+
31+
final CookieManager _cookieManager;
32+
33+
@override
34+
Future<bool> clearCookies() {
35+
return _cookieManager.clearCookies();
36+
}
37+
38+
@override
39+
Future<void> setCookie(WebViewCookie cookie) {
40+
if (!_isValidPath(cookie.path)) {
41+
throw ArgumentError(
42+
'The path property for the provided cookie was not given a legal value.');
43+
}
44+
return _cookieManager.setCookie(
45+
cookie.domain,
46+
'${Uri.encodeComponent(cookie.name)}=${Uri.encodeComponent(cookie.value)}; path=${cookie.path}',
47+
);
48+
}
49+
50+
bool _isValidPath(String path) {
51+
// Permitted ranges based on RFC6265bis: https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-02#section-4.1.1
52+
for (final int char in path.codeUnits) {
53+
if ((char < 0x20 || char > 0x3A) && (char < 0x3C || char > 0x7E)) {
54+
return false;
55+
}
56+
}
57+
return true;
58+
}
59+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:webview_flutter_platform_interface/v4/webview_flutter_platform_interface.dart';
6+
7+
import 'android_webview_cookie_manager.dart';
8+
import 'types/android_webview_cookie_manager_creation_params.dart';
9+
10+
/// Provides Android specific implementations of a webview.
11+
class AndroidWebViewPlatform extends WebViewPlatform {
12+
@override
13+
PlatformWebViewCookieManager createPlatformCookieManager(
14+
PlatformWebViewCookieManagerCreationParams params) {
15+
if (params is AndroidWebViewCookieManagerCreationParams) {
16+
return AndroidWebViewCookieManager(params);
17+
}
18+
19+
return AndroidWebViewCookieManager(
20+
AndroidWebViewCookieManagerCreationParams
21+
.fromPlatformWebViewCookieManagerCreationParams(params),
22+
);
23+
}
24+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/material.dart';
6+
import 'package:webview_flutter_platform_interface/v4/src/types/types.dart';
7+
8+
/// Object specifying creation parameters for creating a [AndroidWebViewCookieManager].
9+
///
10+
/// When adding additional fields make sure they can be null or have a default
11+
/// value to avoid breaking changes. See [PlatformWebViewCookieManagerCreationParams] for
12+
/// more information.
13+
@immutable
14+
class AndroidWebViewCookieManagerCreationParams
15+
extends PlatformWebViewCookieManagerCreationParams {
16+
/// Creates a new [AndroidWebViewCookieManagerCreationParams] instance.
17+
const AndroidWebViewCookieManagerCreationParams._(
18+
// This parameter prevents breaking changes later.
19+
// ignore: avoid_unused_constructor_parameters
20+
PlatformWebViewCookieManagerCreationParams params,
21+
) : super();
22+
23+
/// Creates a [AndroidWebViewCookieManagerCreationParams] instance based on [PlatformWebViewCookieManagerCreationParams].
24+
factory AndroidWebViewCookieManagerCreationParams.fromPlatformWebViewCookieManagerCreationParams(
25+
PlatformWebViewCookieManagerCreationParams params) {
26+
return AndroidWebViewCookieManagerCreationParams._(params);
27+
}
28+
}

packages/webview_flutter/webview_flutter_android/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: webview_flutter_android
22
description: A Flutter plugin that provides a WebView widget on Android.
33
repository: https://github.com/flutter/plugins/tree/main/packages/webview_flutter/webview_flutter_android
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
5-
version: 2.8.8
5+
version: 2.9.0
66

77
environment:
88
sdk: ">=2.14.0 <3.0.0"
@@ -19,7 +19,7 @@ flutter:
1919
dependencies:
2020
flutter:
2121
sdk: flutter
22-
webview_flutter_platform_interface: ^1.8.0
22+
webview_flutter_platform_interface: ^1.9.0
2323

2424
dev_dependencies:
2525
build_runner: ^2.1.4
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter_test/flutter_test.dart';
6+
import 'package:mockito/annotations.dart';
7+
import 'package:mockito/mockito.dart';
8+
import 'package:webview_flutter_android/src/android_webview.dart'
9+
as android_webview;
10+
import 'package:webview_flutter_android/src/v4/android_webview_cookie_manager.dart';
11+
import 'package:webview_flutter_android/src/v4/types/android_webview_cookie_manager_creation_params.dart';
12+
import 'package:webview_flutter_platform_interface/v4/src/webview_platform.dart';
13+
14+
import 'android_webview_cookie_manager_test.mocks.dart';
15+
16+
@GenerateMocks(<Type>[android_webview.CookieManager])
17+
void main() {
18+
TestWidgetsFlutterBinding.ensureInitialized();
19+
20+
test('clearCookies should call android_webview.clearCookies', () {
21+
final android_webview.CookieManager mockCookieManager = MockCookieManager();
22+
23+
when(mockCookieManager.clearCookies())
24+
.thenAnswer((_) => Future<bool>.value(true));
25+
26+
final AndroidWebViewCookieManagerCreationParams params =
27+
AndroidWebViewCookieManagerCreationParams
28+
.fromPlatformWebViewCookieManagerCreationParams(
29+
const PlatformWebViewCookieManagerCreationParams());
30+
31+
AndroidWebViewCookieManager.fromNativeApi(params,
32+
cookieManager: mockCookieManager)
33+
.clearCookies();
34+
verify(mockCookieManager.clearCookies());
35+
});
36+
37+
test('setCookie should throw ArgumentError for cookie with invalid path', () {
38+
final AndroidWebViewCookieManagerCreationParams params =
39+
AndroidWebViewCookieManagerCreationParams
40+
.fromPlatformWebViewCookieManagerCreationParams(
41+
const PlatformWebViewCookieManagerCreationParams());
42+
43+
final AndroidWebViewCookieManager androidCookieManager =
44+
AndroidWebViewCookieManager.fromNativeApi(params,
45+
cookieManager: MockCookieManager());
46+
47+
expect(
48+
() => androidCookieManager.setCookie(const WebViewCookie(
49+
name: 'foo',
50+
value: 'bar',
51+
domain: 'flutter.dev',
52+
path: 'invalid;path',
53+
)),
54+
throwsA(const TypeMatcher<ArgumentError>()),
55+
);
56+
});
57+
58+
test(
59+
'setCookie should call android_webview.csetCookie with properly formatted cookie value',
60+
() {
61+
final android_webview.CookieManager mockCookieManager = MockCookieManager();
62+
final AndroidWebViewCookieManagerCreationParams params =
63+
AndroidWebViewCookieManagerCreationParams
64+
.fromPlatformWebViewCookieManagerCreationParams(
65+
const PlatformWebViewCookieManagerCreationParams());
66+
67+
AndroidWebViewCookieManager.fromNativeApi(params,
68+
cookieManager: mockCookieManager)
69+
.setCookie(const WebViewCookie(
70+
name: 'foo&',
71+
value: 'bar@',
72+
domain: 'flutter.dev',
73+
));
74+
75+
verify(mockCookieManager.setCookie(
76+
'flutter.dev',
77+
'foo%26=bar%40; path=/',
78+
));
79+
});
80+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Mocks generated by Mockito 5.1.0 from annotations
2+
// in webview_flutter_android/test/v4/android_webview_cookie_manager_test.dart.
3+
// Do not manually edit this file.
4+
5+
import 'dart:async' as _i3;
6+
7+
import 'package:mockito/mockito.dart' as _i1;
8+
import 'package:webview_flutter_android/src/android_webview.dart' as _i2;
9+
10+
// ignore_for_file: type=lint
11+
// ignore_for_file: avoid_redundant_argument_values
12+
// ignore_for_file: avoid_setters_without_getters
13+
// ignore_for_file: comment_references
14+
// ignore_for_file: implementation_imports
15+
// ignore_for_file: invalid_use_of_visible_for_testing_member
16+
// ignore_for_file: prefer_const_constructors
17+
// ignore_for_file: unnecessary_parenthesis
18+
// ignore_for_file: camel_case_types
19+
20+
/// A class which mocks [CookieManager].
21+
///
22+
/// See the documentation for Mockito's code generation for more information.
23+
class MockCookieManager extends _i1.Mock implements _i2.CookieManager {
24+
MockCookieManager() {
25+
_i1.throwOnMissingStub(this);
26+
}
27+
28+
@override
29+
_i3.Future<void> setCookie(String? url, String? value) =>
30+
(super.noSuchMethod(Invocation.method(#setCookie, [url, value]),
31+
returnValue: Future<void>.value(),
32+
returnValueForMissingStub: Future<void>.value()) as _i3.Future<void>);
33+
@override
34+
_i3.Future<bool> clearCookies() =>
35+
(super.noSuchMethod(Invocation.method(#clearCookies, []),
36+
returnValue: Future<bool>.value(false)) as _i3.Future<bool>);
37+
}

0 commit comments

Comments
 (0)