Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9950ee5
Added cookie manager to interface.
BeMacized Nov 29, 2021
4782a68
Added Android implementation for new CookieManager.
BeMacized Nov 29, 2021
0577815
Added iOS implementation for new CookieManager.
BeMacized Nov 29, 2021
2e3dba3
Update pubspec
BeMacized Nov 29, 2021
4816d71
Revert accidental push of ios changes
BeMacized Nov 29, 2021
34c680e
Update deprecation notice
BeMacized Nov 29, 2021
44eca64
Merge branch 'master' into webview_flutter/set_cookies_platform
BeMacized Nov 29, 2021
e1f45b9
Merge branch 'webview_flutter/set_cookies_platform' into webview_flut…
BeMacized Nov 29, 2021
0d0f281
Fix analysis issues
BeMacized Nov 29, 2021
176b55c
Merge branch 'webview_flutter/set_cookies_platform' into webview_flut…
BeMacized Nov 29, 2021
490da19
Enforce extending class for cookie manager platform interface
BeMacized Nov 29, 2021
60b5945
Merge branch 'webview_flutter/set_cookies_platform' into webview_flut…
BeMacized Nov 29, 2021
8eb7bf5
Update to match platform interface changes
BeMacized Nov 29, 2021
6f9742a
Process PR feedback
BeMacized Nov 30, 2021
c7067c0
Process PR feedback
BeMacized Nov 30, 2021
e557cbc
Merge branch 'webview_flutter/set_cookies_platform' into webview_flut…
BeMacized Nov 30, 2021
8f5bb77
Fix issue with WebViewCookieManager
BeMacized Nov 30, 2021
cdc302e
Add fix for platform implementation registration.
BeMacized Dec 1, 2021
9f98faf
Fix build issue
BeMacized Dec 2, 2021
e75383f
Merge remote-tracking branch 'upstream/master' into webview_flutter/s…
BeMacized Dec 2, 2021
a0c5c76
Fix analysis errors (excl. pubspec)
BeMacized Dec 2, 2021
a4e663f
Format
BeMacized Dec 2, 2021
a6c93e6
Merge branch 'master' into webview_flutter/set_cookies_android
BeMacized Dec 3, 2021
d80dc54
Updated platform interface dependency
BeMacized Dec 3, 2021
b75ceda
Add missing license headers
BeMacized Dec 3, 2021
5a9075d
Updated changelog and pubspec
BeMacized Dec 3, 2021
3d5c13f
Revert automatic gradle updates
BeMacized Dec 3, 2021
5d0408f
Implemented PR feedback
BeMacized Dec 7, 2021
5bfcc7d
Merge remote-tracking branch 'upstream/master' into webview_flutter/s…
BeMacized Dec 7, 2021
b95d8cc
Fix mocks
BeMacized Dec 7, 2021
6d79274
Merge branch 'master' into webview_flutter/set_cookies_android
BeMacized Dec 7, 2021
f201bc1
Revert "Merge branch 'master' into webview_flutter/set_cookies_android"
BeMacized Dec 7, 2021
7b367f0
Merge branch 'master' into webview_flutter/set_cookies_android
BeMacized Dec 7, 2021
3bfbe9e
Update changelog, pubspec version and mocks.
BeMacized Dec 7, 2021
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
4 changes: 4 additions & 0 deletions packages/webview_flutter/webview_flutter_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.8.0

* Implements new cookie manager for setting cookies and providing initial cookies.

## 2.7.0

* Adds support for the `loadRequest` method from the platform interface.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.webviewflutter;

import android.os.Build;
import android.webkit.CookieManager;

class CookieManagerHostApiImpl implements GeneratedAndroidWebView.CookieManagerHostApi {
@Override
public void clearCookies(GeneratedAndroidWebView.Result<Boolean> result) {
CookieManager cookieManager = CookieManager.getInstance();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
cookieManager.removeAllCookies(result::success);
} else {
final boolean hasCookies = cookieManager.hasCookies();
if (hasCookies) {
cookieManager.removeAllCookie();
}
result.success(hasCookies);
}
}

@Override
public void setCookie(String url, String value) {
CookieManager.getInstance().setCookie(url, value);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,94 @@ public interface Result<T> {
void error(Throwable error);
}

private static class CookieManagerHostApiCodec extends StandardMessageCodec {
public static final CookieManagerHostApiCodec INSTANCE = new CookieManagerHostApiCodec();

private CookieManagerHostApiCodec() {}
}

/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
public interface CookieManagerHostApi {
void clearCookies(Result<Boolean> result);

void setCookie(String url, String value);

/** The codec used by CookieManagerHostApi. */
static MessageCodec<Object> getCodec() {
return CookieManagerHostApiCodec.INSTANCE;
}

/**
* Sets up an instance of `CookieManagerHostApi` to handle messages through the
* `binaryMessenger`.
*/
static void setup(BinaryMessenger binaryMessenger, CookieManagerHostApi api) {
{
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger,
"dev.flutter.pigeon.CookieManagerHostApi.clearCookies",
getCodec());
if (api != null) {
channel.setMessageHandler(
(message, reply) -> {
Map<String, Object> wrapped = new HashMap<>();
try {
Result<Boolean> resultCallback =
new Result<Boolean>() {
public void success(Boolean result) {
wrapped.put("result", result);
reply.reply(wrapped);
}

public void error(Throwable error) {
wrapped.put("error", wrapError(error));
reply.reply(wrapped);
}
};

api.clearCookies(resultCallback);
} catch (Error | RuntimeException exception) {
wrapped.put("error", wrapError(exception));
reply.reply(wrapped);
}
});
} else {
channel.setMessageHandler(null);
}
}
{
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger, "dev.flutter.pigeon.CookieManagerHostApi.setCookie", getCodec());
if (api != null) {
channel.setMessageHandler(
(message, reply) -> {
Map<String, Object> wrapped = new HashMap<>();
try {
ArrayList<Object> args = (ArrayList<Object>) message;
String urlArg = (String) args.get(0);
if (urlArg == null) {
throw new NullPointerException("urlArg unexpectedly null.");
}
String valueArg = (String) args.get(1);
if (valueArg == null) {
throw new NullPointerException("valueArg unexpectedly null.");
}
api.setCookie(urlArg, valueArg);
wrapped.put("result", null);
} catch (Error | RuntimeException exception) {
wrapped.put("error", wrapError(exception));
}
reply.reply(wrapped);
});
} else {
channel.setMessageHandler(null);
}
}
}
}

private static class WebViewHostApiCodec extends StandardMessageCodec {
public static final WebViewHostApiCodec INSTANCE = new WebViewHostApiCodec();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.platform.PlatformViewRegistry;
import io.flutter.plugins.webviewflutter.GeneratedAndroidWebView.CookieManagerHostApi;
import io.flutter.plugins.webviewflutter.GeneratedAndroidWebView.DownloadListenerHostApi;
import io.flutter.plugins.webviewflutter.GeneratedAndroidWebView.FlutterAssetManagerHostApi;
import io.flutter.plugins.webviewflutter.GeneratedAndroidWebView.JavaScriptChannelHostApi;
Expand All @@ -30,7 +31,6 @@
*/
public class WebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
private FlutterPluginBinding pluginBinding;
private FlutterCookieManager flutterCookieManager;
private WebViewHostApiImpl webViewHostApi;
private JavaScriptChannelHostApiImpl javaScriptChannelHostApi;

Expand Down Expand Up @@ -65,7 +65,6 @@ public static void registerWith(io.flutter.plugin.common.PluginRegistry.Registra
registrar.view(),
new FlutterAssetManager.RegistrarFlutterAssetManager(
registrar.context().getAssets(), registrar));
new FlutterCookieManager(registrar.messenger());
}

private void setUp(
Expand All @@ -74,7 +73,6 @@ private void setUp(
Context context,
View containerView,
FlutterAssetManager flutterAssetManager) {
new FlutterCookieManager(binaryMessenger);

InstanceManager instanceManager = new InstanceManager();

Expand Down Expand Up @@ -117,6 +115,7 @@ private void setUp(
instanceManager, new WebSettingsHostApiImpl.WebSettingsCreator()));
FlutterAssetManagerHostApi.setup(
binaryMessenger, new FlutterAssetManagerHostApiImpl(flutterAssetManager));
CookieManagerHostApi.setup(binaryMessenger, new CookieManagerHostApiImpl());
}

@Override
Expand All @@ -132,14 +131,7 @@ public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
}

@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
if (flutterCookieManager == null) {
return;
}

flutterCookieManager.dispose();
flutterCookieManager = null;
}
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {}

@Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding activityPluginBinding) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.webviewflutter;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.os.Build;
import android.webkit.CookieManager;
import android.webkit.ValueCallback;
import io.flutter.plugins.webviewflutter.utils.TestUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.MockedStatic;

public class CookieManagerHostApiImplTest {

private CookieManager cookieManager;
private MockedStatic<CookieManager> staticMockCookieManager;

@Before
public void setup() {
staticMockCookieManager = mockStatic(CookieManager.class);
cookieManager = mock(CookieManager.class);
when(CookieManager.getInstance()).thenReturn(cookieManager);
when(cookieManager.hasCookies()).thenReturn(true);
doAnswer(
answer -> {
((ValueCallback<Boolean>) answer.getArgument(0)).onReceiveValue(true);
return null;
})
.when(cookieManager)
.removeAllCookies(any());
}

@After
public void tearDown() {
staticMockCookieManager.close();
}

@Test
public void setCookieShouldCallSetCookie() {
// Setup
CookieManagerHostApiImpl impl = new CookieManagerHostApiImpl();
// Run
impl.setCookie("flutter.dev", "foo=bar; path=/");
// Verify
verify(cookieManager).setCookie("flutter.dev", "foo=bar; path=/");
}

@Test
public void clearCookiesShouldCallRemoveAllCookiesOnAndroidLAbove() {
// Setup
TestUtils.setFinalStatic(Build.VERSION.class, "SDK_INT", Build.VERSION_CODES.LOLLIPOP);
GeneratedAndroidWebView.Result<Boolean> result = mock(GeneratedAndroidWebView.Result.class);
CookieManagerHostApiImpl impl = new CookieManagerHostApiImpl();
// Run
impl.clearCookies(result);
// Verify
verify(cookieManager).removeAllCookies(any());
verify(result).success(true);
}

@Test
public void clearCookiesShouldCallRemoveAllCookieBelowAndroidL() {
// Setup
TestUtils.setFinalStatic(Build.VERSION.class, "SDK_INT", Build.VERSION_CODES.KITKAT_WATCH);
GeneratedAndroidWebView.Result<Boolean> result = mock(GeneratedAndroidWebView.Result.class);
CookieManagerHostApiImpl impl = new CookieManagerHostApiImpl();
// Run
impl.clearCookies(result);
// Verify
verify(cookieManager).removeAllCookie();
verify(result).success(true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.webviewflutter.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import org.junit.Assert;

public class TestUtils {
public static <T> void setFinalStatic(Class<T> classToModify, String fieldName, Object newValue) {
try {
Field field = classToModify.getField(fieldName);
field.setAccessible(true);

Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

field.set(null, newValue);
} catch (Exception e) {
Assert.fail("Unable to mock static field: " + fieldName);
}
}

public static <T> void setPrivateField(T instance, String fieldName, Object newValue) {
try {
Field field = instance.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(instance, newValue);
} catch (Exception e) {
Assert.fail("Unable to mock private field: " + fieldName);
}
}

public static <T> Object getPrivateField(T instance, String fieldName) {
try {
Field field = instance.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(instance);
} catch (Exception e) {
Assert.fail("Unable to mock private field: " + fieldName);
return null;
}
}
}
Loading