From 6bc1164d58a79602452ead9b7e5e370ad4ced65a Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Wed, 9 Jan 2019 19:23:07 -0800 Subject: [PATCH] more wip on oculus login --- .../qml/LoginDialog/CompleteProfileBody.qml | 28 +++- .../qml/LoginDialog/LinkAccountBody.qml | 27 ++-- .../qml/LoginDialog/LoggingInBody.qml | 38 ++++-- .../resources/qml/LoginDialog/SignUpBody.qml | 3 +- .../qml/LoginDialog/UsernameCollisionBody.qml | 24 +++- interface/src/Application.cpp | 8 +- interface/src/ui/LoginDialog.cpp | 129 ++++++++++-------- interface/src/ui/LoginDialog.h | 4 + libraries/networking/src/AccountManager.cpp | 1 + .../src/plugins/OculusPlatformPlugin.h | 13 +- plugins/oculus/src/OculusPlatformPlugin.cpp | 31 ++++- plugins/oculus/src/OculusPlatformPlugin.h | 5 +- 12 files changed, 204 insertions(+), 107 deletions(-) diff --git a/interface/resources/qml/LoginDialog/CompleteProfileBody.qml b/interface/resources/qml/LoginDialog/CompleteProfileBody.qml index 6859b7ab3d..4213daea6d 100644 --- a/interface/resources/qml/LoginDialog/CompleteProfileBody.qml +++ b/interface/resources/qml/LoginDialog/CompleteProfileBody.qml @@ -26,7 +26,8 @@ Item { readonly property int fontSize: 15 readonly property bool fontBold: true - readonly property bool withSteam: withSteam + property bool withOculus: withOculus + property bool withSteam: withSteam property string errorString: errorString QtObject { @@ -143,7 +144,13 @@ Item { fontBold: completeProfileBody.fontBold onClicked: { loginErrorMessage.visible = false; - loginDialog.createAccountFromSteam(); + console.log("withOculus: " + completeProfileBody.withOculus); + if (completeProfileBody.withOculus) { + console.log("creating account through oculus"); + loginDialog.createAccountFromOculus(); + } else if (completeProfileBody.withSteam) { + loginDialog.createAccountFromSteam(); + } } } } @@ -180,7 +187,9 @@ Item { onLinkActivated: { loginDialog.isLogIn = true; - bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "errorString": "", "withSteam": true, "linkSteam": true }); + bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "errorString": "", + "withSteam": completeProfileBody.withSteam, "linkSteam": completeProfileBody.withSteam, "withOculus": completeProfileBody.withOculus, + "linkOculus": completeProfileBody.withOculus }); } Component.onCompleted: { if (additionalTextMetrics.width > root.bannerWidth && root.isTablet) { @@ -252,14 +261,19 @@ Item { target: loginDialog onHandleCreateCompleted: { console.log("Create Succeeded") - - loginDialog.loginThroughSteam(); - bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": true, "linkSteam": false }); + if (completeProfileBody.withOculus) { + loginDialog.loginThroughOculus(); + } else if (completeProfileBody.withSteam) { + loginDialog.loginThroughSteam(); + } + bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam, "linkSteam": false, + "withOculus": completeProfileBody.withOculus, "linkOculus": false }); } onHandleCreateFailed: { console.log("Create Failed: " + error); - bodyLoader.setSource("UsernameCollisionBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader }); + bodyLoader.setSource("UsernameCollisionBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam, + "withOculus": completeProfileBody.withOculus }); } } diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index f467bfe5d1..22a47da953 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -69,7 +69,8 @@ Item { function login() { loginDialog.login(emailField.text, passwordField.text); - bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": linkAccountBody.withSteam, "withOculus": linkAccountBody.withOculus, "linkSteam": linkAccountBody.linkSteam }); + bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": linkAccountBody.withSteam, + "withOculus": linkAccountBody.withOculus, "linkSteam": linkAccountBody.linkSteam, "linkOculus": linkAccountBody.linkOculus }); } function init() { @@ -77,12 +78,12 @@ Item { loginDialog.isLogIn = true; loginErrorMessage.text = linkAccountBody.errorString; loginErrorMessage.visible = (linkAccountBody.errorString !== ""); - loginButton.text = !linkAccountBody.linkSteam ? "Log In" : "Link Account"; + loginButton.text = (!linkAccountBody.linkSteam && !linkAccountBody.linkOculus) ? "Log In" : "Link Account"; loginButton.color = hifi.buttons.blue; emailField.placeholderText = "Username or Email"; var savedUsername = Settings.getValue("keepMeLoggedIn/savedUsername", ""); emailField.text = keepMeLoggedInCheckbox.checked ? savedUsername === "Unknown user" ? "" : savedUsername : ""; - if (linkAccountBody.linkSteam) { + if (linkAccountBody.linkSteam || linkAccountBody.linkOculus) { steamInfoText.anchors.top = passwordField.bottom; keepMeLoggedInCheckbox.anchors.top = steamInfoText.bottom; loginButton.width = (passwordField.width - hifi.dimensions.contentSpacing.x) / 2; @@ -289,13 +290,14 @@ Item { fontSize: linkAccountBody.fontSize fontBold: linkAccountBody.fontBold color: hifi.buttons.noneBorderlessWhite; - visible: linkAccountBody.linkSteam + visible: linkAccountBody.linkSteam || linkAccountBody.linkOculus anchors { top: keepMeLoggedInCheckbox.bottom topMargin: hifi.dimensions.contentSpacing.y } onClicked: { - bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": linkAccountBody.withSteam, "errorString": "" }); + bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": linkAccountBody.withSteam, + "withOculus": linkAccountBody.withOculus, "errorString": "" }); } } HifiControlsUit.Button { @@ -322,7 +324,7 @@ Item { Text { id: steamInfoText width: root.bannerWidth - visible: linkAccountBody.linkSteam + visible: linkAccountBody.linkSteam || linkAccountBody.linkOculus anchors { top: loginButton.bottom topMargin: hifi.dimensions.contentSpacing.y @@ -349,7 +351,7 @@ Item { HifiStylesUit.ShortcutText { id: cantAccessText z: 10 - visible: !linkAccountBody.linkSteam + visible: !linkAccountBody.linkSteam && !linkAccountBody.linkOculus anchors { top: loginButton.bottom topMargin: hifi.dimensions.contentSpacing.y @@ -404,10 +406,10 @@ Item { } bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, - "withSteam": linkAccountBody.withSteam, "withOculus": linkAccountBody.withOculus, "linkSteam": linkAccountBody.linkSteam }); + "withSteam": linkAccountBody.withSteam, "withOculus": linkAccountBody.withOculus, "linkSteam": linkAccountBody.linkSteam, "linkOculus": linkAccountBody.linkOculus }); } Component.onCompleted: { - if (linkAccountBody.linkSteam) { + if (linkAccountBody.linkSteam || linkAccountBody.linkOculus) { continueButton.visible = false; return; } @@ -470,7 +472,7 @@ Item { onLinkActivated: { Tablet.playSound(TabletEnums.ButtonClick); bodyLoader.setSource("SignUpBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, - "errorString": "", "linkSteam": linkAccountBody.linkSteam }); + "errorString": "" }); } } } @@ -494,7 +496,7 @@ Item { fontFamily: linkAccountBody.fontFamily fontSize: linkAccountBody.fontSize fontBold: linkAccountBody.fontBold - visible: loginDialog.getLoginDialogPoppedUp() && !linkAccountBody.linkSteam; + visible: loginDialog.getLoginDialogPoppedUp() && !linkAccountBody.linkSteam && !linkAccountBody.linkOculus; onClicked: { if (loginDialog.getLoginDialogPoppedUp()) { console.log("[ENCOURAGELOGINDIALOG]: user dismissed login screen") @@ -527,9 +529,6 @@ Item { }); } } - onLoginFailed: { - console.log("login failed"); - } } Component.onCompleted: { diff --git a/interface/resources/qml/LoginDialog/LoggingInBody.qml b/interface/resources/qml/LoginDialog/LoggingInBody.qml index 0cdee9856b..f89e6fae2b 100644 --- a/interface/resources/qml/LoginDialog/LoggingInBody.qml +++ b/interface/resources/qml/LoginDialog/LoggingInBody.qml @@ -79,6 +79,12 @@ Item { loggingInText.text = "Linking to Steam"; loggingInText.x = loggingInHeader.width/2 - loggingInTextMetrics.width/2 + loggingInGlyphTextMetrics.width/2; loginDialog.linkSteam(); + } else if (loggingInBody.linkOculus) { + loggingInGlyph.text = hifi.glyphs.oculus; + loggingInGlyph.visible = true; + loggingInText.text = "Linking to Oculus"; + loggingInText.x = loggingInHeader.width/2 - loggingInTextMetrics.width/2 + loggingInGlyphTextMetrics.width/2; + loginDialog.linkOculus(); } else if (loggingInBody.withSteam) { loggingInGlyph.visible = true; loggingInText.text = "Logging in to Steam"; @@ -100,6 +106,10 @@ Item { loggingInText.text = "Linking to Steam"; loginDialog.linkSteam(); return; + } else if (loggingInBody.linkOculus) { + loggingInText.text = "Linking to Oculus"; + loginDialog.linkOculus(); + return; } if (loggingInBody.withSteam) { // reset the flag. @@ -236,11 +246,13 @@ Item { onHandleLinkCompleted: { console.log("Link Succeeded"); loggingInBody.linkSteam = false; + loggingInBody.linkOculus = false; loggingInBody.loadingSuccess(); } onHandleLinkFailed: { console.log("Link Failed: " + error); - bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": true, "errorString": error }); + bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": loggingInBody.linkSteam, + "linkOculus": loggingInBody.linkOculus, "errorString": error }); } onHandleLoginCompleted: { @@ -251,24 +263,26 @@ Item { onHandleLoginFailed: { console.log("Login Failed") loggingInSpinner.visible = false; + loggingInGlyph.visible = false; var errorString = ""; - if (loggingInBody.withOculus) { - loggingInGlyph.visible = false; - errorString = "Your Oculus authentication has failed. Please make sure you are logged into Oculus and try again."; - bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": false, "errorString": errorString }); + if (loggingInBody.linkOculus && loggingInBody.withOculus) { + errorString = "Username or password is incorrect."; + bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam, + "withOculus": loggingInBody.withOculus, "linkSteam": loggingInBody.linkSteam, "errorString": errorString }); } else if (loggingInBody.linkSteam && loggingInBody.withSteam) { errorString = "Username or password is incorrect."; - bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam, "linkSteam": loggingInBody.linkSteam, "errorString": errorString }); + bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam, + "withOculus": loggingInBody.withOculus, "linkSteam": loggingInBody.linkSteam, "errorString": errorString }); } else if (loggingInBody.withSteam) { - loggingInGlyph.visible = false; errorString = "Your Steam authentication has failed. Please make sure you are logged into Steam and try again."; - bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam, "errorString": errorString }); + bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam, + "withOculus": loggingInBody.withOculus, "errorString": errorString }); } else if (loggingInBody.withOculus) { - loggingInGlyph.visible = false; errorString = "Your Oculus authentication has failed. Please make sure you are logged into Oculus and try again." - bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "errorString": errorString }); - } - else { + console.log("loggingInBody- withOculus: " + loggingInBody.withOculus); + bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam, + "withOculus": loggingInBody.withOculus, "errorString": errorString }); + } else { errorString = "Username or password is incorrect."; bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "errorString": errorString }); } diff --git a/interface/resources/qml/LoginDialog/SignUpBody.qml b/interface/resources/qml/LoginDialog/SignUpBody.qml index 5e0e955330..e151179f8f 100644 --- a/interface/resources/qml/LoginDialog/SignUpBody.qml +++ b/interface/resources/qml/LoginDialog/SignUpBody.qml @@ -37,7 +37,6 @@ Item { onKeyboardRaisedChanged: d.resize(); property string errorString: errorString - property bool linkSteam: linkSteam property bool lostFocus: false QtObject { @@ -345,7 +344,7 @@ Item { fontSize: signUpBody.fontSize fontBold: signUpBody.fontBold onClicked: { - bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": signUpBody.linkSteam }); + bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": false }); } } HifiControlsUit.Button { diff --git a/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml b/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml index d44f5b733c..edf568beac 100644 --- a/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml +++ b/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml @@ -26,6 +26,9 @@ Item { readonly property int textFieldFontSize: 18 readonly property bool fontBold: true + property bool withSteam: withSteam + property bool withOculus: withOculus + function create() { mainTextContainer.visible = false loginDialog.createAccountFromSteam(textField.text); @@ -86,12 +89,19 @@ Item { font.family: usernameCollisionBody.fontFamily font.pixelSize: usernameCollisionBody.fontSize font.bold: usernameCollisionBody.fontBold - text: qsTr("Your Steam username is not available."); + text: qsTr(""); wrapMode: Text.WordWrap color: hifi.colors.redAccent lineHeight: 1 lineHeightMode: Text.ProportionalHeight horizontalAlignment: Text.AlignHCenter + Component.onCompleted: { + if (usernameCollisionBody.withOculus) { + text = qsTr("Your Oculus username is not available."); + } else if (usernameCollisionBody.withSteam) { + text = qsTr("Your Steam username is not available."); + } + } } @@ -160,7 +170,8 @@ Item { fontSize: usernameCollisionBody.fontSize fontBold: usernameCollisionBody.fontBold onClicked: { - bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "errorString": "" }); + bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": usernameCollisionBody.withSteam, + "withOculus": usernameCollisionBody.withOculus, "errorString": "" }); } } HifiControlsUit.Button { @@ -197,8 +208,13 @@ Item { target: loginDialog onHandleCreateCompleted: { console.log("Create Succeeded"); - loginDialog.loginThroughSteam(); - bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": true, "linkSteam": false }) + if (usernameCollisionBody.withOculus) { + loginDialog.loginThroughOculus(); + } else if (usernameCollisionBody.withSteam) { + loginDialog.loginThroughSteam(); + } + bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": usernameCollisionBody.withSteam, + "withOculus": usernameCollisionBody.withOculus, "linkSteam": false, "linkOculus": false }) } onHandleCreateFailed: { console.log("Create Failed: " + error) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0b41254f97..167921f7b0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4733,6 +4733,10 @@ void Application::idle() { steamClient->runCallbacks(); } + if (auto oculusPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) { + oculusPlugin->handleOVREvents(); + } + float secondsSinceLastUpdate = (float)_lastTimeUpdated.nsecsElapsed() / NSECS_PER_MSEC / MSECS_PER_SECOND; _lastTimeUpdated.start(); @@ -5959,10 +5963,6 @@ void Application::update(float deltaTime) { } } - if (auto oculusPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) { - oculusPlugin->handleOVREvents(); - } - userInputMapper->setInputCalibrationData(calibrationData); userInputMapper->update(deltaTime); diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp index 0a8c276b90..bf57f421a9 100644 --- a/interface/src/ui/LoginDialog.cpp +++ b/interface/src/ui/LoginDialog.cpp @@ -46,6 +46,10 @@ LoginDialog::LoginDialog(QQuickItem *parent) : OffscreenQmlDialog(parent) { this, &LoginDialog::handleLoginFailed); connect(qApp, &Application::loginDialogFocusEnabled, this, &LoginDialog::focusEnabled); connect(qApp, &Application::loginDialogFocusDisabled, this, &LoginDialog::focusDisabled); + if (auto oculusPlatformPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) { + connect(oculusPlatformPlugin.get(), &OculusPlatformPlugin::loginReady, this, &LoginDialog::onLoginThroughOculusReady); + connect(oculusPlatformPlugin.get(), &OculusPlatformPlugin::linkAccountReady, this, &LoginDialog::onLinkOculusReady); + } connect(this, SIGNAL(dismissedLoginDialog()), qApp, SLOT(onDismissedLoginDialog())); #endif } @@ -124,74 +128,29 @@ 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](QString nonce, QString userID) { - // if (nonce.isEmpty() || userID.isEmpty()) { - // emit handleLoginFailed(); - // return; - // } - - // DependencyManager::get()->requestAccessTokenWithOculus(nonce, userID); - //}); + qDebug() << "Attempting to login through Oculus"; + if (auto oculusPlatformPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) { + oculusPlatformPlugin->requestNonceAndUserID(LoginState::LOGIN); + connect(oculusPlatformPlugin.get(), &OculusPlatformPlugin::loginReady, this, [&] (QString nonce, QString userID) { + onLoginThroughOculusReady(nonce, userID); + }); } } void LoginDialog::linkOculus() { qDebug() << "Attempting to link Oculus account"; - if (auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin()) { - //oculusPlatform->requestTicket([this](QString nonce, QString userID) { - // if (nonce.isEmpty() || userID.isEmpty()) { - // emit handleLoginFailed(); - // return; - // } - - // JSONCallbackParameters callbackParams; - // callbackParams.callbackReceiver = this; - // callbackParams.jsonCallbackMethod = "linkCompleted"; - // callbackParams.errorCallbackMethod = "linkFailed"; - // const QString LINK_OCULUS_PATH = "api/v1/user/oculus/link"; - - // QJsonObject payload; - // payload.insert("oculus_nonce", QJsonValue::fromVariant(QVariant(nonce))); - // payload.insert("oculus_user_id", QJsonValue::fromVariant(QVariant(userID))); - - // auto accountManager = DependencyManager::get(); - // accountManager->sendRequest(LINK_OCULUS_PATH, AccountManagerAuth::Required, - // QNetworkAccessManager::PostOperation, callbackParams, - // QJsonDocument(payload).toJson()); - //}); + if (auto oculusPlatformPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) { + oculusPlatformPlugin->requestNonceAndUserID(LoginState::LINK_ACCOUNT); } } void LoginDialog::createAccountFromOculus(QString username) { qDebug() << "Attempting to create account from Oculus info"; - if (auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin()) { - //oculusPlatform->requestTicket([this, username](QString nonce, QString userID) { - // if (nonce.isEmpty() || userID.isEmpty()) { - // emit handleLoginFailed(); - // return; - // } - - // JSONCallbackParameters callbackParams; - // callbackParams.callbackReceiver = this; - // callbackParams.jsonCallbackMethod = "createCompleted"; - // callbackParams.errorCallbackMethod = "createFailed"; - - // const QString CREATE_ACCOUNT_FROM_OCULUS_PATH = "api/v1/user/oculus/create"; - - // QJsonObject payload; - // payload.insert("oculus_nonce", QJsonValue::fromVariant(QVariant(nonce))); - // payload.insert("oculus_user_id", QJsonValue::fromVariant(QVariant(userID))); - // if (!username.isEmpty()) { - // payload.insert("username", QJsonValue::fromVariant(QVariant(username))); - // } - - // auto accountManager = DependencyManager::get(); - // accountManager->sendRequest(CREATE_ACCOUNT_FROM_OCULUS_PATH, AccountManagerAuth::None, - // QNetworkAccessManager::PostOperation, callbackParams, - // QJsonDocument(payload).toJson()); - //}); + if (auto oculusPlatformPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) { + oculusPlatformPlugin->requestNonceAndUserID(LoginState::CREATE_ACCOUNT); + connect(oculusPlatformPlugin.get(), &OculusPlatformPlugin::createAccountReady, this, [&] (QString nonce, QString userID) { + onCreateAccountThroughOculusReady(nonce, userID, username); + }); } } @@ -317,6 +276,60 @@ bool LoginDialog::getLoginDialogPoppedUp() const { return qApp->getLoginDialogPoppedUp(); } +void LoginDialog::onLoginThroughOculusReady(QString nonce, QString userID) { + DependencyManager::get()->requestAccessTokenWithOculus(nonce, userID); +} + +void LoginDialog::onLinkOculusReady(QString nonce, QString userID) { + if (nonce.isEmpty() || userID.isEmpty()) { + emit handleLoginFailed(); + return; + } + + JSONCallbackParameters callbackParams; + callbackParams.callbackReceiver = this; + callbackParams.jsonCallbackMethod = "linkCompleted"; + callbackParams.errorCallbackMethod = "linkFailed"; + const QString LINK_OCULUS_PATH = "api/v1/user/oculus/link"; + + QJsonObject payload; + payload.insert("oculus_nonce", QJsonValue::fromVariant(QVariant(nonce))); + payload.insert("oculus_user_id", QJsonValue::fromVariant(QVariant(userID))); + + auto accountManager = DependencyManager::get(); + accountManager->sendRequest(LINK_OCULUS_PATH, AccountManagerAuth::Required, + QNetworkAccessManager::PostOperation, callbackParams, + QJsonDocument(payload).toJson()); + +} + +void LoginDialog::onCreateAccountThroughOculusReady(QString nonce, QString userID, QString username) { + if (nonce.isEmpty() || userID.isEmpty()) { + emit handleLoginFailed(); + return; + } + + JSONCallbackParameters callbackParams; + callbackParams.callbackReceiver = this; + callbackParams.jsonCallbackMethod = "createCompleted"; + callbackParams.errorCallbackMethod = "createFailed"; + + const QString CREATE_ACCOUNT_FROM_OCULUS_PATH = "api/v1/user/oculus/create"; + + QJsonObject payload; + payload.insert("oculus_nonce", QJsonValue::fromVariant(QVariant(nonce))); + payload.insert("oculus_user_id", QJsonValue::fromVariant(QVariant(userID))); + if (!username.isEmpty()) { + payload.insert("username", QJsonValue::fromVariant(QVariant(username))); + } + + auto accountManager = DependencyManager::get(); + accountManager->sendRequest(CREATE_ACCOUNT_FROM_OCULUS_PATH, AccountManagerAuth::None, + QNetworkAccessManager::PostOperation, callbackParams, + QJsonDocument(payload).toJson()); + +} + QString errorStringFromAPIObject(const QJsonValue& apiObject) { if (apiObject.isArray()) { return apiObject.toArray()[0].toString(); diff --git a/interface/src/ui/LoginDialog.h b/interface/src/ui/LoginDialog.h index 981d7cdd27..5bdcf3fb8d 100644 --- a/interface/src/ui/LoginDialog.h +++ b/interface/src/ui/LoginDialog.h @@ -83,6 +83,10 @@ protected slots: Q_INVOKABLE bool getLoginDialogPoppedUp() const; + void onLoginThroughOculusReady(QString nonce, QString userID); + void onLinkOculusReady(QString nonce, QString userID); + void onCreateAccountThroughOculusReady(QString nonce, QString userID, QString username); + private: bool getIsLogIn() const { return _isLogIn; } void setIsLogIn(const bool isLogIn) { _isLogIn = isLogIn; } diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index 38d286d131..2c7018d23a 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -587,6 +587,7 @@ void AccountManager::requestAccessTokenWithSteam(QByteArray authSessionTicket) { } void AccountManager::requestAccessTokenWithOculus(const QString& nonce, const QString& userID) { + qDebug() << nonce << ", " << userID; QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkRequest request; diff --git a/libraries/plugins/src/plugins/OculusPlatformPlugin.h b/libraries/plugins/src/plugins/OculusPlatformPlugin.h index 1f2bf1cfbb..70097b12c1 100644 --- a/libraries/plugins/src/plugins/OculusPlatformPlugin.h +++ b/libraries/plugins/src/plugins/OculusPlatformPlugin.h @@ -12,6 +12,13 @@ #include +enum LoginState { + INVALID_STATE = 0, + LOGIN, + LINK_ACCOUNT, + CREATE_ACCOUNT +}; + class OculusPlatformPlugin : public QObject { Q_OBJECT public: @@ -20,8 +27,12 @@ public: virtual const QString getName() const = 0; + virtual void requestNonceAndUserID(LoginState state = LoginState::INVALID_STATE) = 0; + virtual void handleOVREvents() = 0; signals: - void nonceAndUserIDChanged(QString nonce, QString userID); + void loginReady(QString nonce, QString userID); + void linkAccountReady(QString nonce, QString userID); + void createAccountReady(QString nonce, QString userID); }; diff --git a/plugins/oculus/src/OculusPlatformPlugin.cpp b/plugins/oculus/src/OculusPlatformPlugin.cpp index 0d0d7c447c..ef8cfd660d 100644 --- a/plugins/oculus/src/OculusPlatformPlugin.cpp +++ b/plugins/oculus/src/OculusPlatformPlugin.cpp @@ -24,6 +24,12 @@ OculusAPIPlugin::~OculusAPIPlugin() { hifi::ovr::releaseRenderSession(_session); } +void OculusAPIPlugin::requestNonceAndUserID(LoginState loginState) { + _loginState = loginState; + ovr_User_GetUserProof(); + ovr_User_GetLoggedInUser(); +} + void OculusAPIPlugin::handleOVREvents() { #ifdef OCULUS_APP_ID if (qApp->property(hifi::properties::OCULUS_STORE).toBool()) { @@ -47,10 +53,13 @@ void OculusAPIPlugin::handleOVREvents() { if (!ovr_Message_IsError(message)) { qCDebug(oculusLog) << "Oculus Platform user retrieval succeeded"; ovrUserHandle user = ovr_Message_GetUser(message); - ovr_FreeMessage(message); _user = ovr_User_GetOculusID(user); + // went all the way through the `requestNonceAndUserID()` pipeline successfully. + _nonceChanged = true; } else { qCDebug(oculusLog) << "Oculus Platform user retrieval failed" << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); + // emit the signal so we don't hang for it anywhere else. + _nonceChanged = true; _user = ""; } break; @@ -58,28 +67,42 @@ void OculusAPIPlugin::handleOVREvents() { case ovrMessage_User_GetLoggedInUser: { if (!ovr_Message_IsError(message)) { ovrUserHandle user = ovr_Message_GetUser(message); - ovr_FreeMessage(message); _userID = ovr_User_GetID(user); + ovr_User_Get(_userID); } else { qCDebug(oculusLog) << "Oculus Platform user ID retrieval failed" << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); + // emit the signal so we don't hang for it anywhere else. + _nonceChanged = true; } break; } case ovrMessage_User_GetUserProof: { - _nonceChanged = true; if (!ovr_Message_IsError(message)) { ovrUserProofHandle userProof = ovr_Message_GetUserProof(message); _nonce = ovr_UserProof_GetNonce(userProof); } else { qCDebug(oculusLog) << "Oculus Platform nonce retrieval failed" << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); _nonce = ""; + // emit the signal so we don't hang for it anywhere else. + _nonceChanged = true; } break; } } if (_nonceChanged) { - emit nonceAndUserIDChanged(_nonce, _user); + switch (_loginState) { + case LoginState::LOGIN: + emit loginReady(_nonce, _user); + break; + case LoginState::LINK_ACCOUNT: + emit linkAccountReady(_nonce, _user); + break; + case LoginState::CREATE_ACCOUNT: + emit createAccountReady(_nonce, _user); + break; + } + _loginState = LoginState::INVALID_STATE; _nonce = _user = ""; _nonceChanged = false; } diff --git a/plugins/oculus/src/OculusPlatformPlugin.h b/plugins/oculus/src/OculusPlatformPlugin.h index a59c4f0b84..ce43b399a1 100644 --- a/plugins/oculus/src/OculusPlatformPlugin.h +++ b/plugins/oculus/src/OculusPlatformPlugin.h @@ -20,12 +20,15 @@ public: virtual ~OculusAPIPlugin(); const QString getName() const { return NAME; } + virtual void requestNonceAndUserID(LoginState loginState); + virtual void handleOVREvents(); private: static const char* NAME; + LoginState _loginState{ LoginState::INVALID_STATE }; QString _nonce; - bool _nonceChanged; + bool _nonceChanged{ false }; QString _user; ovrID _userID; ovrSession _session{ nullptr };