Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
115fecc
[webview_flutter] Create method for retriving cookies
khaled-0 Jan 20, 2026
ca32485
[webview_flutter_wkwebview] Implement getCookies method to retrieve c…
khaled-0 Jan 20, 2026
bf04b65
[webview_flutter_android] Implement getCookies method
khaled-0 Jan 20, 2026
bb96ade
[webview_flutter_platform_interface] Use Uri for getCookies
khaled-0 Jan 20, 2026
f79d7e8
[webview_flutter] make-deps-path-based (temp)
khaled-0 Jan 21, 2026
f3186cb
[webview_flutter] test for getCookies in PlatformWebViewCookieManage
khaled-0 Jan 21, 2026
088ccda
[webview_flutter_android] test for getCookies
khaled-0 Jan 21, 2026
7bc3de2
[webview_flutter_wkwebview] test for getCookies
khaled-0 Jan 21, 2026
04995bd
[webview_flutter] Use CookieManager.getCookies instead of document.co…
khaled-0 Jan 21, 2026
1a11291
[webview_flutter] Format with flutter_plugin_tools format
khaled-0 Jan 21, 2026
1317fc6
[webview_flutter_wkwebview] match getAllCookies function signature
khaled-0 Jan 21, 2026
a3ffce3
[webview_flutter_web] Revert "make-deps-path-based (temp)" [skip ci]
khaled-0 Jan 21, 2026
29c8059
[webview_flutter] Update some comments to be more explicit
khaled-0 Jan 25, 2026
4f0c549
[webview_flutter_wkwebview] Refactor getCookies to use if let
khaled-0 Jan 25, 2026
b38e3e7
[webview_flutter] make api more consistent across platforms
khaled-0 Feb 8, 2026
a1623e3
[webview_flutter_platform_interface] Create PlatformWebViewCookieMana…
khaled-0 Mar 1, 2026
a54dc43
[webview_flutter_platform_interface] Remove changes merged in #11037
khaled-0 Mar 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions packages/webview_flutter/webview_flutter/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -428,9 +428,17 @@ class SampleMenu extends StatelessWidget {
}

Future<void> _onListCookies(BuildContext context) async {
final cookies =
await webViewController.runJavaScriptReturningResult('document.cookie')
as String;
final Uri? domain = Uri.tryParse(
(await webViewController.currentUrl()) ?? '',
);

late final List<WebViewCookie> cookies;
if (domain == null) {
cookies = [];
} else {
cookies = await cookieManager.getCookies(domain: domain);
}

if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
Expand Down Expand Up @@ -536,13 +544,12 @@ class SampleMenu extends StatelessWidget {
return webViewController.loadHtmlString(kTransparentBackgroundPage);
}

Widget _getCookieList(String cookies) {
if (cookies == '""') {
Widget _getCookieList(List<WebViewCookie> cookies) {
if (cookies.isEmpty) {
return Container();
}
final List<String> cookieList = cookies.split(';');
final Iterable<Text> cookieWidgets = cookieList.map(
(String cookie) => Text(cookie),
final Iterable<Text> cookieWidgets = cookies.map(
(WebViewCookie cookie) => Text(cookie.toString()),
);
return Column(
mainAxisAlignment: MainAxisAlignment.end,
Expand Down
6 changes: 6 additions & 0 deletions packages/webview_flutter/webview_flutter/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,9 @@ flutter:
- assets/sample_video.mp4
- assets/www/index.html
- assets/www/styles/style.css
# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE.
# See https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changing-federated-plugins
dependency_overrides:
webview_flutter_android: {path: ../../../../packages/webview_flutter/webview_flutter_android}
webview_flutter_platform_interface: {path: ../../../../packages/webview_flutter/webview_flutter_platform_interface}
webview_flutter_wkwebview: {path: ../../../../packages/webview_flutter/webview_flutter_wkwebview}
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,12 @@ class WebViewCookieManager {
///
/// This is a no op on iOS versions below 11.
Future<void> setCookie(WebViewCookie cookie) => platform.setCookie(cookie);

/// Gets a list of existing cookie for specified domain from all
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
/// Gets a list of existing cookie for specified domain from all
/// Returns a list of existing cookies for the specified domain from all

/// WebView instances of the application.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment here as the platform implementation. Is this true that it retrieves cookies for all WebView instances and not the associated one: https://developer.apple.com/documentation/webkit/wkhttpcookiestore/getallcookies(_:)#Discussion

///
/// Each platform can have different url requirements. Please check individual
/// platform implementation for details
Future<List<WebViewCookie>> getCookies({required Uri domain}) =>
platform.getCookies(domain);
}
6 changes: 6 additions & 0 deletions packages/webview_flutter/webview_flutter/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,9 @@ topics:
- html
- webview
- webview-flutter
# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE.
# See https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changing-federated-plugins
dependency_overrides:
webview_flutter_android: {path: ../../../packages/webview_flutter/webview_flutter_android}
webview_flutter_platform_interface: {path: ../../../packages/webview_flutter/webview_flutter_platform_interface}
webview_flutter_wkwebview: {path: ../../../packages/webview_flutter/webview_flutter_wkwebview}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Mocks generated by Mockito 5.4.5 from annotations
// Mocks generated by Mockito 5.4.6 from annotations
// in webview_flutter/test/legacy/webview_flutter_test.dart.
// Do not manually edit this file.

Expand Down Expand Up @@ -34,6 +34,7 @@ import 'package:webview_flutter_platform_interface/src/legacy/types/types.dart'
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
// ignore_for_file: subtype_of_sealed_class
// ignore_for_file: invalid_use_of_internal_member

class _FakeWidget_0 extends _i1.SmartFake implements _i2.Widget {
_FakeWidget_0(Object parent, Invocation parentInvocation)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Mocks generated by Mockito 5.4.5 from annotations
// Mocks generated by Mockito 5.4.6 from annotations
// in webview_flutter/test/navigation_delegate_test.dart.
// Do not manually edit this file.

Expand Down Expand Up @@ -34,6 +34,7 @@ import 'package:webview_flutter_platform_interface/src/webview_platform.dart'
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
// ignore_for_file: subtype_of_sealed_class
// ignore_for_file: invalid_use_of_internal_member

class _FakePlatformWebViewCookieManager_0 extends _i1.SmartFake
implements _i2.PlatformWebViewCookieManager {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Mocks generated by Mockito 5.4.5 from annotations
// Mocks generated by Mockito 5.4.6 from annotations
// in webview_flutter/test/webview_controller_test.dart.
// Do not manually edit this file.

Expand Down Expand Up @@ -26,6 +26,7 @@ import 'package:webview_flutter_platform_interface/src/types/types.dart' as _i2;
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
// ignore_for_file: subtype_of_sealed_class
// ignore_for_file: invalid_use_of_internal_member

class _FakePlatformWebViewControllerCreationParams_0 extends _i1.SmartFake
implements _i2.PlatformWebViewControllerCreationParams {
Expand Down Expand Up @@ -82,6 +83,15 @@ class MockPlatformWebViewController extends _i1.Mock
)
as _i5.Future<void>);

@override
_i5.Future<void> loadFileWithParams(_i2.LoadFileParams? params) =>
(super.noSuchMethod(
Invocation.method(#loadFileWithParams, [params]),
returnValue: _i5.Future<void>.value(),
returnValueForMissingStub: _i5.Future<void>.value(),
)
as _i5.Future<void>);

@override
_i5.Future<void> loadFlutterAsset(String? key) =>
(super.noSuchMethod(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,43 @@ void main() {
as WebViewCookie;
expect(capturedCookie, cookie);
});

test('getCookies', () async {
final mockPlatformWebViewCookieManager =
MockPlatformWebViewCookieManager();
final cookieManager = WebViewCookieManager.fromPlatform(
mockPlatformWebViewCookieManager,
);

when(
mockPlatformWebViewCookieManager.getCookies(Uri(host: 'flutter.dev')),
).thenAnswer((_) async => []);

final List<WebViewCookie> cookies = await cookieManager.getCookies(
domain: Uri(host: 'flutter.dev'),
);

expect(cookies, isEmpty);

verify(
mockPlatformWebViewCookieManager.getCookies(Uri(host: 'flutter.dev')),
).called(1);

const cookie = WebViewCookie(
name: 'name',
value: 'value',
domain: 'domain',
);

when(
mockPlatformWebViewCookieManager.getCookies(Uri(host: 'domain')),
).thenAnswer((_) => Future.value([cookie]));

await cookieManager.getCookies(domain: Uri(host: 'domain'));

verify(
mockPlatformWebViewCookieManager.getCookies(Uri(host: 'domain')),
).called(1);
});
});
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Mocks generated by Mockito 5.4.5 from annotations
// Mocks generated by Mockito 5.4.6 from annotations
// in webview_flutter/test/webview_cookie_manager_test.dart.
// Do not manually edit this file.

Expand All @@ -23,6 +23,7 @@ import 'package:webview_flutter_platform_interface/src/types/types.dart' as _i2;
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
// ignore_for_file: subtype_of_sealed_class
// ignore_for_file: invalid_use_of_internal_member

class _FakePlatformWebViewCookieManagerCreationParams_0 extends _i1.SmartFake
implements _i2.PlatformWebViewCookieManagerCreationParams {
Expand Down Expand Up @@ -68,4 +69,14 @@ class MockPlatformWebViewCookieManager extends _i1.Mock
returnValueForMissingStub: _i4.Future<void>.value(),
)
as _i4.Future<void>);

@override
_i4.Future<List<_i2.WebViewCookie>> getCookies(Uri? domain) =>
(super.noSuchMethod(
Invocation.method(#getCookies, [domain]),
returnValue: _i4.Future<List<_i2.WebViewCookie>>.value(
<_i2.WebViewCookie>[],
),
)
as _i4.Future<List<_i2.WebViewCookie>>);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Mocks generated by Mockito 5.4.5 from annotations
// Mocks generated by Mockito 5.4.6 from annotations
// in webview_flutter/test/webview_widget_test.dart.
// Do not manually edit this file.

Expand Down Expand Up @@ -30,6 +30,7 @@ import 'package:webview_flutter_platform_interface/src/types/types.dart' as _i2;
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
// ignore_for_file: subtype_of_sealed_class
// ignore_for_file: invalid_use_of_internal_member

class _FakePlatformWebViewControllerCreationParams_0 extends _i1.SmartFake
implements _i2.PlatformWebViewControllerCreationParams {
Expand Down Expand Up @@ -95,6 +96,15 @@ class MockPlatformWebViewController extends _i1.Mock
)
as _i7.Future<void>);

@override
_i7.Future<void> loadFileWithParams(_i2.LoadFileParams? params) =>
(super.noSuchMethod(
Invocation.method(#loadFileWithParams, [params]),
returnValue: _i7.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(),
)
as _i7.Future<void>);

@override
_i7.Future<void> loadFlutterAsset(String? key) =>
(super.noSuchMethod(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2013 The Flutter Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Autogenerated from Pigeon (v26.1.4), do not edit directly.
// Autogenerated from Pigeon (v26.1.5), do not edit directly.
// See also: https://pub.dev/packages/pigeon
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")

Expand Down Expand Up @@ -155,10 +155,6 @@ class AndroidWebkitLibraryPigeonInstanceManager(
*/
fun <T> remove(identifier: Long): T? {
logWarningIfFinalizationListenerHasStopped()
val instance: Any? = getInstance(identifier)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this needs to be manually added back in, but this can wait for the implementation PR.

if (instance is WebViewProxyApi.WebViewPlatformView) {
instance.destroy()
}
return strongInstances.remove(identifier) as T?
}

Expand Down Expand Up @@ -1519,6 +1515,18 @@ abstract class PigeonApiCookieManager(
accept: Boolean
)

/**
* Gets all the cookies for the given URL.
*
* This may return multiple key-value pairs if multiple cookies are associated with this URL, in
* which case each cookie will be delimited by "; " characters (semicolon followed by a space).
* Each key-value pair will be of the form "key=value".
*
* Note: Any cookies set with the "Partitioned" attribute will only be returned for the top-level
* partition of url.
*/
abstract fun getCookies(pigeon_instance: android.webkit.CookieManager, url: String): String?

companion object {
@Suppress("LocalVariableName")
fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiCookieManager?) {
Expand Down Expand Up @@ -1621,6 +1629,29 @@ abstract class PigeonApiCookieManager(
channel.setMessageHandler(null)
}
}
run {
val channel =
BasicMessageChannel<Any?>(
binaryMessenger,
"dev.flutter.pigeon.webview_flutter_android.CookieManager.getCookies",
codec)
if (api != null) {
channel.setMessageHandler { message, reply ->
val args = message as List<Any?>
val pigeon_instanceArg = args[0] as android.webkit.CookieManager
val urlArg = args[1] as String
val wrapped: List<Any?> =
try {
listOf(api.getCookies(pigeon_instanceArg, urlArg))
} catch (exception: Throwable) {
AndroidWebkitLibraryPigeonUtils.wrapError(exception)
}
reply.reply(wrapped)
}
} else {
channel.setMessageHandler(null)
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,9 @@ public void setAcceptThirdPartyCookies(
@NonNull CookieManager pigeon_instance, @NonNull WebView webView, boolean accept) {
pigeon_instance.setAcceptThirdPartyCookies(webView, accept);
}

@Override
public @NonNull String getCookies(@NonNull CookieManager pigeon_instance, @NonNull String url) {
return pigeon_instance.getCookie(url);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.webkit.CookieManager;
import android.webkit.ValueCallback;
Expand Down Expand Up @@ -64,4 +65,35 @@ public void setAcceptThirdPartyCookies() {

verify(instance).setAcceptThirdPartyCookies(webView, accept);
}

@Test
public void getCookies_returnsCookieString() {
final PigeonApiCookieManager api = new TestProxyApiRegistrar().getPigeonApiCookieManager();

final CookieManager instance = mock(CookieManager.class);
final String domain = "https://flutter.dev";
final String cookieValue = "session=12345";

// Mock the CookieManager to return the cookie string
when(instance.getCookie(domain)).thenReturn(cookieValue);

final String result = api.getCookies(instance, domain);

assertEquals(cookieValue, result);
}

@Test
public void getCookies_returnsEmptyStringIfNull() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test should now be removable due to the change from #10833

final PigeonApiCookieManager api = new TestProxyApiRegistrar().getPigeonApiCookieManager();

final CookieManager instance = mock(CookieManager.class);
final String domain = "https://flutter.dev";

// Mock the CookieManager to return null
when(instance.getCookie(domain)).thenReturn(null);

final String result = api.getCookies(instance, domain);

assertEquals("", result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -496,9 +496,17 @@ class SampleMenu extends StatelessWidget {
}

Future<void> _onListCookies(BuildContext context) async {
final cookies =
await webViewController.runJavaScriptReturningResult('document.cookie')
as String;
final Uri? domain = Uri.tryParse(
(await webViewController.currentUrl()) ?? '',
);
late final List<WebViewCookie> cookies;

if (domain == null) {
cookies = [];
} else {
cookies = await cookieManager.getCookies(domain);
}

if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
Expand Down Expand Up @@ -662,13 +670,12 @@ class SampleMenu extends StatelessWidget {
return webViewController.loadHtmlString(kAlertTestPage);
}

Widget _getCookieList(String cookies) {
if (cookies == '""') {
Widget _getCookieList(List<WebViewCookie> cookies) {
if (cookies.isEmpty) {
return Container();
}
final List<String> cookieList = cookies.split(';');
final Iterable<Text> cookieWidgets = cookieList.map(
(String cookie) => Text(cookie),
final Iterable<Text> cookieWidgets = cookies.map(
(WebViewCookie cookie) => Text(cookie.toString()),
);
return Column(
mainAxisAlignment: MainAxisAlignment.end,
Expand Down
Loading