Showing the changes to interface/src/scripting/ScreenshareScriptingInterface.cpp (1 of 2 files). Show all
Unified · Split
| @@ -21,9 +21,11 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <QNetworkRequest> |
| 22 | 22 | #include <QProcessEnvironment> |
| 23 | 23 | |
| 24 | +#include <AccountManager.h> | |
| 24 | 25 | #include <AddressManager.h> |
| 25 | 26 | #include <EntityTreeRenderer.h> |
| 26 | 27 | #include <EntityTree.h> |
| 28 | +#include <UUID.h> | |
| 27 | 29 | |
| 28 | 30 | #include "EntityScriptingInterface.h" |
| 29 | 31 | #include "ScreenshareScriptingInterface.h" |
| @@ -63,11 +65,15 @@ void ScreenshareScriptingInterface::startScreenshare(const QUuid& screenshareZon · 33 unmodified lines | ||
| 63 | 65 | return; |
| 64 | 66 | } |
| 65 | 67 | |
| 66 | − if (isPresenter && _screenshareProcess && _screenshareProcess->state() != QProcess::NotRunning) { | |
| 68 | + _screenshareZoneID = screenshareZoneID; | |
| 69 | + _smartboardEntityID = smartboardEntityID; | |
| 70 | + _isPresenter = isPresenter; | |
| 71 | + | |
| 72 | + if (_isPresenter && _screenshareProcess && _screenshareProcess->state() != QProcess::NotRunning) { | |
| 67 | 73 | return; |
| 68 | 74 | } |
| 69 | 75 | |
| 70 | − if (isPresenter) { | |
| 76 | + if (_isPresenter) { | |
| 71 | 77 | _screenshareProcess.reset(new QProcess(this)); |
| 72 | 78 | |
| 73 | 79 | QFileInfo screenshareExecutable(SCREENSHARE_EXE_PATH); |
| @@ -77,81 +83,31 @@ void ScreenshareScriptingInterface::startScreenshare(const QUuid& screenshareZon · 3 unmodified lines | ||
| 77 | 83 | } |
| 78 | 84 | } |
| 79 | 85 | |
| 80 | − QUuid currentDomainID = DependencyManager::get<AddressManager>()->getDomainID(); | |
| 81 | − // `https://metaverse.highfidelity.com/api/v1/domain/:domain_id/screenshare`, | |
| 82 | − // passing the Domain ID that the user is connected to, as well as the `roomName`. | |
| 83 | − // The server will respond with the relevant OpenTok , Session ID, and API Key. | |
| 84 | − // Upon error-free response, do the logic below, passing in that info as necessary. | |
| 85 | − QNetworkAccessManager* manager = new QNetworkAccessManager(); | |
| 86 | − QObject::connect(manager, &QNetworkAccessManager::finished, this, [=](QNetworkReply* reply) { | |
| 87 | − if (reply->error()) { | |
| 88 | − qDebug() << "\n\n MN HERE: REPLY" << reply->errorString(); | |
| 89 | − return; | |
| 90 | − } | |
| 91 | − | |
| 92 | − QString answer = reply->readAll(); | |
| 93 | − qDebug() << "\n\n MN HERE: REPLY" << answer; | |
| 94 | − | |
| 95 | − QByteArray answerByteArray = answer.toUtf8(); | |
| 96 | − QJsonDocument answerJSONObject = QJsonDocument::fromJson(answerByteArray); | |
| 97 | − | |
| 98 | − _token = answerJSONObject["token"].toString(); | |
| 99 | − _projectAPIKey = answerJSONObject["projectAPIKey"].toString(); | |
| 100 | − _sessionID = answerJSONObject["sessionID"].toString(); | |
| 101 | − qDebug() << "token:" << _token << " projectAPIKey:" << _projectAPIKey << " sessionID: " << _sessionID; | |
| 102 | − | |
| 103 | − if (isPresenter) { | |
| 104 | − QStringList arguments; | |
| 105 | − arguments << " "; | |
| 106 | − arguments << "--token=" + _token << " "; | |
| 107 | − arguments << "--projectAPIKey=" + _projectAPIKey << " "; | |
| 108 | − arguments << "--sessionID=" + _sessionID << " "; | |
| 109 | − | |
| 110 | − connect(_screenshareProcess.get(), &QProcess::errorOccurred, | |
| 111 | − [=](QProcess::ProcessError error) { qDebug() << "ZRF QProcess::errorOccurred. `error`:" << error; }); | |
| 112 | − connect(_screenshareProcess.get(), &QProcess::started, [=]() { qDebug() << "ZRF QProcess::started"; }); | |
| 113 | − connect(_screenshareProcess.get(), &QProcess::stateChanged, [=](QProcess::ProcessState newState) { | |
| 114 | − qDebug() << "ZRF QProcess::stateChanged. `newState`:" << newState; | |
| 115 | − }); | |
| 116 | − connect(_screenshareProcess.get(), QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), | |
| 117 | − [=](int exitCode, QProcess::ExitStatus exitStatus) { | |
| 118 | − qDebug() << "ZRF QProcess::finished. `exitCode`:" << exitCode << "`exitStatus`:" << exitStatus; | |
| 119 | − emit screenshareStopped(); | |
| 120 | − }); | |
| 121 | − | |
| 122 | − _screenshareProcess->start(SCREENSHARE_EXE_PATH, arguments); | |
| 123 | − } | |
| 124 | − | |
| 125 | − if (!_screenshareViewerLocalWebEntityUUID.isNull()) { | |
| 126 | − return; | |
| 127 | − } | |
| 128 | − | |
| 129 | − auto esi = DependencyManager::get<EntityScriptingInterface>(); | |
| 130 | − if (!esi) { | |
| 131 | − return; | |
| 132 | − } | |
| 86 | + auto accountManager = DependencyManager::get<AccountManager>(); | |
| 87 | + if (!accountManager) { | |
| 88 | + return; | |
| 89 | + } | |
| 90 | + auto addressManager = DependencyManager::get<AddressManager>(); | |
| 91 | + if (!addressManager) { | |
| 92 | + return; | |
| 93 | + } | |
| 133 | 94 | |
| 134 | − EntityItemProperties localScreenshareWebEntityProps; | |
| 135 | − localScreenshareWebEntityProps.setType(LOCAL_SCREENSHARE_WEB_ENTITY_TYPE); | |
| 136 | − localScreenshareWebEntityProps.setMaxFPS(LOCAL_SCREENSHARE_WEB_ENTITY_FPS); | |
| 137 | − localScreenshareWebEntityProps.setLocalPosition(LOCAL_SCREENSHARE_WEB_ENTITY_LOCAL_POSITION); | |
| 138 | − localScreenshareWebEntityProps.setSourceUrl(LOCAL_SCREENSHARE_WEB_ENTITY_URL); | |
| 139 | − localScreenshareWebEntityProps.setParentID(smartboardEntityID); | |
| 140 | − localScreenshareWebEntityProps.setDimensions(LOCAL_SCREENSHARE_WEB_ENTITY_DIMENSIONS); | |
| 141 | − | |
| 142 | − // EntityPropertyFlags desiredSmartboardProperties; | |
| 143 | − // desiredSmartboardProperties += PROP_POSITION; | |
| 144 | − // desiredSmartboardProperties += PROP_DIMENSIONS; | |
| 145 | − // EntityItemProperties smartboardProps = esi->getEntityProperties(smartboardEntityID, desiredSmartboardProperties); | |
| 146 | − | |
| 147 | − QString hostType = "local"; | |
| 148 | − _screenshareViewerLocalWebEntityUUID = esi->addEntity(localScreenshareWebEntityProps, hostType); | |
| 149 | − | |
| 150 | − QNetworkRequest request; | |
| 151 | − QString tokboxURL = QProcessEnvironment::systemEnvironment().value("hifiScreenshareUrl"); | |
| 152 | − request.setUrl(QUrl(tokboxURL)); | |
| 153 | − manager->get(request); | |
| 154 | −}; | |
| 95 | + QString currentDomainID = uuidStringWithoutCurlyBraces(addressManager->getDomainID()); | |
| 96 | + QString requestURLPath = "api/v1/domains"; | |
| 97 | + requestURLPath = requestURLPath.append(currentDomainID); | |
| 98 | + requestURLPath = requestURLPath.append("/screenshare"); | |
| 99 | + | |
| 100 | + JSONCallbackParameters callbackParams; | |
| 101 | + callbackParams.callbackReceiver = this; | |
| 102 | + callbackParams.jsonCallbackMethod = "handleSuccessfulScreenshareInfoGet"; | |
| 103 | + callbackParams.errorCallbackMethod = "handleFailedScreenshareInfoGet"; | |
| 104 | + accountManager->sendRequest( | |
| 105 | + requestURLPath, | |
| 106 | + AccountManagerAuth::Required, | |
| 107 | + QNetworkAccessManager::PutOperation, | |
| 108 | + callbackParams | |
| 109 | + ); | |
| 110 | +} | |
| 155 | 111 | |
| 156 | 112 | void ScreenshareScriptingInterface::stopScreenshare() { |
| 157 | 113 | if (QThread::currentThread() != thread()) { |
| @@ -173,35 +129,106 @@ void ScreenshareScriptingInterface::stopScreenshare() { · 15 unmodified lines | ||
| 173 | 129 | _token = ""; |
| 174 | 130 | _projectAPIKey = ""; |
| 175 | 131 | _sessionID = ""; |
| 132 | + _isPresenter = false; | |
| 133 | +} | |
| 134 | + | |
| 135 | +void ScreenshareScriptingInterface::handleSuccessfulScreenshareInfoGet(QNetworkReply* reply) { | |
| 136 | + QString answer = reply->readAll(); | |
| 137 | + qDebug() << "\n\n MN HERE: REPLY" << answer; | |
| 138 | + | |
| 139 | + QByteArray answerByteArray = answer.toUtf8(); | |
| 140 | + QJsonDocument answerJSONObject = QJsonDocument::fromJson(answerByteArray); | |
| 141 | + | |
| 142 | + QString status = answerJSONObject["status"].toString(); | |
| 143 | + if (status == "fail") { | |
| 144 | + qDebug() << "\n\n MN HERE: SCREENSHARE REPLY FAIL"; | |
| 145 | + return; | |
| 146 | + } | |
| 147 | + | |
| 148 | + _token = answerJSONObject["token"].toString(); | |
| 149 | + _projectAPIKey = answerJSONObject["projectAPIKey"].toString(); | |
| 150 | + _sessionID = answerJSONObject["sessionID"].toString(); | |
| 151 | + qDebug() << "token:" << _token << " projectAPIKey:" << _projectAPIKey << " sessionID: " << _sessionID; | |
| 152 | + | |
| 153 | + if (_isPresenter) { | |
| 154 | + QStringList arguments; | |
| 155 | + arguments << " "; | |
| 156 | + arguments << "--token=" + _token << " "; | |
| 157 | + arguments << "--projectAPIKey=" + _projectAPIKey << " "; | |
| 158 | + arguments << "--sessionID=" + _sessionID << " "; | |
| 159 | + | |
| 160 | + connect(_screenshareProcess.get(), &QProcess::errorOccurred, | |
| 161 | + [=](QProcess::ProcessError error) { qDebug() << "ZRF QProcess::errorOccurred. `error`:" << error; }); | |
| 162 | + connect(_screenshareProcess.get(), &QProcess::started, [=]() { qDebug() << "ZRF QProcess::started"; }); | |
| 163 | + connect(_screenshareProcess.get(), &QProcess::stateChanged, [=](QProcess::ProcessState newState) { | |
| 164 | + qDebug() << "ZRF QProcess::stateChanged. `newState`:" << newState; | |
| 165 | + }); | |
| 166 | + connect(_screenshareProcess.get(), QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), | |
| 167 | + [=](int exitCode, QProcess::ExitStatus exitStatus) { | |
| 168 | + qDebug() << "ZRF QProcess::finished. `exitCode`:" << exitCode << "`exitStatus`:" << exitStatus; | |
| 169 | + emit screenshareStopped(); | |
| 170 | + }); | |
| 171 | + | |
| 172 | + _screenshareProcess->start(SCREENSHARE_EXE_PATH, arguments); | |
| 173 | + } | |
| 174 | + | |
| 175 | + if (!_screenshareViewerLocalWebEntityUUID.isNull()) { | |
| 176 | + return; | |
| 177 | + } | |
| 178 | + | |
| 179 | + auto esi = DependencyManager::get<EntityScriptingInterface>(); | |
| 180 | + if (!esi) { | |
| 181 | + return; | |
| 182 | + } | |
| 183 | + | |
| 184 | + EntityItemProperties localScreenshareWebEntityProps; | |
| 185 | + localScreenshareWebEntityProps.setType(LOCAL_SCREENSHARE_WEB_ENTITY_TYPE); | |
| 186 | + localScreenshareWebEntityProps.setMaxFPS(LOCAL_SCREENSHARE_WEB_ENTITY_FPS); | |
| 187 | + localScreenshareWebEntityProps.setLocalPosition(LOCAL_SCREENSHARE_WEB_ENTITY_LOCAL_POSITION); | |
| 188 | + localScreenshareWebEntityProps.setSourceUrl(LOCAL_SCREENSHARE_WEB_ENTITY_URL); | |
| 189 | + localScreenshareWebEntityProps.setParentID(_smartboardEntityID); | |
| 190 | + localScreenshareWebEntityProps.setDimensions(LOCAL_SCREENSHARE_WEB_ENTITY_DIMENSIONS); | |
| 191 | + | |
| 192 | + // The lines below will be used when writing the feature to ensure that the smartboard can be of any arbitrary size. | |
| 193 | + //EntityPropertyFlags desiredSmartboardProperties; | |
| 194 | + //desiredSmartboardProperties += PROP_POSITION; | |
| 195 | + //desiredSmartboardProperties += PROP_DIMENSIONS; | |
| 196 | + //EntityItemProperties smartboardProps = esi->getEntityProperties(smartboardEntityID, desiredSmartboardProperties); | |
| 197 | + | |
| 198 | + QString hostType = "local"; | |
| 199 | + _screenshareViewerLocalWebEntityUUID = esi->addEntity(localScreenshareWebEntityProps, hostType); | |
| 200 | +} | |
| 201 | + | |
| 202 | +void ScreenshareScriptingInterface::handleFailedScreenshareInfoGet(QNetworkReply* reply) { | |
| 203 | + qDebug() << "\n\n MN HERE: handleFailedScreenshareInfoGet():" << reply->errorString(); | |
| 176 | 204 | } |
| 177 | 205 | |
| 178 | 206 | void ScreenshareScriptingInterface::onWebEventReceived(const QUuid& entityID, const QVariant& message) { |
| 179 | 207 | if (entityID == _screenshareViewerLocalWebEntityUUID) { |
| 208 | + auto esi = DependencyManager::get<EntityScriptingInterface>(); | |
| 209 | + if (!esi) { | |
| 210 | + return; | |
| 211 | + } | |
| 212 | + | |
| 213 | + QByteArray jsonByteArray = QVariant(message).toString().toUtf8(); | |
| 214 | + QJsonDocument jsonObject = QJsonDocument::fromJson(jsonByteArray); | |
| 215 | + | |
| 216 | + if (jsonObject["app"] != "screenshare") { | |
| 217 | + return; | |
| 218 | + } | |
| 219 | + | |
| 220 | + if (jsonObject["method"] == "eventBridgeReady") { | |
| 221 | + QJsonObject responseObject; | |
| 222 | + responseObject.insert("app", "screenshare"); | |
| 223 | + responseObject.insert("method", "receiveConnectionInfo"); | |
| 224 | + QJsonObject responseObjectData; | |
| 225 | + responseObjectData.insert("token", _token); | |
| 226 | + responseObjectData.insert("projectAPIKey", _projectAPIKey); | |
| 227 | + responseObjectData.insert("sessionID", _sessionID); | |
| 228 | + responseObject.insert("data", responseObjectData); | |
| 229 | + | |
| 180 | 230 | auto esi = DependencyManager::get<EntityScriptingInterface>(); |
| 181 | − if (!esi) { | |
| 182 | − return; | |
| 183 | − } | |
| 184 | − | |
| 185 | − QByteArray jsonByteArray = QVariant(message).toString().toUtf8(); | |
| 186 | − QJsonDocument jsonObject = QJsonDocument::fromJson(jsonByteArray); | |
| 187 | − | |
| 188 | − if (jsonObject["app"] != "screenshare") { | |
| 189 | − return; | |
| 190 | − } | |
| 191 | − | |
| 192 | − if (jsonObject["method"] == "eventBridgeReady") { | |
| 193 | − QJsonObject responseObject; | |
| 194 | − responseObject.insert("app", "screenshare"); | |
| 195 | − responseObject.insert("method", "receiveConnectionInfo"); | |
| 196 | − QJsonObject responseObjectData; | |
| 197 | − responseObjectData.insert("token", _token); | |
| 198 | − responseObjectData.insert("projectAPIKey", _projectAPIKey); | |
| 199 | − responseObjectData.insert("sessionID", _sessionID); | |
| 200 | − responseObject.insert("data", responseObjectData); | |
| 201 | − | |
| 202 | − auto esi = DependencyManager::get<EntityScriptingInterface>(); | |
| 203 | − esi->emitScriptEvent(_screenshareViewerLocalWebEntityUUID, responseObject.toVariantMap()); | |
| 204 | − } | |
| 231 | + esi->emitScriptEvent(_screenshareViewerLocalWebEntityUUID, responseObject.toVariantMap()); | |
| 205 | 232 | } |
| 206 | 233 | } |
| 207 | 234 | } |