public void PatchAndroidManifest(string path) { string manifestFolder = Path.Combine(path, "src/main"); string file = manifestFolder + "/AndroidManifest.xml"; bool patchedSecurityConfig = false; // If Enable NSC Config, copy XML file into gradle project OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig(); if (projectConfig != null) { if (projectConfig.enableNSCConfig) { string securityConfigFile = GetOculusProjectNetworkSecConfigPath(); string xmlDirectory = Path.Combine(path, "src/main/res/xml"); try { if (!Directory.Exists(xmlDirectory)) { Directory.CreateDirectory(xmlDirectory); } File.Copy(securityConfigFile, Path.Combine(xmlDirectory, "network_sec_config.xml"), true); patchedSecurityConfig = true; } catch (Exception e) { UnityEngine.Debug.LogError(e.Message); } } } OVRManifestPreprocessor.PatchAndroidManifest(file, enableSecurity: patchedSecurityConfig); }
public void OnPreprocessBuild(BuildReport report) { //Debug.Log("MyCustomBuildProcessor.OnPreprocessBuild for target " + report.summary.platform + " at path " + report.summary.outputPath); OVRProjectConfig ovrConfig = OVRProjectConfig.GetProjectConfig(); if (ovrConfig.handTrackingSupport != OVRProjectConfig.HandTrackingSupport.ControllersAndHands) { ovrConfig.handTrackingSupport = OVRProjectConfig.HandTrackingSupport.ControllersAndHands; ovrConfig.handTrackingFrequency = OVRProjectConfig.HandTrackingFrequency.MAX; OVRProjectConfig.CommitProjectConfig(ovrConfig); } }
internal static void InitializeOculusProjectConfig() { #if OCULUSINTEGRATION_PRESENT // Updating the oculus project config to allow for handtracking and system keyboard usage OVRProjectConfig defaultOculusProjectConfig = OVRProjectConfig.GetProjectConfig(); if (defaultOculusProjectConfig != null) { defaultOculusProjectConfig.handTrackingSupport = OVRProjectConfig.HandTrackingSupport.ControllersAndHands; defaultOculusProjectConfig.requiresSystemKeyboard = true; Debug.Log("Enabled Oculus Quest Keyboard and Handtracking in the Oculus Project Config"); } #endif }
public void OnPostGenerateGradleAndroidProject(string path) { UnityEngine.Debug.Log("OVRGradleGeneration triggered."); var targetOculusPlatform = new List <string>(); if (OVRDeviceSelector.isTargetDeviceQuestFamily) { targetOculusPlatform.Add("quest"); } UnityEngine.Debug.LogFormat("QuestFamily = {0}: Quest = {1}, Quest2 = {2}", OVRDeviceSelector.isTargetDeviceQuestFamily, OVRDeviceSelector.isTargetDeviceQuest, OVRDeviceSelector.isTargetDeviceQuest2); OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig(); if (projectConfig != null && projectConfig.systemSplashScreen != null) { if (PlayerSettings.virtualRealitySplashScreen != null) { UnityEngine.Debug.LogWarning("Virtual Reality Splash Screen (in Player Settings) is active. It would be displayed after the system splash screen, before the first game frame be rendered."); } string splashScreenAssetPath = AssetDatabase.GetAssetPath(projectConfig.systemSplashScreen); if (Path.GetExtension(splashScreenAssetPath).ToLower() != ".png") { throw new BuildFailedException("Invalid file format of System Splash Screen. It has to be a PNG file to be used by the Quest OS. The asset path: " + splashScreenAssetPath); } else { string sourcePath = splashScreenAssetPath; string targetFolder = Path.Combine(path, "src/main/assets"); string targetPath = targetFolder + "/vr_splash.png"; UnityEngine.Debug.LogFormat("Copy splash screen asset from {0} to {1}", sourcePath, targetPath); try { File.Copy(sourcePath, targetPath, true); } catch (Exception e) { throw new BuildFailedException(e.Message); } } } PatchAndroidManifest(path); }
public void PatchAndroidManifest(string path) { string manifestFolder = Path.Combine(path, "src/main"); string file = manifestFolder + "/AndroidManifest.xml"; bool patchedSecurityConfig = false; // If Enable NSC Config, copy XML file into gradle project OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig(); if (projectConfig != null) { if (projectConfig.enableNSCConfig) { // If no custom xml security path is specified, look for the default location in the integrations package. string securityConfigFile = projectConfig.securityXmlPath; if (string.IsNullOrEmpty(securityConfigFile)) { securityConfigFile = GetOculusProjectNetworkSecConfigPath(); } else { Uri configUri = new Uri(Path.GetFullPath(securityConfigFile)); Uri projectUri = new Uri(Application.dataPath); Uri relativeUri = projectUri.MakeRelativeUri(configUri); securityConfigFile = relativeUri.ToString(); } string xmlDirectory = Path.Combine(path, "src/main/res/xml"); try { if (!Directory.Exists(xmlDirectory)) { Directory.CreateDirectory(xmlDirectory); } File.Copy(securityConfigFile, Path.Combine(xmlDirectory, "network_sec_config.xml"), true); patchedSecurityConfig = true; } catch (Exception e) { UnityEngine.Debug.LogError(e.Message); } } } OVRManifestPreprocessor.PatchAndroidManifest(file, enableSecurity: patchedSecurityConfig); }
public void OnProcessShader( Shader shader, ShaderSnippetData snippet, IList <ShaderCompilerData> shaderCompilerData) { var projectConfig = OVRProjectConfig.GetProjectConfig(); if (projectConfig == null) { return; } if (!projectConfig.skipUnneededShaders) { return; } if (EditorUserBuildSettings.activeBuildTarget != BuildTarget.Android) { return; } var strippedGraphicsTiers = new HashSet <GraphicsTier>(); // Unity only uses shader Tier2 on Quest and Go (regardless of graphics API) if (projectConfig.targetDeviceTypes.Contains(OVRProjectConfig.DeviceType.GearVrOrGo) || projectConfig.targetDeviceTypes.Contains(OVRProjectConfig.DeviceType.Quest)) { strippedGraphicsTiers.Add(GraphicsTier.Tier1); strippedGraphicsTiers.Add(GraphicsTier.Tier3); } if (strippedGraphicsTiers.Count == 0) { return; } for (int i = shaderCompilerData.Count - 1; i >= 0; --i) { if (strippedGraphicsTiers.Contains(shaderCompilerData[i].graphicsTier)) { shaderCompilerData.RemoveAt(i); } } }
private void SetOVRProjectConfig(TargetPlatform targetPlatform) { #if UNITY_ANDROID var targetDeviceTypes = new List <OVRProjectConfig.DeviceType>(); if (targetPlatform == TargetPlatform.Quest && !OVRDeviceSelector.isTargetDeviceQuest) { targetDeviceTypes.Add(OVRProjectConfig.DeviceType.Quest); } else if (targetPlatform == TargetPlatform.OculusGoGearVR && !OVRDeviceSelector.isTargetDeviceGearVrOrGo) { targetDeviceTypes.Add(OVRProjectConfig.DeviceType.GearVrOrGo); } if (targetDeviceTypes.Count != 0) { OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig(); projectConfig.targetDeviceTypes = targetDeviceTypes; OVRProjectConfig.CommitProjectConfig(projectConfig); } #endif }
private static void ApplyRequiredManfiestTags(XmlDocument doc, string androidNamespaceURI, bool modifyIfFound, bool enableSecurity) { OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig(); AddOrRemoveTag(doc, androidNamespaceURI, "/manifest/application/activity/intent-filter", "category", "android.intent.category.LEANBACK_LAUNCHER", required: false, modifyIfFound: true); // always remove leanback launcher // First add or remove headtracking flag if targeting Quest AddOrRemoveTag(doc, androidNamespaceURI, "/manifest", "uses-feature", "android.hardware.vr.headtracking", OVRDeviceSelector.isTargetDeviceQuestFamily, true, "version", "1", "required", OVRProjectConfig.GetProjectConfig().allowOptional3DofHeadTracking ? "false" : "true"); // make sure android label and icon are set in the manifest AddOrRemoveTag(doc, androidNamespaceURI, "/manifest", "application", null, true, modifyIfFound, "label", "@string/app_name", "icon", "@mipmap/app_icon", // Disable allowBackup in manifest and add Android NSC XML file "allowBackup", projectConfig.disableBackups ? "false" : "true", "networkSecurityConfig", projectConfig.enableNSCConfig && enableSecurity ? "@xml/network_sec_config" : null ); }
override public void OnInspectorGUI() { #if UNITY_ANDROID EditorGUILayout.LabelField("Target Devices"); EditorGUI.indentLevel++; OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig(); List <OVRProjectConfig.DeviceType> oldTargetDeviceTypes = projectConfig.targetDeviceTypes; List <OVRProjectConfig.DeviceType> targetDeviceTypes = new List <OVRProjectConfig.DeviceType>(oldTargetDeviceTypes); bool hasModified = false; int newCount = Mathf.Max(0, EditorGUILayout.IntField("Size", targetDeviceTypes.Count)); while (newCount < targetDeviceTypes.Count) { targetDeviceTypes.RemoveAt(targetDeviceTypes.Count - 1); hasModified = true; } while (newCount > targetDeviceTypes.Count) { targetDeviceTypes.Add(OVRProjectConfig.DeviceType.GearVrOrGo); hasModified = true; } for (int i = 0; i < targetDeviceTypes.Count; i++) { var deviceType = (OVRProjectConfig.DeviceType)EditorGUILayout.EnumPopup(string.Format("Element {0}", i), targetDeviceTypes[i]); if (deviceType != targetDeviceTypes[i]) { targetDeviceTypes[i] = deviceType; hasModified = true; } } if (hasModified) { projectConfig.targetDeviceTypes = targetDeviceTypes; OVRProjectConfig.CommitProjectConfig(projectConfig); } EditorGUI.indentLevel--; EditorGUILayout.Space(); #endif DrawDefaultInspector(); #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN OVRManager manager = (OVRManager)target; EditorGUILayout.Space(); EditorGUILayout.LabelField("Mixed Reality Capture", EditorStyles.boldLabel); SetupBoolField("Show Properties", ref manager.expandMixedRealityCapturePropertySheet); if (manager.expandMixedRealityCapturePropertySheet) { string[] layerMaskOptions = new string[32]; for (int i = 0; i < 32; ++i) { layerMaskOptions[i] = LayerMask.LayerToName(i); if (layerMaskOptions[i].Length == 0) { layerMaskOptions[i] = "<Layer " + i.ToString() + ">"; } } EditorGUI.indentLevel++; EditorGUILayout.Space(); SetupBoolField("enableMixedReality", ref manager.enableMixedReality); SetupCompositoinMethodField("compositionMethod", ref manager.compositionMethod); SetupLayerMaskField("extraHiddenLayers", ref manager.extraHiddenLayers, layerMaskOptions); if (manager.compositionMethod == OVRManager.CompositionMethod.Direct || manager.compositionMethod == OVRManager.CompositionMethod.Sandwich) { EditorGUILayout.Space(); if (manager.compositionMethod == OVRManager.CompositionMethod.Direct) { EditorGUILayout.LabelField("Direct Composition", EditorStyles.boldLabel); } else { EditorGUILayout.LabelField("Sandwich Composition", EditorStyles.boldLabel); } EditorGUI.indentLevel++; EditorGUILayout.Space(); EditorGUILayout.LabelField("Camera", EditorStyles.boldLabel); SetupCameraDeviceField("capturingCameraDevice", ref manager.capturingCameraDevice); SetupBoolField("flipCameraFrameHorizontally", ref manager.flipCameraFrameHorizontally); SetupBoolField("flipCameraFrameVertically", ref manager.flipCameraFrameVertically); EditorGUILayout.Space(); EditorGUILayout.LabelField("Chroma Key", EditorStyles.boldLabel); SetupColorField("chromaKeyColor", ref manager.chromaKeyColor); SetupFloatField("chromaKeySimilarity", ref manager.chromaKeySimilarity); SetupFloatField("chromaKeySmoothRange", ref manager.chromaKeySmoothRange); SetupFloatField("chromaKeySpillRange", ref manager.chromaKeySpillRange); EditorGUILayout.Space(); EditorGUILayout.LabelField("Dynamic Lighting", EditorStyles.boldLabel); SetupBoolField("useDynamicLighting", ref manager.useDynamicLighting); SetupDepthQualityField("depthQuality", ref manager.depthQuality); SetupFloatField("dynamicLightingSmoothFactor", ref manager.dynamicLightingSmoothFactor); SetupFloatField("dynamicLightingDepthVariationClampingValue", ref manager.dynamicLightingDepthVariationClampingValue); EditorGUILayout.Space(); EditorGUILayout.LabelField("Virtual Green Screen", EditorStyles.boldLabel); SetupVirtualGreenTypeField("virtualGreenScreenType", ref manager.virtualGreenScreenType); SetupFloatField("virtualGreenScreenTopY", ref manager.virtualGreenScreenTopY); SetupFloatField("virtualGreenScreenBottomY", ref manager.virtualGreenScreenBottomY); SetupBoolField("virtualGreenScreenApplyDepthCulling", ref manager.virtualGreenScreenApplyDepthCulling); SetupFloatField("virtualGreenScreenDepthTolerance", ref manager.virtualGreenScreenDepthTolerance); EditorGUILayout.Space(); EditorGUILayout.LabelField("Latency Control", EditorStyles.boldLabel); SetupFloatField("handPoseStateLatency", ref manager.handPoseStateLatency); if (manager.compositionMethod == OVRManager.CompositionMethod.Sandwich) { SetupFloatField("sandwichCompositionRenderLatency", ref manager.sandwichCompositionRenderLatency); SetupIntField("sandwichCompositionBufferedFrames", ref manager.sandwichCompositionBufferedFrames); } EditorGUI.indentLevel--; } EditorGUI.indentLevel--; } #endif }
override public void OnInspectorGUI() { #if UNITY_ANDROID OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig(); OVRProjectConfigEditor.DrawTargetDeviceInspector(projectConfig); EditorGUILayout.Space(); #endif DrawDefaultInspector(); #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_ANDROID OVRManager manager = (OVRManager)target; #endif bool modified = false; #if UNITY_ANDROID EditorGUILayout.Space(); OVRProjectConfigEditor.DrawProjectConfigInspector(projectConfig); EditorGUILayout.Space(); EditorGUILayout.LabelField("Mixed Reality Capture for Quest (experimental)", EditorStyles.boldLabel); EditorGUI.indentLevel++; OVREditorUtil.SetupEnumField(target, "ActivationMode", ref manager.mrcActivationMode, ref modified); EditorGUI.indentLevel--; #endif #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN EditorGUILayout.Space(); EditorGUILayout.LabelField("Mixed Reality Capture", EditorStyles.boldLabel); OVREditorUtil.SetupBoolField(target, "Show Properties", ref manager.expandMixedRealityCapturePropertySheet, ref modified); if (manager.expandMixedRealityCapturePropertySheet) { string[] layerMaskOptions = new string[32]; for (int i = 0; i < 32; ++i) { layerMaskOptions[i] = LayerMask.LayerToName(i); if (layerMaskOptions[i].Length == 0) { layerMaskOptions[i] = "<Layer " + i.ToString() + ">"; } } EditorGUI.indentLevel++; EditorGUILayout.Space(); OVREditorUtil.SetupBoolField(target, "enableMixedReality", ref manager.enableMixedReality, ref modified); OVREditorUtil.SetupEnumField(target, "compositionMethod", ref manager.compositionMethod, ref modified); OVREditorUtil.SetupLayerMaskField(target, "extraHiddenLayers", ref manager.extraHiddenLayers, layerMaskOptions, ref modified); if (manager.compositionMethod == OVRManager.CompositionMethod.External) { EditorGUILayout.Space(); EditorGUILayout.LabelField("External Composition", EditorStyles.boldLabel); EditorGUI.indentLevel++; OVREditorUtil.SetupColorField(target, "backdropColor (target, Rift)", ref manager.externalCompositionBackdropColorRift, ref modified); OVREditorUtil.SetupColorField(target, "backdropColor (target, Quest)", ref manager.externalCompositionBackdropColorQuest, ref modified); } if (manager.compositionMethod == OVRManager.CompositionMethod.Direct) { EditorGUILayout.Space(); EditorGUILayout.LabelField("Direct Composition", EditorStyles.boldLabel); EditorGUI.indentLevel++; EditorGUILayout.Space(); EditorGUILayout.LabelField("Camera", EditorStyles.boldLabel); OVREditorUtil.SetupEnumField(target, "capturingCameraDevice", ref manager.capturingCameraDevice, ref modified); OVREditorUtil.SetupBoolField(target, "flipCameraFrameHorizontally", ref manager.flipCameraFrameHorizontally, ref modified); OVREditorUtil.SetupBoolField(target, "flipCameraFrameVertically", ref manager.flipCameraFrameVertically, ref modified); EditorGUILayout.Space(); EditorGUILayout.LabelField("Chroma Key", EditorStyles.boldLabel); OVREditorUtil.SetupColorField(target, "chromaKeyColor", ref manager.chromaKeyColor, ref modified); OVREditorUtil.SetupFloatField(target, "chromaKeySimilarity", ref manager.chromaKeySimilarity, ref modified); OVREditorUtil.SetupFloatField(target, "chromaKeySmoothRange", ref manager.chromaKeySmoothRange, ref modified); OVREditorUtil.SetupFloatField(target, "chromaKeySpillRange", ref manager.chromaKeySpillRange, ref modified); EditorGUILayout.Space(); EditorGUILayout.LabelField("Dynamic Lighting", EditorStyles.boldLabel); OVREditorUtil.SetupBoolField(target, "useDynamicLighting", ref manager.useDynamicLighting, ref modified); OVREditorUtil.SetupEnumField(target, "depthQuality", ref manager.depthQuality, ref modified); OVREditorUtil.SetupFloatField(target, "dynamicLightingSmoothFactor", ref manager.dynamicLightingSmoothFactor, ref modified); OVREditorUtil.SetupFloatField(target, "dynamicLightingDepthVariationClampingValue", ref manager.dynamicLightingDepthVariationClampingValue, ref modified); EditorGUILayout.Space(); EditorGUILayout.LabelField("Virtual Green Screen", EditorStyles.boldLabel); OVREditorUtil.SetupEnumField(target, "virtualGreenScreenType", ref manager.virtualGreenScreenType, ref modified); OVREditorUtil.SetupFloatField(target, "virtualGreenScreenTopY", ref manager.virtualGreenScreenTopY, ref modified); OVREditorUtil.SetupFloatField(target, "virtualGreenScreenBottomY", ref manager.virtualGreenScreenBottomY, ref modified); OVREditorUtil.SetupBoolField(target, "virtualGreenScreenApplyDepthCulling", ref manager.virtualGreenScreenApplyDepthCulling, ref modified); OVREditorUtil.SetupFloatField(target, "virtualGreenScreenDepthTolerance", ref manager.virtualGreenScreenDepthTolerance, ref modified); EditorGUILayout.Space(); EditorGUILayout.LabelField("Latency Control", EditorStyles.boldLabel); OVREditorUtil.SetupFloatField(target, "handPoseStateLatency", ref manager.handPoseStateLatency, ref modified); EditorGUI.indentLevel--; } EditorGUI.indentLevel--; } #endif if (modified) { EditorUtility.SetDirty(target); } }
override public void OnInspectorGUI() { OVRRuntimeSettings runtimeSettings = OVRRuntimeSettings.GetRuntimeSettings(); #if UNITY_ANDROID OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig(); OVRProjectConfigEditor.DrawTargetDeviceInspector(projectConfig); EditorGUILayout.Space(); #endif DrawDefaultInspector(); bool modified = false; #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_ANDROID OVRManager manager = (OVRManager)target; EditorGUILayout.Space(); EditorGUILayout.LabelField("Display", EditorStyles.boldLabel); OVRManager.ColorSpace colorGamut = runtimeSettings.colorSpace; OVREditorUtil.SetupEnumField(target, new GUIContent("Color Gamut", "The target color gamut when displayed on the HMD"), ref colorGamut, ref modified, "https://developer.oculus.com/documentation/unity/unity-color-space/"); manager.colorGamut = colorGamut; if (modified) { runtimeSettings.colorSpace = colorGamut; OVRRuntimeSettings.CommitRuntimeSettings(runtimeSettings); } #endif #if UNITY_ANDROID EditorGUILayout.Space(); OVRProjectConfigEditor.DrawProjectConfigInspector(projectConfig); EditorGUILayout.Space(); EditorGUILayout.LabelField("Mixed Reality Capture for Quest", EditorStyles.boldLabel); EditorGUI.indentLevel++; OVREditorUtil.SetupEnumField(target, "ActivationMode", ref manager.mrcActivationMode, ref modified); EditorGUI.indentLevel--; #endif #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); manager.expandMixedRealityCapturePropertySheet = EditorGUILayout.BeginFoldoutHeaderGroup(manager.expandMixedRealityCapturePropertySheet, "Mixed Reality Capture"); OVREditorUtil.DisplayDocLink("https://developer.oculus.com/documentation/unity/unity-mrc/"); EditorGUILayout.EndHorizontal(); if (manager.expandMixedRealityCapturePropertySheet) { string[] layerMaskOptions = new string[32]; for (int i = 0; i < 32; ++i) { layerMaskOptions[i] = LayerMask.LayerToName(i); if (layerMaskOptions[i].Length == 0) { layerMaskOptions[i] = "<Layer " + i.ToString() + ">"; } } EditorGUI.indentLevel++; OVREditorUtil.SetupBoolField(target, "enableMixedReality", ref manager.enableMixedReality, ref modified); OVREditorUtil.SetupEnumField(target, "compositionMethod", ref manager.compositionMethod, ref modified); OVREditorUtil.SetupLayerMaskField(target, "extraHiddenLayers", ref manager.extraHiddenLayers, layerMaskOptions, ref modified); OVREditorUtil.SetupLayerMaskField(target, "extraVisibleLayers", ref manager.extraVisibleLayers, layerMaskOptions, ref modified); OVREditorUtil.SetupBoolField(target, "dynamicCullingMask", ref manager.dynamicCullingMask, ref modified); if (manager.compositionMethod == OVRManager.CompositionMethod.External) { EditorGUILayout.Space(); EditorGUILayout.LabelField("External Composition", EditorStyles.boldLabel); EditorGUI.indentLevel++; OVREditorUtil.SetupColorField(target, "backdropColor (target, Rift)", ref manager.externalCompositionBackdropColorRift, ref modified); OVREditorUtil.SetupColorField(target, "backdropColor (target, Quest)", ref manager.externalCompositionBackdropColorQuest, ref modified); EditorGUI.indentLevel--; } if (manager.compositionMethod == OVRManager.CompositionMethod.Direct) { EditorGUILayout.Space(); EditorGUILayout.LabelField("Direct Composition", EditorStyles.boldLabel); EditorGUI.indentLevel++; EditorGUILayout.Space(); EditorGUILayout.LabelField("Camera", EditorStyles.boldLabel); OVREditorUtil.SetupEnumField(target, "capturingCameraDevice", ref manager.capturingCameraDevice, ref modified); OVREditorUtil.SetupBoolField(target, "flipCameraFrameHorizontally", ref manager.flipCameraFrameHorizontally, ref modified); OVREditorUtil.SetupBoolField(target, "flipCameraFrameVertically", ref manager.flipCameraFrameVertically, ref modified); EditorGUILayout.Space(); EditorGUILayout.LabelField("Chroma Key", EditorStyles.boldLabel); OVREditorUtil.SetupColorField(target, "chromaKeyColor", ref manager.chromaKeyColor, ref modified); OVREditorUtil.SetupFloatField(target, "chromaKeySimilarity", ref manager.chromaKeySimilarity, ref modified); OVREditorUtil.SetupFloatField(target, "chromaKeySmoothRange", ref manager.chromaKeySmoothRange, ref modified); OVREditorUtil.SetupFloatField(target, "chromaKeySpillRange", ref manager.chromaKeySpillRange, ref modified); EditorGUILayout.Space(); EditorGUILayout.LabelField("Dynamic Lighting", EditorStyles.boldLabel); OVREditorUtil.SetupBoolField(target, "useDynamicLighting", ref manager.useDynamicLighting, ref modified); OVREditorUtil.SetupEnumField(target, "depthQuality", ref manager.depthQuality, ref modified); OVREditorUtil.SetupFloatField(target, "dynamicLightingSmoothFactor", ref manager.dynamicLightingSmoothFactor, ref modified); OVREditorUtil.SetupFloatField(target, "dynamicLightingDepthVariationClampingValue", ref manager.dynamicLightingDepthVariationClampingValue, ref modified); EditorGUILayout.Space(); EditorGUILayout.LabelField("Virtual Green Screen", EditorStyles.boldLabel); OVREditorUtil.SetupEnumField(target, "virtualGreenScreenType", ref manager.virtualGreenScreenType, ref modified); OVREditorUtil.SetupFloatField(target, "virtualGreenScreenTopY", ref manager.virtualGreenScreenTopY, ref modified); OVREditorUtil.SetupFloatField(target, "virtualGreenScreenBottomY", ref manager.virtualGreenScreenBottomY, ref modified); OVREditorUtil.SetupBoolField(target, "virtualGreenScreenApplyDepthCulling", ref manager.virtualGreenScreenApplyDepthCulling, ref modified); OVREditorUtil.SetupFloatField(target, "virtualGreenScreenDepthTolerance", ref manager.virtualGreenScreenDepthTolerance, ref modified); EditorGUILayout.Space(); EditorGUILayout.LabelField("Latency Control", EditorStyles.boldLabel); OVREditorUtil.SetupFloatField(target, "handPoseStateLatency", ref manager.handPoseStateLatency, ref modified); EditorGUI.indentLevel--; } EditorGUI.indentLevel--; } #endif #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_ANDROID // Insight Passthrough section #if UNITY_ANDROID bool passthroughCapabilityEnabled = projectConfig.insightPassthroughEnabled; EditorGUI.BeginDisabledGroup(!passthroughCapabilityEnabled); GUIContent enablePassthroughContent = new GUIContent("Enable Passthrough", "Enables passthrough functionality for the scene. Can be toggled at runtime. Passthrough Capability must be enabled in the project settings."); #else GUIContent enablePassthroughContent = new GUIContent("Enable Passthrough", "Enables passthrough functionality for the scene. Can be toggled at runtime."); #endif EditorGUILayout.Space(); EditorGUILayout.LabelField("Insight Passthrough", EditorStyles.boldLabel); #if UNITY_ANDROID if (!passthroughCapabilityEnabled) { EditorGUILayout.LabelField("Requires Passthrough Capability to be enabled in the General section of the Quest features.", EditorStyles.wordWrappedLabel); } #endif OVREditorUtil.SetupBoolField(target, enablePassthroughContent, ref manager.isInsightPassthroughEnabled, ref modified); #if UNITY_ANDROID EditorGUI.EndDisabledGroup(); #endif #endif if (modified) { EditorUtility.SetDirty(target); } }
override public void OnInspectorGUI() { #if UNITY_ANDROID OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig(); bool hasModified = false; // Target Devices EditorGUILayout.LabelField("Target Devices"); EditorGUI.indentLevel++; List <OVRProjectConfig.DeviceType> oldTargetDeviceTypes = projectConfig.targetDeviceTypes; List <OVRProjectConfig.DeviceType> targetDeviceTypes = new List <OVRProjectConfig.DeviceType>(oldTargetDeviceTypes); int newCount = Mathf.Max(0, EditorGUILayout.IntField("Size", targetDeviceTypes.Count)); while (newCount < targetDeviceTypes.Count) { targetDeviceTypes.RemoveAt(targetDeviceTypes.Count - 1); hasModified = true; } while (newCount > targetDeviceTypes.Count) { targetDeviceTypes.Add(OVRProjectConfig.DeviceType.Quest); hasModified = true; } for (int i = 0; i < targetDeviceTypes.Count; i++) { var deviceType = (OVRProjectConfig.DeviceType)EditorGUILayout.EnumPopup(string.Format("Element {0}", i), targetDeviceTypes[i]); if (deviceType != targetDeviceTypes[i]) { targetDeviceTypes[i] = deviceType; hasModified = true; } } if (hasModified) { projectConfig.targetDeviceTypes = targetDeviceTypes; } EditorGUI.indentLevel--; EditorGUILayout.Space(); // Hand Tracking Support EditorGUI.BeginDisabledGroup(!targetDeviceTypes.Contains(OVRProjectConfig.DeviceType.Quest)); EditorGUILayout.LabelField("Input", EditorStyles.boldLabel); OVRProjectConfig.HandTrackingSupport oldHandTrackingSupport = projectConfig.handTrackingSupport; OVRProjectConfig.HandTrackingSupport newHandTrackingSupport = (OVRProjectConfig.HandTrackingSupport)EditorGUILayout.EnumPopup( "Hand Tracking Support", oldHandTrackingSupport); if (newHandTrackingSupport != oldHandTrackingSupport) { projectConfig.handTrackingSupport = newHandTrackingSupport; hasModified = true; } EditorGUILayout.Space(); EditorGUI.EndDisabledGroup(); // apply any pending changes to project config if (hasModified) { OVRProjectConfig.CommitProjectConfig(projectConfig); } #endif DrawDefaultInspector(); #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_ANDROID OVRManager manager = (OVRManager)target; #endif #if UNITY_ANDROID EditorGUILayout.Space(); EditorGUILayout.LabelField("Security", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); bool disableBackups = projectConfig.disableBackups; bool enableNSCConfig = projectConfig.enableNSCConfig; SetupBoolField("Disable Backups", ref disableBackups); SetupBoolField("Enable NSC Configuration", ref enableNSCConfig); if (EditorGUI.EndChangeCheck()) { projectConfig.disableBackups = disableBackups; projectConfig.enableNSCConfig = enableNSCConfig; OVRProjectConfig.CommitProjectConfig(projectConfig); } EditorGUILayout.Space(); EditorGUILayout.LabelField("Mixed Reality Capture for Quest (experimental)", EditorStyles.boldLabel); EditorGUI.indentLevel++; SetupMrcActivationModeField("ActivationMode", ref manager.mrcActivationMode); EditorGUI.indentLevel--; #endif #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN EditorGUILayout.Space(); EditorGUILayout.LabelField("Mixed Reality Capture", EditorStyles.boldLabel); SetupBoolField("Show Properties", ref manager.expandMixedRealityCapturePropertySheet); if (manager.expandMixedRealityCapturePropertySheet) { string[] layerMaskOptions = new string[32]; for (int i = 0; i < 32; ++i) { layerMaskOptions[i] = LayerMask.LayerToName(i); if (layerMaskOptions[i].Length == 0) { layerMaskOptions[i] = "<Layer " + i.ToString() + ">"; } } EditorGUI.indentLevel++; EditorGUILayout.Space(); SetupBoolField("enableMixedReality", ref manager.enableMixedReality); SetupCompositoinMethodField("compositionMethod", ref manager.compositionMethod); SetupLayerMaskField("extraHiddenLayers", ref manager.extraHiddenLayers, layerMaskOptions); if (manager.compositionMethod == OVRManager.CompositionMethod.External) { EditorGUILayout.Space(); EditorGUILayout.LabelField("External Composition", EditorStyles.boldLabel); EditorGUI.indentLevel++; SetupColorField("backdropColor (Rift)", ref manager.externalCompositionBackdropColorRift); SetupColorField("backdropColor (Quest)", ref manager.externalCompositionBackdropColorQuest); } if (manager.compositionMethod == OVRManager.CompositionMethod.Direct) { EditorGUILayout.Space(); EditorGUILayout.LabelField("Direct Composition", EditorStyles.boldLabel); EditorGUI.indentLevel++; EditorGUILayout.Space(); EditorGUILayout.LabelField("Camera", EditorStyles.boldLabel); SetupCameraDeviceField("capturingCameraDevice", ref manager.capturingCameraDevice); SetupBoolField("flipCameraFrameHorizontally", ref manager.flipCameraFrameHorizontally); SetupBoolField("flipCameraFrameVertically", ref manager.flipCameraFrameVertically); EditorGUILayout.Space(); EditorGUILayout.LabelField("Chroma Key", EditorStyles.boldLabel); SetupColorField("chromaKeyColor", ref manager.chromaKeyColor); SetupFloatField("chromaKeySimilarity", ref manager.chromaKeySimilarity); SetupFloatField("chromaKeySmoothRange", ref manager.chromaKeySmoothRange); SetupFloatField("chromaKeySpillRange", ref manager.chromaKeySpillRange); EditorGUILayout.Space(); EditorGUILayout.LabelField("Dynamic Lighting", EditorStyles.boldLabel); SetupBoolField("useDynamicLighting", ref manager.useDynamicLighting); SetupDepthQualityField("depthQuality", ref manager.depthQuality); SetupFloatField("dynamicLightingSmoothFactor", ref manager.dynamicLightingSmoothFactor); SetupFloatField("dynamicLightingDepthVariationClampingValue", ref manager.dynamicLightingDepthVariationClampingValue); EditorGUILayout.Space(); EditorGUILayout.LabelField("Virtual Green Screen", EditorStyles.boldLabel); SetupVirtualGreenTypeField("virtualGreenScreenType", ref manager.virtualGreenScreenType); SetupFloatField("virtualGreenScreenTopY", ref manager.virtualGreenScreenTopY); SetupFloatField("virtualGreenScreenBottomY", ref manager.virtualGreenScreenBottomY); SetupBoolField("virtualGreenScreenApplyDepthCulling", ref manager.virtualGreenScreenApplyDepthCulling); SetupFloatField("virtualGreenScreenDepthTolerance", ref manager.virtualGreenScreenDepthTolerance); EditorGUILayout.Space(); EditorGUILayout.LabelField("Latency Control", EditorStyles.boldLabel); SetupFloatField("handPoseStateLatency", ref manager.handPoseStateLatency); EditorGUI.indentLevel--; } EditorGUI.indentLevel--; } #endif }
public static void PatchAndroidManifest(string sourceFile, string destinationFile = null, bool skipExistingAttributes = true, bool enableSecurity = false) { if (destinationFile == null) { destinationFile = sourceFile; } bool modifyIfFound = !skipExistingAttributes; try { OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig(); // Load android manfiest file XmlDocument doc = new XmlDocument(); doc.Load(sourceFile); string androidNamepsaceURI; XmlElement element = (XmlElement)doc.SelectSingleNode("/manifest"); if (element == null) { UnityEngine.Debug.LogError("Could not find manifest tag in android manifest."); return; } // Get android namespace URI from the manifest androidNamepsaceURI = element.GetAttribute("xmlns:android"); if (string.IsNullOrEmpty(androidNamepsaceURI)) { UnityEngine.Debug.LogError("Could not find Android Namespace in manifest."); return; } // remove launcher and leanback launcher AddOrRemoveTag(doc, androidNamepsaceURI, "/manifest/application/activity/intent-filter", "category", "android.intent.category.LAUNCHER", required: false, modifyIfFound: true); // always remove launcher AddOrRemoveTag(doc, androidNamepsaceURI, "/manifest/application/activity/intent-filter", "category", "android.intent.category.LEANBACK_LAUNCHER", required: false, modifyIfFound: true); // always remove leanback launcher // add info category AddOrRemoveTag(doc, androidNamepsaceURI, "/manifest/application/activity/intent-filter", "category", "android.intent.category.INFO", required: true, modifyIfFound: true); // always add info launcher // First add or remove headtracking flag if targeting Quest AddOrRemoveTag(doc, androidNamepsaceURI, "/manifest", "uses-feature", "android.hardware.vr.headtracking", OVRDeviceSelector.isTargetDeviceQuestFamily, true, "version", "1", "required", "true"); // If Quest is the target device, add the handtracking manifest tags if needed // Mapping of project setting to manifest setting: // OVRProjectConfig.HandTrackingSupport.ControllersOnly => manifest entry not present // OVRProjectConfig.HandTrackingSupport.ControllersAndHands => manifest entry present and required=false // OVRProjectConfig.HandTrackingSupport.HandsOnly => manifest entry present and required=true OVRProjectConfig.HandTrackingSupport targetHandTrackingSupport = OVRProjectConfig.GetProjectConfig().handTrackingSupport; bool handTrackingEntryNeeded = OVRDeviceSelector.isTargetDeviceQuestFamily && (targetHandTrackingSupport != OVRProjectConfig.HandTrackingSupport.ControllersOnly); AddOrRemoveTag(doc, androidNamepsaceURI, "/manifest", "uses-feature", "oculus.software.handtracking", handTrackingEntryNeeded, modifyIfFound, "required", (targetHandTrackingSupport == OVRProjectConfig.HandTrackingSupport.HandsOnly) ? "true" : "false"); AddOrRemoveTag(doc, androidNamepsaceURI, "/manifest", "uses-permission", "com.oculus.permission.HAND_TRACKING", handTrackingEntryNeeded, modifyIfFound); // Add focus aware tag if this app is targeting Quest Family AddOrRemoveTag(doc, androidNamepsaceURI, "/manifest/application/activity", "meta-data", "com.oculus.vr.focusaware", OVRDeviceSelector.isTargetDeviceQuestFamily, modifyIfFound, "value", projectConfig.focusAware ? "true" : "false"); // Add support devices manifest according to the target devices if (OVRDeviceSelector.isTargetDeviceQuestFamily) { string targetDeviceValue = "quest"; if (OVRDeviceSelector.isTargetDeviceQuest && OVRDeviceSelector.isTargetDeviceQuest2) { targetDeviceValue = "quest|quest2"; } else if (OVRDeviceSelector.isTargetDeviceQuest2) { targetDeviceValue = "quest2"; } else if (OVRDeviceSelector.isTargetDeviceQuest) { targetDeviceValue = "quest"; } else { Debug.LogError("Unexpected target devices"); } AddOrRemoveTag(doc, androidNamepsaceURI, "/manifest/application", "meta-data", "com.oculus.supportedDevices", true, modifyIfFound, "value", targetDeviceValue); } // Add system keyboard tag AddOrRemoveTag(doc, androidNamepsaceURI, "/manifest", "uses-feature", "oculus.software.overlay_keyboard", projectConfig.focusAware && projectConfig.requiresSystemKeyboard, modifyIfFound, "required", "false"); // make sure the VR Mode tag is set in the manifest AddOrRemoveTag(doc, androidNamepsaceURI, "/manifest/application", "meta-data", "com.samsung.android.vr.application.mode", true, modifyIfFound, "value", "vr_only"); // make sure android label and icon are set in the manifest AddOrRemoveTag(doc, androidNamepsaceURI, "/manifest", "application", null, true, modifyIfFound, "label", "@string/app_name", "icon", "@mipmap/app_icon", // Disable allowBackup in manifest and add Android NSC XML file "allowBackup", projectConfig.disableBackups ? "false" : "true", "networkSecurityConfig", projectConfig.enableNSCConfig && enableSecurity ? "@xml/network_sec_config" : null ); doc.Save(destinationFile); } catch (System.Exception e) { UnityEngine.Debug.LogException(e); } }
public static void GenerateManifestForSubmission() { var so = ScriptableObject.CreateInstance(typeof(OVRPluginUpdaterStub)); var script = MonoScript.FromScriptableObject(so); string assetPath = AssetDatabase.GetAssetPath(script); string editorDir = Directory.GetParent(assetPath).FullName; string srcFile = editorDir + "/AndroidManifest.OVRSubmission.xml"; if (!File.Exists(srcFile)) { Debug.LogError("Cannot find Android manifest template for submission." + " Please delete the OVR folder and reimport the Oculus Utilities."); return; } string manifestFolder = Application.dataPath + "/Plugins/Android"; if (!Directory.Exists(manifestFolder)) { Directory.CreateDirectory(manifestFolder); } string dstFile = manifestFolder + "/AndroidManifest.xml"; if (File.Exists(dstFile)) { Debug.LogWarning("Cannot create Oculus store-compatible manifest due to conflicting file: \"" + dstFile + "\". Please remove it and try again."); return; } string manifestText = File.ReadAllText(srcFile); int dofTextIndex = manifestText.IndexOf("<!-- Request the headset DoF mode -->"); if (dofTextIndex != -1) { if (OVRDeviceSelector.isTargetDeviceQuest) { string headTrackingFeatureText = string.Format("<uses-feature android:name=\"android.hardware.vr.headtracking\" android:version=\"1\" android:required=\"{0}\" />", OVRDeviceSelector.isTargetDeviceGearVrOrGo ? "false" : "true"); manifestText = manifestText.Insert(dofTextIndex, headTrackingFeatureText); } } else { Debug.LogWarning("Manifest error: unable to locate headset DoF mode"); } int handTrackingTextIndex = manifestText.IndexOf("<!-- Request the headset handtracking mode -->"); if (handTrackingTextIndex != -1) { if (OVRDeviceSelector.isTargetDeviceQuest) { OVRProjectConfig.HandTrackingSupport targetHandTrackingSupport = OVRProjectConfig.GetProjectConfig().handTrackingSupport; bool handTrackingEntryNeeded = (targetHandTrackingSupport != OVRProjectConfig.HandTrackingSupport.ControllersOnly); bool handTrackingRequired = (targetHandTrackingSupport == OVRProjectConfig.HandTrackingSupport.HandsOnly); if (handTrackingEntryNeeded) { string handTrackingFeatureText = string.Format("<uses-feature android:name=\"oculus.software.handtracking\" android:required=\"{0}\" />", handTrackingRequired ? "true" : "false"); string handTrackingPermissionText = string.Format("<uses-permission android:name=\"oculus.permission.handtracking\" />"); manifestText = manifestText.Insert(handTrackingTextIndex, handTrackingPermissionText); manifestText = manifestText.Insert(handTrackingTextIndex, handTrackingFeatureText); } } } else { Debug.LogWarning("Manifest error: unable to locate headset handtracking mode"); } #if !UNITY_2018_2_OR_NEWER int iconLabelText = manifestText.IndexOf("android:icon=\"@mipmap/app_icon\""); if (iconLabelText != -1) { manifestText = manifestText.Replace("android:icon=\"@mipmap/app_icon\"", "android:icon=\"@drawable/app_icon\""); } else { Debug.LogWarning("Manifest error: failed to update icon label for older version of Unity"); } #endif System.IO.File.WriteAllText(dstFile, manifestText); AssetDatabase.Refresh(); }
public void OnPostGenerateGradleAndroidProject(string path) { UnityEngine.Debug.Log("OVRGradleGeneration triggered."); var targetOculusPlatform = new List <string>(); if (OVRDeviceSelector.isTargetDeviceQuestFamily) { targetOculusPlatform.Add("quest"); } OVRPlugin.AddCustomMetadata("target_oculus_platform", String.Join("_", targetOculusPlatform.ToArray())); UnityEngine.Debug.LogFormat("QuestFamily = {0}: Quest = {1}, Quest2 = {2}", OVRDeviceSelector.isTargetDeviceQuestFamily, OVRDeviceSelector.isTargetDeviceQuest, OVRDeviceSelector.isTargetDeviceQuest2); #if UNITY_2019_3_OR_NEWER string gradleBuildPath = Path.Combine(path, "../launcher/build.gradle"); #else string gradleBuildPath = Path.Combine(path, "build.gradle"); #endif bool v2SigningEnabled = true; if (File.Exists(gradleBuildPath)) { try { string gradle = File.ReadAllText(gradleBuildPath); int v2Signingindex = gradle.IndexOf("v2SigningEnabled false"); if (v2Signingindex != -1) { //v2 Signing flag found, ensure the correct value is set based on platform. if (v2SigningEnabled) { gradle = gradle.Replace("v2SigningEnabled false", "v2SigningEnabled true"); System.IO.File.WriteAllText(gradleBuildPath, gradle); } } else { //v2 Signing flag missing, add it right after the key store password and set the value based on platform. int keyPassIndex = gradle.IndexOf("keyPassword"); if (keyPassIndex != -1) { int v2Index = gradle.IndexOf("\n", keyPassIndex) + 1; if (v2Index != -1) { gradle = gradle.Insert(v2Index, "v2SigningEnabled " + (v2SigningEnabled ? "true" : "false") + "\n"); System.IO.File.WriteAllText(gradleBuildPath, gradle); } } } } catch (System.Exception e) { UnityEngine.Debug.LogWarningFormat("Unable to overwrite build.gradle, error {0}", e.Message); } } else { UnityEngine.Debug.LogWarning("Unable to locate build.gradle"); } OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig(); if (projectConfig != null && projectConfig.systemSplashScreen != null) { if (PlayerSettings.virtualRealitySplashScreen != null) { UnityEngine.Debug.LogWarning("Virtual Reality Splash Screen (in Player Settings) is active. It would be displayed after the system splash screen, before the first game frame be rendered."); } string splashScreenAssetPath = AssetDatabase.GetAssetPath(projectConfig.systemSplashScreen); if (Path.GetExtension(splashScreenAssetPath).ToLower() != ".png") { throw new BuildFailedException("Invalid file format of System Splash Screen. It has to be a PNG file to be used by the Quest OS. The asset path: " + splashScreenAssetPath); } else { string sourcePath = splashScreenAssetPath; string targetFolder = Path.Combine(path, "src/main/assets"); string targetPath = targetFolder + "/vr_splash.png"; UnityEngine.Debug.LogFormat("Copy splash screen asset from {0} to {1}", sourcePath, targetPath); try { File.Copy(sourcePath, targetPath); } catch (Exception e) { throw new BuildFailedException(e.Message); } } } PatchAndroidManifest(path); }
public void PatchAndroidManifest(string path) { string manifestFolder = Path.Combine(path, "src/main"); try { // Load android manfiest file XmlDocument doc = new XmlDocument(); doc.Load(manifestFolder + "/AndroidManifest.xml"); string androidNamepsaceURI; XmlElement element = (XmlElement)doc.SelectSingleNode("/manifest"); if (element == null) { UnityEngine.Debug.LogError("Could not find manifest tag in android manifest."); return; } // Get android namespace URI from the manifest androidNamepsaceURI = element.GetAttribute("xmlns:android"); if (!string.IsNullOrEmpty(androidNamepsaceURI)) { // Look for intent filter category and change LAUNCHER to INFO XmlNodeList nodeList = doc.SelectNodes("/manifest/application/activity/intent-filter/category"); foreach (XmlElement e in nodeList) { string attr = e.GetAttribute("name", androidNamepsaceURI); if (attr == "android.intent.category.LAUNCHER") { e.SetAttribute("name", androidNamepsaceURI, "android.intent.category.INFO"); } } //If Quest is the target device, add the headtracking manifest tag if (OVRDeviceSelector.isTargetDeviceQuest) { XmlNodeList manifestUsesFeatureNodes = doc.SelectNodes("/manifest/uses-feature"); bool foundHeadtrackingTag = false; foreach (XmlElement e in manifestUsesFeatureNodes) { string attr = e.GetAttribute("name", androidNamepsaceURI); if (attr == "android.hardware.vr.headtracking") { foundHeadtrackingTag = true; } } //If the tag already exists, don't patch with a new one. If it doesn't, we add it. if (!foundHeadtrackingTag) { XmlNode manifestElement = doc.SelectSingleNode("/manifest"); XmlElement headtrackingTag = doc.CreateElement("uses-feature"); headtrackingTag.SetAttribute("name", androidNamepsaceURI, "android.hardware.vr.headtracking"); headtrackingTag.SetAttribute("version", androidNamepsaceURI, "1"); string tagRequired = OVRDeviceSelector.isTargetDeviceGearVrOrGo ? "false" : "true"; headtrackingTag.SetAttribute("required", androidNamepsaceURI, tagRequired); manifestElement.AppendChild(headtrackingTag); } } // If Quest is the target device, add the handtracking manifest tags if needed // Mapping of project setting to manifest setting: // OVRProjectConfig.HandTrackingSupport.ControllersOnly => manifest entry not present // OVRProjectConfig.HandTrackingSupport.ControllersAndHands => manifest entry present and required=false // OVRProjectConfig.HandTrackingSupport.HandsOnly => manifest entry present and required=true if (OVRDeviceSelector.isTargetDeviceQuest) { OVRProjectConfig.HandTrackingSupport targetHandTrackingSupport = OVRProjectConfig.GetProjectConfig().handTrackingSupport; bool handTrackingEntryNeeded = (targetHandTrackingSupport != OVRProjectConfig.HandTrackingSupport.ControllersOnly); if (handTrackingEntryNeeded) { // uses-feature: <uses-feature android:name="oculus.software.handtracking" android:required="false" /> XmlNodeList manifestUsesFeatureNodes = doc.SelectNodes("/manifest/uses-feature"); bool foundHandTrackingFeature = false; foreach (XmlElement e in manifestUsesFeatureNodes) { string attr = e.GetAttribute("name", androidNamepsaceURI); if (attr == "oculus.software.handtracking") { foundHandTrackingFeature = true; } } //If the tag already exists, don't patch with a new one. If it doesn't, we add it. if (!foundHandTrackingFeature) { XmlNode manifestElement = doc.SelectSingleNode("/manifest"); XmlElement handTrackingFeature = doc.CreateElement("uses-feature"); handTrackingFeature.SetAttribute("name", androidNamepsaceURI, "oculus.software.handtracking"); string tagRequired = (targetHandTrackingSupport == OVRProjectConfig.HandTrackingSupport.HandsOnly) ? "true" : "false"; handTrackingFeature.SetAttribute("required", androidNamepsaceURI, tagRequired); manifestElement.AppendChild(handTrackingFeature); } // uses-permission: <uses-permission android:name="oculus.permission.handtracking" /> XmlNodeList manifestUsesPermissionNodes = doc.SelectNodes("/manifest/uses-permission"); bool foundHandTrackingPermission = false; foreach (XmlElement e in manifestUsesPermissionNodes) { string attr = e.GetAttribute("name", androidNamepsaceURI); if (attr == "oculus.permission.handtracking") { foundHandTrackingPermission = true; } } //If the tag already exists, don't patch with a new one. If it doesn't, we add it. if (!foundHandTrackingPermission) { XmlNode manifestElement = doc.SelectSingleNode("/manifest"); XmlElement handTrackingPermission = doc.CreateElement("uses-permission"); handTrackingPermission.SetAttribute("name", androidNamepsaceURI, "oculus.permission.handtracking"); manifestElement.AppendChild(handTrackingPermission); } } } XmlElement applicationNode = (XmlElement)doc.SelectSingleNode("/manifest/application"); if (applicationNode != null) { // If android label and icon are missing from the xml, add them if (applicationNode.GetAttribute("android:label") == null) { applicationNode.SetAttribute("label", androidNamepsaceURI, "@string/app_name"); } if (applicationNode.GetAttribute("android:icon") == null) { applicationNode.SetAttribute("icon", androidNamepsaceURI, "@mipmap/app_icon"); } // Check for VR tag, if missing, append it bool vrTagFound = false; XmlNodeList appNodeList = applicationNode.ChildNodes; foreach (XmlElement e in appNodeList) { if (e.GetAttribute("android:name") == "com.samsung.android.vr.application.mode") { vrTagFound = true; break; } } if (!vrTagFound) { XmlElement vrTag = doc.CreateElement("meta-data"); vrTag.SetAttribute("name", androidNamepsaceURI, "com.samsung.android.vr.application.mode"); vrTag.SetAttribute("value", androidNamepsaceURI, "vr_only"); applicationNode.AppendChild(vrTag);; } // Disable allowBackup in manifest and add Android NSC XML file OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig(); if (projectConfig != null) { if (projectConfig.disableBackups) { applicationNode.SetAttribute("allowBackup", androidNamepsaceURI, "false"); } if (projectConfig.enableNSCConfig) { applicationNode.SetAttribute("networkSecurityConfig", androidNamepsaceURI, "@xml/network_sec_config"); string securityConfigFile = Path.Combine(Application.dataPath, "Oculus/VR/Editor/network_sec_config.xml"); string xmlDirectory = Path.Combine(path, "src/main/res/xml"); try { if (!Directory.Exists(xmlDirectory)) { Directory.CreateDirectory(xmlDirectory); } File.Copy(securityConfigFile, Path.Combine(xmlDirectory, "network_sec_config.xml"), true); } catch (Exception e) { UnityEngine.Debug.LogError(e.Message); } } } } doc.Save(manifestFolder + "/AndroidManifest.xml"); } } catch (Exception e) { UnityEngine.Debug.LogError(e.Message); } }
private static void ApplyFeatureManfiestTags(XmlDocument doc, string androidNamespaceURI, bool modifyIfFound) { OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig(); OVRRuntimeSettings runtimeSettings = OVRRuntimeSettings.GetRuntimeSettings(); //============================================================================ // Hand Tracking // If Quest is the target device, add the handtracking manifest tags if needed // Mapping of project setting to manifest setting: // OVRProjectConfig.HandTrackingSupport.ControllersOnly => manifest entry not present // OVRProjectConfig.HandTrackingSupport.ControllersAndHands => manifest entry present and required=false // OVRProjectConfig.HandTrackingSupport.HandsOnly => manifest entry present and required=true OVRProjectConfig.HandTrackingSupport targetHandTrackingSupport = OVRProjectConfig.GetProjectConfig().handTrackingSupport; bool handTrackingEntryNeeded = OVRDeviceSelector.isTargetDeviceQuestFamily && (targetHandTrackingSupport != OVRProjectConfig.HandTrackingSupport.ControllersOnly); AddOrRemoveTag(doc, androidNamespaceURI, "/manifest", "uses-feature", "oculus.software.handtracking", handTrackingEntryNeeded, modifyIfFound, "required", (targetHandTrackingSupport == OVRProjectConfig.HandTrackingSupport.HandsOnly) ? "true" : "false"); AddOrRemoveTag(doc, androidNamespaceURI, "/manifest", "uses-permission", "com.oculus.permission.HAND_TRACKING", handTrackingEntryNeeded, modifyIfFound); AddOrRemoveTag(doc, androidNamespaceURI, "/manifest/application", "meta-data", "com.oculus.handtracking.frequency", handTrackingEntryNeeded, modifyIfFound, "value", projectConfig.handTrackingFrequency.ToString()); //============================================================================ // System Keyboard AddOrRemoveTag(doc, androidNamespaceURI, "/manifest", "uses-feature", "oculus.software.overlay_keyboard", projectConfig.requiresSystemKeyboard, modifyIfFound, "required", "false"); //============================================================================ // Experimental Features AddOrRemoveTag(doc, androidNamespaceURI, "/manifest", "uses-feature", "com.oculus.experimental.enabled", projectConfig.experimentalFeaturesEnabled, modifyIfFound, "required", "true"); //============================================================================ // Spatial Anchors OVRProjectConfig.SpatialAnchorsSupport targetSpatialAnchorsSupport = OVRProjectConfig.GetProjectConfig().spatialAnchorsSupport; bool spatialAnchorsEntryNeeded = OVRDeviceSelector.isTargetDeviceQuestFamily && (targetSpatialAnchorsSupport == OVRProjectConfig.SpatialAnchorsSupport.Enabled); AddOrRemoveTag(doc, androidNamespaceURI, "/manifest", "uses-permission", "com.oculus.permission.USE_ANCHOR_API", spatialAnchorsEntryNeeded, modifyIfFound); //============================================================================ // Passthrough AddOrRemoveTag(doc, androidNamespaceURI, "/manifest", "uses-feature", "com.oculus.feature.PASSTHROUGH", projectConfig.insightPassthroughEnabled, modifyIfFound, "required", "true"); //============================================================================ // System Splash Screen if (projectConfig.systemSplashScreen != null) { AddOrRemoveTag(doc, androidNamespaceURI, "/manifest/application", "meta-data", "com.oculus.ossplash", true, modifyIfFound, "value", "true"); AddOrRemoveTag(doc, androidNamespaceURI, "/manifest/application", "meta-data", "com.oculus.ossplash.colorspace", true, modifyIfFound, "value", ColorSpaceToManifestTag(runtimeSettings.colorSpace)); } }
public void PatchAndroidManifest(string path) { string manifestFolder = Path.Combine(path, "src/main"); try { // Load android manfiest file XmlDocument doc = new XmlDocument(); doc.Load(manifestFolder + "/AndroidManifest.xml"); string androidNamepsaceURI; XmlElement element = (XmlElement)doc.SelectSingleNode("/manifest"); if (element == null) { UnityEngine.Debug.LogError("Could not find manifest tag in android manifest."); return; } // Get android namespace URI from the manifest androidNamepsaceURI = element.GetAttribute("xmlns:android"); if (!string.IsNullOrEmpty(androidNamepsaceURI)) { // Look for intent filter category and change LAUNCHER to INFO XmlNodeList nodeList = doc.SelectNodes("/manifest/application/activity/intent-filter/category"); foreach (XmlElement e in nodeList) { string attr = e.GetAttribute("name", androidNamepsaceURI); if (attr == "android.intent.category.LAUNCHER") { e.SetAttribute("name", androidNamepsaceURI, "android.intent.category.INFO"); } } //If Quest is the target device, add the headtracking manifest tag if (OVRDeviceSelector.isTargetDeviceQuest) { XmlNodeList manifestUsesFeatureNodes = doc.SelectNodes("/manifest/uses-feature"); bool foundHeadtrackingTag = false; foreach (XmlElement e in manifestUsesFeatureNodes) { string attr = e.GetAttribute("name", androidNamepsaceURI); if (attr == "android.hardware.vr.headtracking") { foundHeadtrackingTag = true; } } //If the tag already exists, don't patch with a new one. If it doesn't, we add it. if (!foundHeadtrackingTag) { XmlNode manifestElement = doc.SelectSingleNode("/manifest"); XmlElement headtrackingTag = doc.CreateElement("uses-feature"); headtrackingTag.SetAttribute("name", androidNamepsaceURI, "android.hardware.vr.headtracking"); headtrackingTag.SetAttribute("version", androidNamepsaceURI, "1"); string tagRequired = OVRDeviceSelector.isTargetDeviceGearVrOrGo ? "false" : "true"; headtrackingTag.SetAttribute("required", androidNamepsaceURI, tagRequired); manifestElement.AppendChild(headtrackingTag); } } // Disable allowBackup in manifest and add Android NSC XML file XmlElement applicationNode = (XmlElement)doc.SelectSingleNode("/manifest/application"); if (applicationNode != null) { OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig(); if (projectConfig != null) { if (projectConfig.disableBackups) { applicationNode.SetAttribute("allowBackup", androidNamepsaceURI, "false"); } if (projectConfig.enableNSCConfig) { applicationNode.SetAttribute("networkSecurityConfig", androidNamepsaceURI, "@xml/network_sec_config"); string securityConfigFile = Path.Combine(Application.dataPath, "Oculus/VR/Editor/network_sec_config.xml"); string xmlDirectory = Path.Combine(path, "src/main/res/xml"); try { if (!Directory.Exists(xmlDirectory)) { Directory.CreateDirectory(xmlDirectory); } File.Copy(securityConfigFile, Path.Combine(xmlDirectory, "network_sec_config.xml"), true); } catch (Exception e) { UnityEngine.Debug.LogError(e.Message); } } } } doc.Save(manifestFolder + "/AndroidManifest.xml"); } } catch (Exception e) { UnityEngine.Debug.LogError(e.Message); } }