added isInFullscreen method

This commit is contained in:
Lorenzo Pichilli 2022-05-01 04:03:17 +02:00
parent 2a3e368780
commit 449bfd06ef
11 changed files with 110 additions and 29 deletions

View File

@ -2,7 +2,7 @@
- Deprecated old classes/properties/methods to make them eventually compatible with other Platforms and WebView engines.
- Added Web support
- Added `pauseAllMediaPlayback`, `setAllMediaPlaybackSuspended`, `closeAllMediaPresentations`, `requestMediaPlaybackState` WebView controller methods
- Added `pauseAllMediaPlayback`, `setAllMediaPlaybackSuspended`, `closeAllMediaPresentations`, `requestMediaPlaybackState`, `isInFullscreen` WebView controller methods
- Added `underPageBackgroundColor`, `isTextInteractionEnabled`, `isSiteSpecificQuirksModeEnabled`, `upgradeKnownHostsToHTTPS` WebView settings
- Added support for `onPermissionRequest` event on iOS 15.0+
- Updated `getMetaThemeColor` on iOS 15.0+

View File

@ -598,6 +598,13 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle
result.success(false);
}
break;
case "isInFullscreen":
if (webView != null) {
result.success(webView.isInFullscreen());
} else {
result.success(false);
}
break;
default:
result.notImplemented();
}

View File

@ -121,6 +121,7 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie
public JavaScriptBridgeInterface javaScriptBridgeInterface;
public InAppWebViewSettings customSettings;
public boolean isLoading = false;
private boolean inFullscreen = false;
public OkHttpClient httpClient;
public float zoomScale = 1.0f;
int okHttpClientCacheSize = 10 * 1024 * 1024; // 10MB
@ -187,7 +188,7 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie
javaScriptBridgeInterface = new JavaScriptBridgeInterface(this);
addJavascriptInterface(javaScriptBridgeInterface, JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME);
inAppWebViewChromeClient = new InAppWebViewChromeClient(plugin, channel, inAppBrowserDelegate);
inAppWebViewChromeClient = new InAppWebViewChromeClient(plugin, channel, this, inAppBrowserDelegate);
setWebChromeClient(inAppWebViewChromeClient);
inAppWebViewClient = new InAppWebViewClient(channel, inAppBrowserDelegate);
@ -1691,6 +1692,16 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie
return Looper.getMainLooper();
}
@Override
public boolean isInFullscreen() {
return inFullscreen;
}
@Override
public void setInFullscreen(boolean inFullscreen) {
this.inFullscreen = inFullscreen;
}
@Override
public void postWebMessage(com.pichillilorenzo.flutter_inappwebview.types.WebMessage message, Uri targetOrigin, ValueCallback<String> callback) throws Exception {
throw new UnsupportedOperationException();

View File

@ -34,6 +34,7 @@ import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
@ -45,6 +46,7 @@ import com.pichillilorenzo.flutter_inappwebview.in_app_browser.ActivityResultLis
import com.pichillilorenzo.flutter_inappwebview.in_app_browser.InAppBrowserDelegate;
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
import com.pichillilorenzo.flutter_inappwebview.R;
import com.pichillilorenzo.flutter_inappwebview.types.InAppWebViewInterface;
import com.pichillilorenzo.flutter_inappwebview.types.URLRequest;
import java.io.ByteArrayOutputStream;
@ -101,11 +103,15 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
private int mOriginalSystemUiVisibility;
@Nullable
public InAppWebViewFlutterPlugin plugin;
@Nullable
public InAppWebViewInterface inAppWebView;
public InAppWebViewChromeClient(final InAppWebViewFlutterPlugin plugin, MethodChannel channel, InAppBrowserDelegate inAppBrowserDelegate) {
public InAppWebViewChromeClient(@NonNull final InAppWebViewFlutterPlugin plugin, MethodChannel channel,
@NonNull InAppWebViewInterface inAppWebView, InAppBrowserDelegate inAppBrowserDelegate) {
super();
this.plugin = plugin;
this.channel = channel;
this.inAppWebView = inAppWebView;
this.inAppBrowserDelegate = inAppBrowserDelegate;
if (this.inAppBrowserDelegate != null) {
this.inAppBrowserDelegate.getActivityResultListeners().add(this);
@ -142,6 +148,10 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
Map<String, Object> obj = new HashMap<>();
channel.invokeMethod("onExitFullscreen", obj);
if (inAppWebView != null) {
inAppWebView.setInFullscreen(false);
}
}
@Override
@ -173,9 +183,13 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
}
activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
((FrameLayout) decorView).addView(this.mCustomView, FULLSCREEN_LAYOUT_PARAMS);
Map<String, Object> obj = new HashMap<>();
channel.invokeMethod("onEnterFullscreen", obj);
if (inAppWebView != null) {
inAppWebView.setInFullscreen(true);
}
}
@Override
@ -1221,5 +1235,6 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
inAppBrowserDelegate = null;
}
plugin = null;
inAppWebView = null;
}
}

View File

@ -100,4 +100,6 @@ public interface InAppWebViewInterface {
void disposeWebMessageChannels();
void disposeWebMessageListeners();
Looper getWebViewLooper();
boolean isInFullscreen();
void setInFullscreen(boolean inFullscreen);
}

View File

@ -3,11 +3,11 @@
export "FLUTTER_ROOT=/Users/lorenzopichilli/fvm/versions/2.10.4"
export "FLUTTER_APPLICATION_PATH=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example"
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_TARGET=integration_test/webview_flutter_test.dart"
export "FLUTTER_TARGET=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/lib/main.dart"
export "FLUTTER_BUILD_DIR=build"
export "FLUTTER_BUILD_NAME=1.0.0"
export "FLUTTER_BUILD_NUMBER=1"
export "DART_DEFINES=RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ=="
export "DART_DEFINES=Zmx1dHRlci5pbnNwZWN0b3Iuc3RydWN0dXJlZEVycm9ycz10cnVl,RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ=="
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=true"
export "TREE_SHAKE_ICONS=false"

View File

@ -21,8 +21,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
mediaPlaybackRequiresUserGesture: false,
allowsInlineMediaPlayback: true,
iframeAllow: "camera; microphone",
iframeAllowFullscreen: true,
javaScriptEnabled: false
iframeAllowFullscreen: true
);
PullToRefreshController? pullToRefreshController;
@ -115,7 +114,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
InAppWebView(
key: webViewKey,
initialUrlRequest:
URLRequest(url: Uri.parse("https://flutter.dev")),
URLRequest(url: Uri.parse("https://www.youtube.com/watch?v=CylXr3AF3uU")),
// initialUrlRequest:
// URLRequest(url: Uri.parse(Uri.base.toString().replaceFirst("/#/", "/") + 'page.html')),
// initialFile: "assets/index.html",
@ -218,12 +217,6 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
webViewController?.reload();
},
),
ElevatedButton(
child: Icon(Icons.refresh),
onPressed: () {
webViewController?.evaluateJavascript(source: "document.title='test';");
},
),
],
),
])));

View File

@ -19,7 +19,7 @@ Future main() async {
// await Permission.microphone.request();
// await Permission.storage.request();
WebView.debugLogging = true;
WebView.debugLogging = false;
if (defaultTargetPlatform == TargetPlatform.android) {
await InAppWebViewController.setWebContentsDebuggingEnabled(true);

View File

@ -23,6 +23,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
var webMessageChannels: [String:WebMessageChannel] = [:]
var webMessageListeners: [WebMessageListener] = []
var currentOriginalUrl: URL?
var inFullscreen = false
static var sslCertificatesMap: [String: SslCertificate] = [:] // [URL host name : SslCertificate]
static var credentialsProposed: [URLCredential] = []
@ -320,17 +321,24 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
name: UIMenuController.didHideMenuNotification,
object: nil)
// listen for videos playing in fullscreen
NotificationCenter.default.addObserver(self,
selector: #selector(onEnterFullscreen(_:)),
name: UIWindow.didBecomeVisibleNotification,
object: window)
// if #available(iOS 15.0, *) {
// addObserver(self,
// forKeyPath: #keyPath(WKWebView.fullscreenState),
// options: .new,
// context: nil)
// } else {
// listen for videos playing in fullscreen
NotificationCenter.default.addObserver(self,
selector: #selector(onEnterFullscreen(_:)),
name: UIWindow.didBecomeVisibleNotification,
object: window)
// listen for videos stopping to play in fullscreen
NotificationCenter.default.addObserver(self,
selector: #selector(onExitFullscreen(_:)),
name: UIWindow.didBecomeHiddenNotification,
object: window)
// listen for videos stopping to play in fullscreen
NotificationCenter.default.addObserver(self,
selector: #selector(onExitFullscreen(_:)),
name: UIWindow.didBecomeHiddenNotification,
object: window)
// }
if let settings = settings {
if settings.transparentBackground {
@ -639,6 +647,15 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
}
}
}
// else if #available(iOS 15.0, *) {
// if keyPath == #keyPath(WKWebView.fullscreenState) {
// if fullscreenState == .enteringFullscreen {
// onEnterFullscreen()
// } else if fullscreenState == .exitingFullscreen {
// onExitFullscreen()
// }
// }
// }
replaceGestureHandlerIfNeeded()
}
@ -2676,7 +2693,9 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
public func isVideoPlayerWindow(_ notificationObject: AnyObject?) -> Bool {
let nonVideoClasses = ["_UIAlertControllerShimPresenterWindow",
"UITextEffectsWindow",
"UIRemoteKeyboardWindow"]
"UIRemoteKeyboardWindow",
"PGHostedWindow"]
var isVideo = true
if let obj = notificationObject {
for nonVideoClass in nonVideoClasses {
@ -2690,16 +2709,26 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
@objc func onEnterFullscreen(_ notification: Notification) {
if (isVideoPlayerWindow(notification.object as AnyObject?)) {
channel?.invokeMethod("onEnterFullscreen", arguments: [])
onEnterFullscreen()
inFullscreen = true
}
}
public func onEnterFullscreen() {
channel?.invokeMethod("onEnterFullscreen", arguments: [])
}
@objc func onExitFullscreen(_ notification: Notification) {
if (isVideoPlayerWindow(notification.object as AnyObject?)) {
channel?.invokeMethod("onExitFullscreen", arguments: [])
onExitFullscreen()
inFullscreen = false
}
}
public func onExitFullscreen() {
channel?.invokeMethod("onExitFullscreen", arguments: [])
}
// public func onContextMenuConfigurationForElement(linkURL: String?, result: FlutterResult?) {
// let arguments: [String: Any?] = ["linkURL": linkURL]
// channel?.invokeMethod("onContextMenuConfigurationForElement", arguments: arguments, result: result)
@ -3074,6 +3103,9 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
removeObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress))
removeObserver(self, forKeyPath: #keyPath(WKWebView.url))
removeObserver(self, forKeyPath: #keyPath(WKWebView.title))
// if #available(iOS 15.0, *) {
// removeObserver(self, forKeyPath: #keyPath(WKWebView.fullscreenState))
// }
scrollView.removeObserver(self, forKeyPath: #keyPath(UIScrollView.contentOffset))
scrollView.removeObserver(self, forKeyPath: #keyPath(UIScrollView.zoomScale))
resumeTimers()

View File

@ -592,6 +592,17 @@ public class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
result(nil)
}
break
case "isInFullscreen":
// if let webView = webView, #available(iOS 15.0, *) {
// result(webView.fullscreenState == .inFullscreen)
// }
if let webView = webView {
result(webView.inFullscreen)
}
else {
result(false)
}
break
default:
result(FlutterMethodNotImplemented)
break

View File

@ -3192,6 +3192,16 @@ class InAppWebViewController {
await _channel.invokeMethod('requestMediaPlaybackState', args));
}
///Returns `true` if the [WebView] is in fullscreen mode, otherwise `false`.
///
///**Supported Platforms/Implementations**:
///- Android native WebView
///- iOS
Future<bool> isInFullscreen() async {
Map<String, dynamic> args = <String, dynamic>{};
return await _channel.invokeMethod('isInFullscreen', args);
}
///Returns the iframe `id` attribute used on the Web platform.
///
///**Supported Platforms/Implementations**: