mirror of
https://github.com/lubosz/overte.git
synced 2025-04-07 14:22:06 +02:00
Support web3d overlays in android
This commit is contained in:
parent
4088035b3b
commit
fedc0a9e61
9 changed files with 185 additions and 32 deletions
|
@ -29,6 +29,7 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="io.highfidelity.hifiinterface.WebViewActivity"
|
||||
android:configChanges="orientation"
|
||||
android:theme="@android:style/Theme.Material.Light.NoActionBar"/>
|
||||
<!-- We don't want to show this on Daydream yet (we need to fix the turn-around problem on this screen)
|
||||
<activity android:name="io.highfidelity.hifiinterface.GvrLoaderActivity">
|
||||
|
|
|
@ -153,10 +153,29 @@ JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnCrea
|
|||
unpackAndroidAssets();
|
||||
qInstallMessageHandler(oldMessageHandler);
|
||||
|
||||
QObject::connect(&AndroidHelper::instance(), &AndroidHelper::androidActivityRequested, [](const QString& a, const bool backToScene) {
|
||||
JavaVM* jvm;
|
||||
env->GetJavaVM(&jvm);
|
||||
|
||||
QObject::connect(&AndroidHelper::instance(), &AndroidHelper::androidActivityRequested, [jvm](const QString& a, const bool backToScene, QList<QString> args) {
|
||||
JNIEnv* myNewEnv;
|
||||
JavaVMAttachArgs jvmArgs;
|
||||
jvmArgs.version = JNI_VERSION_1_6; // choose your JNI version
|
||||
jvmArgs.name = NULL; // you might want to give the java thread a name
|
||||
jvmArgs.group = NULL; // you might want to assign the java thread to a ThreadGroup
|
||||
jvm->AttachCurrentThread(reinterpret_cast<JNIEnv **>(&myNewEnv), &jvmArgs);
|
||||
|
||||
QAndroidJniObject string = QAndroidJniObject::fromString(a);
|
||||
jboolean jBackToScene = (jboolean) backToScene;
|
||||
__interfaceActivity.callMethod<void>("openAndroidActivity", "(Ljava/lang/String;Z)V", string.object<jstring>(), jBackToScene);
|
||||
jclass hashMapClass = myNewEnv->FindClass("java/util/HashMap");
|
||||
jmethodID mapClassConstructor = myNewEnv->GetMethodID(hashMapClass, "<init>", "()V");
|
||||
jobject hashmap = myNewEnv->NewObject(hashMapClass, mapClassConstructor);
|
||||
jmethodID mapClassPut = myNewEnv->GetMethodID(hashMapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
||||
for (const QString& arg: args) {
|
||||
QAndroidJniObject jArg = QAndroidJniObject::fromString(arg);
|
||||
myNewEnv->CallObjectMethod(hashmap, mapClassPut, QAndroidJniObject::fromString("url").object<jstring>(), jArg.object<jstring>());
|
||||
}
|
||||
__interfaceActivity.callMethod<void>("openAndroidActivity", "(Ljava/lang/String;ZLjava/util/HashMap;)V", string.object<jstring>(), jBackToScene, hashmap);
|
||||
jvm->DetachCurrentThread();
|
||||
});
|
||||
|
||||
QObject::connect(&AndroidHelper::instance(), &AndroidHelper::hapticFeedbackRequested, [](int duration) {
|
||||
|
@ -295,4 +314,10 @@ Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeEnterForeground(JNIEn
|
|||
AndroidHelper::instance().notifyEnterForeground();
|
||||
}
|
||||
|
||||
JNIEXPORT void Java_io_highfidelity_hifiinterface_WebViewActivity_nativeProcessURL(JNIEnv* env, jobject obj, jstring url_str) {
|
||||
const char *nativeString = env->GetStringUTFChars(url_str, 0);
|
||||
AndroidHelper::instance().processURL(QString::fromUtf8(nativeString));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -12,32 +12,31 @@
|
|||
package io.highfidelity.hifiinterface;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.AssetManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Point;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Vibrator;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.WindowManager;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import org.qtproject.qt5.android.QtLayout;
|
||||
import org.qtproject.qt5.android.QtSurface;
|
||||
import org.qtproject.qt5.android.bindings.QtActivity;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
|
||||
/*import com.google.vr.cardboard.DisplaySynchronizer;
|
||||
import com.google.vr.cardboard.DisplayUtils;
|
||||
import com.google.vr.ndk.base.GvrApi;*/
|
||||
import android.graphics.Point;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class InterfaceActivity extends QtActivity {
|
||||
|
||||
|
@ -244,6 +243,10 @@ public class InterfaceActivity extends QtActivity {
|
|||
}
|
||||
|
||||
public void openAndroidActivity(String activityName, boolean backToScene) {
|
||||
openAndroidActivity(activityName, backToScene, null);
|
||||
}
|
||||
|
||||
public void openAndroidActivity(String activityName, boolean backToScene, HashMap args) {
|
||||
switch (activityName) {
|
||||
case "Home":
|
||||
case "Privacy Policy":
|
||||
|
@ -254,6 +257,13 @@ public class InterfaceActivity extends QtActivity {
|
|||
startActivity(intent);
|
||||
break;
|
||||
}
|
||||
case "WebView":
|
||||
Intent intent = new Intent(this, WebViewActivity.class);
|
||||
if (args != null && args.containsKey(WebViewActivity.WEB_VIEW_ACTIVITY_EXTRA_URL)) {
|
||||
intent.putExtra(WebViewActivity.WEB_VIEW_ACTIVITY_EXTRA_URL, (String) args.get(WebViewActivity.WEB_VIEW_ACTIVITY_EXTRA_URL));
|
||||
}
|
||||
startActivity(intent);
|
||||
break;
|
||||
default: {
|
||||
Log.w(TAG, "Could not open activity by name " + activityName);
|
||||
break;
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
//package hifiinterface.highfidelity.io.mybrowserapplication;
|
||||
package io.highfidelity.hifiinterface;
|
||||
|
||||
import android.app.ActionBar;
|
||||
|
@ -36,9 +34,6 @@ import android.webkit.WebViewClient;
|
|||
import android.widget.ProgressBar;
|
||||
import android.widget.Toast;
|
||||
import android.widget.Toolbar;
|
||||
import android.os.Looper;
|
||||
import java.lang.Thread;
|
||||
import java.lang.Runnable;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
@ -73,14 +68,13 @@ public class WebViewActivity extends Activity {
|
|||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_web_view);
|
||||
|
||||
setActionBar((Toolbar) findViewById(R.id.toolbar_actionbar));
|
||||
setActionBar(findViewById(R.id.toolbar_actionbar));
|
||||
mActionBar = getActionBar();
|
||||
mActionBar.setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
mProgressBar = (ProgressBar) findViewById(R.id.toolbarProgressBar);
|
||||
|
||||
mProgressBar = findViewById(R.id.toolbarProgressBar);
|
||||
mUrl = getIntent().getStringExtra(WEB_VIEW_ACTIVITY_EXTRA_URL);
|
||||
myWebView = (WebView) findViewById(R.id.web_view);
|
||||
myWebView = findViewById(R.id.web_view);
|
||||
myWebView.setWebViewClient(new HiFiWebViewClient());
|
||||
myWebView.setWebChromeClient(new HiFiWebChromeClient());
|
||||
WebSettings webSettings = myWebView.getSettings();
|
||||
|
@ -203,11 +197,7 @@ public class WebViewActivity extends Activity {
|
|||
// managing avatar selections
|
||||
if (isFst(request)) {
|
||||
final String url = request.getUrl().toString();
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
nativeProcessURL(url);
|
||||
}
|
||||
}).start(); // Avoid deadlock in Qt dialog
|
||||
new Thread(() -> nativeProcessURL(url)).start(); // Avoid deadlock in Qt dialog
|
||||
WebViewActivity.this.finish();
|
||||
return true;
|
||||
}
|
||||
|
|
36
interface/resources/qml/+android/Web3DOverlay.qml
Normal file
36
interface/resources/qml/+android/Web3DOverlay.qml
Normal file
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// Web3DOverlay.qml
|
||||
//
|
||||
// Created by Gabriel Calero & Cristian Duarte on Jun 22, 2018
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import QtQuick 2.5
|
||||
|
||||
|
||||
Item {
|
||||
|
||||
property string url
|
||||
|
||||
Text {
|
||||
id: webContentText
|
||||
anchors.horizontalCenter : parent.horizontalCenter
|
||||
text: "Web content\nClick to view"
|
||||
font.family: "Helvetica"
|
||||
font.pointSize: 24
|
||||
color: "#0098CA"
|
||||
}
|
||||
|
||||
Text {
|
||||
id: urlText
|
||||
text: url
|
||||
anchors.horizontalCenter : parent.horizontalCenter
|
||||
anchors.top : webContentText.bottom
|
||||
font.family: "Helvetica"
|
||||
font.pointSize: 18
|
||||
color: "#0098CA"
|
||||
}
|
||||
}
|
|
@ -11,6 +11,12 @@
|
|||
#include "AndroidHelper.h"
|
||||
#include <QDebug>
|
||||
#include <AccountManager.h>
|
||||
#include "Application.h"
|
||||
|
||||
#if defined(qApp)
|
||||
#undef qApp
|
||||
#endif
|
||||
#define qApp (static_cast<Application*>(QCoreApplication::instance()))
|
||||
|
||||
AndroidHelper::AndroidHelper() {
|
||||
}
|
||||
|
@ -37,8 +43,8 @@ void AndroidHelper::init() {
|
|||
_accountManager->moveToThread(&workerThread);
|
||||
}
|
||||
|
||||
void AndroidHelper::requestActivity(const QString &activityName, const bool backToScene) {
|
||||
emit androidActivityRequested(activityName, backToScene);
|
||||
void AndroidHelper::requestActivity(const QString &activityName, const bool backToScene, QList<QString> args) {
|
||||
emit androidActivityRequested(activityName, backToScene, args);
|
||||
}
|
||||
|
||||
void AndroidHelper::notifyLoadComplete() {
|
||||
|
@ -60,3 +66,9 @@ void AndroidHelper::performHapticFeedback(int duration) {
|
|||
void AndroidHelper::showLoginDialog() {
|
||||
emit androidActivityRequested("Login", true);
|
||||
}
|
||||
|
||||
void AndroidHelper::processURL(const QString &url) {
|
||||
if (qApp->canAcceptURL(url)) {
|
||||
qApp->acceptURL(url);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,12 +24,13 @@ public:
|
|||
return instance;
|
||||
}
|
||||
void init();
|
||||
void requestActivity(const QString &activityName, const bool backToScene);
|
||||
void requestActivity(const QString &activityName, const bool backToScene, QList<QString> args = QList<QString>());
|
||||
void notifyLoadComplete();
|
||||
void notifyEnterForeground();
|
||||
void notifyEnterBackground();
|
||||
|
||||
void performHapticFeedback(int duration);
|
||||
void processURL(const QString &url);
|
||||
|
||||
QSharedPointer<AccountManager> getAccountManager() { return _accountManager; }
|
||||
AndroidHelper(AndroidHelper const&) = delete;
|
||||
|
@ -39,7 +40,7 @@ public slots:
|
|||
void showLoginDialog();
|
||||
|
||||
signals:
|
||||
void androidActivityRequested(const QString &activityName, const bool backToScene);
|
||||
void androidActivityRequested(const QString &activityName, const bool backToScene, QList<QString> args = QList<QString>());
|
||||
void qtAppLoadComplete();
|
||||
void enterForeground();
|
||||
void enterBackground();
|
||||
|
|
|
@ -137,8 +137,13 @@ void WindowScriptingInterface::openUrl(const QUrl& url) {
|
|||
if (url.scheme() == URL_SCHEME_HIFI) {
|
||||
DependencyManager::get<AddressManager>()->handleLookupString(url.toString());
|
||||
} else {
|
||||
#if defined(Q_OS_ANDROID)
|
||||
QList<QString> args = { url.toString() };
|
||||
AndroidHelper::instance().requestActivity("WebView", true, args);
|
||||
#else
|
||||
// address manager did not handle - ask QDesktopServices to handle
|
||||
QDesktopServices::openUrl(url);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
73
scripts/system/+android/clickOverlays.js
Normal file
73
scripts/system/+android/clickOverlays.js
Normal file
|
@ -0,0 +1,73 @@
|
|||
"use strict";
|
||||
//
|
||||
// clickOverlays.js
|
||||
// scripts/system/+android
|
||||
//
|
||||
// Created by Gabriel Calero & Cristian Duarte on Jun 22, 2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
(function() { // BEGIN LOCAL_SCOPE
|
||||
|
||||
var logEnabled = false;
|
||||
var touchOverlayID;
|
||||
|
||||
function printd(str) {
|
||||
if (logEnabled)
|
||||
print("[clickOverlays.js] " + str);
|
||||
}
|
||||
|
||||
function touchBegin(event) {
|
||||
var rayIntersection = Overlays.findRayIntersection(Camera.computePickRay(event.x, event.y));
|
||||
if (rayIntersection && rayIntersection.intersects && rayIntersection.overlayID &&
|
||||
Overlays.getOverlayType(rayIntersection.overlayID) == "web3d") {
|
||||
touchOverlayID = rayIntersection.overlayID;
|
||||
} else {
|
||||
touchOverlayID = null;
|
||||
}
|
||||
}
|
||||
|
||||
function touchEnd(event) {
|
||||
var rayIntersection = Overlays.findRayIntersection(Camera.computePickRay(event.x, event.y));
|
||||
if (rayIntersection && rayIntersection.intersects && rayIntersection.overlayID &&
|
||||
touchOverlayID == rayIntersection.overlayID) {
|
||||
var propertiesToGet = {};
|
||||
propertiesToGet[rayIntersection.overlayID] = ['url'];
|
||||
var properties = Overlays.getOverlaysProperties(propertiesToGet);
|
||||
if (properties[rayIntersection.overlayID].url) {
|
||||
Window.openUrl(properties[rayIntersection.overlayID].url);
|
||||
}
|
||||
var overlayObj = Overlays.getOverlayObject(rayIntersection.overlayID);
|
||||
Overlays.sendMousePressOnOverlay(rayIntersection.overlayID, {
|
||||
type: "press",
|
||||
id: 0,
|
||||
pos2D: event
|
||||
});
|
||||
}
|
||||
touchOverlayID = null;
|
||||
}
|
||||
|
||||
function ending() {
|
||||
Controller.touchBeginEvent.disconnect(touchBegin);
|
||||
Controller.touchEndEvent.disconnect(touchEnd);
|
||||
}
|
||||
|
||||
function init() {
|
||||
Controller.touchBeginEvent.connect(touchBegin);
|
||||
Controller.touchEndEvent.connect(touchEnd);
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
ending();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
init: init,
|
||||
ending: ending
|
||||
}
|
||||
|
||||
}()); // END LOCAL_SCOPE
|
Loading…
Reference in a new issue