Showing the changes to interface/src/scripting/ScreenshareScriptingInterface.cpp (1 of 2 files). Show all
Unified · Split
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | // ScreenshareScriptingInterface.cpp |
| 3 | 3 | // interface/src/scripting/ |
| 4 | 4 | // |
| 5 | −// Created by Milad Nazeri on 2019-10-23. | |
| 5 | +// Created by Milad Nazeri and Zach Fox on 2019-10-23. | |
| 6 | 6 | // Copyright 2019 High Fidelity, Inc. |
| 7 | 7 | // |
| 8 | 8 | // Distributed under the Apache License, Version 2.0. |
| @@ -14,12 +14,23 @@ · 5 unmodified lines | ||
| 14 | 14 | #include <QJsonDocument> |
| 15 | 15 | #include <QThread> |
| 16 | 16 | #include <QUrl> |
| 17 | +#include <QObject> | |
| 18 | +#include <QNetworkAccessManager> | |
| 19 | +#include <QNetworkReply> | |
| 20 | +#include <QNetworkRequest> | |
| 21 | +#include <QProcessEnvironment> | |
| 17 | 22 | |
| 18 | 23 | #include <AddressManager.h> |
| 24 | +#include <EntityTreeRenderer.h> | |
| 25 | +#include <EntityTree.h> | |
| 19 | 26 | |
| 20 | 27 | #include "EntityScriptingInterface.h" |
| 21 | 28 | #include "ScreenshareScriptingInterface.h" |
| 22 | 29 | |
| 30 | +#include <RenderableEntityItem.h> | |
| 31 | +#include <RenderableTextEntityItem.h> | |
| 32 | +#include <RenderableWebEntityItem.h> | |
| 33 | + | |
| 23 | 34 | ScreenshareScriptingInterface::ScreenshareScriptingInterface() { |
| 24 | 35 | }; |
| 25 | 36 | |
| @@ -29,8 +40,9 @@ ScreenshareScriptingInterface::~ScreenshareScriptingInterface() { · 3 unmodified lines | ||
| 29 | 40 | |
| 30 | 41 | static const EntityTypes::EntityType LOCAL_SCREENSHARE_WEB_ENTITY_TYPE = EntityTypes::Web; |
| 31 | 42 | static const uint8_t LOCAL_SCREENSHARE_WEB_ENTITY_FPS = 30; |
| 32 | −static const glm::vec3 LOCAL_SCREENSHARE_WEB_ENTITY_LOCAL_POSITION(0.0f, 0.0f, 0.1f); | |
| 43 | +static const glm::vec3 LOCAL_SCREENSHARE_WEB_ENTITY_LOCAL_POSITION(0.0f, -0.0862f, 0.0311f); | |
| 33 | 44 | static const QString LOCAL_SCREENSHARE_WEB_ENTITY_URL = "https://hifi-content.s3.amazonaws.com/Experiences/Releases/usefulUtilities/smartBoard/screenshareViewer/screenshareClient.html?1"; |
| 45 | +static const glm::vec3 LOCAL_SCREENSHARE_WEB_ENTITY_DIMENSIONS(4.0419f, 2.2735f, 0.0100f); | |
| 34 | 46 | void ScreenshareScriptingInterface::startScreenshare(const QUuid& screenshareZoneID, const QUuid& smartboardEntityID, const bool& isPresenter) { |
| 35 | 47 | if (QThread::currentThread() != thread()) { |
| 36 | 48 | // We must start a new QProcess from the main thread. |
| @@ -59,99 +71,120 @@ void ScreenshareScriptingInterface::startScreenshare(const QUuid& screenshareZon · 22 unmodified lines | ||
| 59 | 71 | } |
| 60 | 72 | |
| 61 | 73 | QUuid currentDomainID = DependencyManager::get<AddressManager>()->getDomainID(); |
| 62 | − | |
| 63 | − // Make HTTP GET request to: | |
| 64 | 74 | // `https://metaverse.highfidelity.com/api/v1/domain/:domain_id/screenshare`, |
| 65 | 75 | // passing the Domain ID that the user is connected to, as well as the `roomName`. |
| 66 | 76 | // The server will respond with the relevant OpenTok Token, Session ID, and API Key. |
| 67 | 77 | // Upon error-free response, do the logic below, passing in that info as necessary. |
| 68 | − QString token = ""; | |
| 69 | − QString apiKey = ""; | |
| 70 | − QString sessionID = ""; | |
| 71 | − | |
| 72 | − if (isPresenter) { | |
| 73 | − QStringList arguments; | |
| 74 | − arguments << "--token=" + token; | |
| 75 | − arguments << "--apiKey=" + apiKey; | |
| 76 | − arguments << "--sessionID=" + sessionID; | |
| 77 | − | |
| 78 | − connect(_screenshareProcess.get(), &QProcess::errorOccurred, | |
| 79 | − [=](QProcess::ProcessError error) { qDebug() << "ZRF QProcess::errorOccurred. `error`:" << error; }); | |
| 80 | − connect(_screenshareProcess.get(), &QProcess::started, [=]() { qDebug() << "ZRF QProcess::started"; }); | |
| 81 | − connect(_screenshareProcess.get(), &QProcess::stateChanged, | |
| 82 | − [=](QProcess::ProcessState newState) { qDebug() << "ZRF QProcess::stateChanged. `newState`:" << newState; }); | |
| 83 | − connect(_screenshareProcess.get(), QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), | |
| 84 | − [=](int exitCode, QProcess::ExitStatus exitStatus) { | |
| 85 | − qDebug() << "ZRF QProcess::finished. `exitCode`:" << exitCode << "`exitStatus`:" << exitStatus; | |
| 86 | − emit screenshareStopped(); | |
| 87 | − }); | |
| 88 | − | |
| 89 | − _screenshareProcess->start(SCREENSHARE_EXE_PATH, arguments); | |
| 90 | − } | |
| 91 | − | |
| 92 | − if (!_screenshareViewerLocalWebEntityUUID.isNull()) { | |
| 93 | − return; | |
| 94 | − } | |
| 95 | − | |
| 96 | − auto esi = DependencyManager::get<EntityScriptingInterface>(); | |
| 97 | − if (!esi) { | |
| 98 | − return; | |
| 99 | − } | |
| 100 | − | |
| 101 | − EntityItemProperties localScreenshareWebEntityProps; | |
| 102 | − localScreenshareWebEntityProps.setType(LOCAL_SCREENSHARE_WEB_ENTITY_TYPE); | |
| 103 | − localScreenshareWebEntityProps.setMaxFPS(LOCAL_SCREENSHARE_WEB_ENTITY_FPS); | |
| 104 | − localScreenshareWebEntityProps.setLocalPosition(LOCAL_SCREENSHARE_WEB_ENTITY_LOCAL_POSITION); | |
| 105 | − localScreenshareWebEntityProps.setSourceUrl(LOCAL_SCREENSHARE_WEB_ENTITY_URL); | |
| 106 | − localScreenshareWebEntityProps.setParentID(smartboardEntityID); | |
| 107 | − | |
| 108 | − EntityPropertyFlags desiredSmartboardProperties; | |
| 109 | − desiredSmartboardProperties += PROP_POSITION; | |
| 110 | − desiredSmartboardProperties += PROP_DIMENSIONS; | |
| 111 | − EntityItemProperties smartboardProps = esi->getEntityProperties(smartboardEntityID, desiredSmartboardProperties); | |
| 112 | − | |
| 113 | − localScreenshareWebEntityProps.setPosition(smartboardProps.getPosition()); | |
| 114 | − localScreenshareWebEntityProps.setDimensions(smartboardProps.getDimensions()); | |
| 115 | − | |
| 116 | − QString hostType = "local"; | |
| 117 | − _screenshareViewerLocalWebEntityUUID = esi->addEntity(localScreenshareWebEntityProps, hostType); | |
| 118 | − | |
| 119 | − QObject::connect(esi.data(), &EntityScriptingInterface::webEventReceived, this, [&](const QUuid& entityID, const QVariant& message) { | |
| 120 | − if (entityID == _screenshareViewerLocalWebEntityUUID) { | |
| 121 | − qDebug() << "ZRF HERE! Inside `webEventReceived(). `entityID`:" << entityID << "`_screenshareViewerLocalWebEntityUUID`:" << _screenshareViewerLocalWebEntityUUID; | |
| 122 | − | |
| 123 | − auto esi = DependencyManager::get<EntityScriptingInterface>(); | |
| 124 | − if (!esi) { | |
| 125 | − return; | |
| 126 | − } | |
| 127 | − | |
| 128 | − QJsonDocument jsonMessage = QJsonDocument::fromVariant(message); | |
| 129 | − QJsonObject jsonObject = jsonMessage.object(); | |
| 130 | − | |
| 131 | − qDebug() << "ZRF HERE! Inside `webEventReceived(). `message`:" << message << "`jsonMessage`:" << jsonMessage; | |
| 78 | + QNetworkAccessManager* manager = new QNetworkAccessManager(); | |
| 79 | + QObject::connect(manager, &QNetworkAccessManager::finished, this, [=](QNetworkReply *reply) { | |
| 80 | + if (reply->error()) { | |
| 81 | + qDebug() << "\n\n MN HERE: REPLY" << reply->errorString(); | |
| 82 | + return; | |
| 83 | + } | |
| 132 | 84 | |
| 133 | − if (jsonObject["app"] != "screenshare") { | |
| 134 | − return; | |
| 135 | − } | |
| 85 | + QString answer = reply->readAll(); | |
| 86 | + qDebug() << "\n\n MN HERE: REPLY" << answer; | |
| 136 | 87 | |
| 137 | − qDebug() << "ZRF HERE! Inside `webEventReceived(). we're still here!"; | |
| 88 | + | |
| 89 | + QString token = ""; | |
| 90 | + QString apiKey = ""; | |
| 91 | + QString sessionID = ""; | |
| 92 | + | |
| 93 | + if (isPresenter) { | |
| 94 | + QStringList arguments; | |
| 95 | + arguments << "--token=" + token; | |
| 96 | + arguments << "--apiKey=" + apiKey; | |
| 97 | + arguments << "--sessionID=" + sessionID; | |
| 98 | + | |
| 99 | + connect(_screenshareProcess.get(), &QProcess::errorOccurred, | |
| 100 | + [=](QProcess::ProcessError error) { qDebug() << "ZRF QProcess::errorOccurred. `error`:" << error; }); | |
| 101 | + connect(_screenshareProcess.get(), &QProcess::started, [=]() { qDebug() << "ZRF QProcess::started"; }); | |
| 102 | + connect(_screenshareProcess.get(), &QProcess::stateChanged, | |
| 103 | + [=](QProcess::ProcessState newState) { qDebug() << "ZRF QProcess::stateChanged. `newState`:" << newState; }); | |
| 104 | + connect(_screenshareProcess.get(), QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), | |
| 105 | + [=](int exitCode, QProcess::ExitStatus exitStatus) { | |
| 106 | + qDebug() << "ZRF QProcess::finished. `exitCode`:" << exitCode << "`exitStatus`:" << exitStatus; | |
| 107 | + emit screenshareStopped(); | |
| 108 | + }); | |
| 109 | + | |
| 110 | + _screenshareProcess->start(SCREENSHARE_EXE_PATH, arguments); | |
| 111 | + } | |
| 138 | 112 | |
| 139 | − if (jsonObject["method"] == "eventBridgeReady") { | |
| 140 | − QJsonObject responseObject; | |
| 141 | − responseObject.insert("app", "screenshare"); | |
| 142 | − responseObject.insert("method", "receiveConnectionInfo"); | |
| 143 | − QJsonObject responseObjectData; | |
| 144 | − responseObjectData.insert("token", token); | |
| 145 | − responseObjectData.insert("projectAPIKey", apiKey); | |
| 146 | − responseObjectData.insert("sessionID", sessionID); | |
| 147 | − responseObject.insert("data", responseObjectData); | |
| 113 | + if (!_screenshareViewerLocalWebEntityUUID.isNull()) { | |
| 114 | + return; | |
| 115 | + } | |
| 148 | 116 | |
| 149 | − qDebug() << "ZRF HERE! Inside `webEventReceived(). `responseObject.toVariantMap()`:" << responseObject.toVariantMap(); | |
| 117 | + auto esi = DependencyManager::get<EntityScriptingInterface>(); | |
| 118 | + if (!esi) { | |
| 119 | + return; | |
| 120 | + } | |
| 150 | 121 | |
| 151 | − esi->emitScriptEvent(_screenshareViewerLocalWebEntityUUID, responseObject.toVariantMap()); | |
| 122 | + EntityItemProperties localScreenshareWebEntityProps; | |
| 123 | + localScreenshareWebEntityProps.setType(LOCAL_SCREENSHARE_WEB_ENTITY_TYPE); | |
| 124 | + localScreenshareWebEntityProps.setMaxFPS(LOCAL_SCREENSHARE_WEB_ENTITY_FPS); | |
| 125 | + localScreenshareWebEntityProps.setLocalPosition(LOCAL_SCREENSHARE_WEB_ENTITY_LOCAL_POSITION); | |
| 126 | + localScreenshareWebEntityProps.setSourceUrl(LOCAL_SCREENSHARE_WEB_ENTITY_URL); | |
| 127 | + localScreenshareWebEntityProps.setParentID(smartboardEntityID); | |
| 128 | + localScreenshareWebEntityProps.setDimensions(LOCAL_SCREENSHARE_WEB_ENTITY_DIMENSIONS); | |
| 129 | + | |
| 130 | + // EntityPropertyFlags desiredSmartboardProperties; | |
| 131 | + // desiredSmartboardProperties += PROP_POSITION; | |
| 132 | + // desiredSmartboardProperties += PROP_DIMENSIONS; | |
| 133 | + // EntityItemProperties smartboardProps = esi->getEntityProperties(smartboardEntityID, desiredSmartboardProperties); | |
| 134 | + | |
| 135 | + QString hostType = "local"; | |
| 136 | + _screenshareViewerLocalWebEntityUUID = esi->addEntity(localScreenshareWebEntityProps, hostType); | |
| 137 | + | |
| 138 | + QObject::connect(esi.data(), &EntityScriptingInterface::webEventReceived, this, [&](const QUuid& entityID, const QVariant& message) { | |
| 139 | + if (entityID == _screenshareViewerLocalWebEntityUUID) { | |
| 140 | + qDebug() << "ZRF HERE! Inside `webEventReceived(). `entityID`:" << entityID << "`_screenshareViewerLocalWebEntityUUID`:" << _screenshareViewerLocalWebEntityUUID; | |
| 141 | + | |
| 142 | + auto esi = DependencyManager::get<EntityScriptingInterface>(); | |
| 143 | + if (!esi) { | |
| 144 | + return; | |
| 145 | + } | |
| 146 | + | |
| 147 | + QJsonDocument jsonMessage = QJsonDocument::fromVariant(message); | |
| 148 | + QJsonObject jsonObject = jsonMessage.object(); | |
| 149 | + | |
| 150 | + qDebug() << "ZRF HERE! Inside `webEventReceived(). `message`:" << message << "`jsonMessage`:" << jsonMessage; | |
| 151 | + | |
| 152 | + if (jsonObject["app"] != "screenshare") { | |
| 153 | + return; | |
| 154 | + } | |
| 155 | + | |
| 156 | + qDebug() << "ZRF HERE! Inside `webEventReceived(). we're still here!"; | |
| 157 | + | |
| 158 | + if (jsonObject["method"] == "eventBridgeReady") { | |
| 159 | + QJsonObject responseObject; | |
| 160 | + responseObject.insert("app", "screenshare"); | |
| 161 | + responseObject.insert("method", "receiveConnectionInfo"); | |
| 162 | + QJsonObject responseObjectData; | |
| 163 | + responseObjectData.insert("token", token); | |
| 164 | + responseObjectData.insert("projectAPIKey", apiKey); | |
| 165 | + responseObjectData.insert("sessionID", sessionID); | |
| 166 | + responseObject.insert("data", responseObjectData); | |
| 167 | + | |
| 168 | + qDebug() << "ZRF HERE! Inside `webEventReceived(). `responseObject.toVariantMap()`:" << responseObject.toVariantMap(); | |
| 169 | + | |
| 170 | + // Attempt 1, we receive the eventBridge message, but this won't send a message | |
| 171 | + // to that js | |
| 172 | + auto esi = DependencyManager::get<EntityScriptingInterface>(); | |
| 173 | + esi->emitScriptEvent(_screenshareViewerLocalWebEntityUUID, responseObject.toVariantMap()); | |
| 174 | + | |
| 175 | + // atempt 2, same outcome | |
| 176 | + auto entityTreeRenderer = DependencyManager::get<EntityTreeRenderer>(); | |
| 177 | + auto webEntityRenderable = entityTreeRenderer->renderableForEntityId(_screenshareViewerLocalWebEntityUUID); | |
| 178 | + webEntityRenderable->emitScriptEvent(responseObject.toVariantMap()); | |
| 179 | + } | |
| 152 | 180 | } |
| 153 | − } | |
| 181 | + }); | |
| 154 | 182 | }); |
| 183 | + | |
| 184 | + QNetworkRequest request; | |
| 185 | + QString tokboxURL = QProcessEnvironment::systemEnvironment().value("hifiScreenshareUrl"); | |
| 186 | + request.setUrl(QUrl(tokboxURL)); | |
| 187 | + manager->get(request); | |
| 155 | 188 | }; |
| 156 | 189 | |
| 157 | 190 | void ScreenshareScriptingInterface::stopScreenshare() { |