|
|
- /************************************************************************************
-
- Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
-
- Licensed under the Oculus SDK License Version 3.4.1 (the "License");
- you may not use the Oculus SDK except in compliance with the License,
- which is provided at the time of installation or download, or which
- otherwise accompanies this software in either electronic or hard copy form.
-
- You may obtain a copy of the License at
-
- https://developer.oculus.com/licenses/sdk-3.4.1
-
- Unless required by applicable law or agreed to in writing, the Oculus SDK
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- ************************************************************************************/
-
- using UnityEngine;
- using UnityEditor;
- using System.IO;
- using System.Xml;
-
- public class OVRManifestPreprocessor
- {
- [MenuItem("Oculus/Tools/Create store-compatible AndroidManifest.xml", false, 100000)]
- 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))
- {
- if (!EditorUtility.DisplayDialog("AndroidManifest.xml Already Exists!", "Would you like to replace the existing manifest with a new one? All modifications will be lost.", "Replace", "Cancel"))
- {
- return;
- }
- }
-
- PatchAndroidManifest(srcFile, dstFile, false);
-
- AssetDatabase.Refresh();
- }
-
- [MenuItem("Oculus/Tools/Update AndroidManifest.xml")]
- public static void UpdateAndroidManifest()
- {
- string manifestFile = "Assets/Plugins/Android/AndroidManifest.xml";
-
- if (!File.Exists(manifestFile))
- {
- Debug.LogError("Unable to update manifest because it does not exist! Run \"Create store-compatible AndroidManifest.xml\" first");
- return;
- }
-
- if (!EditorUtility.DisplayDialog("Update AndroidManifest.xml", "This will overwrite all Oculus specific AndroidManifest Settings. Continue?", "Overwrite", "Cancel"))
- {
- return;
- }
-
- PatchAndroidManifest(manifestFile, skipExistingAttributes: false);
- AssetDatabase.Refresh();
- }
-
- [MenuItem("Oculus/Tools/Remove AndroidManifest.xml")]
- public static void RemoveAndroidManifest()
- {
- AssetDatabase.DeleteAsset("Assets/Plugins/Android/AndroidManifest.xml");
- AssetDatabase.Refresh();
- }
-
- private static void AddOrRemoveTag(XmlDocument doc, string @namespace, string path, string elementName, string name, bool required, bool modifyIfFound, params string[] attrs) // name, value pairs
- {
- var nodes = doc.SelectNodes(path + "/" + elementName);
- XmlElement element = null;
- foreach (XmlElement e in nodes)
- {
- if (name == null || name == e.GetAttribute("name", @namespace))
- {
- element = e;
- break;
- }
- }
-
- if (required)
- {
- if (element == null)
- {
- var parent = doc.SelectSingleNode(path);
- element = doc.CreateElement(elementName);
- element.SetAttribute("name", @namespace, name);
- parent.AppendChild(element);
- }
-
- for (int i = 0; i < attrs.Length; i += 2)
- {
- if (modifyIfFound || string.IsNullOrEmpty(element.GetAttribute(attrs[i], @namespace)))
- {
- if (attrs[i + 1] != null)
- {
- element.SetAttribute(attrs[i], @namespace, attrs[i + 1]);
- }
- else
- {
- element.RemoveAttribute(attrs[i], @namespace);
- }
- }
- }
- }
- else
- {
- if (element != null && modifyIfFound)
- {
- element.ParentNode.RemoveChild(element);
- }
- }
- }
-
- 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.isTargetDeviceQuest,
- modifyIfFound,
- "version", "1",
- "required", OVRDeviceSelector.isTargetDeviceGearVrOrGo ? "false" : "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.isTargetDeviceQuest && (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",
- "oculus.permission.handtracking",
- handTrackingEntryNeeded,
- modifyIfFound);
-
- // Add Colorspace metadata if targeting Quest
- AddOrRemoveTag(doc,
- androidNamepsaceURI,
- "/manifest/application",
- "meta-data",
- "com.oculus.application.colorspace",
- OVRDeviceSelector.isTargetDeviceQuest && projectConfig.colorGamut != OVRProjectConfig.ColorGamut.Default,
- modifyIfFound,
- "value", OVRProjectConfig.ColorGamutToString(projectConfig.colorGamut));
-
- // Add focus aware tag if this app is targeting Quest
- AddOrRemoveTag(doc,
- androidNamepsaceURI,
- "/manifest/application/activity",
- "meta-data",
- "com.oculus.vr.focusaware",
- OVRDeviceSelector.isTargetDeviceQuest,
- modifyIfFound,
- "value", projectConfig.focusAware ? "true" : "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",
- #if UNITY_2018_2_OR_NEWER
- "icon", "@mipmap/app_icon",
- #else
- "icon", "@drawable/app_icon",
- #endif
- // 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);
- }
- }
- }
|