Showing the changes to interface/src/scripting/ScreenshareScriptingInterface.cpp (1 of 2 files). Show all
Unified · Split
| @@ -23,6 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | #include "EntityScriptingInterface.h" |
| 24 | 24 | #include "ScreenshareScriptingInterface.h" |
| 25 | 25 | |
| 26 | +static const int SCREENSHARE_INFO_REQUEST_RETRY_TIMEOUT_MS = 300; | |
| 26 | 27 | ScreenshareScriptingInterface::ScreenshareScriptingInterface() { |
| 27 | 28 | auto esi = DependencyManager::get<EntityScriptingInterface>(); |
| 28 | 29 | if (!esi) { |
| @@ -31,12 +32,60 @@ ScreenshareScriptingInterface::ScreenshareScriptingInterface() { · 2 unmodified lines | ||
| 31 | 32 | |
| 32 | 33 | // This signal/slot connection is used when the screen share local web entity sends an event bridge message. |
| 33 | 34 | QObject::connect(esi.data(), &EntityScriptingInterface::webEventReceived, this, &ScreenshareScriptingInterface::onWebEventReceived); |
| 35 | + | |
| 36 | + _requestScreenshareInfoRetryTimer = new QTimer; | |
| 37 | + _requestScreenshareInfoRetryTimer->setSingleShot(true); | |
| 38 | + _requestScreenshareInfoRetryTimer->setInterval(SCREENSHARE_INFO_REQUEST_RETRY_TIMEOUT_MS); | |
| 39 | + connect(_requestScreenshareInfoRetryTimer, &QTimer::timeout, this, &ScreenshareScriptingInterface::requestScreenshareInfo); | |
| 34 | 40 | }; |
| 35 | 41 | |
| 36 | 42 | ScreenshareScriptingInterface::~ScreenshareScriptingInterface() { |
| 37 | 43 | stopScreenshare(); |
| 38 | 44 | } |
| 39 | 45 | |
| 46 | +static const int MAX_NUM_SCREENSHARE_INFO_REQUEST_RETRIES = 5; | |
| 47 | +void ScreenshareScriptingInterface::requestScreenshareInfo() { | |
| 48 | + _requestScreenshareInfoRetries++; | |
| 49 | + | |
| 50 | + if (_requestScreenshareInfoRetries >= MAX_NUM_SCREENSHARE_INFO_REQUEST_RETRIES) { | |
| 51 | + qDebug() << "Maximum number of retries for screenshare info exceeded. Screenshare will not function."; | |
| 52 | + return; | |
| 53 | + } | |
| 54 | + | |
| 55 | + // Don't continue with any more of this logic if we can't get the `AccountManager` or `AddressManager`. | |
| 56 | + auto accountManager = DependencyManager::get<AccountManager>(); | |
| 57 | + if (!accountManager) { | |
| 58 | + return; | |
| 59 | + } | |
| 60 | + auto addressManager = DependencyManager::get<AddressManager>(); | |
| 61 | + if (!addressManager) { | |
| 62 | + return; | |
| 63 | + } | |
| 64 | + | |
| 65 | + // Construct and send a request to the Metaverse to obtain the information | |
| 66 | + // necessary to start the screen sharing process. | |
| 67 | + // This request requires: | |
| 68 | + // 1. The domain ID of the domain in which the user's avatar is present | |
| 69 | + // 2. User authentication information that is automatically included when `sendRequest()` is passed | |
| 70 | + // with the `AccountManagerAuth::Required` argument. | |
| 71 | + // Note that this request will only return successfully if the Domain Server has already registered | |
| 72 | + // the user paired with the current domain with the Metaverse. | |
| 73 | + // See `DomainServer::screensharePresence()` for more info about that. | |
| 74 | + | |
| 75 | + QString currentDomainID = uuidStringWithoutCurlyBraces(addressManager->getDomainID()); | |
| 76 | + QString requestURLPath = "api/v1/domains/%1/screenshare"; | |
| 77 | + JSONCallbackParameters callbackParams; | |
| 78 | + callbackParams.callbackReceiver = this; | |
| 79 | + callbackParams.jsonCallbackMethod = "handleSuccessfulScreenshareInfoGet"; | |
| 80 | + callbackParams.errorCallbackMethod = "handleFailedScreenshareInfoGet"; | |
| 81 | + accountManager->sendRequest( | |
| 82 | + requestURLPath.arg(currentDomainID), | |
| 83 | + AccountManagerAuth::Required, | |
| 84 | + QNetworkAccessManager::GetOperation, | |
| 85 | + callbackParams | |
| 86 | + ); | |
| 87 | +} | |
| 88 | + | |
| 40 | 89 | static const EntityTypes::EntityType LOCAL_SCREENSHARE_WEB_ENTITY_TYPE = EntityTypes::Web; |
| 41 | 90 | static const uint8_t LOCAL_SCREENSHARE_WEB_ENTITY_FPS = 30; |
| 42 | 91 | // This is going to be a good amount of work to make this work dynamically for any screensize. |
| @@ -45,7 +94,7 @@ static const glm::vec3 LOCAL_SCREENSHARE_WEB_ENTITY_LOCAL_POSITION(0.0f, -0.0862 · 2 unmodified lines | ||
| 45 | 94 | static const glm::vec3 LOCAL_SCREENSHARE_WEB_ENTITY_DIMENSIONS(4.0419f, 2.2735f, 0.0100f); |
| 46 | 95 | static const QString LOCAL_SCREENSHARE_WEB_ENTITY_URL = |
| 47 | 96 | "https://content.highfidelity.com/Experiences/Releases/usefulUtilities/smartBoard/screenshareViewer/screenshareClient.html"; |
| 48 | −static const QString LOCAL_SCREENSHARE_WEB_ENTITY_HOST_TYPE ="local"; | |
| 97 | +static const QString LOCAL_SCREENSHARE_WEB_ENTITY_HOST_TYPE = "local"; | |
| 49 | 98 | void ScreenshareScriptingInterface::startScreenshare(const QUuid& screenshareZoneID, |
| 50 | 99 | const QUuid& smartboardEntityID, |
| 51 | 100 | const bool& isPresenter) { |
| @@ -83,37 +132,12 @@ void ScreenshareScriptingInterface::startScreenshare(const QUuid& screenshareZon · 31 unmodified lines | ||
| 83 | 132 | } |
| 84 | 133 | } |
| 85 | 134 | |
| 86 | − // Don't continue with any more of this logic if we can't get the `AccountManager` or `AddressManager`. | |
| 87 | − auto accountManager = DependencyManager::get<AccountManager>(); | |
| 88 | − if (!accountManager) { | |
| 89 | − return; | |
| 90 | − } | |
| 91 | − auto addressManager = DependencyManager::get<AddressManager>(); | |
| 92 | − if (!addressManager) { | |
| 93 | − return; | |
| 135 | + if (_requestScreenshareInfoRetryTimer && _requestScreenshareInfoRetryTimer->isActive()) { | |
| 136 | + _requestScreenshareInfoRetryTimer->stop(); | |
| 94 | 137 | } |
| 95 | 138 | |
| 96 | − // Construct and send a request to the Metaverse to obtain the information | |
| 97 | − // necessary to start the screen sharing process. | |
| 98 | − // This request requires: | |
| 99 | − // 1. The domain ID of the domain in which the user's avatar is present | |
| 100 | − // 2. User authentication information that is automatically included when `sendRequest()` is passed | |
| 101 | − // with the `AccountManagerAuth::Required` argument. | |
| 102 | − // Note that this request will only return successfully if the Domain Server has already registered | |
| 103 | − // the user paired with the current domain with the Metaverse. | |
| 104 | − // See `DomainServer::screensharePresence()` for more info about that. | |
| 105 | − QString currentDomainID = uuidStringWithoutCurlyBraces(addressManager->getDomainID()); | |
| 106 | − QString requestURLPath = "api/v1/domains/%1/screenshare"; | |
| 107 | − JSONCallbackParameters callbackParams; | |
| 108 | − callbackParams.callbackReceiver = this; | |
| 109 | − callbackParams.jsonCallbackMethod = "handleSuccessfulScreenshareInfoGet"; | |
| 110 | − callbackParams.errorCallbackMethod = "handleFailedScreenshareInfoGet"; | |
| 111 | − accountManager->sendRequest( | |
| 112 | − requestURLPath.arg(currentDomainID), | |
| 113 | − AccountManagerAuth::Required, | |
| 114 | − QNetworkAccessManager::GetOperation, | |
| 115 | − callbackParams | |
| 116 | − ); | |
| 139 | + _requestScreenshareInfoRetries = 0; | |
| 140 | + requestScreenshareInfo(); | |
| 117 | 141 | } |
| 118 | 142 | |
| 119 | 143 | void ScreenshareScriptingInterface::stopScreenshare() { |
| @@ -123,6 +147,11 @@ void ScreenshareScriptingInterface::stopScreenshare() { · 3 unmodified lines | ||
| 123 | 147 | return; |
| 124 | 148 | } |
| 125 | 149 | |
| 150 | + // If the retry timer is active, stop it. | |
| 151 | + if (_requestScreenshareInfoRetryTimer && _requestScreenshareInfoRetryTimer->isActive()) { | |
| 152 | + _requestScreenshareInfoRetryTimer->stop(); | |
| 153 | + } | |
| 154 | + | |
| 126 | 155 | // If the Screen Share process is running... |
| 127 | 156 | if (_screenshareProcess && _screenshareProcess->state() != QProcess::NotRunning) { |
| 128 | 157 | //...terminate it and make sure that scripts know we terminated it by emitting |
| @@ -231,9 +260,14 @@ void ScreenshareScriptingInterface::handleSuccessfulScreenshareInfoGet(QNetworkR · 102 unmodified lines | ||
| 231 | 260 | } |
| 232 | 261 | |
| 233 | 262 | void ScreenshareScriptingInterface::handleFailedScreenshareInfoGet(QNetworkReply* reply) { |
| 234 | − qDebug() << "Failed to get screenshare info via HTTP. Error:" << reply->errorString(); | |
| 235 | − stopScreenshare(); | |
| 236 | − emit screenshareError(); | |
| 263 | + if (_requestScreenshareInfoRetries >= MAX_NUM_SCREENSHARE_INFO_REQUEST_RETRIES) { | |
| 264 | + qDebug() << "Failed to get screenshare info via HTTP after" << MAX_NUM_SCREENSHARE_INFO_REQUEST_RETRIES << "retries. Error:" << reply->errorString(); | |
| 265 | + stopScreenshare(); | |
| 266 | + emit screenshareError(); | |
| 267 | + return; | |
| 268 | + } | |
| 269 | + | |
| 270 | + _requestScreenshareInfoRetryTimer->start(); | |
| 237 | 271 | } |
| 238 | 272 | |
| 239 | 273 | // This function will handle _all_ web events received via `EntityScriptingInterface::webEventReceived()`, including |