From 1af57bdba63f8d5ba9353dd3198d15dc86f4e14d Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Thu, 3 Jan 2019 14:58:38 -0800 Subject: [PATCH] staging --- interface/src/ui/LoginDialog.cpp | 38 +++++++-- interface/src/ui/LoginDialog.h | 5 +- libraries/networking/src/AccountManager.cpp | 23 ++++++ libraries/networking/src/AccountManager.h | 1 + .../src/plugins/OculusPlatformPlugin.h | 2 + .../oculusPlatform/src/OculusAPIPlugin.cpp | 79 +++++++++++++++---- plugins/oculusPlatform/src/OculusAPIPlugin.h | 1 + 7 files changed, 123 insertions(+), 26 deletions(-) diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp index 834c381593..c241ee28e9 100644 --- a/interface/src/ui/LoginDialog.cpp +++ b/interface/src/ui/LoginDialog.cpp @@ -110,13 +110,6 @@ bool LoginDialog::isOculusRunning() const { return oculusPlatform && oculusPlatform->isRunning(); } -QString LoginDialog::getLoggedInUserID() const { - auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin(); - auto userID = oculusPlatform->getLoggedInUserID(); - qDebug() << "userID: " << userID; - return userID; -} - void LoginDialog::dismissLoginDialog() { QAction* loginAction = Menu::getInstance()->getActionForOption(MenuOption::Login); Q_CHECK_PTR(loginAction); @@ -132,7 +125,38 @@ void LoginDialog::login(const QString& username, const QString& password) const void LoginDialog::loginThroughOculus() { qDebug() << "Attempting to login through Oculus"; + if (auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin()) { + oculusPlatform->requestTicket([this](Ticket ticket) { + if (ticket.isNull()) { + emit handleLoginFailed(); + return; + } + }); + } +} +void LoginDialog::linkOculus() { + qDebug() << "Attempting to link Oculus account"; + if (auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin()) { + oculusPlatform->requestTicket([this](Ticket ticket) { + if (ticket.isNull()) { + emit handleLoginFailed(); + return; + } + }); + } +} + +void LoginDialog::createAccountFromOculus(QString username) { + qDebug() << "Attempting to create account from Oculus info"; + if (auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin()) { + oculusPlatform->requestTicket([this](Ticket ticket) { + if (ticket.isNull()) { + emit handleLoginFailed(); + return; + } + }); + } } void LoginDialog::loginThroughSteam() { diff --git a/interface/src/ui/LoginDialog.h b/interface/src/ui/LoginDialog.h index ca17d40b13..981d7cdd27 100644 --- a/interface/src/ui/LoginDialog.h +++ b/interface/src/ui/LoginDialog.h @@ -68,15 +68,14 @@ protected slots: Q_INVOKABLE bool isSteamRunning() const; Q_INVOKABLE bool isOculusRunning() const; - Q_INVOKABLE QString getLoggedInUserID() const; Q_INVOKABLE void login(const QString& username, const QString& password) const; Q_INVOKABLE void loginThroughSteam(); Q_INVOKABLE void linkSteam(); Q_INVOKABLE void createAccountFromSteam(QString username = QString()); Q_INVOKABLE void loginThroughOculus(); - //Q_INVOKABLE void linkOculus(); - //Q_INVOKABLE void createAccountFromOculus(QString username = QString()); + Q_INVOKABLE void linkOculus(); + Q_INVOKABLE void createAccountFromOculus(QString username = QString()); Q_INVOKABLE void signup(const QString& email, const QString& username, const QString& password); diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index 5721ac9334..2570b18b48 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -586,6 +586,29 @@ void AccountManager::requestAccessTokenWithSteam(QByteArray authSessionTicket) { connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestAccessTokenError(QNetworkReply::NetworkError))); } +void AccountManager::requestAccessTokenWithOculus(QByteArray authSessionTicket) { + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + + QNetworkRequest request; + request.setHeader(QNetworkRequest::UserAgentHeader, _userAgentGetter()); + + QUrl grantURL = _authURL; + grantURL.setPath("/oauth/token"); + + QByteArray postData; + postData.append("grant_type=password&"); + postData.append("oculus_nonce=" + QUrl::toPercentEncoding(authSessionTicket) + "&"); + postData.append("oculus_user_id=" + QUrl::toPercentEncoding(authSessionTicket) + "&"); + postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE); + + request.setUrl(grantURL); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + + QNetworkReply* requestReply = networkAccessManager.post(request, postData); + connect(requestReply, &QNetworkReply::finished, this, &AccountManager::requestAccessTokenFinished); + connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestAccessTokenError(QNetworkReply::NetworkError))); +} + void AccountManager::refreshAccessToken() { // we can't refresh our access token if we don't have a refresh token, so check for that first diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index d5406707e7..7fdf3a36b2 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -104,6 +104,7 @@ public: public slots: void requestAccessToken(const QString& login, const QString& password); void requestAccessTokenWithSteam(QByteArray authSessionTicket); + void requestAccessTokenWithOculus(QByteArray authSessionTicket); void requestAccessTokenWithAuthCode(const QString& authCode, const QString& clientId, const QString& clientSecret, const QString& redirectUri); void refreshAccessToken(); diff --git a/libraries/plugins/src/plugins/OculusPlatformPlugin.h b/libraries/plugins/src/plugins/OculusPlatformPlugin.h index fc28b983df..ed797292bb 100644 --- a/libraries/plugins/src/plugins/OculusPlatformPlugin.h +++ b/libraries/plugins/src/plugins/OculusPlatformPlugin.h @@ -29,6 +29,8 @@ public: virtual void requestTicket(TicketRequestCallback callback) = 0; + virtual QString getUserProof() = 0; + virtual QString getLoggedInUserID() = 0; virtual QString getOculusVRBuildID() = 0; diff --git a/plugins/oculusPlatform/src/OculusAPIPlugin.cpp b/plugins/oculusPlatform/src/OculusAPIPlugin.cpp index 4646b595fd..8c1a63ab56 100644 --- a/plugins/oculusPlatform/src/OculusAPIPlugin.cpp +++ b/plugins/oculusPlatform/src/OculusAPIPlugin.cpp @@ -21,10 +21,16 @@ #include "OculusHelpers.h" static const Ticket INVALID_TICKET = Ticket(); -//static std::atomic_bool initialized { false }; static std::atomic_bool initialized { false }; static ovrSession session { nullptr }; +class OculusCallbackManager { +public: + OculusCallbackManager(); +}; + +static OculusCallbackManager oculusCallbackManager; + bool OculusAPIPlugin::init() { if (session) { return initialized; @@ -39,7 +45,6 @@ bool OculusAPIPlugin::init() { } #ifdef OCULUS_APP_ID - if (qApp->property(hifi::properties::OCULUS_STORE).toBool()) { auto result = ovr_PlatformInitializeWindows(OCULUS_APP_ID); if (result != ovrPlatformInitialize_Success && result != ovrPlatformInitialize_PreLoaded) { @@ -57,16 +62,6 @@ bool OculusAPIPlugin::init() { } #endif - //ovrGraphicsLuid luid; - //if (!OVR_SUCCESS(ovr_Create(&session, &luid))) { - // qCWarning(oculusLog) << "Failed to acquire Oculus session" << hifi::ovr::getError(); - // return initialized; - //} else { - // ovrResult setFloorLevelOrigin = ovr_SetTrackingOriginType(session, ovrTrackingOrigin::ovrTrackingOrigin_FloorLevel); - // if (!OVR_SUCCESS(setFloorLevelOrigin)) { - // qCWarning(oculusLog) << "Failed to set the Oculus tracking origin to floor level" << hifi::ovr::getError(); - // } - //} initialized = true; return initialized; } @@ -78,22 +73,74 @@ void OculusAPIPlugin::runCallbacks() { } void OculusAPIPlugin::requestTicket(TicketRequestCallback callback) { + if (!initialized) { + if (!ovr_IsPlatformInitialized()) { + init(); + } + else { + qWarning() << "Oculus is not running"; + callback(INVALID_TICKET); + return; + } + } + + if (!initialized) { + qDebug() << "Oculus not initialized"; + return; + } + + auto userProof = requestUserProof(); + if (userProof == "") { + qWarning() << "User proof unavailable."; + callback(INVALID_TICKET); + return; + } else { + oculusCallbackManager; + } } bool OculusAPIPlugin::isRunning() { return initialized; } +QString OculusAPIPlugin::requestUserProof() { + if (initialized) { + QTimer timer; + timer.start(1000); + auto request = ovr_User_GetUserProof(); + ovrMessageHandle message { nullptr }; + while (message = ovr_PopMessage()) { + if (message == nullptr) { + break; + } else if (!timer.isActive()) { + qCDebug(oculusLog) << "login user id timeout after 1 second"; + return ""; + } else if (ovr_Message_GetType(message) == ovrMessage_User_GetUserProof) { + if (!ovr_Message_IsError(message)) { + ovrUserProofHandle userProof = ovr_Message_GetUserProof(message); + QString nonce = ovr_UserProof_GetNonce(userProof); + qCDebug(oculusLog) << "User nonce: " << nonce; + return nonce; + } else { + qDebug() << "Error getting user proof: " << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); + return ""; + } + } + } + return ""; + } +} + QString OculusAPIPlugin::getLoggedInUserID() { if (initialized) { QTimer timer; timer.start(1000); auto request = ovr_User_GetLoggedInUser(); ovrMessageHandle message { nullptr }; - using namespace std::chrono_literals; - std::this_thread::sleep_for(100ms); - while ((message = ovr_PopMessage()) != nullptr) { - if (!timer.isActive()) { + while (message = ovr_PopMessage()) { + if (message == nullptr) { + break; + } else if (!timer.isActive()) { qCDebug(oculusLog) << "login user id timeout after 1 second"; return ""; } else if (ovr_Message_GetType(message) == ovrMessage_User_GetLoggedInUser) { diff --git a/plugins/oculusPlatform/src/OculusAPIPlugin.h b/plugins/oculusPlatform/src/OculusAPIPlugin.h index 90acf65fc6..7c8bb9617e 100644 --- a/plugins/oculusPlatform/src/OculusAPIPlugin.h +++ b/plugins/oculusPlatform/src/OculusAPIPlugin.h @@ -20,6 +20,7 @@ public: void requestTicket(TicketRequestCallback callback) override; + QString requestUserProof() override; QString getLoggedInUserID() override; QString getOculusVRBuildID() override;