Bug 1529105 - Replace tmpname in OpenVRSession when using action input. r=kip

Differential Revision: https://phabricator.services.mozilla.com/D28136

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Daosheng Mu 2019-04-22 20:41:38 +00:00
Родитель 377244bae8
Коммит 19d96836d5
2 изменённых файлов: 102 добавлений и 30 удалений

Просмотреть файл

@ -19,6 +19,10 @@
# include "mozilla/gfx/MacIOSurface.h" # include "mozilla/gfx/MacIOSurface.h"
#endif #endif
#if !defined(XP_WIN)
# include <sys/stat.h> // for umask()
#endif
#include "mozilla/dom/GamepadEventTypes.h" #include "mozilla/dom/GamepadEventTypes.h"
#include "mozilla/dom/GamepadBinding.h" #include "mozilla/dom/GamepadBinding.h"
#include "binding/OpenVRKnucklesBinding.h" #include "binding/OpenVRKnucklesBinding.h"
@ -53,13 +57,11 @@ namespace {
// This is for controller action file writer. // This is for controller action file writer.
struct StringWriteFunc : public JSONWriteFunc { struct StringWriteFunc : public JSONWriteFunc {
nsAString& mBuffer; // This struct must not outlive this buffer nsACString& mBuffer; // This struct must not outlive this buffer
explicit StringWriteFunc(nsAString& buffer) : mBuffer(buffer) {} explicit StringWriteFunc(nsACString& buffer) : mBuffer(buffer) {}
void Write(const char* aStr) override { void Write(const char* aStr) override { mBuffer.Append(aStr); }
mBuffer.Append(NS_ConvertUTF8toUTF16(aStr));
}
}; };
class ControllerManifestFile { class ControllerManifestFile {
@ -72,7 +74,8 @@ class ControllerManifestFile {
} }
bool IsExisting() { bool IsExisting() {
if (mFileName.IsEmpty() || !std::ifstream(mFileName.BeginReading())) { if (mFileName.IsEmpty() ||
!std::ifstream(mFileName.BeginReading()).good()) {
return false; return false;
} }
return true; return true;
@ -172,7 +175,7 @@ void UpdateButton(VRControllerState& aState,
} }
bool FileIsExisting(const nsCString& aPath) { bool FileIsExisting(const nsCString& aPath) {
if (aPath.IsEmpty() || !std::ifstream(aPath.BeginReading())) { if (aPath.IsEmpty() || !std::ifstream(aPath.BeginReading()).good()) {
return false; return false;
} }
return true; return true;
@ -180,6 +183,52 @@ bool FileIsExisting(const nsCString& aPath) {
}; // anonymous namespace }; // anonymous namespace
#if defined(XP_WIN)
bool GenerateTempFileName(nsCString& aPath) {
TCHAR tempPathBuffer[MAX_PATH];
TCHAR tempFileName[MAX_PATH];
// Gets the temp path env string (no guarantee it's a valid path).
DWORD dwRetVal = GetTempPath(MAX_PATH, tempPathBuffer);
if (dwRetVal > MAX_PATH || (dwRetVal == 0)) {
NS_WARNING("OpenVR - Creating temp path failed.");
return false;
}
// Generates a temporary file name.
UINT uRetVal = GetTempFileName(tempPathBuffer, // directory for tmp files
TEXT("mozvr"), // temp file name prefix
0, // create unique name
tempFileName); // buffer for name
if (uRetVal == 0) {
NS_WARNING("OpenVR - Creating temp file failed.");
return false;
}
aPath.Assign(NS_ConvertUTF16toUTF8(tempFileName));
return true;
}
#else
bool GenerateTempFileName(nsCString& aPath) {
const char tmp[] = "/tmp/mozvrXXXXXX";
char fileName[PATH_MAX];
strcpy(fileName, tmp);
const mode_t prevMask = umask(S_IXUSR | S_IRWXO | S_IRWXG);
const int fd = mkstemp(fileName);
umask(prevMask);
if (fd == -1) {
NS_WARNING(nsPrintfCString("OpenVR - Creating temp file failed: %s",
strerror(errno)).get());
return false;
}
close(fd);
aPath.Assign(fileName);
return true;
}
#endif // defined(XP_WIN)
OpenVRSession::OpenVRSession() OpenVRSession::OpenVRSession()
: VRSession(), : VRSession(),
mVRSystem(nullptr), mVRSystem(nullptr),
@ -256,8 +305,8 @@ bool OpenVRSession::Initialize(mozilla::gfx::VRSystemState& aSystemState) {
return false; return false;
} }
if (gfxPrefs::VROpenVRActionInputEnabled()) { if (gfxPrefs::VROpenVRActionInputEnabled() && !SetupContollerActions()) {
SetupContollerActions(); return false;
} }
NS_DispatchToMainThread(NS_NewRunnableFunction( NS_DispatchToMainThread(NS_NewRunnableFunction(
@ -267,7 +316,7 @@ bool OpenVRSession::Initialize(mozilla::gfx::VRSystemState& aSystemState) {
return true; return true;
} }
void OpenVRSession::SetupContollerActions() { bool OpenVRSession::SetupContollerActions() {
// Check if this device binding file has been created. // Check if this device binding file has been created.
// If it didn't exist yet, create a new temp file. // If it didn't exist yet, create a new temp file.
nsCString controllerAction; nsCString controllerAction;
@ -275,23 +324,23 @@ void OpenVRSession::SetupContollerActions() {
nsCString WMRManifest; nsCString WMRManifest;
nsCString knucklesManifest; nsCString knucklesManifest;
// Getting / Generating manifest file paths.
if (gfxPrefs::VRProcessEnabled()) { if (gfxPrefs::VRProcessEnabled()) {
VRParent* vrParent = VRProcessChild::GetVRParent(); VRParent* vrParent = VRProcessChild::GetVRParent();
nsCString output; nsCString output;
if (vrParent->GetOpenVRControllerActionPath(&output)) { if (vrParent->GetOpenVRControllerActionPath(&output)) {
controllerAction = output; controllerAction = output;
} else {
controllerAction = std::tmpnam(nullptr);
} }
if (vrParent->GetOpenVRControllerManifestPath(OpenVRControllerType::Vive, if (vrParent->GetOpenVRControllerManifestPath(OpenVRControllerType::Vive,
&output)) { &output)) {
viveManifest = output; viveManifest = output;
} else {
viveManifest = std::tmpnam(nullptr);
} }
if (!FileIsExisting(viveManifest)) { if (!viveManifest.Length() || !FileIsExisting(viveManifest)) {
if (!GenerateTempFileName(viveManifest)) {
return false;
}
OpenVRViveBinding viveBinding; OpenVRViveBinding viveBinding;
std::ofstream viveBindingFile(viveManifest.BeginReading()); std::ofstream viveBindingFile(viveManifest.BeginReading());
if (viveBindingFile.is_open()) { if (viveBindingFile.is_open()) {
@ -304,10 +353,11 @@ void OpenVRSession::SetupContollerActions() {
if (vrParent->GetOpenVRControllerManifestPath(OpenVRControllerType::WMR, if (vrParent->GetOpenVRControllerManifestPath(OpenVRControllerType::WMR,
&output)) { &output)) {
WMRManifest = output; WMRManifest = output;
} else {
WMRManifest = std::tmpnam(nullptr);
} }
if (!FileIsExisting(WMRManifest)) { if (!WMRManifest.Length() || !FileIsExisting(WMRManifest)) {
if (!GenerateTempFileName(WMRManifest)) {
return false;
}
OpenVRWMRBinding WMRBinding; OpenVRWMRBinding WMRBinding;
std::ofstream WMRBindingFile(WMRManifest.BeginReading()); std::ofstream WMRBindingFile(WMRManifest.BeginReading());
if (WMRBindingFile.is_open()) { if (WMRBindingFile.is_open()) {
@ -320,10 +370,11 @@ void OpenVRSession::SetupContollerActions() {
if (vrParent->GetOpenVRControllerManifestPath( if (vrParent->GetOpenVRControllerManifestPath(
OpenVRControllerType::Knuckles, &output)) { OpenVRControllerType::Knuckles, &output)) {
knucklesManifest = output; knucklesManifest = output;
} else {
knucklesManifest = std::tmpnam(nullptr);
} }
if (!FileIsExisting(knucklesManifest)) { if (!knucklesManifest.Length() || !FileIsExisting(knucklesManifest)) {
if (!GenerateTempFileName(knucklesManifest)) {
return false;
}
OpenVRKnucklesBinding knucklesBinding; OpenVRKnucklesBinding knucklesBinding;
std::ofstream knucklesBindingFile(knucklesManifest.BeginReading()); std::ofstream knucklesBindingFile(knucklesManifest.BeginReading());
if (knucklesBindingFile.is_open()) { if (knucklesBindingFile.is_open()) {
@ -332,13 +383,12 @@ void OpenVRSession::SetupContollerActions() {
} }
} }
} else { } else {
// Without using VR process
if (!sControllerActionFile) { if (!sControllerActionFile) {
sControllerActionFile = ControllerManifestFile::CreateManifest(); sControllerActionFile = ControllerManifestFile::CreateManifest();
NS_DispatchToMainThread(NS_NewRunnableFunction( NS_DispatchToMainThread(NS_NewRunnableFunction(
"ClearOnShutdown ControllerManifestFile", "ClearOnShutdown ControllerManifestFile",
[]() { ClearOnShutdown(&sControllerActionFile); })); []() { ClearOnShutdown(&sControllerActionFile); }));
sControllerActionFile->SetFileName(std::tmpnam(nullptr));
} }
controllerAction = sControllerActionFile->GetFileName(); controllerAction = sControllerActionFile->GetFileName();
@ -349,7 +399,11 @@ void OpenVRSession::SetupContollerActions() {
[]() { ClearOnShutdown(&sViveBindingFile); })); []() { ClearOnShutdown(&sViveBindingFile); }));
} }
if (!sViveBindingFile->IsExisting()) { if (!sViveBindingFile->IsExisting()) {
sViveBindingFile->SetFileName(std::tmpnam(nullptr)); nsCString viveBindingPath;
if (!GenerateTempFileName(viveBindingPath)) {
return false;
}
sViveBindingFile->SetFileName(viveBindingPath.BeginReading());
OpenVRViveBinding viveBinding; OpenVRViveBinding viveBinding;
std::ofstream viveBindingFile(sViveBindingFile->GetFileName()); std::ofstream viveBindingFile(sViveBindingFile->GetFileName());
if (viveBindingFile.is_open()) { if (viveBindingFile.is_open()) {
@ -366,7 +420,11 @@ void OpenVRSession::SetupContollerActions() {
[]() { ClearOnShutdown(&sKnucklesBindingFile); })); []() { ClearOnShutdown(&sKnucklesBindingFile); }));
} }
if (!sKnucklesBindingFile->IsExisting()) { if (!sKnucklesBindingFile->IsExisting()) {
sKnucklesBindingFile->SetFileName(std::tmpnam(nullptr)); nsCString knucklesBindingPath;
if (!GenerateTempFileName(knucklesBindingPath)) {
return false;
}
sKnucklesBindingFile->SetFileName(knucklesBindingPath.BeginReading());
OpenVRKnucklesBinding knucklesBinding; OpenVRKnucklesBinding knucklesBinding;
std::ofstream knucklesBindingFile(sKnucklesBindingFile->GetFileName()); std::ofstream knucklesBindingFile(sKnucklesBindingFile->GetFileName());
if (knucklesBindingFile.is_open()) { if (knucklesBindingFile.is_open()) {
@ -384,7 +442,11 @@ void OpenVRSession::SetupContollerActions() {
[]() { ClearOnShutdown(&sWMRBindingFile); })); []() { ClearOnShutdown(&sWMRBindingFile); }));
} }
if (!sWMRBindingFile->IsExisting()) { if (!sWMRBindingFile->IsExisting()) {
sWMRBindingFile->SetFileName(std::tmpnam(nullptr)); nsCString WMRBindingPath;
if (!GenerateTempFileName(WMRBindingPath)) {
return false;
}
sWMRBindingFile->SetFileName(WMRBindingPath.BeginReading());
OpenVRWMRBinding WMRBinding; OpenVRWMRBinding WMRBinding;
std::ofstream WMRBindingFile(sWMRBindingFile->GetFileName()); std::ofstream WMRBindingFile(sWMRBindingFile->GetFileName());
if (WMRBindingFile.is_open()) { if (WMRBindingFile.is_open()) {
@ -395,7 +457,9 @@ void OpenVRSession::SetupContollerActions() {
WMRManifest = sWMRBindingFile->GetFileName(); WMRManifest = sWMRBindingFile->GetFileName();
#endif #endif
} }
// End of Getting / Generating manifest file paths.
// Setup controller actions.
ControllerInfo leftContollerInfo; ControllerInfo leftContollerInfo;
leftContollerInfo.mActionPose = leftContollerInfo.mActionPose =
ControllerAction("/actions/firefox/in/LHand_pose", "pose"); ControllerAction("/actions/firefox/in/LHand_pose", "pose");
@ -495,8 +559,11 @@ void OpenVRSession::SetupContollerActions() {
mControllerHand[OpenVRHand::Left] = leftContollerInfo; mControllerHand[OpenVRHand::Left] = leftContollerInfo;
mControllerHand[OpenVRHand::Right] = rightContollerInfo; mControllerHand[OpenVRHand::Right] = rightContollerInfo;
if (!FileIsExisting(controllerAction)) { if (!controllerAction.Length() || !FileIsExisting(controllerAction)) {
nsAutoString actionData; if (!GenerateTempFileName(controllerAction)) {
return false;
}
nsCString actionData;
JSONWriter actionWriter(MakeUnique<StringWriteFunc>(actionData)); JSONWriter actionWriter(MakeUnique<StringWriteFunc>(actionData));
actionWriter.Start(); actionWriter.Start();
@ -690,7 +757,7 @@ void OpenVRSession::SetupContollerActions() {
actionWriter.End(); actionWriter.End();
std::ofstream actionfile(controllerAction.BeginReading()); std::ofstream actionfile(controllerAction.BeginReading());
nsCString actionResult(NS_ConvertUTF16toUTF8(actionData.get())); nsCString actionResult(actionData.get());
if (actionfile.is_open()) { if (actionfile.is_open()) {
actionfile << actionResult.get(); actionfile << actionResult.get();
actionfile.close(); actionfile.close();
@ -698,6 +765,7 @@ void OpenVRSession::SetupContollerActions() {
} }
vr::VRInput()->SetActionManifestPath(controllerAction.BeginReading()); vr::VRInput()->SetActionManifestPath(controllerAction.BeginReading());
// End of setup controller actions.
// Notify the parent process these manifest files are already been recorded. // Notify the parent process these manifest files are already been recorded.
if (gfxPrefs::VRProcessEnabled()) { if (gfxPrefs::VRProcessEnabled()) {
@ -714,7 +782,11 @@ void OpenVRSession::SetupContollerActions() {
Unused << vrParent->SendOpenVRControllerManifestPathToParent( Unused << vrParent->SendOpenVRControllerManifestPathToParent(
OpenVRControllerType::Knuckles, knucklesManifest); OpenVRControllerType::Knuckles, knucklesManifest);
})); }));
} else {
sControllerActionFile->SetFileName(controllerAction.BeginReading());
} }
return true;
} }
#if defined(XP_WIN) #if defined(XP_WIN)

Просмотреть файл

@ -129,7 +129,7 @@ class OpenVRSession : public VRSession {
void UpdateControllerButtons(VRSystemState& aState); void UpdateControllerButtons(VRSystemState& aState);
void UpdateControllerButtonsObsolete(VRSystemState& aState); void UpdateControllerButtonsObsolete(VRSystemState& aState);
void UpdateTelemetry(VRSystemState& aSystemState); void UpdateTelemetry(VRSystemState& aSystemState);
void SetupContollerActions(); bool SetupContollerActions();
bool SubmitFrame(const VRLayerTextureHandle& aTextureHandle, bool SubmitFrame(const VRLayerTextureHandle& aTextureHandle,
::vr::ETextureType aTextureType, ::vr::ETextureType aTextureType,