diff --git a/build/Rakefile b/build/Rakefile index 8e82e7de..7fb82eb7 100644 --- a/build/Rakefile +++ b/build/Rakefile @@ -64,8 +64,8 @@ task :build do end ["Android"].each do |t| Dir.chdir("#{SRCDIR[0]}/#{t}") do - sh "git clean -dxf .; ./install.sh" - sh "git clean -dxf .; ./install.sh --development" + sh "git clean -dxf .; ./install.sh --zorderpatch" + sh "git clean -dxf .; ./install.sh --zorderpatch --development" end end ["Mac"].each do |t| @@ -102,8 +102,8 @@ task :buildnofragment do end ["Android"].each do |t| Dir.chdir("#{SRCDIR[0]}/#{t}") do - sh "git clean -dxf .; ./install.sh --nofragment" - sh "git clean -dxf .; ./install.sh --nofragment --development" + sh "git clean -dxf .; ./install.sh --zorderpatch --nofragment" + sh "git clean -dxf .; ./install.sh --zorderpatch --nofragment --development" end end ["Mac"].each do |t| diff --git a/dist/package-nofragment/Assets/Plugins/Android/WebViewPlugin-development.aar.tmpl b/dist/package-nofragment/Assets/Plugins/Android/WebViewPlugin-development.aar.tmpl index d3a6f060..8c677e29 100644 Binary files a/dist/package-nofragment/Assets/Plugins/Android/WebViewPlugin-development.aar.tmpl and b/dist/package-nofragment/Assets/Plugins/Android/WebViewPlugin-development.aar.tmpl differ diff --git a/dist/package-nofragment/Assets/Plugins/Android/WebViewPlugin-release.aar.tmpl b/dist/package-nofragment/Assets/Plugins/Android/WebViewPlugin-release.aar.tmpl index 7da18326..de4fdd13 100644 Binary files a/dist/package-nofragment/Assets/Plugins/Android/WebViewPlugin-release.aar.tmpl and b/dist/package-nofragment/Assets/Plugins/Android/WebViewPlugin-release.aar.tmpl differ diff --git a/dist/package-nofragment/Assets/Plugins/Editor/UnityWebViewPostprocessBuild.cs b/dist/package-nofragment/Assets/Plugins/Editor/UnityWebViewPostprocessBuild.cs index d2a72dbf..a04a29b6 100644 --- a/dist/package-nofragment/Assets/Plugins/Editor/UnityWebViewPostprocessBuild.cs +++ b/dist/package-nofragment/Assets/Plugins/Editor/UnityWebViewPostprocessBuild.cs @@ -95,6 +95,8 @@ public void OnPostGenerateGradleAndroidProject(string basePath) { } } changed = (androidManifest.SetExported(true) || changed); + changed = (androidManifest.SetApplicationTheme("@style/UnityThemeSelector") || changed); + changed = (androidManifest.SetActivityTheme("@style/UnityThemeSelector.Translucent") || changed); changed = (androidManifest.SetWindowSoftInputMode("adjustPan") || changed); changed = (androidManifest.SetHardwareAccelerated(true) || changed); #if UNITYWEBVIEW_ANDROID_USES_CLEARTEXT_TRAFFIC @@ -107,6 +109,9 @@ public void OnPostGenerateGradleAndroidProject(string basePath) { #if UNITYWEBVIEW_ANDROID_ENABLE_MICROPHONE changed = (androidManifest.AddMicrophone() || changed); #endif +//#if UNITY_5_6_0 || UNITY_5_6_1 + changed = (androidManifest.SetActivityName("net.gree.unitywebview.CUnityPlayerActivity") || changed); +//#endif if (changed) { androidManifest.Save(); Debug.Log("unitywebview: adjusted AndroidManifest.xml."); @@ -217,9 +222,9 @@ public static void OnPostprocessBuild(BuildTarget buildTarget, string path) { #if UNITYWEBVIEW_ANDROID_ENABLE_MICROPHONE changed = (androidManifest.AddMicrophone() || changed); #endif -#if UNITY_5_6_0 || UNITY_5_6_1 +//#if UNITY_5_6_0 || UNITY_5_6_1 changed = (androidManifest.SetActivityName("net.gree.unitywebview.CUnityPlayerActivity") || changed); -#endif +//#endif if (changed) { androidManifest.Save(); Debug.LogError("unitywebview: adjusted AndroidManifest.xml and/or WebView.aar. Please rebuild the app."); @@ -281,6 +286,133 @@ public static void OnPostprocessBuild(BuildTarget buildTarget, string path) { dst = (string)method.Invoke(proj, null); } File.WriteAllText(projPath, dst); + + // Classes/UI/UnityAppController+ViewHandling.mm + { + var text = File.ReadAllText(path + "/Classes/UI/UnityAppController+ViewHandling.mm"); + text = text.Replace( + @" + _rootController.view = _rootView = _unityView; +", + @" + UIView *view = [[UIView alloc] initWithFrame:controller.view.bounds]; + view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + [view addSubview:_unityView]; + _rootController.view = _rootView = view; +"); + File.WriteAllText(path + "/Classes/UI/UnityAppController+ViewHandling.mm", text); + } + // Classes/UI/UnityView.h + { + var lines0 = File.ReadAllText(path + "/Classes/UI/UnityView.h").Split('\n'); + var lines = new List(); + var phase = 0; + foreach (var line in lines0) { + switch (phase) { + case 0: + lines.Add(line); + if (line.StartsWith("@interface UnityView : UnityRenderingView")) { + phase++; + } + break; + case 1: + lines.Add(line); + if (line.StartsWith("}")) { + phase++; + lines.Add(""); + lines.Add("- (void)clearMasks;"); + lines.Add("- (void)addMask:(CGRect)r;"); + } + break; + default: + lines.Add(line); + break; + } + } + File.WriteAllText(path + "/Classes/UI/UnityView.h", string.Join("\n", lines)); + } + // Classes/UI/UnityView.mm + { + var lines0 = File.ReadAllText(path + "/Classes/UI/UnityView.mm").Split('\n'); + var lines = new List(); + var phase = 0; + foreach (var line in lines0) { + switch (phase) { + case 0: + lines.Add(line); + if (line.StartsWith("@implementation UnityView")) { + phase++; + } + break; + case 1: + if (line.StartsWith("}")) { + phase++; + lines.Add(" NSMutableArray *_masks;"); + lines.Add(line); + lines.Add(@" +- (void)clearMasks +{ + if (_masks == nil) { + _masks = [[NSMutableArray alloc] init]; + } + [_masks removeAllObjects]; +} + +- (void)addMask:(CGRect)r +{ + if (_masks == nil) { + _masks = [[NSMutableArray alloc] init]; + } + [_masks addObject:[NSValue valueWithCGRect:r]]; +} + +- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event +{ + //CGRect mask = CGRectMake(0, 0, 1334, 100); + //return CGRectContainsPoint(mask, point); + for (NSValue *v in _masks) { + if (CGRectContainsPoint([v CGRectValue], point)) { + return TRUE; + } + } + return FALSE; +} +"); + } else { + lines.Add(line); + } + break; + default: + lines.Add(line); + break; + } + } + lines.Add(@" +extern ""C"" { + UIView *UnityGetGLView(); + void CWebViewPlugin_ClearMasks(); + void CWebViewPlugin_AddMask(int x, int y, int w, int h); +} + +void CWebViewPlugin_ClearMasks() +{ + [(UnityView *)UnityGetGLView() clearMasks]; +} + +void CWebViewPlugin_AddMask(int x, int y, int w, int h) +{ + UIView *view = UnityGetGLViewController().view; + CGFloat scale = 1.0f; + if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) { + scale = view.window.screen.nativeScale; + } else { + scale = view.contentScaleFactor; + } + [(UnityView *)UnityGetGLView() addMask:CGRectMake(x / scale, y / scale, w / scale, h / scale)]; +} +"); + File.WriteAllText(path + "/Classes/UI/UnityView.mm", string.Join("\n", lines)); + } } } } @@ -357,6 +489,25 @@ internal bool SetExported(bool enabled) { return changed; } + internal bool SetApplicationTheme(string theme) { + bool changed = false; + if (ApplicationElement.GetAttribute("theme", AndroidXmlNamespace) != theme) { + ApplicationElement.SetAttribute("theme", AndroidXmlNamespace, theme); + changed = true; + } + return changed; + } + + internal bool SetActivityTheme(string theme) { + bool changed = false; + var activity = GetActivityWithLaunchIntent() as XmlElement; + if (activity.GetAttribute("theme", AndroidXmlNamespace) != theme) { + activity.SetAttribute("theme", AndroidXmlNamespace, theme); + changed = true; + } + return changed; + } + internal bool SetWindowSoftInputMode(string mode) { bool changed = false; var activity = GetActivityWithLaunchIntent() as XmlElement; diff --git a/dist/package-nofragment/Assets/Plugins/WebView.bundle/Contents/Info.plist b/dist/package-nofragment/Assets/Plugins/WebView.bundle/Contents/Info.plist index 32b46465..78ab16dc 100644 --- a/dist/package-nofragment/Assets/Plugins/WebView.bundle/Contents/Info.plist +++ b/dist/package-nofragment/Assets/Plugins/WebView.bundle/Contents/Info.plist @@ -3,7 +3,7 @@ BuildMachineOSBuild - 23H124 + 23H311 CFBundleDevelopmentRegion English CFBundleExecutable @@ -29,19 +29,19 @@ DTCompiler com.apple.compilers.llvm.clang.1_0 DTPlatformBuild - + 24B75 DTPlatformName macosx DTPlatformVersion - 14.5 + 15.1 DTSDKBuild - 23F73 + 24B75 DTSDKName - macosx14.5 + macosx15.1 DTXcode - 1540 + 1610 DTXcodeBuild - 15F31d + 16B40 LSMinimumSystemVersion 10.13 diff --git a/dist/package-nofragment/Assets/Plugins/WebView.bundle/Contents/MacOS/WebView b/dist/package-nofragment/Assets/Plugins/WebView.bundle/Contents/MacOS/WebView index 7646c0d2..82fea697 100755 Binary files a/dist/package-nofragment/Assets/Plugins/WebView.bundle/Contents/MacOS/WebView and b/dist/package-nofragment/Assets/Plugins/WebView.bundle/Contents/MacOS/WebView differ diff --git a/dist/package-nofragment/Assets/Plugins/WebViewObject.cs b/dist/package-nofragment/Assets/Plugins/WebViewObject.cs index 01c826e0..d0b1abc8 100644 --- a/dist/package-nofragment/Assets/Plugins/WebViewObject.cs +++ b/dist/package-nofragment/Assets/Plugins/WebViewObject.cs @@ -510,6 +510,9 @@ private static extern void _CWebViewPlugin_Reload( private static extern string _CWebViewPlugin_GetMessage(IntPtr instance); #elif UNITY_IPHONE [DllImport("__Internal")] + private static extern void CWebViewPlugin_ClearMasks(); + [DllImport("__Internal")] + private static extern void CWebViewPlugin_AddMask(int x, int y, int w, int h); private static extern bool _CWebViewPlugin_IsInitialized( IntPtr instance); [DllImport("__Internal")] @@ -611,6 +614,32 @@ public static bool IsWebViewAvailable() #endif } + public static void ClearMasks() + { +#if !UNITY_EDITOR && UNITY_ANDROID + using(AndroidJavaClass UnityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) + { + var activity = UnityClass.GetStatic("currentActivity"); + activity.Call("clearMasks"); + } +#elif !UNITY_EDITOR && UNITY_IPHONE + CWebViewPlugin_ClearMasks(); +#endif + } + + public static void AddMask(int x, int y, int w, int h) + { +#if !UNITY_EDITOR && UNITY_ANDROID + using(AndroidJavaClass UnityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) + { + var activity = UnityClass.GetStatic("currentActivity"); + activity.Call("addMask", x, y, w, h); + } +#elif !UNITY_EDITOR && UNITY_IPHONE + CWebViewPlugin_AddMask(x, y, w, h); +#endif + } + public bool IsInitialized() { #if UNITY_WEBPLAYER || UNITY_WEBGL diff --git a/dist/package-nofragment/Assets/Plugins/iOS/WebView.mm b/dist/package-nofragment/Assets/Plugins/iOS/WebView.mm index 4620012e..3b1d3c9b 100644 --- a/dist/package-nofragment/Assets/Plugins/iOS/WebView.mm +++ b/dist/package-nofragment/Assets/Plugins/iOS/WebView.mm @@ -265,7 +265,7 @@ - (id)initWithGameObjectName:(const char *)gameObjectName_ transparent:(BOOL)tra [webView addObserver:self forKeyPath: @"loading" options: NSKeyValueObservingOptionNew context:nil]; - [view addSubview:webView]; + [view insertSubview:webView atIndex:0]; return self; } diff --git a/dist/package-nofragment/Assets/Plugins/iOS/WebViewWithUIWebView.mm b/dist/package-nofragment/Assets/Plugins/iOS/WebViewWithUIWebView.mm index 1f288658..bf0bf2f7 100644 --- a/dist/package-nofragment/Assets/Plugins/iOS/WebViewWithUIWebView.mm +++ b/dist/package-nofragment/Assets/Plugins/iOS/WebViewWithUIWebView.mm @@ -325,7 +325,7 @@ - (id)initWithGameObjectName:(const char *)gameObjectName_ transparent:(BOOL)tra [webView addObserver:self forKeyPath: @"loading" options: NSKeyValueObservingOptionNew context:nil]; - [view addSubview:webView]; + [view insertSubview:webView atIndex:0]; return self; } diff --git a/dist/package/Assets/Plugins/Android/WebViewPlugin-development.aar.tmpl b/dist/package/Assets/Plugins/Android/WebViewPlugin-development.aar.tmpl index ef69fe9b..6bcf0a78 100644 Binary files a/dist/package/Assets/Plugins/Android/WebViewPlugin-development.aar.tmpl and b/dist/package/Assets/Plugins/Android/WebViewPlugin-development.aar.tmpl differ diff --git a/dist/package/Assets/Plugins/Android/WebViewPlugin-release.aar.tmpl b/dist/package/Assets/Plugins/Android/WebViewPlugin-release.aar.tmpl index ed47788b..dbaad3fe 100644 Binary files a/dist/package/Assets/Plugins/Android/WebViewPlugin-release.aar.tmpl and b/dist/package/Assets/Plugins/Android/WebViewPlugin-release.aar.tmpl differ diff --git a/dist/package/Assets/Plugins/Editor/UnityWebViewPostprocessBuild.cs b/dist/package/Assets/Plugins/Editor/UnityWebViewPostprocessBuild.cs index 19d9a961..e689ffbb 100644 --- a/dist/package/Assets/Plugins/Editor/UnityWebViewPostprocessBuild.cs +++ b/dist/package/Assets/Plugins/Editor/UnityWebViewPostprocessBuild.cs @@ -95,6 +95,8 @@ public void OnPostGenerateGradleAndroidProject(string basePath) { } } changed = (androidManifest.SetExported(true) || changed); + changed = (androidManifest.SetApplicationTheme("@style/UnityThemeSelector") || changed); + changed = (androidManifest.SetActivityTheme("@style/UnityThemeSelector.Translucent") || changed); changed = (androidManifest.SetWindowSoftInputMode("adjustPan") || changed); changed = (androidManifest.SetHardwareAccelerated(true) || changed); #if UNITYWEBVIEW_ANDROID_USES_CLEARTEXT_TRAFFIC @@ -107,6 +109,9 @@ public void OnPostGenerateGradleAndroidProject(string basePath) { #if UNITYWEBVIEW_ANDROID_ENABLE_MICROPHONE changed = (androidManifest.AddMicrophone() || changed); #endif +//#if UNITY_5_6_0 || UNITY_5_6_1 + changed = (androidManifest.SetActivityName("net.gree.unitywebview.CUnityPlayerActivity") || changed); +//#endif if (changed) { androidManifest.Save(); Debug.Log("unitywebview: adjusted AndroidManifest.xml."); @@ -217,9 +222,9 @@ public static void OnPostprocessBuild(BuildTarget buildTarget, string path) { #if UNITYWEBVIEW_ANDROID_ENABLE_MICROPHONE changed = (androidManifest.AddMicrophone() || changed); #endif -#if UNITY_5_6_0 || UNITY_5_6_1 +//#if UNITY_5_6_0 || UNITY_5_6_1 changed = (androidManifest.SetActivityName("net.gree.unitywebview.CUnityPlayerActivity") || changed); -#endif +//#endif if (changed) { androidManifest.Save(); Debug.LogError("unitywebview: adjusted AndroidManifest.xml and/or WebView.aar. Please rebuild the app."); @@ -281,6 +286,133 @@ public static void OnPostprocessBuild(BuildTarget buildTarget, string path) { dst = (string)method.Invoke(proj, null); } File.WriteAllText(projPath, dst); + + // Classes/UI/UnityAppController+ViewHandling.mm + { + var text = File.ReadAllText(path + "/Classes/UI/UnityAppController+ViewHandling.mm"); + text = text.Replace( + @" + _rootController.view = _rootView = _unityView; +", + @" + UIView *view = [[UIView alloc] initWithFrame:controller.view.bounds]; + view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + [view addSubview:_unityView]; + _rootController.view = _rootView = view; +"); + File.WriteAllText(path + "/Classes/UI/UnityAppController+ViewHandling.mm", text); + } + // Classes/UI/UnityView.h + { + var lines0 = File.ReadAllText(path + "/Classes/UI/UnityView.h").Split('\n'); + var lines = new List(); + var phase = 0; + foreach (var line in lines0) { + switch (phase) { + case 0: + lines.Add(line); + if (line.StartsWith("@interface UnityView : UnityRenderingView")) { + phase++; + } + break; + case 1: + lines.Add(line); + if (line.StartsWith("}")) { + phase++; + lines.Add(""); + lines.Add("- (void)clearMasks;"); + lines.Add("- (void)addMask:(CGRect)r;"); + } + break; + default: + lines.Add(line); + break; + } + } + File.WriteAllText(path + "/Classes/UI/UnityView.h", string.Join("\n", lines)); + } + // Classes/UI/UnityView.mm + { + var lines0 = File.ReadAllText(path + "/Classes/UI/UnityView.mm").Split('\n'); + var lines = new List(); + var phase = 0; + foreach (var line in lines0) { + switch (phase) { + case 0: + lines.Add(line); + if (line.StartsWith("@implementation UnityView")) { + phase++; + } + break; + case 1: + if (line.StartsWith("}")) { + phase++; + lines.Add(" NSMutableArray *_masks;"); + lines.Add(line); + lines.Add(@" +- (void)clearMasks +{ + if (_masks == nil) { + _masks = [[NSMutableArray alloc] init]; + } + [_masks removeAllObjects]; +} + +- (void)addMask:(CGRect)r +{ + if (_masks == nil) { + _masks = [[NSMutableArray alloc] init]; + } + [_masks addObject:[NSValue valueWithCGRect:r]]; +} + +- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event +{ + //CGRect mask = CGRectMake(0, 0, 1334, 100); + //return CGRectContainsPoint(mask, point); + for (NSValue *v in _masks) { + if (CGRectContainsPoint([v CGRectValue], point)) { + return TRUE; + } + } + return FALSE; +} +"); + } else { + lines.Add(line); + } + break; + default: + lines.Add(line); + break; + } + } + lines.Add(@" +extern ""C"" { + UIView *UnityGetGLView(); + void CWebViewPlugin_ClearMasks(); + void CWebViewPlugin_AddMask(int x, int y, int w, int h); +} + +void CWebViewPlugin_ClearMasks() +{ + [(UnityView *)UnityGetGLView() clearMasks]; +} + +void CWebViewPlugin_AddMask(int x, int y, int w, int h) +{ + UIView *view = UnityGetGLViewController().view; + CGFloat scale = 1.0f; + if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) { + scale = view.window.screen.nativeScale; + } else { + scale = view.contentScaleFactor; + } + [(UnityView *)UnityGetGLView() addMask:CGRectMake(x / scale, y / scale, w / scale, h / scale)]; +} +"); + File.WriteAllText(path + "/Classes/UI/UnityView.mm", string.Join("\n", lines)); + } } } } @@ -357,6 +489,25 @@ internal bool SetExported(bool enabled) { return changed; } + internal bool SetApplicationTheme(string theme) { + bool changed = false; + if (ApplicationElement.GetAttribute("theme", AndroidXmlNamespace) != theme) { + ApplicationElement.SetAttribute("theme", AndroidXmlNamespace, theme); + changed = true; + } + return changed; + } + + internal bool SetActivityTheme(string theme) { + bool changed = false; + var activity = GetActivityWithLaunchIntent() as XmlElement; + if (activity.GetAttribute("theme", AndroidXmlNamespace) != theme) { + activity.SetAttribute("theme", AndroidXmlNamespace, theme); + changed = true; + } + return changed; + } + internal bool SetWindowSoftInputMode(string mode) { bool changed = false; var activity = GetActivityWithLaunchIntent() as XmlElement; diff --git a/dist/package/Assets/Plugins/WebView.bundle/Contents/Info.plist b/dist/package/Assets/Plugins/WebView.bundle/Contents/Info.plist index 32b46465..78ab16dc 100644 --- a/dist/package/Assets/Plugins/WebView.bundle/Contents/Info.plist +++ b/dist/package/Assets/Plugins/WebView.bundle/Contents/Info.plist @@ -3,7 +3,7 @@ BuildMachineOSBuild - 23H124 + 23H311 CFBundleDevelopmentRegion English CFBundleExecutable @@ -29,19 +29,19 @@ DTCompiler com.apple.compilers.llvm.clang.1_0 DTPlatformBuild - + 24B75 DTPlatformName macosx DTPlatformVersion - 14.5 + 15.1 DTSDKBuild - 23F73 + 24B75 DTSDKName - macosx14.5 + macosx15.1 DTXcode - 1540 + 1610 DTXcodeBuild - 15F31d + 16B40 LSMinimumSystemVersion 10.13 diff --git a/dist/package/Assets/Plugins/WebView.bundle/Contents/MacOS/WebView b/dist/package/Assets/Plugins/WebView.bundle/Contents/MacOS/WebView index 7646c0d2..82fea697 100755 Binary files a/dist/package/Assets/Plugins/WebView.bundle/Contents/MacOS/WebView and b/dist/package/Assets/Plugins/WebView.bundle/Contents/MacOS/WebView differ diff --git a/dist/package/Assets/Plugins/WebViewObject.cs b/dist/package/Assets/Plugins/WebViewObject.cs index 01c826e0..d0b1abc8 100644 --- a/dist/package/Assets/Plugins/WebViewObject.cs +++ b/dist/package/Assets/Plugins/WebViewObject.cs @@ -510,6 +510,9 @@ private static extern void _CWebViewPlugin_Reload( private static extern string _CWebViewPlugin_GetMessage(IntPtr instance); #elif UNITY_IPHONE [DllImport("__Internal")] + private static extern void CWebViewPlugin_ClearMasks(); + [DllImport("__Internal")] + private static extern void CWebViewPlugin_AddMask(int x, int y, int w, int h); private static extern bool _CWebViewPlugin_IsInitialized( IntPtr instance); [DllImport("__Internal")] @@ -611,6 +614,32 @@ public static bool IsWebViewAvailable() #endif } + public static void ClearMasks() + { +#if !UNITY_EDITOR && UNITY_ANDROID + using(AndroidJavaClass UnityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) + { + var activity = UnityClass.GetStatic("currentActivity"); + activity.Call("clearMasks"); + } +#elif !UNITY_EDITOR && UNITY_IPHONE + CWebViewPlugin_ClearMasks(); +#endif + } + + public static void AddMask(int x, int y, int w, int h) + { +#if !UNITY_EDITOR && UNITY_ANDROID + using(AndroidJavaClass UnityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) + { + var activity = UnityClass.GetStatic("currentActivity"); + activity.Call("addMask", x, y, w, h); + } +#elif !UNITY_EDITOR && UNITY_IPHONE + CWebViewPlugin_AddMask(x, y, w, h); +#endif + } + public bool IsInitialized() { #if UNITY_WEBPLAYER || UNITY_WEBGL diff --git a/dist/package/Assets/Plugins/iOS/WebView.mm b/dist/package/Assets/Plugins/iOS/WebView.mm index 4620012e..3b1d3c9b 100644 --- a/dist/package/Assets/Plugins/iOS/WebView.mm +++ b/dist/package/Assets/Plugins/iOS/WebView.mm @@ -265,7 +265,7 @@ - (id)initWithGameObjectName:(const char *)gameObjectName_ transparent:(BOOL)tra [webView addObserver:self forKeyPath: @"loading" options: NSKeyValueObservingOptionNew context:nil]; - [view addSubview:webView]; + [view insertSubview:webView atIndex:0]; return self; } diff --git a/dist/package/Assets/Plugins/iOS/WebViewWithUIWebView.mm b/dist/package/Assets/Plugins/iOS/WebViewWithUIWebView.mm index 1f288658..bf0bf2f7 100644 --- a/dist/package/Assets/Plugins/iOS/WebViewWithUIWebView.mm +++ b/dist/package/Assets/Plugins/iOS/WebViewWithUIWebView.mm @@ -325,7 +325,7 @@ - (id)initWithGameObjectName:(const char *)gameObjectName_ transparent:(BOOL)tra [webView addObserver:self forKeyPath: @"loading" options: NSKeyValueObservingOptionNew context:nil]; - [view addSubview:webView]; + [view insertSubview:webView atIndex:0]; return self; } diff --git a/dist/unity-webview-nofragment.unitypackage b/dist/unity-webview-nofragment.unitypackage index b73ba783..f925ac04 100644 Binary files a/dist/unity-webview-nofragment.unitypackage and b/dist/unity-webview-nofragment.unitypackage differ diff --git a/dist/unity-webview-nofragment.zip b/dist/unity-webview-nofragment.zip index dacff38c..6a48f6f2 100644 Binary files a/dist/unity-webview-nofragment.zip and b/dist/unity-webview-nofragment.zip differ diff --git a/dist/unity-webview.unitypackage b/dist/unity-webview.unitypackage index 1128e690..b0fd5cb7 100644 Binary files a/dist/unity-webview.unitypackage and b/dist/unity-webview.unitypackage differ diff --git a/dist/unity-webview.zip b/dist/unity-webview.zip index 33881ad0..f3bc66be 100644 Binary files a/dist/unity-webview.zip and b/dist/unity-webview.zip differ diff --git a/plugins/Android/webview-nofragment/src/main/java/net/gree/unitywebview/CUnityPlayer.java b/plugins/Android/webview-nofragment/src/main/java/net/gree/unitywebview/CUnityPlayer.java deleted file mode 100644 index c3f8e613..00000000 --- a/plugins/Android/webview-nofragment/src/main/java/net/gree/unitywebview/CUnityPlayer.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.gree.unitywebview; - -import com.unity3d.player.*; -import android.content.ContextWrapper; -import android.view.SurfaceView; -import android.view.View; - -public class CUnityPlayer - extends UnityPlayer -{ - public CUnityPlayer(ContextWrapper contextwrapper) { - super(contextwrapper); - } - - public void addView(View child) { - if (child instanceof SurfaceView) { - ((SurfaceView)child).setZOrderOnTop(false); - } - super.addView(child); - } -} diff --git a/plugins/Android/webview-nofragment/src/main/java/net/gree/unitywebview/CUnityPlayerActivity.java b/plugins/Android/webview-nofragment/src/main/java/net/gree/unitywebview/CUnityPlayerActivity.java index 308d8a13..230b6fca 100644 --- a/plugins/Android/webview-nofragment/src/main/java/net/gree/unitywebview/CUnityPlayerActivity.java +++ b/plugins/Android/webview-nofragment/src/main/java/net/gree/unitywebview/CUnityPlayerActivity.java @@ -1,18 +1,81 @@ package net.gree.unitywebview; -import com.unity3d.player.*; +import android.app.Activity; +import android.graphics.Color; +import android.graphics.Rect; +import android.os.Build; import android.os.Bundle; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.webkit.WebView; +import com.unity3d.player.*; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; public class CUnityPlayerActivity extends UnityPlayerActivity { + private List _webViewPlugins = new ArrayList(); + private List _masks = new ArrayList(); + @Override - public void onCreate(Bundle bundle) { - requestWindowFeature(1); - super.onCreate(bundle); - getWindow().setFormat(2); - mUnityPlayer = new CUnityPlayer(this); - setContentView(mUnityPlayer); - mUnityPlayer.requestFocus(); + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + // getWindow().getDecorView().setBackgroundColor(Color.BLACK); + // cf. https://stackoverflow.com/questions/9812427/android-how-to-programmatically-make-an-activity-window-transluscent + // cf. https://github.com/ikew0ng/SwipeBackLayout/blob/e4ddae6d2b8af9b606493cba36faef8beba94be2/library/src/main/java/me/imid/swipebacklayout/lib/Utils.java + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + setTranslucent(false); + } else { + try { + Method method = Activity.class.getDeclaredMethod("convertFromTranslucent"); + method.setAccessible(true); + method.invoke(this); + } catch (Throwable t) { + } + } + } + + @Override + public boolean dispatchTouchEvent(MotionEvent event) { + boolean ret = super.dispatchTouchEvent(event); + int pointerCount = event.getPointerCount(); + for (int p = 0; p < pointerCount; p++) { + float x = event.getX(p); + float y = event.getY(p); + for (Rect mask : _masks) { + if (mask.contains((int)x, (int)y)) { + return ret; + } + } + } + for (CWebViewPlugin webViewPlugin : _webViewPlugins) { + // cf. https://stackoverflow.com/questions/17845545/custom-viewgroup-dispatchtouchevent-doesnt-work-correctly/17845670#17845670 + MotionEvent cp = MotionEvent.obtain(event); + View view = (webViewPlugin.mVideoView != null) ? webViewPlugin.mVideoView : webViewPlugin.mWebView; + cp.offsetLocation(-view.getLeft(), -view.getTop()); + view.dispatchTouchEvent(cp); + cp.recycle(); + } + return ret; + } + + void add(CWebViewPlugin webViewPlugin) { + _webViewPlugins.add(webViewPlugin); + } + + void remove(CWebViewPlugin webViewPlugin) { + _webViewPlugins.remove(webViewPlugin); + } + + public void clearMasks() { + _masks.clear(); + } + + public void addMask(int left, int top, int right, int bottom) { + _masks.add(new Rect(left, top, right, bottom)); } } diff --git a/plugins/Android/webview-nofragment/src/main/java/net/gree/unitywebview/CWebViewPlugin.java b/plugins/Android/webview-nofragment/src/main/java/net/gree/unitywebview/CWebViewPlugin.java index 3efd55a3..a2e947d5 100644 --- a/plugins/Android/webview-nofragment/src/main/java/net/gree/unitywebview/CWebViewPlugin.java +++ b/plugins/Android/webview-nofragment/src/main/java/net/gree/unitywebview/CWebViewPlugin.java @@ -105,8 +105,8 @@ public class CWebViewPlugin { private static boolean forceBringToFront; private static FrameLayout layout = null; private Queue mMessages = new ArrayDeque(); - private WebView mWebView; - private View mVideoView; + WebView mWebView; + View mVideoView; private OnGlobalLayoutListener mGlobalLayoutListener; private CWebViewPluginInterface mWebViewPlugin; private int progress; @@ -266,7 +266,7 @@ public void onHideCustomView() { super.onHideCustomView(); if (layout != null) { layout.removeView(mVideoView); - layout.setBackgroundColor(0x00000000); + layout.setBackgroundColor(0xff000000); mVideoView = null; } } @@ -549,6 +549,7 @@ public boolean onTouch(View view, MotionEvent event) { if (layout == null || layout.getParent() != a.findViewById(android.R.id.content)) { layout = new FrameLayout(a); + layout.setBackgroundColor(0xff000000); a.addContentView( layout, new LayoutParams( @@ -556,6 +557,14 @@ public boolean onTouch(View view, MotionEvent event) { LayoutParams.MATCH_PARENT)); layout.setFocusable(true); layout.setFocusableInTouchMode(true); + { + // cf. https://stackoverflow.com/questions/6759036/how-to-send-view-to-back-how-to-control-the-z-order-programmatically/19872801#19872801 + ViewGroup parent = (ViewGroup)layout.getParent(); + if (parent != null) { + parent.removeView(layout); + parent.addView(layout, 0); + } + } } layout.addView( webView, @@ -564,6 +573,7 @@ public boolean onTouch(View view, MotionEvent event) { LayoutParams.MATCH_PARENT, Gravity.NO_GRAVITY)); mWebView = webView; + ((CUnityPlayerActivity)a).add(self); }}); final View activityRootView = a.getWindow().getDecorView().getRootView(); @@ -612,6 +622,7 @@ public void onGlobalLayout() { public void Destroy() { final Activity a = UnityPlayer.currentActivity; + ((CUnityPlayerActivity)a).remove(this); if (CWebViewPlugin.isDestroyed(a)) { return; } @@ -629,7 +640,7 @@ public void Destroy() { webView.stopLoading(); if (mVideoView != null) { layout.removeView(mVideoView); - layout.setBackgroundColor(0x00000000); + layout.setBackgroundColor(0xff000000); mVideoView = null; } layout.removeView(webView); @@ -781,7 +792,7 @@ public void SetVisibility(final boolean visibility) { ((ViewGroup)layout.getParent().getParent()).requestLayout(); } if (forceBringToFront && layout != null) { - layout.bringToFront(); + //layout.bringToFront(); } } else { mWebView.setVisibility(View.GONE); @@ -906,7 +917,7 @@ public void OnApplicationPause(final boolean paused) { mWebView.onResume(); mWebView.resumeTimers(); if (forceBringToFront && layout != null) { - layout.bringToFront(); + //layout.bringToFront(); } } }}); diff --git a/plugins/Android/webview/src/main/java/net/gree/unitywebview/CUnityPlayer.java b/plugins/Android/webview/src/main/java/net/gree/unitywebview/CUnityPlayer.java deleted file mode 100644 index c3f8e613..00000000 --- a/plugins/Android/webview/src/main/java/net/gree/unitywebview/CUnityPlayer.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.gree.unitywebview; - -import com.unity3d.player.*; -import android.content.ContextWrapper; -import android.view.SurfaceView; -import android.view.View; - -public class CUnityPlayer - extends UnityPlayer -{ - public CUnityPlayer(ContextWrapper contextwrapper) { - super(contextwrapper); - } - - public void addView(View child) { - if (child instanceof SurfaceView) { - ((SurfaceView)child).setZOrderOnTop(false); - } - super.addView(child); - } -} diff --git a/plugins/Android/webview/src/main/java/net/gree/unitywebview/CUnityPlayerActivity.java b/plugins/Android/webview/src/main/java/net/gree/unitywebview/CUnityPlayerActivity.java index 308d8a13..230b6fca 100644 --- a/plugins/Android/webview/src/main/java/net/gree/unitywebview/CUnityPlayerActivity.java +++ b/plugins/Android/webview/src/main/java/net/gree/unitywebview/CUnityPlayerActivity.java @@ -1,18 +1,81 @@ package net.gree.unitywebview; -import com.unity3d.player.*; +import android.app.Activity; +import android.graphics.Color; +import android.graphics.Rect; +import android.os.Build; import android.os.Bundle; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.webkit.WebView; +import com.unity3d.player.*; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; public class CUnityPlayerActivity extends UnityPlayerActivity { + private List _webViewPlugins = new ArrayList(); + private List _masks = new ArrayList(); + @Override - public void onCreate(Bundle bundle) { - requestWindowFeature(1); - super.onCreate(bundle); - getWindow().setFormat(2); - mUnityPlayer = new CUnityPlayer(this); - setContentView(mUnityPlayer); - mUnityPlayer.requestFocus(); + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + // getWindow().getDecorView().setBackgroundColor(Color.BLACK); + // cf. https://stackoverflow.com/questions/9812427/android-how-to-programmatically-make-an-activity-window-transluscent + // cf. https://github.com/ikew0ng/SwipeBackLayout/blob/e4ddae6d2b8af9b606493cba36faef8beba94be2/library/src/main/java/me/imid/swipebacklayout/lib/Utils.java + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + setTranslucent(false); + } else { + try { + Method method = Activity.class.getDeclaredMethod("convertFromTranslucent"); + method.setAccessible(true); + method.invoke(this); + } catch (Throwable t) { + } + } + } + + @Override + public boolean dispatchTouchEvent(MotionEvent event) { + boolean ret = super.dispatchTouchEvent(event); + int pointerCount = event.getPointerCount(); + for (int p = 0; p < pointerCount; p++) { + float x = event.getX(p); + float y = event.getY(p); + for (Rect mask : _masks) { + if (mask.contains((int)x, (int)y)) { + return ret; + } + } + } + for (CWebViewPlugin webViewPlugin : _webViewPlugins) { + // cf. https://stackoverflow.com/questions/17845545/custom-viewgroup-dispatchtouchevent-doesnt-work-correctly/17845670#17845670 + MotionEvent cp = MotionEvent.obtain(event); + View view = (webViewPlugin.mVideoView != null) ? webViewPlugin.mVideoView : webViewPlugin.mWebView; + cp.offsetLocation(-view.getLeft(), -view.getTop()); + view.dispatchTouchEvent(cp); + cp.recycle(); + } + return ret; + } + + void add(CWebViewPlugin webViewPlugin) { + _webViewPlugins.add(webViewPlugin); + } + + void remove(CWebViewPlugin webViewPlugin) { + _webViewPlugins.remove(webViewPlugin); + } + + public void clearMasks() { + _masks.clear(); + } + + public void addMask(int left, int top, int right, int bottom) { + _masks.add(new Rect(left, top, right, bottom)); } } diff --git a/plugins/Android/webview/src/main/java/net/gree/unitywebview/CWebViewPlugin.java b/plugins/Android/webview/src/main/java/net/gree/unitywebview/CWebViewPlugin.java index 15d8fdb3..8204aa94 100644 --- a/plugins/Android/webview/src/main/java/net/gree/unitywebview/CWebViewPlugin.java +++ b/plugins/Android/webview/src/main/java/net/gree/unitywebview/CWebViewPlugin.java @@ -136,8 +136,8 @@ public class CWebViewPlugin extends Fragment { private static boolean forceBringToFront; private static FrameLayout layout = null; private Queue mMessages = new ArrayDeque(); - private WebView mWebView; - private View mVideoView; + WebView mWebView; + View mVideoView; private OnGlobalLayoutListener mGlobalLayoutListener; private CWebViewPluginInterface mWebViewPlugin; private int progress; @@ -487,7 +487,7 @@ public void onHideCustomView() { super.onHideCustomView(); if (layout != null) { layout.removeView(mVideoView); - layout.setBackgroundColor(0x00000000); + layout.setBackgroundColor(0xff000000); mVideoView = null; } } @@ -803,6 +803,7 @@ public boolean onTouch(View view, MotionEvent event) { if (layout == null || layout.getParent() != a.findViewById(android.R.id.content)) { layout = new FrameLayout(a); + layout.setBackgroundColor(0xff000000); a.addContentView( layout, new LayoutParams( @@ -810,6 +811,14 @@ public boolean onTouch(View view, MotionEvent event) { LayoutParams.MATCH_PARENT)); layout.setFocusable(true); layout.setFocusableInTouchMode(true); + { + // cf. https://stackoverflow.com/questions/6759036/how-to-send-view-to-back-how-to-control-the-z-order-programmatically/19872801#19872801 + ViewGroup parent = (ViewGroup)layout.getParent(); + if (parent != null) { + parent.removeView(layout); + parent.addView(layout, 0); + } + } } layout.addView( webView, @@ -818,6 +827,7 @@ public boolean onTouch(View view, MotionEvent event) { LayoutParams.MATCH_PARENT, Gravity.NO_GRAVITY)); mWebView = webView; + ((CUnityPlayerActivity)a).add(self); }}); final View activityRootView = a.getWindow().getDecorView().getRootView(); @@ -929,6 +939,7 @@ private File createImageFile() throws IOException { public void Destroy() { final Activity a = UnityPlayer.currentActivity; final CWebViewPlugin self = this; + ((CUnityPlayerActivity)a).remove(self); mMessages.clear(); if (CWebViewPlugin.isDestroyed(a)) { return; @@ -947,7 +958,7 @@ public void Destroy() { webView.stopLoading(); if (mVideoView != null) { layout.removeView(mVideoView); - layout.setBackgroundColor(0x00000000); + layout.setBackgroundColor(0xff000000); mVideoView = null; } layout.removeView(webView); @@ -1113,7 +1124,7 @@ public void SetVisibility(final boolean visibility) { ((ViewGroup)layout.getParent().getParent()).requestLayout(); } if (forceBringToFront && layout != null) { - layout.bringToFront(); + //layout.bringToFront(); } } else { mWebView.setVisibility(View.GONE); @@ -1263,7 +1274,7 @@ public void OnApplicationPause(boolean paused) { mWebView.onResume(); mWebView.resumeTimers(); if (forceBringToFront && layout != null) { - layout.bringToFront(); + //layout.bringToFront(); } } }}); diff --git a/plugins/Editor/UnityWebViewPostprocessBuild.cs b/plugins/Editor/UnityWebViewPostprocessBuild.cs index 19d9a961..e689ffbb 100644 --- a/plugins/Editor/UnityWebViewPostprocessBuild.cs +++ b/plugins/Editor/UnityWebViewPostprocessBuild.cs @@ -95,6 +95,8 @@ public void OnPostGenerateGradleAndroidProject(string basePath) { } } changed = (androidManifest.SetExported(true) || changed); + changed = (androidManifest.SetApplicationTheme("@style/UnityThemeSelector") || changed); + changed = (androidManifest.SetActivityTheme("@style/UnityThemeSelector.Translucent") || changed); changed = (androidManifest.SetWindowSoftInputMode("adjustPan") || changed); changed = (androidManifest.SetHardwareAccelerated(true) || changed); #if UNITYWEBVIEW_ANDROID_USES_CLEARTEXT_TRAFFIC @@ -107,6 +109,9 @@ public void OnPostGenerateGradleAndroidProject(string basePath) { #if UNITYWEBVIEW_ANDROID_ENABLE_MICROPHONE changed = (androidManifest.AddMicrophone() || changed); #endif +//#if UNITY_5_6_0 || UNITY_5_6_1 + changed = (androidManifest.SetActivityName("net.gree.unitywebview.CUnityPlayerActivity") || changed); +//#endif if (changed) { androidManifest.Save(); Debug.Log("unitywebview: adjusted AndroidManifest.xml."); @@ -217,9 +222,9 @@ public static void OnPostprocessBuild(BuildTarget buildTarget, string path) { #if UNITYWEBVIEW_ANDROID_ENABLE_MICROPHONE changed = (androidManifest.AddMicrophone() || changed); #endif -#if UNITY_5_6_0 || UNITY_5_6_1 +//#if UNITY_5_6_0 || UNITY_5_6_1 changed = (androidManifest.SetActivityName("net.gree.unitywebview.CUnityPlayerActivity") || changed); -#endif +//#endif if (changed) { androidManifest.Save(); Debug.LogError("unitywebview: adjusted AndroidManifest.xml and/or WebView.aar. Please rebuild the app."); @@ -281,6 +286,133 @@ public static void OnPostprocessBuild(BuildTarget buildTarget, string path) { dst = (string)method.Invoke(proj, null); } File.WriteAllText(projPath, dst); + + // Classes/UI/UnityAppController+ViewHandling.mm + { + var text = File.ReadAllText(path + "/Classes/UI/UnityAppController+ViewHandling.mm"); + text = text.Replace( + @" + _rootController.view = _rootView = _unityView; +", + @" + UIView *view = [[UIView alloc] initWithFrame:controller.view.bounds]; + view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + [view addSubview:_unityView]; + _rootController.view = _rootView = view; +"); + File.WriteAllText(path + "/Classes/UI/UnityAppController+ViewHandling.mm", text); + } + // Classes/UI/UnityView.h + { + var lines0 = File.ReadAllText(path + "/Classes/UI/UnityView.h").Split('\n'); + var lines = new List(); + var phase = 0; + foreach (var line in lines0) { + switch (phase) { + case 0: + lines.Add(line); + if (line.StartsWith("@interface UnityView : UnityRenderingView")) { + phase++; + } + break; + case 1: + lines.Add(line); + if (line.StartsWith("}")) { + phase++; + lines.Add(""); + lines.Add("- (void)clearMasks;"); + lines.Add("- (void)addMask:(CGRect)r;"); + } + break; + default: + lines.Add(line); + break; + } + } + File.WriteAllText(path + "/Classes/UI/UnityView.h", string.Join("\n", lines)); + } + // Classes/UI/UnityView.mm + { + var lines0 = File.ReadAllText(path + "/Classes/UI/UnityView.mm").Split('\n'); + var lines = new List(); + var phase = 0; + foreach (var line in lines0) { + switch (phase) { + case 0: + lines.Add(line); + if (line.StartsWith("@implementation UnityView")) { + phase++; + } + break; + case 1: + if (line.StartsWith("}")) { + phase++; + lines.Add(" NSMutableArray *_masks;"); + lines.Add(line); + lines.Add(@" +- (void)clearMasks +{ + if (_masks == nil) { + _masks = [[NSMutableArray alloc] init]; + } + [_masks removeAllObjects]; +} + +- (void)addMask:(CGRect)r +{ + if (_masks == nil) { + _masks = [[NSMutableArray alloc] init]; + } + [_masks addObject:[NSValue valueWithCGRect:r]]; +} + +- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event +{ + //CGRect mask = CGRectMake(0, 0, 1334, 100); + //return CGRectContainsPoint(mask, point); + for (NSValue *v in _masks) { + if (CGRectContainsPoint([v CGRectValue], point)) { + return TRUE; + } + } + return FALSE; +} +"); + } else { + lines.Add(line); + } + break; + default: + lines.Add(line); + break; + } + } + lines.Add(@" +extern ""C"" { + UIView *UnityGetGLView(); + void CWebViewPlugin_ClearMasks(); + void CWebViewPlugin_AddMask(int x, int y, int w, int h); +} + +void CWebViewPlugin_ClearMasks() +{ + [(UnityView *)UnityGetGLView() clearMasks]; +} + +void CWebViewPlugin_AddMask(int x, int y, int w, int h) +{ + UIView *view = UnityGetGLViewController().view; + CGFloat scale = 1.0f; + if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) { + scale = view.window.screen.nativeScale; + } else { + scale = view.contentScaleFactor; + } + [(UnityView *)UnityGetGLView() addMask:CGRectMake(x / scale, y / scale, w / scale, h / scale)]; +} +"); + File.WriteAllText(path + "/Classes/UI/UnityView.mm", string.Join("\n", lines)); + } } } } @@ -357,6 +489,25 @@ internal bool SetExported(bool enabled) { return changed; } + internal bool SetApplicationTheme(string theme) { + bool changed = false; + if (ApplicationElement.GetAttribute("theme", AndroidXmlNamespace) != theme) { + ApplicationElement.SetAttribute("theme", AndroidXmlNamespace, theme); + changed = true; + } + return changed; + } + + internal bool SetActivityTheme(string theme) { + bool changed = false; + var activity = GetActivityWithLaunchIntent() as XmlElement; + if (activity.GetAttribute("theme", AndroidXmlNamespace) != theme) { + activity.SetAttribute("theme", AndroidXmlNamespace, theme); + changed = true; + } + return changed; + } + internal bool SetWindowSoftInputMode(string mode) { bool changed = false; var activity = GetActivityWithLaunchIntent() as XmlElement; diff --git a/plugins/WebViewObject.cs b/plugins/WebViewObject.cs index 01c826e0..d0b1abc8 100644 --- a/plugins/WebViewObject.cs +++ b/plugins/WebViewObject.cs @@ -510,6 +510,9 @@ private static extern void _CWebViewPlugin_Reload( private static extern string _CWebViewPlugin_GetMessage(IntPtr instance); #elif UNITY_IPHONE [DllImport("__Internal")] + private static extern void CWebViewPlugin_ClearMasks(); + [DllImport("__Internal")] + private static extern void CWebViewPlugin_AddMask(int x, int y, int w, int h); private static extern bool _CWebViewPlugin_IsInitialized( IntPtr instance); [DllImport("__Internal")] @@ -611,6 +614,32 @@ public static bool IsWebViewAvailable() #endif } + public static void ClearMasks() + { +#if !UNITY_EDITOR && UNITY_ANDROID + using(AndroidJavaClass UnityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) + { + var activity = UnityClass.GetStatic("currentActivity"); + activity.Call("clearMasks"); + } +#elif !UNITY_EDITOR && UNITY_IPHONE + CWebViewPlugin_ClearMasks(); +#endif + } + + public static void AddMask(int x, int y, int w, int h) + { +#if !UNITY_EDITOR && UNITY_ANDROID + using(AndroidJavaClass UnityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) + { + var activity = UnityClass.GetStatic("currentActivity"); + activity.Call("addMask", x, y, w, h); + } +#elif !UNITY_EDITOR && UNITY_IPHONE + CWebViewPlugin_AddMask(x, y, w, h); +#endif + } + public bool IsInitialized() { #if UNITY_WEBPLAYER || UNITY_WEBGL diff --git a/plugins/iOS/WebView.mm b/plugins/iOS/WebView.mm index 4620012e..3b1d3c9b 100644 --- a/plugins/iOS/WebView.mm +++ b/plugins/iOS/WebView.mm @@ -265,7 +265,7 @@ - (id)initWithGameObjectName:(const char *)gameObjectName_ transparent:(BOOL)tra [webView addObserver:self forKeyPath: @"loading" options: NSKeyValueObservingOptionNew context:nil]; - [view addSubview:webView]; + [view insertSubview:webView atIndex:0]; return self; } diff --git a/plugins/iOS/WebViewWithUIWebView.mm b/plugins/iOS/WebViewWithUIWebView.mm index 1f288658..bf0bf2f7 100644 --- a/plugins/iOS/WebViewWithUIWebView.mm +++ b/plugins/iOS/WebViewWithUIWebView.mm @@ -325,7 +325,7 @@ - (id)initWithGameObjectName:(const char *)gameObjectName_ transparent:(BOOL)tra [webView addObserver:self forKeyPath: @"loading" options: NSKeyValueObservingOptionNew context:nil]; - [view addSubview:webView]; + [view insertSubview:webView atIndex:0]; return self; } diff --git a/sample/Assets/Scripts/SampleWebView.cs b/sample/Assets/Scripts/SampleWebView.cs index d06f28ca..cad896ec 100644 --- a/sample/Assets/Scripts/SampleWebView.cs +++ b/sample/Assets/Scripts/SampleWebView.cs @@ -161,6 +161,9 @@ IEnumerator Start() //webViewObject.SetMixedContentMode(2); // android only. 0: MIXED_CONTENT_ALWAYS_ALLOW, 1: MIXED_CONTENT_NEVER_ALLOW, 2: MIXED_CONTENT_COMPATIBILITY_MODE webViewObject.SetVisibility(true); + WebViewObject.ClearMasks(); + WebViewObject.AddMask(0, 0, Screen.width, 100); + #if !UNITY_WEBPLAYER && !UNITY_WEBGL if (Url.StartsWith("http")) { webViewObject.LoadURL(Url.Replace(" ", "%20"));