History

Fix DEV-2789: Implement retry timer when retrieving screen share info

Zach Fox committed 6 years ago

Commit 73590d21 parent f112ca42 files · +71 −33Browse files

Showing the changes to interface/src/scripting/ScreenshareScriptingInterface.cpp (1 of 2 files). Show all

Unified · Split

interface/src/scripting/ScreenshareScriptingInterface.cpp+67−33
@@ -23,6 +23,7 @@ · 22 unmodified lines
23#include "EntityScriptingInterface.h"23#include "EntityScriptingInterface.h"
24#include "ScreenshareScriptingInterface.h"24#include "ScreenshareScriptingInterface.h"
25 25
26static const int SCREENSHARE_INFO_REQUEST_RETRY_TIMEOUT_MS = 300;
26ScreenshareScriptingInterface::ScreenshareScriptingInterface() {27ScreenshareScriptingInterface::ScreenshareScriptingInterface() {
27 auto esi = DependencyManager::get<EntityScriptingInterface>();28 auto esi = DependencyManager::get<EntityScriptingInterface>();
28 if (!esi) {29 if (!esi) {
@@ -31,12 +32,60 @@ ScreenshareScriptingInterface::ScreenshareScriptingInterface() { · 2 unmodified lines
31 32
32 // This signal/slot connection is used when the screen share local web entity sends an event bridge message. 33 // This signal/slot connection is used when the screen share local web entity sends an event bridge message.
33 QObject::connect(esi.data(), &EntityScriptingInterface::webEventReceived, this, &ScreenshareScriptingInterface::onWebEventReceived);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
36ScreenshareScriptingInterface::~ScreenshareScriptingInterface() {42ScreenshareScriptingInterface::~ScreenshareScriptingInterface() {
37 stopScreenshare();43 stopScreenshare();
38}44}
39 45
46static const int MAX_NUM_SCREENSHARE_INFO_REQUEST_RETRIES = 5;
47void 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
40static const EntityTypes::EntityType LOCAL_SCREENSHARE_WEB_ENTITY_TYPE = EntityTypes::Web;89static const EntityTypes::EntityType LOCAL_SCREENSHARE_WEB_ENTITY_TYPE = EntityTypes::Web;
41static const uint8_t LOCAL_SCREENSHARE_WEB_ENTITY_FPS = 30;90static const uint8_t LOCAL_SCREENSHARE_WEB_ENTITY_FPS = 30;
42// This is going to be a good amount of work to make this work dynamically for any screensize.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
45static const glm::vec3 LOCAL_SCREENSHARE_WEB_ENTITY_DIMENSIONS(4.0419f, 2.2735f, 0.0100f);94static const glm::vec3 LOCAL_SCREENSHARE_WEB_ENTITY_DIMENSIONS(4.0419f, 2.2735f, 0.0100f);
46static const QString LOCAL_SCREENSHARE_WEB_ENTITY_URL =95static const QString LOCAL_SCREENSHARE_WEB_ENTITY_URL =
47 "https://content.highfidelity.com/Experiences/Releases/usefulUtilities/smartBoard/screenshareViewer/screenshareClient.html";96 "https://content.highfidelity.com/Experiences/Releases/usefulUtilities/smartBoard/screenshareViewer/screenshareClient.html";
48static const QString LOCAL_SCREENSHARE_WEB_ENTITY_HOST_TYPE ="local";97static const QString LOCAL_SCREENSHARE_WEB_ENTITY_HOST_TYPE = "local";
49void ScreenshareScriptingInterface::startScreenshare(const QUuid& screenshareZoneID,98void ScreenshareScriptingInterface::startScreenshare(const QUuid& screenshareZoneID,
50 const QUuid& smartboardEntityID,99 const QUuid& smartboardEntityID,
51 const bool& isPresenter) {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`.135 if (_requestScreenshareInfoRetryTimer && _requestScreenshareInfoRetryTimer->isActive()) {
87 auto accountManager = DependencyManager::get<AccountManager>();136 _requestScreenshareInfoRetryTimer->stop();
88 if (!accountManager) {
89 return;
90 }
91 auto addressManager = DependencyManager::get<AddressManager>();
92 if (!addressManager) {
93 return;
94 }137 }
95 138
96 // Construct and send a request to the Metaverse to obtain the information139 _requestScreenshareInfoRetries = 0;
97 // necessary to start the screen sharing process.140 requestScreenshareInfo();
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 );
117}141}
118 142
119void ScreenshareScriptingInterface::stopScreenshare() {143void ScreenshareScriptingInterface::stopScreenshare() {
@@ -123,6 +147,11 @@ void ScreenshareScriptingInterface::stopScreenshare() { · 3 unmodified lines
123 return;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 // If the Screen Share process is running...155 // If the Screen Share process is running...
127 if (_screenshareProcess && _screenshareProcess->state() != QProcess::NotRunning) {156 if (_screenshareProcess && _screenshareProcess->state() != QProcess::NotRunning) {
128 //...terminate it and make sure that scripts know we terminated it by emitting157 //...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
233void ScreenshareScriptingInterface::handleFailedScreenshareInfoGet(QNetworkReply* reply) {262void ScreenshareScriptingInterface::handleFailedScreenshareInfoGet(QNetworkReply* reply) {
234 qDebug() << "Failed to get screenshare info via HTTP. Error:" << reply->errorString();263 if (_requestScreenshareInfoRetries >= MAX_NUM_SCREENSHARE_INFO_REQUEST_RETRIES) {
235 stopScreenshare();264 qDebug() << "Failed to get screenshare info via HTTP after" << MAX_NUM_SCREENSHARE_INFO_REQUEST_RETRIES << "retries. Error:" << reply->errorString();
236 emit screenshareError();265 stopScreenshare();
266 emit screenshareError();
267 return;
268 }
269
270 _requestScreenshareInfoRetryTimer->start();
237}271}
238 272
239// This function will handle _all_ web events received via `EntityScriptingInterface::webEventReceived()`, including273// This function will handle _all_ web events received via `EntityScriptingInterface::webEventReceived()`, including