Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Binary file modified dist/unity-webview-nofragment.unitypackage
Binary file not shown.
Binary file modified dist/unity-webview-nofragment.zip
Binary file not shown.
Binary file modified dist/unity-webview.unitypackage
Binary file not shown.
Binary file modified dist/unity-webview.zip
Binary file not shown.
72 changes: 58 additions & 14 deletions plugins/Android/src/net/gree/unitywebview/CWebViewPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.util.Pair;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
Expand Down Expand Up @@ -63,6 +64,7 @@
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;
Expand Down Expand Up @@ -120,6 +122,8 @@ public class CWebViewPlugin extends Fragment {

private static long instanceCount;
private long mInstanceId;
private boolean mPaused;
private List<Pair<String, CWebViewPlugin>> mTransactions;

private String mBasicAuthUserName;
private String mBasicAuthPassword;
Expand Down Expand Up @@ -206,19 +210,26 @@ public boolean IsInitialized() {
public void Init(final String gameObject, final boolean transparent, final String ua) {
final CWebViewPlugin self = this;
final Activity a = UnityPlayer.currentActivity;
instanceCount++;
mInstanceId = instanceCount;
a.runOnUiThread(new Runnable() {public void run() {
if (mWebView != null) {
return;
}

setRetainInstance(true);
instanceCount++;
mInstanceId = instanceCount;
a
.getFragmentManager()
.beginTransaction()
.add(0, self, "CWebViewPlugin" + mInstanceId)
.commit();
if (mPaused) {
if (mTransactions == null) {
mTransactions = new ArrayList<Pair<String, CWebViewPlugin>>();
}
mTransactions.add(Pair.create("add", self));
} else {
a
.getFragmentManager()
.beginTransaction()
.add(0, self, "CWebViewPlugin" + mInstanceId)
.commit();
}

mAlertDialogEnabled = true;
mCustomHeaders = new Hashtable<String, String>();
Expand Down Expand Up @@ -618,11 +629,19 @@ public void Destroy() {
mWebView.destroy();
mWebView = null;

a
.getFragmentManager()
.beginTransaction()
.remove(self)
.commit();
if (mPaused) {
if (mTransactions == null) {
mTransactions = new ArrayList<Pair<String, CWebViewPlugin>>();
}
mTransactions.add(Pair.create("remove", self));
} else {
a
.getFragmentManager()
.beginTransaction()
.remove(self)
.commit();
}

}});
}

Expand Down Expand Up @@ -743,13 +762,38 @@ public void SetAlertDialogEnabled(final boolean enabled) {
}

// cf. https://stackoverflow.com/questions/31788748/webview-youtube-videos-playing-in-background-on-rotation-and-minimise/31789193#31789193
public void OnApplicationPause(final boolean paused) {
public void OnApplicationPause(boolean paused) {
mPaused = paused;
final Activity a = UnityPlayer.currentActivity;
a.runOnUiThread(new Runnable() {public void run() {
if (!mPaused) {
if (mTransactions != null) {
for (Pair<String, CWebViewPlugin> pair : mTransactions) {
CWebViewPlugin self = pair.second;
switch (pair.first) {
case "add":
a
.getFragmentManager()
.beginTransaction()
.add(0, self, "CWebViewPlugin" + mInstanceId)
.commit();
break;
case "remove":
a
.getFragmentManager()
.beginTransaction()
.remove(self)
.commit();
break;
}
}
mTransactions.clear();
}
}
if (mWebView == null) {
return;
}
if (paused) {
if (mPaused) {
mWebView.onPause();
if (mWebView.getVisibility() == View.VISIBLE) {
// cf. https://qiita.com/nbhd/items/d31711faa8852143f3a4
Expand Down
113 changes: 44 additions & 69 deletions plugins/Mac/Sources/WebView.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,16 @@
#import <AppKit/AppKit.h>
#import <WebKit/WebKit.h>
#import <Carbon/Carbon.h>
#import <OpenGL/gl.h>
#import <unistd.h>

static BOOL inEditor;
static BOOL useMetal;

@interface CWebViewPlugin : NSObject
{
WebView *webView;
NSString *gameObject;
NSBitmapImageRep *bitmap;
int textureId;
BOOL needsDisplay;
NSMutableDictionary *customRequestHeader;
NSMutableArray *messages;
Expand Down Expand Up @@ -364,10 +363,9 @@ - (void)update:(int)x y:(int)y deltaY:(float)deltaY buttonDown:(BOOL)buttonDown
if (bitmap == nil) {
bitmap = [webView bitmapImageRepForCachingDisplayInRect:webView.frame];
}
memset([bitmap bitmapData], 0, [bitmap bytesPerRow] * [bitmap pixelsHigh]);
[webView cacheDisplayInRect:webView.frame toBitmapImageRep:bitmap];
needsDisplay = true;
}
needsDisplay = refreshBitmap;
}
}

Expand All @@ -385,41 +383,46 @@ - (int)bitmapHigh
}
}

- (void)setTextureId:(int)tId
- (void)render:(void *)textureBuffer
{
@synchronized(self) {
textureId = tId;
}
}

- (void)render
{
@synchronized(self) {
if (webView == nil || !needsDisplay || bitmap == nil) {
if (webView == nil)
return;
if (!needsDisplay)
return;
if (bitmap == nil)
return;
int w = (int)[bitmap pixelsWide];
int h = (int)[bitmap pixelsHigh];
int p = (int)[bitmap samplesPerPixel];
int r = (int)[bitmap bytesPerRow];
uint8_t *s0 = (uint8_t *)[bitmap bitmapData];
uint32_t *d0 = (uint32_t *)textureBuffer;
if (p == 3) {
for (int y = 0; y < h; y++) {
uint8_t *s = s0 + y * r;
uint32_t *d = d0 + y * w;
for (int x = 0; x < w; x++) {
uint32_t r = *s++;
uint32_t g = *s++;
uint32_t b = *s++;
*d++ = (0xff << 24) | (b << 16) | (g << 8) | r;
}
}
} else if (p == 4) {
for (int y = 0; y < h; y++) {
uint8_t *s = s0 + y * r;
uint32_t *d = d0 + y * w;
for (int x = 0; x < w; x++) {
uint32_t r = *s++;
uint32_t g = *s++;
uint32_t b = *s++;
uint32_t a = *s++;
*d++ = (a << 24) | (b << 16) | (g << 8) | r;
}
}
}
int samplesPerPixel = (int)[bitmap samplesPerPixel];
int rowLength = 0;
int unpackAlign = 0;
glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowLength);
glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpackAlign);
glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)[bitmap bytesPerRow] / samplesPerPixel);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, textureId);
if (![bitmap isPlanar] && (samplesPerPixel == 3 || samplesPerPixel == 4)) {
glTexSubImage2D(
GL_TEXTURE_2D,
0,
0,
0,
(GLsizei)[bitmap pixelsWide],
(GLsizei)[bitmap pixelsHigh],
samplesPerPixel == 4 ? GL_RGBA : GL_RGB,
GL_UNSIGNED_BYTE,
[bitmap bitmapData]);
}
glPixelStorei(GL_UNPACK_ROW_LENGTH, rowLength);
glPixelStorei(GL_UNPACK_ALIGNMENT, unpackAlign);
needsDisplay = false;
}
}

Expand Down Expand Up @@ -461,13 +464,12 @@ - (const char *)getCustomRequestHeaderValue:(const char *)headerKey

@end

typedef void (*UnityRenderEventFunc)(int eventId);
#ifdef __cplusplus
extern "C" {
#endif
const char *_CWebViewPlugin_GetAppPath(void);
void *_CWebViewPlugin_Init(
const char *gameObject, BOOL transparent, int width, int height, const char *ua, BOOL ineditor);
const char *gameObject, BOOL transparent, int width, int height, const char *ua, BOOL ineditor, BOOL usemetal);
void _CWebViewPlugin_Destroy(void *instance);
void _CWebViewPlugin_SetRect(void *instance, int width, int height);
void _CWebViewPlugin_SetVisibility(void *instance, BOOL visibility);
Expand All @@ -485,10 +487,7 @@ void _CWebViewPlugin_Update(void *instance, int x, int y, float deltaY,
BOOL keyPress, unsigned char keyCode, const char *keyChars, BOOL refreshBitmap);
int _CWebViewPlugin_BitmapWidth(void *instance);
int _CWebViewPlugin_BitmapHeight(void *instance);
void _CWebViewPlugin_SetTextureId(void *instance, int textureId);
void _CWebViewPlugin_SetCurrentInstance(void *instance);
void UnityRenderEvent(int eventId);
UnityRenderEventFunc GetRenderEventFunc(void);
void _CWebViewPlugin_Render(void *instance, void *textureBuffer);
void _CWebViewPlugin_AddCustomHeader(void *instance, const char *headerKey, const char *headerValue);
void _CWebViewPlugin_RemoveCustomHeader(void *instance, const char *headerKey);
void _CWebViewPlugin_ClearCustomHeader(void *instance);
Expand All @@ -509,20 +508,20 @@ void _CWebViewPlugin_Update(void *instance, int x, int y, float deltaY,
static NSMutableSet *pool;

void *_CWebViewPlugin_Init(
const char *gameObject, BOOL transparent, int width, int height, const char *ua, BOOL ineditor)
const char *gameObject, BOOL transparent, int width, int height, const char *ua, BOOL ineditor, BOOL usemetal)
{
if (pool == 0) {
pool = [[NSMutableSet alloc] init];
}
inEditor = ineditor;
useMetal = usemetal;
CWebViewPlugin *webViewPlugin = [[CWebViewPlugin alloc] initWithGameObject:gameObject transparent:transparent width:width height:height ua:ua];
[pool addObject:webViewPlugin];
return (__bridge_retained void *)webViewPlugin;
}

void _CWebViewPlugin_Destroy(void *instance)
{
_CWebViewPlugin_SetCurrentInstance(NULL);
CWebViewPlugin *webViewPlugin = (__bridge_transfer CWebViewPlugin *)instance;
[pool removeObject:webViewPlugin];
[webViewPlugin dispose];
Expand Down Expand Up @@ -617,34 +616,10 @@ int _CWebViewPlugin_BitmapHeight(void *instance)
return [webViewPlugin bitmapHigh];
}

void _CWebViewPlugin_SetTextureId(void *instance, int textureId)
void _CWebViewPlugin_Render(void *instance, void *textureBuffer)
{
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
[webViewPlugin setTextureId:textureId];
}

static void *_instance;

void _CWebViewPlugin_SetCurrentInstance(void *instance)
{
_instance = instance;
}

void UnityRenderEvent(int eventId)
{
if (_instance == nil) {
return;
}
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)_instance;
_instance = nil;
if ([pool containsObject:webViewPlugin]) {
[webViewPlugin render];
}
}

UnityRenderEventFunc GetRenderEventFunc(void)
{
return UnityRenderEvent;
[webViewPlugin render:textureBuffer];
}

void _CWebViewPlugin_AddCustomHeader(void *instance, const char *headerKey, const char *headerValue)
Expand Down
Loading