@@ -682,7 +682,8 @@ XrResult RuntimeManifestFile::FindManifestFiles(const std::string &openxr_comman
682
682
683
683
#if defined(XR_KHR_LOADER_INIT_SUPPORT) && defined(XR_USE_PLATFORM_ANDROID)
684
684
Json::Value virtualManifest;
685
- result = GetPlatformRuntimeVirtualManifest (virtualManifest);
685
+ ManifestFileSource runtimeSource = ManifestFileSource::FROM_JSON_MANIFEST;
686
+ result = GetPlatformRuntimeVirtualManifest (virtualManifest, runtimeSource);
686
687
if (XR_SUCCESS == result) {
687
688
RuntimeManifestFile::CreateIfValid (virtualManifest, " " , manifest_files);
688
689
return result;
@@ -779,6 +780,134 @@ void ApiLayerManifestFile::AddManifestFilesAndroid(const std::string &openxr_com
779
780
}
780
781
#endif // defined(XR_USE_PLATFORM_ANDROID) && defined(XR_KHR_LOADER_INIT_SUPPORT)
781
782
783
+ void ApiLayerManifestFile::CreateIfValid (ManifestFileType type, const Json::Value &root_node, const std::string &filename,
784
+ std::vector<std::unique_ptr<ApiLayerManifestFile>> &manifest_files) {
785
+ std::ostringstream error_ss (" ApiLayerManifestFile::CreateIfValid " );
786
+ JsonVersion file_version = {};
787
+ if (!ManifestFile::IsValidJson (root_node, file_version)) {
788
+ error_ss << " isValidJson indicates " << filename << " is not a valid manifest file." ;
789
+ LoaderLogger::LogErrorMessage (" " , error_ss.str ());
790
+ return ;
791
+ }
792
+
793
+ Json::Value layer_root_node = root_node[" api_layer" ];
794
+
795
+ // The API Layer manifest file needs the "api_layer" root as well as other sub-nodes.
796
+ // If any of those aren't there, fail.
797
+ if (layer_root_node.isNull () || layer_root_node[" name" ].isNull () || !layer_root_node[" name" ].isString () ||
798
+ layer_root_node[" api_version" ].isNull () || !layer_root_node[" api_version" ].isString () ||
799
+ layer_root_node[" library_path" ].isNull () || !layer_root_node[" library_path" ].isString () ||
800
+ layer_root_node[" implementation_version" ].isNull () || !layer_root_node[" implementation_version" ].isString ()) {
801
+ error_ss << filename << " is missing required fields. Verify all proper fields exist." ;
802
+ LoaderLogger::LogErrorMessage (" " , error_ss.str ());
803
+ return ;
804
+ }
805
+ if (MANIFEST_TYPE_IMPLICIT_API_LAYER == type) {
806
+ bool enabled = true ;
807
+ // Implicit layers require the disable environment variable.
808
+ if (layer_root_node[" disable_environment" ].isNull () || !layer_root_node[" disable_environment" ].isString ()) {
809
+ error_ss << " Implicit layer " << filename << " is missing \" disable_environment\" " ;
810
+ LoaderLogger::LogErrorMessage (" " , error_ss.str ());
811
+ return ;
812
+ }
813
+ // Check if there's an enable environment variable provided
814
+ if (!layer_root_node[" enable_environment" ].isNull () && layer_root_node[" enable_environment" ].isString ()) {
815
+ std::string env_var = layer_root_node[" enable_environment" ].asString ();
816
+ // If it's not set in the environment, disable the layer
817
+ if (!PlatformUtilsGetEnvSet (env_var.c_str ())) {
818
+ enabled = false ;
819
+ }
820
+ }
821
+ // Check for the disable environment variable, which must be provided in the JSON
822
+ std::string env_var = layer_root_node[" disable_environment" ].asString ();
823
+ // If the env var is set, disable the layer. Disable env var overrides enable above
824
+ if (PlatformUtilsGetEnvSet (env_var.c_str ())) {
825
+ enabled = false ;
826
+ }
827
+
828
+ #if defined(XR_OS_ANDROID)
829
+ // Check if there's an system property to enable this API layer
830
+ if (!layer_root_node[" enable_sys_prop" ].isNull () && layer_root_node[" enable_sys_prop" ].isString ()) {
831
+ std::string enable_sys_prop = layer_root_node[" enable_sys_prop" ].asString ();
832
+ // If it's not set to true, disable this layer
833
+ if (!PlatformUtilsGetSysProp (enable_sys_prop.c_str (), true )) {
834
+ enabled = false ;
835
+ }
836
+ }
837
+
838
+ std::string disable_sys_prop = layer_root_node[" disable_sys_prop" ].asString ();
839
+ if (PlatformUtilsGetSysProp (disable_sys_prop.c_str (), false )) {
840
+ enabled = false ;
841
+ }
842
+ #endif
843
+
844
+ // Not enabled, so pretend like it isn't even there.
845
+ if (!enabled) {
846
+ error_ss << " Implicit layer " << filename << " is disabled" ;
847
+ LoaderLogger::LogInfoMessage (" " , error_ss.str ());
848
+ return ;
849
+ }
850
+ }
851
+ std::string layer_name = layer_root_node[" name" ].asString ();
852
+ std::string api_version_string = layer_root_node[" api_version" ].asString ();
853
+ JsonVersion api_version = {};
854
+ const int num_fields = sscanf (api_version_string.c_str (), " %u.%u" , &api_version.major , &api_version.minor );
855
+ api_version.patch = 0 ;
856
+
857
+ if ((num_fields != 2 ) || (api_version.major == 0 && api_version.minor == 0 ) ||
858
+ api_version.major > XR_VERSION_MAJOR (XR_CURRENT_API_VERSION)) {
859
+ error_ss << " layer " << filename << " has invalid API Version. Skipping layer." ;
860
+ LoaderLogger::LogWarningMessage (" " , error_ss.str ());
861
+ return ;
862
+ }
863
+
864
+ char *end_ptr;
865
+ uint32_t implementation_version = strtol (layer_root_node[" implementation_version" ].asString ().c_str (), &end_ptr, 10 );
866
+ if (*end_ptr != ' \0 ' ) {
867
+ error_ss << " layer " << filename << " has invalid implementation version." ;
868
+ LoaderLogger::LogWarningMessage (" " , error_ss.str ());
869
+ }
870
+
871
+ std::string library_path = layer_root_node[" library_path" ].asString ();
872
+
873
+ // If the library_path variable has no directory symbol, it's just a file name and should be accessible on the
874
+ // global library path.
875
+ if (library_path.find (' \\ ' ) != std::string::npos || library_path.find (' /' ) != std::string::npos) {
876
+ // If the library_path is an absolute path, just use that if it exists
877
+ if (FileSysUtilsIsAbsolutePath (library_path)) {
878
+ if (!FileSysUtilsPathExists (library_path)) {
879
+ error_ss << filename << " library " << library_path << " does not appear to exist" ;
880
+ LoaderLogger::LogErrorMessage (" " , error_ss.str ());
881
+ return ;
882
+ }
883
+ } else {
884
+ // Otherwise, treat the library path as a relative path based on the JSON file.
885
+ std::string combined_path;
886
+ std::string file_parent;
887
+ if (!FileSysUtilsGetParentPath (filename, file_parent) ||
888
+ !FileSysUtilsCombinePaths (file_parent, library_path, combined_path) || !FileSysUtilsPathExists (combined_path)) {
889
+ error_ss << filename << " library " << combined_path << " does not appear to exist" ;
890
+ LoaderLogger::LogErrorMessage (" " , error_ss.str ());
891
+ return ;
892
+ }
893
+ library_path = combined_path;
894
+ }
895
+ }
896
+
897
+ std::string description;
898
+ if (!layer_root_node[" description" ].isNull () && layer_root_node[" description" ].isString ()) {
899
+ description = layer_root_node[" description" ].asString ();
900
+ }
901
+
902
+ // Add this layer manifest file
903
+ manifest_files.emplace_back (
904
+ new ApiLayerManifestFile (type, filename, layer_name, description, api_version, implementation_version, library_path));
905
+
906
+ // Add any extensions to it after the fact.
907
+ // Handle any renamed functions
908
+ manifest_files.back ()->ParseCommon (layer_root_node);
909
+ }
910
+
782
911
void ApiLayerManifestFile::CreateIfValid (ManifestFileType type, const std::string &filename, std::istream &json_stream,
783
912
LibraryLocator locate_library,
784
913
std::vector<std::unique_ptr<ApiLayerManifestFile>> &manifest_files) {
@@ -892,6 +1021,7 @@ void ApiLayerManifestFile::CreateIfValid(ManifestFileType type, const std::strin
892
1021
new ApiLayerManifestFile (type, filename, layer_name, description, api_version, implementation_version, library_path));
893
1022
894
1023
// Add any extensions to it after the fact.
1024
+ // Handle any renamed functions
895
1025
manifest_files.back ()->ParseCommon (layer_root_node);
896
1026
}
897
1027
@@ -951,6 +1081,24 @@ void ApiLayerManifestFile::PopulateApiLayerProperties(XrApiLayerProperties &prop
951
1081
// Find all layer manifest files in the appropriate search paths/registries for the given type.
952
1082
XrResult ApiLayerManifestFile::FindManifestFiles (const std::string &openxr_command, ManifestFileType type,
953
1083
std::vector<std::unique_ptr<ApiLayerManifestFile>> &manifest_files) {
1084
+ bool search_json_layer = true ;
1085
+ bool search_broker_layer = true ;
1086
+
1087
+ #if defined(XR_KHR_LOADER_INIT_SUPPORT) && defined(XR_USE_PLATFORM_ANDROID)
1088
+ Json::Value virtualManifest;
1089
+ bool systemBroker = true ;
1090
+ ManifestFileSource runtimeSource = ManifestFileSource::FROM_JSON_MANIFEST;
1091
+ XrResult result = GetPlatformRuntimeVirtualManifest (virtualManifest, runtimeSource);
1092
+ if (XR_SUCCESS == result) {
1093
+ if (runtimeSource == ManifestFileSource::FROM_INSTALLABLE_BROKER) {
1094
+ systemBroker = false ;
1095
+ search_json_layer = false ;
1096
+ }
1097
+ } else {
1098
+ search_broker_layer = false ;
1099
+ }
1100
+ #endif // defined(XR_USE_PLATFORM_ANDROID) && defined(XR_KHR_LOADER_INIT_SUPPORT)
1101
+
954
1102
std::string relative_path;
955
1103
std::string override_env_var;
956
1104
std::string registry_location;
@@ -983,7 +1131,9 @@ XrResult ApiLayerManifestFile::FindManifestFiles(const std::string &openxr_comma
983
1131
984
1132
bool override_active = false ;
985
1133
std::vector<std::string> filenames;
986
- ReadDataFilesInSearchPaths (override_env_var, relative_path, override_active, filenames);
1134
+ if (search_json_layer) {
1135
+ ReadDataFilesInSearchPaths (override_env_var, relative_path, override_active, filenames);
1136
+ }
987
1137
988
1138
#ifdef XR_OS_WINDOWS
989
1139
// Read the registry if the override wasn't active.
@@ -997,6 +1147,22 @@ XrResult ApiLayerManifestFile::FindManifestFiles(const std::string &openxr_comma
997
1147
}
998
1148
999
1149
#if defined(XR_KHR_LOADER_INIT_SUPPORT) && defined(XR_USE_PLATFORM_ANDROID)
1150
+ if (search_broker_layer) {
1151
+ std::vector<Json::Value> virtualManifests;
1152
+ std::string layerType = (type == ManifestFileType::MANIFEST_TYPE_IMPLICIT_API_LAYER) ? " implicit" : " explicit" ;
1153
+ result = GetPlatformApiLayerVirtualManifests (layerType, virtualManifests, systemBroker);
1154
+ if (XR_SUCCESS == result) {
1155
+ for (const auto &virtualManifest : virtualManifests) {
1156
+ ApiLayerManifestFile::CreateIfValid (type, virtualManifest, " virtual manifest" , manifest_files);
1157
+ }
1158
+ } else {
1159
+ LoaderLogger::LogErrorMessage (
1160
+ " " ,
1161
+ " ApiLayerManifestFile::FindManifestFiles - failed to get virtual manifest files from system/installable broker." );
1162
+ assert (0 );
1163
+ }
1164
+ }
1165
+
1000
1166
ApiLayerManifestFile::AddManifestFilesAndroid (openxr_command, type, manifest_files);
1001
1167
#endif // defined(XR_USE_PLATFORM_ANDROID) && defined(XR_KHR_LOADER_INIT_SUPPORT)
1002
1168
0 commit comments