Skip to content

Commit

Permalink
com.unity.xr.magicleap@4.2.0-preview.3
Browse files Browse the repository at this point in the history
## [4.2.0-preview.3] - 2020-08-19
- Fix issue causing CI testing to fail erroneously.

## [4.2.0-preview.2] - 2020-08-17
- Update the target Unity version to 2019.4f4.4

## [4.2.0-preview.1] - 2020-04-14
- Update XR Management Dependency to 3.2.10
- Added manifest setting to enable background music privileges
- APIs added for `QuerySupportedTrackingOriginModes`, `QueryTrackingOriginMode`, and `SetTrackingOriginMode`
- Fixed issue where controller state information was incorrectly surfaced from the companion application
- Fixed issue where Zero Iteration libraries where incorrectly imported for MacOS
- Fixed issue where using `NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray` resulted in an error while running in the Editor
- Fix issue where UnityMagicLeap libraries were included in Standalone Desktop builds when using Magic Leap
Zero Iteration Plugin Provider from XR Management (The intent of the Standalone Desktop provider is to allow
rapid iteration from the Unity Editor with Magic Leap's The Lab Zero Iteration module and not for use in standalone
builds)
  • Loading branch information
Unity Technologies committed Aug 19, 2020
1 parent 795f959 commit b7deb2e
Show file tree
Hide file tree
Showing 24 changed files with 390 additions and 144 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Changelog

## [4.2.0-preview.3] - 2020-08-19
- Fix issue causing CI testing to fail erroneously.

## [4.2.0-preview.2] - 2020-08-17
- Update the target Unity version to 2019.4f4.4

## [4.2.0-preview.1] - 2020-04-14
- Update XR Management Dependency to 3.2.10
- Added manifest setting to enable background music privileges
- APIs added for `QuerySupportedTrackingOriginModes`, `QueryTrackingOriginMode`, and `SetTrackingOriginMode`
- Fixed issue where controller state information was incorrectly surfaced from the companion application
- Fixed issue where Zero Iteration libraries where incorrectly imported for MacOS
- Fixed issue where using `NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray` resulted in an error while running in the Editor
- Fix issue where UnityMagicLeap libraries were included in Standalone Desktop builds when using Magic Leap
Zero Iteration Plugin Provider from XR Management (The intent of the Standalone Desktop provider is to allow
rapid iteration from the Unity Editor with Magic Leap's The Lab Zero Iteration module and not for use in standalone
builds)

## [4.1.3] - 2020-04-07
- Conditionally compile out XR Management related classes that depend on XR Management `3.2.x`
- Revert dependency on XR Management `3.0.6`
Expand Down
67 changes: 66 additions & 1 deletion Editor/MagicLeapBuildProcessor.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
using System.Linq;

using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEditor.XR.Management;

using UnityEngine;
using UnityEngine.XR.Management;

using UnityEngine.XR.MagicLeap;

Expand All @@ -11,14 +16,17 @@ public class MagicLeapBuildProcessor : IPreprocessBuildWithReport, IPostprocessB
{
public int callbackOrder => 0;

private string[] runtimePluginNames = new string[] { "UnityMagicLeap.elf", "UnityMagicLeap.so" };
private string[] remotingPluginNames = new string[] { "UnityMagicLeap.dll", "UnityMagicLeap.dylib" };

void CleanOldSettings()
{
UnityEngine.Object[] preloadedAssets = PlayerSettings.GetPreloadedAssets();
if (preloadedAssets == null)
return;

var oldSettings = from s in preloadedAssets
where s.GetType() == typeof(MagicLeapSettings)
where (s != null) && (s.GetType() == typeof(MagicLeapSettings))
select s;

if (oldSettings.Any())
Expand All @@ -33,8 +41,65 @@ where s.GetType() == typeof(MagicLeapSettings)
}
}

public bool ShouldIncludeRuntimePluginsInBuild(string path)
{
// Return false if not on platform Lumin
#if PLATFORM_LUMIN
XRGeneralSettings generalSettings = XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget));
if (generalSettings == null)
return false;

foreach (var loader in generalSettings.Manager.loaders)
{
if (loader is MagicLeapLoader)
return true;
}
#endif // PLATFORM_LUMIN

return false;
}

// Remoting is only intended to work in the editor so builds are disallowed to have the libraries
public bool ShouldIncludeRemotingPluginsInBuild(string path) => false;

void AssignNativePluginIncludeInBuildDelegates()
{
// For each plugin within the project, check if it is a plugin generated by this
// package and assign the Include in build delegate to prevent magic leap libraries
// from being included on other platforms
var allPlugins = PluginImporter.GetAllImporters();
foreach (var plugin in allPlugins)
{
if (plugin.isNativePlugin)
{
foreach (var pluginName in runtimePluginNames)
{
if (plugin.assetPath.Contains(pluginName))
{
plugin.SetIncludeInBuildDelegate(ShouldIncludeRuntimePluginsInBuild);
break;
}
}

foreach (var pluginName in remotingPluginNames)
{
if (plugin.assetPath.Contains(pluginName))
{
plugin.SetIncludeInBuildDelegate(ShouldIncludeRemotingPluginsInBuild);
break;
}
}
}
}
}

public void OnPreprocessBuild(BuildReport report)
{
// Assign each library a "ShouldIncludeInBuild" delegate to indicate whether the plugin
// should be placed in a build on a specific platform. As of right now it's only important
// for runtime on the device but that could change to have standalone include remoting libs
AssignNativePluginIncludeInBuildDelegates();

// Always remember to cleanup preloaded assets after build to make sure we don't
// dirty later builds with assets that may not be needed or are out of date.
CleanOldSettings();
Expand Down
35 changes: 29 additions & 6 deletions Editor/Manifest/MagicLeapManifestBuildProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,16 @@ class MagicLeapManifestBuildProcessor : IPreprocessBuildWithReport

public void OnPreprocessBuild(BuildReport report)
{
//Debug.LogFormat("PreprocessBuild : Manifest");
var path = MagicLeapManifestSettings.kBuildManifestPath;
if (MagicLeapManifestSettings.customManifestExists)
if (report.summary.platform == BuildTarget.Lumin)
{
Debug.LogWarningFormat(kManifestExistsWarning, MagicLeapManifestSettings.kCustomManifestPath);
return;
var path = MagicLeapManifestSettings.kBuildManifestPath;
if (MagicLeapManifestSettings.customManifestExists)
{
Debug.LogWarningFormat(kManifestExistsWarning, MagicLeapManifestSettings.kCustomManifestPath);
return;
}
MergeToCustomManifest(MagicLeap.MagicLeapManifestSettings.GetOrCreateSettings(), path);
}
MergeToCustomManifest(MagicLeap.MagicLeapManifestSettings.GetOrCreateSettings(), path);
}

private XDocument GetManifestTemplate()
Expand Down Expand Up @@ -109,6 +111,27 @@ private void MergeToCustomManifest(MagicLeapManifestSettings ctx, string path)
iconElement.SetAttributeValue(kML + "model_folder", "Icon/Model");
iconElement.SetAttributeValue(kML + "portal_folder", "Icon/Portal");
}

// Remove or Add "<music-attribute ml:name="play" />" element to match ctx.allowBackgroundMusicService setting
XElement playMusicAttribute = componentElement.Elements("music-attribute")
.Where(n => (string)n.Attribute(kML + "name") == "play").FirstOrDefault();

if (ctx.allowBackgroundMusicService)
{
// Add the element if it was not found and allowBackgroundMusicService is true.
if (playMusicAttribute == null)
{
componentElement.Add(new XElement("music-attribute", CreateAttribute("name", "play")));
}
}
else
{
// Remove element if it was found and allowBackgroundMusicService is false.
if (playMusicAttribute != null)
{
playMusicAttribute.Remove();
}
}
}

SetPrivileges(applicationElement, ctx.requiredPermissions.ToArray());
Expand Down
20 changes: 20 additions & 0 deletions Editor/Manifest/MagicLeapManifestSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ public class MagicLeapManifestSettings : ScriptableObject
[SerializeField]
private int m_MinimumAPILevel;

[SerializeField]
private bool m_AllowBackgroundMusicService;

[SerializeField]
private PrivilegeGroup[] m_PrivilegeGroups;

Expand All @@ -34,6 +37,19 @@ public int minimumAPILevel
}
}

public bool allowBackgroundMusicService
{
get
{
return m_AllowBackgroundMusicService;
}
set
{
Undo.RecordObject(this, "Changed Allow Background Music Service");
m_AllowBackgroundMusicService = value;
}
}

public IEnumerable<string> requiredPermissions
{
get
Expand Down Expand Up @@ -63,6 +79,7 @@ public static bool customManifestExists
get { return File.Exists(kCustomManifestPath); }
}


public static MagicLeapManifestSettings GetOrCreateSettings(string path = kDefaultSettingsPath)
{
if (string.IsNullOrEmpty(path))
Expand All @@ -75,8 +92,11 @@ public static MagicLeapManifestSettings GetOrCreateSettings(string path = kDefau
{
settings = ScriptableObject.CreateInstance<MagicLeapManifestSettings>();
settings.m_MinimumAPILevel = 4;
settings.m_AllowBackgroundMusicService = false;
if (SDKUtility.sdkAvailable)
{
settings.RebuildPrivilegeGroups(PrivilegeParser.ParsePrivilegesFromHeader(Path.Combine(SDKUtility.sdkPath, PrivilegeParser.kPrivilegeHeaderPath)));
}
else
Debug.LogWarning(ManifestEditorGUI.Messages.kCannotLocateSDK);

Expand Down
5 changes: 5 additions & 0 deletions Editor/Manifest/ManifestEditorGUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ public static void RenderManifest(MagicLeapManifestSettings settings)
{
var apiLevel = serializedObject.FindProperty("m_MinimumAPILevel");
apiLevel.intValue = PlatformLevelSelector.SelectorGUI(apiLevel.intValue);

var allowBMS = serializedObject.FindProperty("m_AllowBackgroundMusicService");
allowBMS.boolValue = EditorGUILayout.ToggleLeft("Allow Background Music Service", allowBMS.boolValue);

EditorGUILayout.LabelField("Privileges", EditorStyles.boldLabel);
var priv_groups = serializedObject.FindProperty("m_PrivilegeGroups");
for (int i = 0; i < priv_groups.arraySize; i++)
Expand Down Expand Up @@ -60,6 +64,7 @@ public static void RenderManifest(MagicLeapManifestSettings settings)
}
EditorGUILayout.EndFoldoutHeaderGroup();
}

serializedObject.ApplyModifiedProperties();
GUILayout.FlexibleSpace();
EditorGUILayout.HelpBox(Messages.kShouldSynchronize, MessageType.Info, true);
Expand Down
124 changes: 124 additions & 0 deletions Editor/Remote/MacOSDependencyTools.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;

using UnityDebug = UnityEngine.Debug;

namespace UnityEditor.XR.MagicLeap
{
#if UNITY_EDITOR_OSX
class MacOSDependencyChecker
{
const string kRegexPattern = @"\t(.+) \(compatibility version \d{1,4}\.\d{1,4}\.\d{1,4}, current version \d{1,4}\.\d{1,4}\.\d{1,4}\)";

public class DependencyMap
{
public string file = null;
public List<string> dependencies = new List<string>();
}

internal static IEnumerable<string> LaunchOtool(string filepath)
{
var psi = new ProcessStartInfo {
FileName = "/usr/bin/otool",
Arguments = string.Format("-L {0}", filepath),
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true,
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false
};
using (Process p = Process.Start(psi))
{
var output = p.StandardOutput.ReadToEnd();
var error = p.StandardError.ReadToEnd();
p.WaitForExit();
return output.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
}
}

internal static DependencyMap GetDependencies(string file)
{
var regex = new Regex(kRegexPattern);
var dm = new DependencyMap { file = file };
var output = LaunchOtool(file);
foreach (var line in output)
{
var m = regex.Match(line);
if (m.Success)
{
var dep_path = m.Groups[1].Value;
foreach (var prefix in new string[] { "@loader_path", "@rpath"} )
dep_path = dep_path.Replace(prefix, Path.GetDirectoryName(file));
dm.dependencies.Add(dep_path);
}
}
return dm;
}

internal static void Migrate(string src, string dest)
{
var dir = Path.GetDirectoryName(dest);
using (new WorkingDirectoryShift(dir))
{
var psi = new ProcessStartInfo {
FileName = "lipo",
Arguments = string.Format("-create {0} -output {1}", src, Path.GetFileName(dest)),
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true
};
using (Process p = Process.Start(psi))
p.WaitForExit();

psi = new ProcessStartInfo {
FileName = "install_name_tool",
Arguments = string.Format("-id {0} {0}", Path.GetFileName(dest)),
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true
};
using (Process p = Process.Start(psi))
p.WaitForExit();

}

}

internal static void MigrateWithDependencies(string src, string dest)
{
var original_deps = GetDependencies(src);
Migrate(src, dest);
var new_deps = GetDependencies(dest);
var missing = new List<string>();
using (new WorkingDirectoryShift(Path.GetDirectoryName(dest)))
{
foreach (var dep in new_deps.dependencies)
{
if (File.Exists(dep))
continue;
else
missing.Add(dep);
}
}
foreach (var item in missing)
{
var dep_path = Path.GetFullPath(item);
if (!File.Exists(dep_path))
{
var dep_file = Path.GetFileName(item);
foreach (var old_dep in original_deps.dependencies)
{
if (Path.GetFileName(old_dep) == dep_file)
{
Directory.CreateDirectory(Path.GetDirectoryName(dep_path));
if (File.Exists(old_dep))
File.Copy(old_dep, dep_path);
}
}
}
}
}
}
#endif
}
11 changes: 11 additions & 0 deletions Editor/Remote/MacOSDependencyTools.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b7deb2e

Please sign in to comment.