上传YomovSDK
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d12249ab0d5646ff8f3e46fab464bd46
|
||||
timeCreated: 1677813281
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using UnityEditor.Build.Reporting;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.OpenXR.Features.MetaQuestSupport;
|
||||
|
||||
namespace UnityEditor.XR.OpenXR.Features.MetaQuestSupport
|
||||
{
|
||||
internal class MetaQuestFeatureBuildHooks : OpenXRFeatureBuildHooks
|
||||
{
|
||||
private const string kLateLatchingSupported = "xr-latelatching-enabled";
|
||||
private const string kLateLatchingDebug = "xr-latelatchingdebug-enabled";
|
||||
private const string kVulkanExtensionFragmentDensityMap = "xr-vulkan-extension-fragment-density-map-enabled";
|
||||
private const string kLowLatencyAudioEnabled = "xr-low-latency-audio-enabled";
|
||||
private const string kRequireBackbufferTextures = "xr-require-backbuffer-textures";
|
||||
private const string kKeyboardOverlayEnabled = "xr-keyboard-overlay-enabled";
|
||||
private const string kPipelineCacheEnabled = "xr-pipeline-cache-enabled";
|
||||
private const string kSkipB10G11R11SpecialCasing = "xr-skip-B10G11R11-special-casing";
|
||||
private const string kHideMemorylessRenderTexture = "xr-hide-memoryless-render-texture";
|
||||
private const string kSkipAudioBufferSizeCheck = "xr-skip-audio-buffer-size-check";
|
||||
private const string kUsableCoreMaskEnabled = "xr-usable-core-mask-enabled";
|
||||
private const string kMvpvvEnabled = "xr-mvpvv-enabled";
|
||||
|
||||
private MetaQuestFeature GetMetaQuestFeature()
|
||||
{
|
||||
var featureGuids = AssetDatabase.FindAssets("t:" + typeof(MetaQuestFeature).Name);
|
||||
|
||||
// we should only find one
|
||||
if (featureGuids.Length != 1)
|
||||
return null;
|
||||
|
||||
string path = AssetDatabase.GUIDToAssetPath(featureGuids[0]);
|
||||
return AssetDatabase.LoadAssetAtPath<MetaQuestFeature>(path);
|
||||
}
|
||||
|
||||
public override int callbackOrder => 2;
|
||||
|
||||
public override Type featureType => typeof(MetaQuestFeature);
|
||||
|
||||
protected override void OnPreprocessBuildExt(BuildReport report)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnProcessBootConfigExt(BuildReport report, BootConfigBuilder builder)
|
||||
{
|
||||
if (report.summary.platform != BuildTarget.Android)
|
||||
return;
|
||||
|
||||
var item = GetMetaQuestFeature();
|
||||
if (item == null)
|
||||
{
|
||||
Debug.Log("Unable to locate the MetaQuestFeature Asset");
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the boot config
|
||||
builder.SetBootConfigBoolean(kLateLatchingSupported, item.lateLatchingMode);
|
||||
builder.SetBootConfigBoolean(kLateLatchingDebug, item.lateLatchingDebug);
|
||||
builder.SetBootConfigBoolean(kVulkanExtensionFragmentDensityMap, true);
|
||||
builder.SetBootConfigBoolean(kLowLatencyAudioEnabled, true);
|
||||
builder.SetBootConfigBoolean(kRequireBackbufferTextures, false);
|
||||
builder.SetBootConfigBoolean(kKeyboardOverlayEnabled, true);
|
||||
builder.SetBootConfigBoolean(kPipelineCacheEnabled, true);
|
||||
builder.SetBootConfigBoolean(kSkipB10G11R11SpecialCasing, true);
|
||||
builder.SetBootConfigBoolean(kHideMemorylessRenderTexture, true);
|
||||
builder.SetBootConfigBoolean(kSkipAudioBufferSizeCheck, true);
|
||||
builder.SetBootConfigBoolean(kUsableCoreMaskEnabled, true);
|
||||
#if UNITY_6000_1_OR_NEWER
|
||||
builder.SetBootConfigBoolean(kMvpvvEnabled, item.optimizeMultiviewRenderRegions);
|
||||
#endif
|
||||
}
|
||||
|
||||
protected override void OnPostGenerateGradleAndroidProjectExt(string path)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnPostprocessBuildExt(BuildReport report)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e6e545add294555ba87b5c10bab2467
|
||||
timeCreated: 1677813385
|
||||
@@ -0,0 +1,168 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.OpenXR;
|
||||
|
||||
using UnityEngine.XR.OpenXR.Features.MetaQuestSupport;
|
||||
|
||||
namespace UnityEditor.XR.OpenXR.Features.MetaQuestSupport
|
||||
{
|
||||
[CustomEditor(typeof(MetaQuestFeature))]
|
||||
internal class MetaQuestFeatureEditor : Editor
|
||||
{
|
||||
private bool m_ShowAndroidExperimental = false;
|
||||
private bool m_LateLatchingModeEnabled;
|
||||
private bool m_LateLatchingDebug;
|
||||
|
||||
private static GUIContent s_LateLatchingSupportedLabel = EditorGUIUtility.TrTextContent("Late Latching (Vulkan)");
|
||||
private static GUIContent s_LateLatchingDebugLabel = EditorGUIUtility.TrTextContent("Late Latching Debug Mode");
|
||||
private static GUIContent s_ShowAndroidExperimentalLabel = EditorGUIUtility.TrTextContent("Experimental", "Experimental settings that are under active development and should be used with caution.");
|
||||
#if UNITY_6000_1_OR_NEWER
|
||||
private static GUIContent s_OptimizeMultiviewRenderRegionsLabel = EditorGUIUtility.TrTextContent("Optimize Multiview Render Regions (Vulkan)", "Activates Multiview Render Regions optimizations at application start. Requires usage of Unity 6.1 or later, Vulkan as the Graphics API, Render Mode set to Multi-view and Symmetric rendering enabled.");
|
||||
#endif
|
||||
|
||||
struct TargetDeviceProperty
|
||||
{
|
||||
public SerializedProperty property;
|
||||
public GUIContent label;
|
||||
}
|
||||
|
||||
private List<TargetDeviceProperty> targetDeviceProperties;
|
||||
private Dictionary<string, bool> activeTargetDevices;
|
||||
private SerializedProperty forceRemoveInternetPermission;
|
||||
private SerializedProperty systemSplashScreen;
|
||||
|
||||
private SerializedProperty symmetricProjection;
|
||||
|
||||
private SerializedProperty m_LateLatchingModeProperty;
|
||||
private SerializedProperty m_LateLatchingDebugProperty;
|
||||
|
||||
private SerializedProperty optimizeBufferDiscards;
|
||||
#if UNITY_6000_1_OR_NEWER
|
||||
private SerializedProperty optimizeMultiviewRenderRegions;
|
||||
#endif
|
||||
|
||||
private SerializedProperty spacewarpMotionVectorTextureFormat;
|
||||
|
||||
void InitActiveTargetDevices()
|
||||
{
|
||||
activeTargetDevices = new Dictionary<string, bool>();
|
||||
|
||||
OpenXRSettings androidOpenXRSettings = OpenXRSettings.GetSettingsForBuildTargetGroup(BuildTargetGroup.Android);
|
||||
var questFeature = androidOpenXRSettings.GetFeature<MetaQuestFeature>();
|
||||
|
||||
if (questFeature == null)
|
||||
return;
|
||||
|
||||
foreach (var dev in questFeature.targetDevices)
|
||||
{
|
||||
activeTargetDevices.Add(dev.manifestName, dev.active);
|
||||
}
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
forceRemoveInternetPermission =
|
||||
serializedObject.FindProperty("forceRemoveInternetPermission");
|
||||
systemSplashScreen =
|
||||
serializedObject.FindProperty("systemSplashScreen");
|
||||
|
||||
symmetricProjection =
|
||||
serializedObject.FindProperty("symmetricProjection");
|
||||
|
||||
optimizeBufferDiscards =
|
||||
serializedObject.FindProperty("optimizeBufferDiscards");
|
||||
#if UNITY_6000_1_OR_NEWER
|
||||
optimizeMultiviewRenderRegions =
|
||||
serializedObject.FindProperty("optimizeMultiviewRenderRegions");
|
||||
#endif
|
||||
|
||||
targetDeviceProperties = new List<TargetDeviceProperty>();
|
||||
InitActiveTargetDevices();
|
||||
if (activeTargetDevices.Count == 0)
|
||||
return;
|
||||
var targetDevicesProperty = serializedObject.FindProperty("targetDevices");
|
||||
|
||||
// mapping these to Properties so tha we can get Undo/redo functionality
|
||||
m_LateLatchingDebugProperty = serializedObject.FindProperty("lateLatchingDebug");
|
||||
m_LateLatchingModeProperty = serializedObject.FindProperty("lateLatchingMode");
|
||||
|
||||
spacewarpMotionVectorTextureFormat = serializedObject.FindProperty("spacewarpMotionVectorTextureFormat");
|
||||
|
||||
for (int i = 0; i < targetDevicesProperty.arraySize; ++i)
|
||||
{
|
||||
var targetDeviceProp = targetDevicesProperty.GetArrayElementAtIndex(i);
|
||||
var propManifestName = targetDeviceProp.FindPropertyRelative("manifestName");
|
||||
|
||||
// don't present inactive target devices to the user
|
||||
if (propManifestName == null || activeTargetDevices[propManifestName.stringValue] == false)
|
||||
continue;
|
||||
var propEnabled = targetDeviceProp.FindPropertyRelative("enabled");
|
||||
var propName = targetDeviceProp.FindPropertyRelative("visibleName");
|
||||
TargetDeviceProperty curTarget = new TargetDeviceProperty { property = propEnabled, label = EditorGUIUtility.TrTextContent(propName.stringValue) };
|
||||
targetDeviceProperties.Add(curTarget);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
// Update anything from the serializable object
|
||||
EditorGUIUtility.labelWidth = 275.0f;
|
||||
|
||||
serializedObject.Update();
|
||||
EditorGUILayout.LabelField("Rendering Settings", EditorStyles.boldLabel);
|
||||
EditorGUILayout.PropertyField(symmetricProjection, new GUIContent("Symmetric Projection (Vulkan)"));
|
||||
EditorGUILayout.PropertyField(optimizeBufferDiscards, new GUIContent("Optimize Buffer Discards (Vulkan)"));
|
||||
// OptimizeMultiviewRenderRegions (aka MVPVV) only supported on Unity 6.1 onwards
|
||||
#if UNITY_6000_1_OR_NEWER
|
||||
EditorGUILayout.PropertyField(optimizeMultiviewRenderRegions, s_OptimizeMultiviewRenderRegionsLabel);
|
||||
#endif
|
||||
EditorGUILayout.PropertyField(spacewarpMotionVectorTextureFormat, new GUIContent("Space Warp motion vector texture format"));
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.LabelField("Manifest Settings", EditorStyles.boldLabel);
|
||||
EditorGUILayout.PropertyField(forceRemoveInternetPermission);
|
||||
EditorGUILayout.PropertyField(systemSplashScreen);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.LabelField("Target Devices", EditorStyles.boldLabel);
|
||||
|
||||
// Layout the Target Device properties
|
||||
EditorGUI.indentLevel++;
|
||||
foreach (var device in targetDeviceProperties)
|
||||
{
|
||||
EditorGUILayout.PropertyField(device.property, device.label);
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
// Foldout for the Experimental properties
|
||||
if (m_ShowAndroidExperimental = EditorGUILayout.Foldout(m_ShowAndroidExperimental, s_ShowAndroidExperimentalLabel, EditorStyles.miniBoldFont))
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.PropertyField(m_LateLatchingModeProperty, s_LateLatchingSupportedLabel);
|
||||
EditorGUILayout.PropertyField(m_LateLatchingDebugProperty, s_LateLatchingDebugLabel);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
EditorGUIUtility.labelWidth = 0.0f;
|
||||
|
||||
// update any serializable properties
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
OpenXRSettings androidOpenXRSettings = OpenXRSettings.GetSettingsForBuildTargetGroup(BuildTargetGroup.Android);
|
||||
var serializedOpenXrSettings = new SerializedObject(androidOpenXRSettings);
|
||||
|
||||
androidOpenXRSettings.symmetricProjection = symmetricProjection.boolValue;
|
||||
#if UNITY_6000_1_OR_NEWER
|
||||
androidOpenXRSettings.optimizeMultiviewRenderRegions = optimizeMultiviewRenderRegions.boolValue;
|
||||
#endif
|
||||
androidOpenXRSettings.optimizeBufferDiscards = optimizeBufferDiscards.boolValue;
|
||||
androidOpenXRSettings.spacewarpMotionVectorTextureFormat = (OpenXRSettings.SpaceWarpMotionVectorTextureFormat)spacewarpMotionVectorTextureFormat.enumValueIndex;
|
||||
serializedOpenXrSettings.ApplyModifiedProperties();
|
||||
|
||||
EditorGUIUtility.labelWidth = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82210fac00b17f4429ac7f1b85d6e30a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,422 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using UnityEditor.Build.Reporting;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.OpenXR;
|
||||
using UnityEngine.XR.OpenXR.Features.MetaQuestSupport;
|
||||
using UnityEngine.XR.OpenXR.Features;
|
||||
using System.Linq;
|
||||
|
||||
#if XR_MGMT_4_4_0_OR_NEWER
|
||||
using Unity.XR.Management.AndroidManifest.Editor;
|
||||
#endif
|
||||
|
||||
namespace UnityEditor.XR.OpenXR.Features.MetaQuestSupport
|
||||
{
|
||||
internal class ModifyAndroidManifestMeta : OpenXRFeatureBuildHooks
|
||||
{
|
||||
public override int callbackOrder => 1;
|
||||
|
||||
public override Type featureType => typeof(MetaQuestFeature);
|
||||
|
||||
protected override void OnPreprocessBuildExt(BuildReport report)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnPostGenerateGradleAndroidProjectExt(string path)
|
||||
{
|
||||
ProcessSystemSplashScreen(path);
|
||||
|
||||
#if !XR_MGMT_4_4_0_OR_NEWER
|
||||
var androidManifest = new AndroidManifest(GetManifestPath(path));
|
||||
androidManifest.AddMetaData();
|
||||
androidManifest.Save();
|
||||
#endif
|
||||
}
|
||||
|
||||
protected override void OnPostprocessBuildExt(BuildReport report)
|
||||
{
|
||||
}
|
||||
|
||||
#if XR_MGMT_4_4_0_OR_NEWER
|
||||
protected override ManifestRequirement ProvideManifestRequirementExt()
|
||||
{
|
||||
var elementsToRemove = new List<ManifestElement>()
|
||||
{
|
||||
new ManifestElement()
|
||||
{
|
||||
ElementPath = new List<string> { "manifest", "uses-permission" },
|
||||
Attributes = new Dictionary<string, string>
|
||||
{
|
||||
{ "name", "android.permission.BLUETOOTH" }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (ForceRemoveInternetPermission())
|
||||
{
|
||||
elementsToRemove.Add(new ManifestElement()
|
||||
{
|
||||
ElementPath = new List<string> { "manifest", "uses-permission" },
|
||||
Attributes = new Dictionary<string, string>
|
||||
{
|
||||
{ "name", "android.permission.INTERNET" }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var elementsToAdd = new List<ManifestElement>()
|
||||
{
|
||||
new ManifestElement()
|
||||
{
|
||||
ElementPath = new List<string> { "manifest", "uses-feature" },
|
||||
Attributes = new Dictionary<string, string>
|
||||
{
|
||||
{ "name", "android.hardware.vr.headtracking" },
|
||||
{ "required", "true" },
|
||||
{ "version", "1" }
|
||||
}
|
||||
},
|
||||
new ManifestElement()
|
||||
{
|
||||
ElementPath = new List<string> { "manifest", "application", "meta-data" },
|
||||
Attributes = new Dictionary<string, string>
|
||||
{
|
||||
{ "name", "com.oculus.supportedDevices" },
|
||||
{ "value", GetMetaSupportedDevices() }
|
||||
}
|
||||
},
|
||||
new ManifestElement()
|
||||
{
|
||||
ElementPath = new List<string> { "manifest", "application", "activity", "meta-data" },
|
||||
Attributes = new Dictionary<string, string>
|
||||
{
|
||||
{ "name", "com.oculus.vr.focusaware" },
|
||||
{ "value", "true" }
|
||||
}
|
||||
},
|
||||
new ManifestElement()
|
||||
{
|
||||
ElementPath = new List<string> { "manifest", "application", "activity", "intent-filter", "category" },
|
||||
Attributes = new Dictionary<string, string>
|
||||
{
|
||||
{ "name", "com.oculus.intent.category.VR" }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (SystemSplashScreen() != null)
|
||||
{
|
||||
elementsToAdd.Add(new ManifestElement()
|
||||
{
|
||||
ElementPath = new List<string> { "manifest", "application", "meta-data" },
|
||||
Attributes = new Dictionary<string, string>
|
||||
{
|
||||
{ "name", "com.oculus.ossplash" },
|
||||
{ "value", "true" }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (IsAppTargetingQuestPro())
|
||||
{
|
||||
elementsToAdd.Add(
|
||||
new ManifestElement()
|
||||
{
|
||||
ElementPath = new List<string> { "manifest", "uses-feature" },
|
||||
Attributes = new Dictionary<string, string>
|
||||
{
|
||||
{ "name", "oculus.software.eye_tracking" },
|
||||
{ "required", "true" }
|
||||
}
|
||||
});
|
||||
elementsToAdd.Add(
|
||||
new ManifestElement()
|
||||
{
|
||||
ElementPath = new List<string> { "manifest", "uses-permission" },
|
||||
Attributes = new Dictionary<string, string>
|
||||
{
|
||||
{ "name", "com.oculus.permission.EYE_TRACKING" }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return new ManifestRequirement
|
||||
{
|
||||
SupportedXRLoaders = new HashSet<Type>()
|
||||
{
|
||||
typeof(OpenXRLoader)
|
||||
},
|
||||
NewElements = elementsToAdd,
|
||||
RemoveElements = elementsToRemove
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
private static string GetMetaSupportedDevices()
|
||||
{
|
||||
var androidOpenXRSettings = OpenXRSettings.GetSettingsForBuildTargetGroup(BuildTargetGroup.Android);
|
||||
var questFeature = androidOpenXRSettings.GetFeature<MetaQuestFeature>();
|
||||
|
||||
if (questFeature != null)
|
||||
{
|
||||
List<string> deviceList = new List<string>();
|
||||
foreach (var device in questFeature.targetDevices)
|
||||
{
|
||||
if (device.active && device.enabled)
|
||||
deviceList.Add(device.manifestName);
|
||||
}
|
||||
|
||||
if (deviceList.Count > 0)
|
||||
{
|
||||
return string.Join("|", deviceList.ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Debug.LogWarning("No target devices selected in Meta Quest Support Feature. No devices will be listed as supported in the application Android manifest.");
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private static bool ForceRemoveInternetPermission()
|
||||
{
|
||||
var questFeature = GetFeatureFromSettings<MetaQuestFeature>(BuildTargetGroup.Android);
|
||||
|
||||
if (questFeature == null || !questFeature.enabled)
|
||||
return false; // By default the permission is retained
|
||||
|
||||
return questFeature.forceRemoveInternetPermission;
|
||||
}
|
||||
|
||||
private static Texture2D SystemSplashScreen()
|
||||
{
|
||||
var questFeature = GetFeatureFromSettings<MetaQuestFeature>(BuildTargetGroup.Android);
|
||||
|
||||
if (questFeature == null || !questFeature.enabled)
|
||||
return null;
|
||||
|
||||
return questFeature.systemSplashScreen;
|
||||
}
|
||||
|
||||
private static bool IsAppTargetingQuestPro()
|
||||
{
|
||||
var questFeature = GetFeatureFromSettings<MetaQuestFeature>(BuildTargetGroup.Android);
|
||||
return questFeature.targetDevices
|
||||
.Where(device => string.Equals(device.manifestName, "cambria"))
|
||||
.Where(device => device.enabled)
|
||||
.Any();
|
||||
}
|
||||
|
||||
private static T GetFeatureFromSettings<T>(BuildTargetGroup buildTargetGroup) where T : OpenXRFeature
|
||||
{
|
||||
var androidOpenXRSettings = OpenXRSettings.GetSettingsForBuildTargetGroup(buildTargetGroup);
|
||||
return androidOpenXRSettings.GetFeature<T>();
|
||||
}
|
||||
|
||||
private static void ProcessSystemSplashScreen(string gradlePath)
|
||||
{
|
||||
var systemSplashScreen = SystemSplashScreen();
|
||||
if (systemSplashScreen == null)
|
||||
return;
|
||||
|
||||
string splashScreenAssetPath = AssetDatabase.GetAssetPath(systemSplashScreen);
|
||||
string sourcePath = splashScreenAssetPath;
|
||||
string targetFolder = Path.Combine(gradlePath, "src/main/assets");
|
||||
string targetPath = targetFolder + "/vr_splash.png";
|
||||
|
||||
// copy the splash over into the gradle folder and make sure it's not read only
|
||||
FileUtil.ReplaceFile(sourcePath, targetPath);
|
||||
FileInfo targetInfo = new FileInfo(targetPath);
|
||||
targetInfo.IsReadOnly = false;
|
||||
}
|
||||
|
||||
#if !XR_MGMT_4_4_0_OR_NEWER
|
||||
private string _manifestFilePath;
|
||||
|
||||
private string GetManifestPath(string basePath)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_manifestFilePath)) return _manifestFilePath;
|
||||
|
||||
var pathBuilder = new StringBuilder(basePath);
|
||||
pathBuilder.Append(Path.DirectorySeparatorChar).Append("src");
|
||||
pathBuilder.Append(Path.DirectorySeparatorChar).Append("main");
|
||||
pathBuilder.Append(Path.DirectorySeparatorChar).Append("AndroidManifest.xml");
|
||||
_manifestFilePath = pathBuilder.ToString();
|
||||
|
||||
return _manifestFilePath;
|
||||
}
|
||||
|
||||
private class AndroidXmlDocument : XmlDocument
|
||||
{
|
||||
private string m_Path;
|
||||
protected XmlNamespaceManager nsMgr;
|
||||
public readonly string AndroidXmlNamespace = "http://schemas.android.com/apk/res/android";
|
||||
|
||||
public AndroidXmlDocument(string path)
|
||||
{
|
||||
m_Path = path;
|
||||
using (var reader = new XmlTextReader(m_Path))
|
||||
{
|
||||
reader.Read();
|
||||
Load(reader);
|
||||
}
|
||||
|
||||
nsMgr = new XmlNamespaceManager(NameTable);
|
||||
nsMgr.AddNamespace("android", AndroidXmlNamespace);
|
||||
}
|
||||
|
||||
public string Save()
|
||||
{
|
||||
return SaveAs(m_Path);
|
||||
}
|
||||
|
||||
public string SaveAs(string path)
|
||||
{
|
||||
using (var writer = new XmlTextWriter(path, new UTF8Encoding(false)))
|
||||
{
|
||||
writer.Formatting = Formatting.Indented;
|
||||
Save(writer);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
private class AndroidManifest : AndroidXmlDocument
|
||||
{
|
||||
private readonly XmlElement ApplicationElement;
|
||||
private readonly XmlElement ActivityIntentFilterElement;
|
||||
private readonly XmlElement ActivityElement;
|
||||
private readonly XmlElement ManifestElement;
|
||||
|
||||
public AndroidManifest(string path) : base(path)
|
||||
{
|
||||
ApplicationElement = SelectSingleNode("/manifest/application") as XmlElement;
|
||||
ActivityIntentFilterElement = SelectSingleNode("/manifest/application/activity/intent-filter") as XmlElement;
|
||||
ActivityElement = SelectSingleNode("manifest/application/activity") as XmlElement;
|
||||
ManifestElement = SelectSingleNode("/manifest") as XmlElement;
|
||||
}
|
||||
|
||||
private XmlAttribute CreateAndroidAttribute(string key, string value)
|
||||
{
|
||||
XmlAttribute attr = CreateAttribute("android", key, AndroidXmlNamespace);
|
||||
attr.Value = value;
|
||||
return attr;
|
||||
}
|
||||
|
||||
private void UpdateOrCreateAttribute(XmlElement xmlParentElement, string tag, string name, params (string name, string value)[] attributes)
|
||||
{
|
||||
var xmlNodeList = xmlParentElement.SelectNodes(tag);
|
||||
XmlElement targetNode = null;
|
||||
|
||||
// Check all XmlNodes to see if a node with matching name already exists.
|
||||
foreach (XmlNode node in xmlNodeList)
|
||||
{
|
||||
XmlAttribute nameAttr = (XmlAttribute)node.Attributes.GetNamedItem("name", AndroidXmlNamespace);
|
||||
if (nameAttr != null && nameAttr.Value.Equals(name))
|
||||
{
|
||||
targetNode = (XmlElement)node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If node exists, update the attribute values if they are present or create new ones as requested. Else, create new XmlElement.
|
||||
if (targetNode != null)
|
||||
{
|
||||
for (int i = 0; i < attributes.Length; i++)
|
||||
{
|
||||
XmlAttribute attr = (XmlAttribute)targetNode.Attributes.GetNamedItem(attributes[i].name, AndroidXmlNamespace);
|
||||
if (attr != null)
|
||||
{
|
||||
attr.Value = attributes[i].value;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetNode.SetAttribute(attributes[i].name, AndroidXmlNamespace, attributes[i].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
XmlElement newElement = CreateElement(tag);
|
||||
newElement.SetAttribute("name", AndroidXmlNamespace, name);
|
||||
for (int i = 0; i < attributes.Length; i++)
|
||||
newElement.SetAttribute(attributes[i].name, AndroidXmlNamespace, attributes[i].value);
|
||||
xmlParentElement.AppendChild(newElement);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveNameValueElementInTag(string parentPath, string tag, string name, string value)
|
||||
{
|
||||
var xmlNodeList = this.SelectNodes(parentPath + "/" + tag);
|
||||
|
||||
foreach (XmlNode node in xmlNodeList)
|
||||
{
|
||||
var attributeList = ((XmlElement)node).Attributes;
|
||||
|
||||
foreach (XmlAttribute attrib in attributeList)
|
||||
{
|
||||
if (attrib.Name == name && attrib.Value == value)
|
||||
{
|
||||
node.ParentNode?.RemoveChild(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddMetaData()
|
||||
{
|
||||
string supportedDevices = GetMetaSupportedDevices();
|
||||
|
||||
UpdateOrCreateAttribute(ActivityIntentFilterElement,
|
||||
"category", "com.oculus.intent.category.VR"
|
||||
);
|
||||
|
||||
UpdateOrCreateAttribute(ActivityElement,
|
||||
"meta-data", "com.oculus.vr.focusaware",
|
||||
new (string name, string value)[]
|
||||
{
|
||||
("value", "true")
|
||||
});
|
||||
|
||||
UpdateOrCreateAttribute(ApplicationElement,
|
||||
"meta-data", "com.oculus.supportedDevices",
|
||||
new (string name, string value)[]
|
||||
{
|
||||
("value", supportedDevices)
|
||||
});
|
||||
|
||||
UpdateOrCreateAttribute(ManifestElement,
|
||||
"uses-feature", "android.hardware.vr.headtracking",
|
||||
new (string name, string value)[]
|
||||
{
|
||||
("required", "true"),
|
||||
("version", "1")
|
||||
});
|
||||
|
||||
if (SystemSplashScreen() != null)
|
||||
{
|
||||
UpdateOrCreateAttribute(ApplicationElement,
|
||||
"meta-data", "com.oculus.ossplash",
|
||||
new (string name, string value)[]
|
||||
{
|
||||
("value", "true")
|
||||
});
|
||||
}
|
||||
|
||||
// if the Microphone class is used in a project, the BLUETOOTH permission is automatically added to the manifest
|
||||
// we remove it here since it will cause projects to fail Meta cert
|
||||
// this shouldn't affect Bluetooth HID devices, which don't need the permission
|
||||
RemoveNameValueElementInTag("/manifest", "uses-permission", "android:name", "android.permission.BLUETOOTH");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a4b338a7faf8f4408f2320a777b654c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "Unity.XR.OpenXR.Features.MetaQuestSupport.Editor",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:96aa6ba065960476598f8f643e7252b6",
|
||||
"GUID:4847341ff46394e83bb78fbd0652937e",
|
||||
"GUID:95054a9710b0f114a85f6ced6b7f891c",
|
||||
"GUID:f9fe0089ec81f4079af78eb2287a6163"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [
|
||||
{
|
||||
"name": "com.unity.xr.management",
|
||||
"expression": "4.4.0",
|
||||
"define": "XR_MGMT_4_4_0_OR_NEWER"
|
||||
}
|
||||
],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f68571b73246ce44e903d7128579af58
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user