updated onPermissionRequest signature

This commit is contained in:
Lorenzo Pichilli 2022-04-21 12:20:48 +02:00
parent 3cd3b30457
commit ec24f41914
9 changed files with 266 additions and 19 deletions

View File

@ -1113,6 +1113,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
Map<String, Object> obj = new HashMap<>();
obj.put("origin", request.getOrigin().toString());
obj.put("resources", Arrays.asList(request.getResources()));
obj.put("frame", null);
channel.invokeMethod("onPermissionRequest", obj, new MethodChannel.Result() {
@Override
public void success(Object response) {

View File

@ -62,8 +62,8 @@ flutter {
dependencies {
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test:runner:1.3.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'com.android.support:multidex:1.0.3'
}

View File

@ -131,7 +131,6 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
this.url = url.toString();
urlController.text = this.url;
});
print((await controller.getSettings())?.upgradeKnownHostsToHTTPS);
},
onPermissionRequest: (controller, origin, resources) async {
return PermissionRequestResponse(
@ -168,7 +167,6 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
this.url = url.toString();
urlController.text = this.url;
});
print((await controller.getSettings())?.upgradeKnownHostsToHTTPS);
},
onLoadError: (controller, url, code, message) {
pullToRefreshController.endRefreshing();

View File

@ -796,8 +796,8 @@ class InAppBrowser {
///
///**Supported Platforms/Implementations**:
///- Android native WebView ([Official API - WebChromeClient.onPermissionRequest](https://developer.android.com/reference/android/webkit/WebChromeClient#onPermissionRequest(android.webkit.PermissionRequest)))
Future<PermissionRequestResponse?>? onPermissionRequest(
String origin, List<String> resources) {}
Future<PermissionResponse?>? onPermissionRequest(
PermissionRequest permissionRequest) {}
///Use [onGeolocationPermissionsShowPrompt] instead.
@Deprecated("Use onGeolocationPermissionsShowPrompt instead")

View File

@ -570,8 +570,8 @@ class HeadlessInAppWebView implements WebView {
NavigationResponse navigationResponse)? onNavigationResponse;
@override
Future<PermissionRequestResponse?> Function(InAppWebViewController controller,
String origin, List<String> resources)? onPermissionRequest;
Future<PermissionResponse?> Function(InAppWebViewController controller,
PermissionRequest permissionRequest)? onPermissionRequest;
@override
void Function(InAppWebViewController controller, Uint8List icon)?

View File

@ -469,10 +469,9 @@ class InAppWebView extends StatefulWidget implements WebView {
NavigationResponse navigationResponse)? onNavigationResponse;
@override
final Future<PermissionRequestResponse?> Function(
final Future<PermissionResponse?> Function(
InAppWebViewController controller,
String origin,
List<String> resources)? onPermissionRequest;
PermissionRequest permissionRequest)? onPermissionRequest;
@override
final void Function(InAppWebViewController controller, Uint8List icon)?

View File

@ -731,10 +731,15 @@ class InAppWebViewController
String origin = call.arguments["origin"];
List<String> resources = call.arguments["resources"].cast<String>();
Map<String, dynamic> arguments =
call.arguments.cast<String, dynamic>();
PermissionRequest permissionRequest =
PermissionRequest.fromMap(arguments)!;
if (_webview != null) {
if (_webview!.onPermissionRequest != null)
return (await _webview!.onPermissionRequest!(
this, origin, resources))
this, permissionRequest))
?.toMap();
else {
// ignore: deprecated_member_use_from_same_package
@ -743,12 +748,11 @@ class InAppWebViewController
?.toMap();
}
} else {
return ((await _inAppBrowser!
.onPermissionRequest(origin, resources)) ??
return (await _inAppBrowser!
.onPermissionRequest(permissionRequest))?.toMap() ??
(await _inAppBrowser!
// ignore: deprecated_member_use_from_same_package
.androidOnPermissionRequest(origin, resources)))
?.toMap();
.androidOnPermissionRequest(origin, resources))?.toMap();
}
}
break;

View File

@ -510,10 +510,9 @@ abstract class WebView {
///
///**Supported Platforms/Implementations**:
///- Android native WebView ([Official API - WebChromeClient.onPermissionRequest](https://developer.android.com/reference/android/webkit/WebChromeClient#onPermissionRequest(android.webkit.PermissionRequest)))
final Future<PermissionRequestResponse?> Function(
final Future<PermissionResponse?> Function(
InAppWebViewController controller,
String origin,
List<String> resources)? onPermissionRequest;
PermissionRequest permissionRequest)? onPermissionRequest;
///Use [onGeolocationPermissionsShowPrompt] instead.
@Deprecated("Use onGeolocationPermissionsShowPrompt instead")

View File

@ -4703,7 +4703,29 @@ class Cookie {
}
}
///Class used by [PermissionResponse] class.
class PermissionResponseAction {
final int _value;
const PermissionResponseAction._internal(this._value);
int toValue() => _value;
///Denies the request.
static const DENY = const PermissionResponseAction._internal(0);
///Grants origin the permission to access the given resources.
static const GRANT = const PermissionResponseAction._internal(1);
bool operator ==(value) => value == _value;
@override
int get hashCode => _value.hashCode;
}
///Class used by [PermissionRequestResponse] class.
///Use [PermissionResponseAction] instead.
@Deprecated("Use PermissionResponseAction instead")
class PermissionRequestResponseAction {
final int _value;
@ -4723,7 +4745,207 @@ class PermissionRequestResponseAction {
int get hashCode => _value.hashCode;
}
///Class that represents a type of resource used to ask user's permission.
class PermissionResourceType {
final dynamic _value;
const PermissionResourceType._internal(this._value);
static final Set<PermissionResourceType> values = [
PermissionResourceType.RESOURCE_AUDIO_CAPTURE,
PermissionResourceType.RESOURCE_MIDI_SYSEX,
PermissionResourceType.RESOURCE_PROTECTED_MEDIA_ID,
PermissionResourceType.RESOURCE_VIDEO_CAPTURE,
].toSet();
static final Set<PermissionResourceType> _androidValues = [
PermissionResourceType.RESOURCE_AUDIO_CAPTURE,
PermissionResourceType.RESOURCE_MIDI_SYSEX,
PermissionResourceType.RESOURCE_PROTECTED_MEDIA_ID,
PermissionResourceType.RESOURCE_VIDEO_CAPTURE,
].toSet();
static final Set<PermissionResourceType> _appleValues = <PermissionResourceType>[
].toSet();
static PermissionResourceType? fromValue(dynamic? value) {
if (value != null) {
try {
Set<PermissionResourceType> valueList = <PermissionResourceType>[].toSet();
if (Platform.isAndroid) {
valueList = PermissionResourceType._androidValues;
} else if (Platform.isIOS || Platform.isMacOS) {
valueList = PermissionResourceType._appleValues;
}
return valueList.firstWhere((element) => element.toValue() == value);
} catch (e) {
return null;
}
}
return null;
}
dynamic toValue() => _value;
@override
String toString() {
if (_value is String) {
return _value;
}
switch (_value) {
case 0:
return "CAMERA";
case 1:
return "MICROPHONE";
case 2:
return "CAMERA_AND_MICROPHONE";
default:
return "";
}
}
///Resource belongs to audio capture device, like microphone.
///
///**NOTE**: available only on Android.
static const RESOURCE_AUDIO_CAPTURE = const PermissionResourceType._internal('android.webkit.resource.AUDIO_CAPTURE');
///Resource will allow sysex messages to be sent to or received from MIDI devices.
///These messages are privileged operations, e.g. modifying sound libraries and sampling data, or even updating the MIDI device's firmware.
///Permission may be requested for this resource in API levels 21 and above, if the Android device has been updated to WebView 45 or above.
///
///**NOTE**: available only on Android.
static const RESOURCE_MIDI_SYSEX =
const PermissionResourceType._internal('android.webkit.resource.MIDI_SYSEX');
///Resource belongs to protected media identifier. After the user grants this resource, the origin can use EME APIs to generate the license requests.
///
///**NOTE**: available only on Android.
static const RESOURCE_PROTECTED_MEDIA_ID =
const PermissionResourceType._internal('android.webkit.resource.PROTECTED_MEDIA_ID');
///Resource belongs to video capture device, like camera.
///
///**NOTE**: available only on Android.
static const RESOURCE_VIDEO_CAPTURE =
const PermissionResourceType._internal('android.webkit.resource.VIDEO_CAPTURE');
///A media device that can capture video.
///
///**NOTE**: available only on iOS.
static const CAMERA =
const PermissionResourceType._internal(0);
///A media device that can capture audio.
///
///**NOTE**: available only on iOS.
static const MICROPHONE =
const PermissionResourceType._internal(1);
///A media device or devices that can capture audio and video.
///
///**NOTE**: available only on iOS.
static const CAMERA_AND_MICROPHONE =
const PermissionResourceType._internal(2);
///Resource belongs to the devices orientation and motion.
///
///**NOTE**: available only on iOS.
static const DEVICE_ORIENTATION_AND_MOTION =
const PermissionResourceType._internal('deviceOrientationAndMotion');
bool operator ==(value) => value == _value;
@override
int get hashCode => _value.hashCode;
}
///Class that represents the response used by the [WebView.onPermissionRequest] event.
class PermissionRequest {
///The origin of web content which attempt to access the restricted resources.
Uri origin;
///List of resources the web content wants to access.
List<PermissionResourceType> resources;
///The frame that initiates the request in the web view.
FrameInfo? frame;
PermissionRequest(
{required this.origin,
this.resources = const [],
this.frame});
static PermissionRequest? fromMap(Map<String, dynamic>? map) {
if (map == null) {
return null;
}
List<PermissionResourceType> resources = [];
if (map["resources"] != null) {
(map["resources"].cast<dynamic>() as List<dynamic>)
.forEach((element) {
var resource = PermissionResourceType.fromValue(element);
if (resource != null) {
resources.add(resource);
}
});
}
return PermissionRequest(
origin: Uri.parse(map["origin"]),
resources: resources,
frame: FrameInfo.fromMap(map["frame"]?.cast<String, dynamic>()));
}
Map<String, dynamic> toMap() {
return {
"origin": origin.toString(),
"resources": resources.map((e) => e.toValue()).toList(),
"initiatedByFrame": frame?.toMap()
};
}
Map<String, dynamic> toJson() {
return this.toMap();
}
@override
String toString() {
return toMap().toString();
}
}
///Class that represents the response used by the [WebView.onPermissionRequest] event.
class PermissionResponse {
///Resources granted to be accessed by origin.
List<PermissionResourceType> resources;
///Indicate the [PermissionResponseAction] to take in response of a permission request.
PermissionResponseAction? action;
PermissionResponse(
{this.resources = const [],
this.action = PermissionResponseAction.DENY});
Map<String, dynamic> toMap() {
return {"resources": resources, "action": action?.toValue()};
}
Map<String, dynamic> toJson() {
return this.toMap();
}
@override
String toString() {
return toMap().toString();
}
}
///Class that represents the response used by the [WebView.androidOnPermissionRequest] event.
///Use [PermissionResponse] instead.
@Deprecated("Use PermissionResponse instead")
class PermissionRequestResponse {
///Resources granted to be accessed by origin.
List<String> resources;
@ -7182,39 +7404,63 @@ class SslErrorType {
}
///The certificate is not yet valid
///
///**NOTE**: available only on Android
static const SSL_NOTYETVALID = const SslErrorType._internal(0);
///The certificate has expired
///
///**NOTE**: available only on Android
static const SSL_EXPIRED = const SslErrorType._internal(1);
///Hostname mismatch
///
///**NOTE**: available only on Android
static const SSL_IDMISMATCH = const SslErrorType._internal(2);
///The certificate authority is not trusted
///
///**NOTE**: available only on Android
static const SSL_UNTRUSTED = const SslErrorType._internal(3);
///The date of the certificate is invalid
///
///**NOTE**: available only on Android
static const SSL_DATE_INVALID = const SslErrorType._internal(4);
///A generic error occurred
///
///**NOTE**: available only on Android
static const SSL_INVALID = const SslErrorType._internal(5);
///Indicates an invalid setting or result.
///
///**NOTE**: available only on iOS
static const INVALID = const SslErrorType._internal(0);
///Indicates a user-configured deny; do not proceed.
///
///**NOTE**: available only on iOS
static const DENY = const SslErrorType._internal(3);
///Indicates the evaluation succeeded and the certificate is implicitly trusted, but user intent was not explicitly specified.
///
///**NOTE**: available only on iOS
static const UNSPECIFIED = const SslErrorType._internal(4);
///Indicates a trust policy failure which can be overridden by the user.
///
///**NOTE**: available only on iOS
static const RECOVERABLE_TRUST_FAILURE = const SslErrorType._internal(5);
///Indicates a trust failure which cannot be overridden by the user.
///
///**NOTE**: available only on iOS
static const FATAL_TRUST_FAILURE = const SslErrorType._internal(6);
///Indicates a failure other than that of trust evaluation.
///
///**NOTE**: available only on iOS
static const OTHER_ERROR = const SslErrorType._internal(7);
bool operator ==(value) => value == _value;