oculus functions live in the display plugin; display plugins update

This commit is contained in:
Wayne Chen 2019-01-07 16:39:55 -08:00
parent 970798705c
commit a24ebe2718
17 changed files with 218 additions and 124 deletions

View file

@ -120,7 +120,6 @@
#include <plugins/PluginManager.h>
#include <plugins/PluginUtils.h>
#include <plugins/SteamClientPlugin.h>
#include <plugins/OculusPlatformPlugin.h>
#include <plugins/InputConfiguration.h>
#include <RecordingScriptingInterface.h>
#include <render/EngineStats.h>
@ -999,7 +998,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
{
auto steamClient = PluginManager::getInstance()->getSteamClientPlugin();
auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin();
setProperty(hifi::properties::STEAM, (steamClient && steamClient->isRunning()));
setProperty(hifi::properties::CRASHED, _previousSessionCrashed);
@ -1131,9 +1129,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
bool isStore = arguments().indexOf(OCULUS_STORE_ARG) != -1;
setProperty(hifi::properties::OCULUS_STORE, isStore);
DependencyManager::get<WalletScriptingInterface>()->setLimitedCommerce(isStore); // Or we could make it a separate arg, or if either arg is set, etc. And should this instead by a hifi::properties?
if (auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin()) {
oculusPlatform->init();
}
updateHeartbeat();
@ -2656,9 +2651,6 @@ Application::~Application() {
if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
steamClient->shutdown();
}
if (auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin()) {
oculusPlatform->shutdown();
}
DependencyManager::destroy<PluginManager>();
@ -5966,6 +5958,10 @@ void Application::update(float deltaTime) {
}
}
if (auto oculusPlugin = PluginManager::getInstance()->getOculusDisplayPlugin()) {
oculusPlugin->pluginUpdate();
}
userInputMapper->setInputCalibrationData(calibrationData);
userInputMapper->update(deltaTime);

View file

@ -18,7 +18,6 @@
#include <plugins/PluginManager.h>
#include <plugins/SteamClientPlugin.h>
#include <plugins/OculusPlatformPlugin.h>
#include <shared/GlobalAppProperties.h>
#include <ui/TabletScriptingInterface.h>
#include <UserActivityLogger.h>
@ -106,8 +105,8 @@ bool LoginDialog::isSteamRunning() const {
}
bool LoginDialog::isOculusRunning() const {
auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin();
return oculusPlatform && oculusPlatform->isRunning();
auto oculusDisplay = PluginManager::getInstance()->getOculusDisplayPlugin();
return (oculusDisplay != nullptr);
}
void LoginDialog::dismissLoginDialog() {
@ -125,73 +124,73 @@ 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;
}
if (auto oculusDisplay = PluginManager::getInstance()->getOculusDisplayPlugin()) {
//oculusDisplay->requestTicket([this](QString nonce, QString userID) {
// if (nonce.isEmpty() || userID.isEmpty()) {
// emit handleLoginFailed();
// return;
// }
DependencyManager::get<AccountManager>()->requestAccessTokenWithOculus(nonce, userID);
});
// DependencyManager::get<AccountManager>()->requestAccessTokenWithOculus(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;
}
if (auto oculusDisplay = PluginManager::getInstance()->getOculusDisplayPlugin()) {
//oculusDisplay->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";
// 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)));
// QJsonObject payload;
// payload.insert("oculus_nonce", QJsonValue::fromVariant(QVariant(nonce)));
// payload.insert("oculus_user_id", QJsonValue::fromVariant(QVariant(userID)));
auto accountManager = DependencyManager::get<AccountManager>();
accountManager->sendRequest(LINK_OCULUS_PATH, AccountManagerAuth::Required,
QNetworkAccessManager::PostOperation, callbackParams,
QJsonDocument(payload).toJson());
});
// auto accountManager = DependencyManager::get<AccountManager>();
// accountManager->sendRequest(LINK_OCULUS_PATH, AccountManagerAuth::Required,
// QNetworkAccessManager::PostOperation, callbackParams,
// QJsonDocument(payload).toJson());
//});
}
}
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;
}
if (auto oculusDisplay = PluginManager::getInstance()->getOculusDisplayPlugin()) {
//oculusDisplay->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";
// JSONCallbackParameters callbackParams;
// callbackParams.callbackReceiver = this;
// callbackParams.jsonCallbackMethod = "createCompleted";
// callbackParams.errorCallbackMethod = "createFailed";
const QString CREATE_ACCOUNT_FROM_OCULUS_PATH = "api/v1/user/oculus/create";
// 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)));
}
// 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>();
accountManager->sendRequest(CREATE_ACCOUNT_FROM_OCULUS_PATH, AccountManagerAuth::None,
QNetworkAccessManager::PostOperation, callbackParams,
QJsonDocument(payload).toJson());
});
// auto accountManager = DependencyManager::get<AccountManager>();
// accountManager->sendRequest(CREATE_ACCOUNT_FROM_OCULUS_PATH, AccountManagerAuth::None,
// QNetworkAccessManager::PostOperation, callbackParams,
// QJsonDocument(payload).toJson());
//});
}
}

View file

@ -31,6 +31,8 @@ public:
virtual void compositeExtra() override;
virtual void pluginUpdate() override {};
protected:
mutable bool _isThrottled = false;

View file

@ -20,6 +20,7 @@ public:
QImage getScreenshot(float aspectRatio = 0.0f) const override;
QImage getSecondaryCameraScreenshot() const override;
void copyTextureToQuickFramebuffer(NetworkTexturePointer source, QOpenGLFramebufferObject* target, GLsync* fenceSync) override {};
void pluginUpdate() override {};
private:
static const QString NAME;
};

View file

@ -46,6 +46,8 @@ public:
virtual bool onDisplayTextureReset() override { _clearPreviewFlag = true; return true; };
void pluginUpdate() override {};
signals:
void hmdMountedChanged();
void hmdVisibleChanged(bool visible);

View file

@ -28,6 +28,8 @@ public:
// to the HMD plugins.
//virtual glm::mat4 getEyeToHeadTransform(Eye eye) const override;
virtual void pluginUpdate() override {};
protected:
virtual bool internalActivate() override;
virtual void internalDeactivate() override;

View file

@ -217,6 +217,9 @@ public:
static const QString& MENU_PATH();
// for updating plugin-related commands. Mimics the input plugin.
virtual void pluginUpdate() = 0;
signals:
void recommendedFramebufferSizeChanged(const QSize& size);
void resetSensorsRequested();

View file

@ -179,21 +179,19 @@ const SteamClientPluginPointer PluginManager::getSteamClientPlugin() {
return steamClientPlugin;
}
const OculusPlatformPluginPointer PluginManager::getOculusPlatformPlugin() {
static OculusPlatformPluginPointer oculusPlatformPlugin;
const DisplayPluginPointer PluginManager::getOculusDisplayPlugin() {
static DisplayPluginPointer oculusDisplayPlugin;
static std::once_flag once;
std::call_once(once, [&] {
// Now grab the dynamic plugins
for (auto loader : getLoadedPlugins()) {
OculusPlatformProvider* oculusPlatformProvider = qobject_cast<OculusPlatformProvider*>(loader->instance());
if (oculusPlatformProvider) {
oculusPlatformPlugin = oculusPlatformProvider->getOculusPlatformPlugin();
// Now grab the display plugins - might break in the main update loop if user unplugs the headset I think?
for (auto plugin : getDisplayPlugins()) {
if (plugin->getName() == "Oculus Rift") {
oculusDisplayPlugin = plugin;
break;
}
}
});
return oculusPlatformPlugin;
return oculusDisplayPlugin;
}
const DisplayPluginList& PluginManager::getDisplayPlugins() {

View file

@ -28,7 +28,7 @@ public:
const InputPluginList& getInputPlugins();
const CodecPluginList& getCodecPlugins();
const SteamClientPluginPointer getSteamClientPlugin();
const OculusPlatformPluginPointer getOculusPlatformPlugin();
const DisplayPluginPointer getOculusDisplayPlugin();
DisplayPluginList getPreferredDisplayPlugins();
void setPreferredDisplayPlugins(const QStringList& displays);

View file

@ -60,6 +60,5 @@ public:
#define SteamClientProvider_iid "com.highfidelity.plugins.steamclient"
Q_DECLARE_INTERFACE(SteamClientProvider, SteamClientProvider_iid)
#define OculusPlatformProvider_iid "com.highfidelity.plugins.oculusplatform"
Q_DECLARE_INTERFACE(OculusPlatformProvider, OculusPlatformProvider_iid)
Q_DECLARE_INTERFACE(OculusPlatformProvider, OculusPlatformProvider_iid)

View file

@ -12,6 +12,10 @@
#include <display-plugins/CompositorHelper.h>
#include <gpu/Frame.h>
#include <gl/Config.h>
#include <shared/GlobalAppProperties.h>
#define OVRPL_DISABLED
#include <OVR_Platform.h>
#include "OculusHelpers.h"
@ -30,7 +34,7 @@ bool OculusBaseDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
return false;
}
if (ovr::quitRequested(status) || ovr::displayLost(status) || !ovr::handleOVREvents()) {
if (ovr::quitRequested(status) || ovr::displayLost(status) || _isViewerEntitled) {
QMetaObject::invokeMethod(qApp, "quit");
return false;
}
@ -226,3 +230,64 @@ QVector<glm::vec3> OculusBaseDisplayPlugin::getSensorPositions() {
return result;
}
void OculusBaseDisplayPlugin::handleOVREvents() {
#ifdef OCULUS_APP_ID
if (qApp->property(hifi::properties::OCULUS_STORE).toBool()) {
// pop messages to see if we got a return for an entitlement check
ovrMessageHandle message = ovr_PopMessage();
while (message) {
switch (ovr_Message_GetType(message)) {
case ovrMessage_Entitlement_GetIsViewerEntitled: {
_isViewerEntitled = !ovr_Message_IsError(message);
if (_isViewerEntitled) {
// this viewer is entitled, no need to flag anything
qCDebug(oculusLog) << "Oculus Platform entitlement check succeeded, proceeding normally";
} else {
// we failed the entitlement check, quit
qCDebug(oculusLog) << "Oculus Platform entitlement check failed, app will now quit" << OCULUS_APP_ID;
}
break;
}
case ovrMessage_User_Get: {
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);
} else {
qCDebug(oculusLog) << "Oculus Platform user retrieval failed" << QString(ovr_Error_GetMessage(ovr_Message_GetError(message)));
}
break;
}
case ovrMessage_User_GetLoggedInUser: {
if (!ovr_Message_IsError(message)) {
ovrUserHandle user = ovr_Message_GetUser(message);
ovr_FreeMessage(message);
_userID = ovr_User_GetID(user);
} else {
qCDebug(oculusLog) << "Oculus Platform user ID retrieval failed" << QString(ovr_Error_GetMessage(ovr_Message_GetError(message)));
}
break;
}
case ovrMessage_User_GetUserProof: {
if (!ovr_Message_IsError(message)) {
ovrUserProofHandle userProof = ovr_Message_GetUserProof(message);
QString nonce = ovr_UserProof_GetNonce(userProof);
} else {
qCDebug(oculusLog) << "Oculus Platform nonce retrieval failed" << QString(ovr_Error_GetMessage(ovr_Message_GetError(message)));
}
break;
}
}
// free the message handle to cleanup and not leak
ovr_FreeMessage(message);
// pop the next message to check, if there is one
message = ovr_PopMessage();
}
}
#endif
}

View file

@ -30,15 +30,25 @@ public:
QRectF getPlayAreaRect() override;
QVector<glm::vec3> getSensorPositions() override;
signals:
void userIDChanged(uint64_t userID);
void userChanged(QString user);
void nonceChanged(QString nonce);
protected:
void customizeContext() override;
void uncustomizeContext() override;
bool internalActivate() override;
void internalDeactivate() override;
void updatePresentPose() override;
void handleOVREvents();
protected:
bool _isViewerEntitled;
QString _nonce;
QString _user;
uint64_t _userID;
ovrSession _session{ nullptr };
ovrGraphicsLuid _luid;
std::array<ovrEyeRenderDesc, 2> _eyeRenderDescs;

View file

@ -56,6 +56,10 @@ void OculusDisplayPlugin::init() {
emit deviceConnected(getName());
}
void OculusDisplayPlugin::pluginUpdate() {
handleOVREvents();
}
void OculusDisplayPlugin::cycleDebugOutput() {
if (_session) {
currentDebugMode = static_cast<ovrPerfHudMode>((currentDebugMode + 1) % ovrPerfHud_Count);

View file

@ -23,6 +23,7 @@ public:
float getTargetFrameRate() const override;
virtual QJsonObject getHardwareStats() const;
void pluginUpdate() override final;
protected:
QThread::Priority getPresentPriority() override { return QThread::TimeCriticalPriority; }

View file

@ -293,34 +293,3 @@ controller::Pose hifi::ovr::toControllerPose(ovrHandType hand,
pose.valid = true;
return pose;
}
bool hifi::ovr::handleOVREvents() {
#ifdef OCULUS_APP_ID
if (qApp->property(hifi::properties::OCULUS_STORE).toBool()) {
// pop messages to see if we got a return for an entitlement check
ovrMessageHandle message = ovr_PopMessage();
while (message) {
switch (ovr_Message_GetType(message)) {
case ovrMessage_Entitlement_GetIsViewerEntitled: {
if (!ovr_Message_IsError(message)) {
// this viewer is entitled, no need to flag anything
qCDebug(oculusLog) << "Oculus Platform entitlement check succeeded, proceeding normally";
} else {
// we failed the entitlement check, quit
qCDebug(oculusLog) << "Oculus Platform entitlement check failed, app will now quit" << OCULUS_APP_ID;
return false;
}
}
}
// free the message handle to cleanup and not leak
ovr_FreeMessage(message);
// pop the next message to check, if there is one
message = ovr_PopMessage();
}
}
#endif
return true;
}

View file

@ -30,7 +30,6 @@ struct ovr {
static ovrSessionStatus getStatus(ovrResult& result);
static ovrTrackingState getTrackingState(double absTime = 0.0, ovrBool latencyMarker = ovrFalse);
static QString getError();
static bool handleOVREvents();
static inline bool quitRequested() { return quitRequested(getStatus()); }
static inline bool reorientRequested() { return reorientRequested(getStatus()); }

View file

@ -94,9 +94,11 @@ void OculusAPIPlugin::requestTicket(OculusTicketRequestCallback callback) {
return;
}
auto userProof = getUserProof();
auto nonce = getUserProof();
auto userID = getLoggedInUserID();
callback(userProof, userID);
qDebug() << "Nonce: " << nonce << ", " << userID;
callback(nonce, userID);
return;
}
@ -111,7 +113,7 @@ QString OculusAPIPlugin::getUserProof() {
auto request = ovr_User_GetUserProof();
ovrMessageHandle message { nullptr };
bool messageNotReceived = true;
while (timer.isActive() && messageNotReceived) {
while (messageNotReceived) {
message = ovr_PopMessage();
if (timer.remainingTime() == 0) {
qCDebug(oculusLog) << "user proof timeout after 5 seconds";
@ -142,25 +144,26 @@ QString OculusAPIPlugin::getUserProof() {
return "";
}
QString OculusAPIPlugin::getLoggedInUserID() {
if (initialized) {
QTimer timer;
timer.start(5000);
auto request = ovr_User_GetLoggedInUser();
ovrMessageHandle message { nullptr };
bool messageNotReceived = true;
while (messageNotReceived) {
if (timer.remainingTime() == 0) {
qCDebug(oculusLog) << "login user id timeout after 5 seconds";
return "";
}
QString getOculusUserID(ovrID userID) {
QTimer timer;
timer.start(5000);
timer.setSingleShot(true);
auto request = ovr_User_Get(userID);
bool messageNotReceived = true;
while (messageNotReceived) {
auto message = ovr_PopMessage();
if (timer.remainingTime() == 0) {
qCDebug(oculusLog) << "login user id timeout after 5 seconds";
return "";
}
if (message != nullptr) {
switch (ovr_Message_GetType(message)) {
case ovrMessage_User_GetLoggedInUser:
messageNotReceived = false;
case ovrMessage_User_Get:
if (!ovr_Message_IsError(message)) {
messageNotReceived = false;
ovrUserHandle user = ovr_Message_GetUser(message);
ovr_FreeMessage(message);
qCDebug(oculusLog) << "UserID: " << ovr_User_GetID(user) << ", Oculus ID: " << QString(ovr_User_GetOculusID(user));
qCDebug(oculusLog) << "UserID: " << userID << "\nOculus ID: " << QString(ovr_User_GetOculusID(user));
return QString(ovr_User_GetOculusID(user));
} else {
qDebug() << "Error getting user id: " << QString(ovr_Error_GetMessage(ovr_Message_GetError(message)));
@ -174,6 +177,47 @@ QString OculusAPIPlugin::getLoggedInUserID() {
}
}
}
}
QString OculusAPIPlugin::getLoggedInUserID() {
if (initialized) {
QTimer timer;
timer.start(5000);
timer.setSingleShot(true);
auto request = ovr_User_GetLoggedInUser();
ovrMessageHandle message { nullptr };
ovrID userID = 0;
bool messageNotReceived = true;
while (messageNotReceived) {
message = ovr_PopMessage();
if (timer.remainingTime() == 0) {
qCDebug(oculusLog) << "login user id timeout after 5 seconds";
return "";
}
if (message != nullptr) {
switch (ovr_Message_GetType(message)) {
case ovrMessage_User_GetLoggedInUser:
if (!ovr_Message_IsError(message)) {
messageNotReceived = false;
ovrUserHandle user = ovr_Message_GetUser(message);
ovr_FreeMessage(message);
userID = ovr_User_GetID(user);
break;
} else {
qDebug() << "Error getting user id: " << QString(ovr_Error_GetMessage(ovr_Message_GetError(message)));
ovr_FreeMessage(message);
return "";
}
break;
default:
ovr_FreeMessage(message);
break;
}
}
}
timer.stop();
return getOculusUserID(userID);
}
return "";
}