update test based on ad-hoc CR in slack from team. (#78)

* update test based on ad-hoc CR in slack from team.

* Only use UnityTest when we need to skip frames, remove HoloLens binaries as these are no longer going to be used from this test project.
This commit is contained in:
Sean Stolberg 2019-05-06 15:35:07 -07:00 коммит произвёл GitHub Enterprise
Родитель 5aaff4e5cb
Коммит c32f0e835e
72 изменённых файлов: 110 добавлений и 4512 удалений

Просмотреть файл

@ -44,16 +44,8 @@ public class Build
case BuildTarget.PS4: case BuildTarget.PS4:
break; break;
} }
if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.WSAPlayer)
{
HoloToolkit.Unity.HoloToolkitCommands.BuildSLNAndAPPX(path + $"{Name}");
}
else
{
// Build player. // Build player.
BuildPipeline.BuildPlayer(EditorBuildSettings.scenes, path + $"{Name}" + $"{extension}", EditorUserBuildSettings.activeBuildTarget, BuildOptions.None); BuildPipeline.BuildPlayer(EditorBuildSettings.scenes, path + $"{Name}" + $"{extension}", EditorUserBuildSettings.activeBuildTarget, BuildOptions.None);
}
} }

Просмотреть файл

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: ee45a3e1088b44e6b97ce1887eff0510
timeCreated: 1551729795

Просмотреть файл

@ -1,54 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
namespace HoloToolkit.Unity
{
/// <summary>
/// Extensions for the action class.
/// These methods encapsulate the null check before raising an event for an Action.
/// </summary>
public static class ActionExtensions
{
public static void RaiseEvent(this Action action)
{
if (action != null)
{
action();
}
}
public static void RaiseEvent<T>(this Action<T> action, T arg)
{
if (action != null)
{
action(arg);
}
}
public static void RaiseEvent<T1, T2>(this Action<T1, T2> action, T1 arg1, T2 arg2)
{
if (action != null)
{
action(arg1, arg2);
}
}
public static void RaiseEvent<T1, T2, T3>(this Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3)
{
if (action != null)
{
action(arg1, arg2, arg3);
}
}
public static void RaiseEvent<T1, T2, T3, T4>(this Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
{
if (action != null)
{
action(arg1, arg2, arg3, arg4);
}
}
}
}

Просмотреть файл

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 0cc56044ef18aa942b078349f887608f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,741 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using UnityEditor;
using UnityEngine;
using UnityEngine.Networking;
using Debug = UnityEngine.Debug;
namespace HoloToolkit.Unity
{
/// <summary>
/// Function used to communicate with the device through the REST API
/// </summary>
public static class BuildDeployPortal
{
private enum AppInstallStatus
{
Invalid,
Installing,
InstallSuccess,
InstallFail
}
private const float TimeOut = 10.0f;
private const float MaxWaitTime = 20.0f;
// Device Portal API Resources
// https://docs.microsoft.com/en-us/windows/uwp/debug-test-perf/device-portal-api-hololens#holographic-os
// https://docs.microsoft.com/en-us/windows/uwp/debug-test-perf/device-portal-api-core
private static readonly string API_GetMachineNameQuery = @"{0}/api/os/machinename";
private static readonly string API_ProcessQuery = @"{0}/api/resourcemanager/processes";
private static readonly string API_PackagesQuery = @"{0}/api/appx/packagemanager/packages";
private static readonly string API_InstallQuery = @"{0}/api/app/packagemanager/package";
private static readonly string API_InstallStatusQuery = @"{0}/api/app/packagemanager/state";
private static readonly string API_AppQuery = @"{0}/api/taskmanager/app";
private static readonly string API_FileQuery = @"{0}/api/filesystem/apps/file?knownfolderid=LocalAppData&filename=UnityPlayer.log&packagefullname={1}&path=%5C%5CTempState";
private static readonly string API_IpConfigQuery = @"{0}/api/networking/ipconfig";
/// <summary>
/// Gets the Basic auth header.
/// <remarks>If you're using SSL and making HTTPS requests you must also specify if the request is of GET type or not,
/// so we know if we should append the "auto-" prefix to bypass CSRF.</remarks>
/// </summary>
/// <param name="connectionInfo">target device connection info.</param>
/// <param name="isGetRequest">If the request you're attempting to make is a GET type</param>
/// <returns></returns>
private static string GetBasicAuthHeader(ConnectInfo connectionInfo, bool isGetRequest = false)
{
var auth = string.Format("{0}{1}:{2}", BuildDeployPrefs.UseSSL && !isGetRequest ? "auto-" : "", connectionInfo.User, connectionInfo.Password);
auth = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(auth));
return string.Format("Basic {0}", auth);
}
/// <summary>
/// Send a Unity Web Request to GET.
/// </summary>
/// <param name="query">Full Query to GET</param>
/// <param name="auth">Authorization header</param>
/// <param name="showProgressDialog">Show the progress dialog.</param>
/// <returns>Response string.</returns>
private static string WebRequestGet(string query, string auth, bool showProgressDialog = true)
{
try
{
using (var webRequest = UnityWebRequest.Get(query))
{
webRequest.SetRequestHeader("Authorization", auth);
#if UNITY_2017_1_OR_NEWER
webRequest.timeout = (int)TimeOut;
#endif
#if UNITY_2017_2_OR_NEWER
webRequest.SendWebRequest();
#else
webRequest.Send();
#endif
while (!webRequest.isDone)
{
if (webRequest.downloadProgress > -1 && showProgressDialog)
{
EditorUtility.DisplayProgressBar("Connecting to Device Portal",
"Progress...", webRequest.downloadProgress);
}
}
if (showProgressDialog)
{
EditorUtility.ClearProgressBar();
}
if (
#if UNITY_2017_2_OR_NEWER
webRequest.isNetworkError || webRequest.isHttpError &&
#else
webRequest.isError &&
#endif
webRequest.responseCode != 401)
{
string response = string.Empty;
var responseHeaders = webRequest.GetResponseHeaders();
if (responseHeaders != null)
{
response = responseHeaders.Aggregate(string.Empty, (current, header) => string.Format("{0}{1}: {2}\n", current, header.Key, header.Value));
}
Debug.LogErrorFormat("Network Error: {0}\n{1}", webRequest.error, response);
return string.Empty;
}
switch (webRequest.responseCode)
{
case 200:
case 204:
return webRequest.downloadHandler.text;
case 401:
Debug.LogError("Unauthorized: Access is denied due to invalid credentials.");
break;
default:
Debug.LogError(webRequest.responseCode);
break;
}
}
}
catch (Exception e)
{
Debug.LogException(e);
}
return string.Empty;
}
/// <summary>
/// Send a Unity Web Request to POST.
/// </summary>
/// <param name="query">Full Query to GET</param>
/// <param name="postData">Post Data</param>
/// <param name="auth">Authorization Header</param>
/// <param name="showDialog">Show the progress dialog.</param>
/// <returns>Response string.</returns>
private static string WebRequestPost(string query, WWWForm postData, string auth, bool showDialog = true)
{
try
{
using (var webRequest = UnityWebRequest.Post(query, postData))
{
webRequest.SetRequestHeader("Authorization", auth);
#if UNITY_2017_1_OR_NEWER
webRequest.timeout = (int)TimeOut;
#endif
// HACK: Workaround for extra quotes around boundary.
string contentType = webRequest.GetRequestHeader("Content-Type");
if (contentType != null)
{
contentType = contentType.Replace("\"", "");
webRequest.SetRequestHeader("Content-Type", contentType);
}
#if UNITY_2017_2_OR_NEWER
webRequest.SendWebRequest();
#else
webRequest.Send();
#endif
while (!webRequest.isDone)
{
if (webRequest.uploadProgress > -1 && showDialog)
{
EditorUtility.DisplayProgressBar("Connecting to Device Portal",
"Uploading...", webRequest.uploadProgress);
}
else if (webRequest.downloadProgress > -1 && showDialog)
{
EditorUtility.DisplayProgressBar("Connecting to Device Portal",
"Progress...", webRequest.downloadProgress);
}
}
EditorUtility.ClearProgressBar();
if (
#if UNITY_2017_2_OR_NEWER
webRequest.isNetworkError || webRequest.isHttpError &&
#else
webRequest.isError &&
#endif
webRequest.responseCode != 401)
{
string response = string.Empty;
var responseHeaders = webRequest.GetResponseHeaders();
if (responseHeaders != null)
{
response = responseHeaders.Aggregate(string.Empty, (current, header) => string.Format("{0}{1}: {2}\n", current, header.Key, header.Value));
}
Debug.LogErrorFormat("Network Error: {0}\n{1}", webRequest.error, response);
return string.Empty;
}
switch (webRequest.responseCode)
{
case 200:
case 202:
return webRequest.downloadHandler.text;
case 401:
Debug.LogError("Unauthorized: Access is denied due to invalid credentials.");
break;
default:
Debug.LogError(webRequest.responseCode);
break;
}
}
}
catch (Exception e)
{
Debug.LogException(e);
}
return string.Empty;
}
/// <summary>
/// Send a Unity Web Request to DELETE
/// </summary>
/// <param name="query">Full Query.</param>
/// <param name="auth">Authorization Header</param>
/// <param name="showDialog">Show to progress dialog</param>
/// <returns>Successful or not.</returns>
private static bool WebRequestDelete(string query, string auth, bool showDialog = true)
{
try
{
using (var webRequest = UnityWebRequest.Delete(query))
{
webRequest.SetRequestHeader("Authorization", auth);
#if UNITY_2017_1_OR_NEWER
webRequest.timeout = (int)TimeOut;
#endif
#if UNITY_2017_2_OR_NEWER
webRequest.SendWebRequest();
#else
webRequest.Send();
#endif
while (!webRequest.isDone)
{
if (showDialog && webRequest.downloadProgress > -1)
{
EditorUtility.DisplayProgressBar("Connecting to Device Portal",
"Progress...", webRequest.downloadProgress);
}
}
EditorUtility.ClearProgressBar();
if (
#if UNITY_2017_2_OR_NEWER
webRequest.isNetworkError || webRequest.isHttpError &&
#else
webRequest.isError &&
#endif
webRequest.responseCode != 401)
{
string response = string.Empty;
var responseHeaders = webRequest.GetResponseHeaders();
if (responseHeaders != null)
{
response = responseHeaders.Aggregate(string.Empty, (current, header) => string.Format("{0}{1}: {2}\n", current, header.Key, header.Value));
}
Debug.LogErrorFormat("Network Error: {0}\n{1}", webRequest.error, response);
return false;
}
switch (webRequest.responseCode)
{
case 200:
return true;
case 401:
Debug.LogError("Unauthorized: Access is denied due to invalid credentials.");
break;
default:
Debug.LogError(webRequest.responseCode);
break;
}
}
}
catch (Exception e)
{
Debug.LogException(e);
}
return false;
}
/// <summary>
/// Opens the Device Portal for the target device.
/// </summary>
/// <param name="targetDevice"></param>
public static void OpenWebPortal(ConnectInfo targetDevice)
{
//TODO: Figure out how to pass username and password to browser?
Process.Start(FinalizeUrl(targetDevice.IP));
}
/// <summary>
/// Gets the <see cref="MachineName"/> of the target device.
/// </summary>
/// <param name="targetDevice"></param>
/// <returns><see cref="MachineName"/></returns>
public static MachineName GetMachineName(ConnectInfo targetDevice)
{
MachineName machineName = null;
string query = string.Format(API_GetMachineNameQuery, FinalizeUrl(targetDevice.IP));
string response = WebRequestGet(query, GetBasicAuthHeader(targetDevice, true), false);
if (!string.IsNullOrEmpty(response))
{
machineName = JsonUtility.FromJson<MachineName>(response);
}
return machineName;
}
[Obsolete("Use IsAppInstalled(string packageFamilyName, ConnectInfo targetDevice)")]
public static bool IsAppInstalled(string packageFamilyName, string targetIp)
{
return QueryAppDetails(packageFamilyName, new ConnectInfo(targetIp, BuildDeployPrefs.DeviceUser, BuildDeployPrefs.DevicePassword)) != null;
}
/// <summary>
/// Determines if the target application is currently running on the target device.
/// </summary>
/// <param name="packageFamilyName"></param>
/// <param name="targetDevice"></param>
/// <returns>True, if application is currently installed on device.</returns>
public static bool IsAppInstalled(string packageFamilyName, ConnectInfo targetDevice)
{
return QueryAppDetails(packageFamilyName, targetDevice) != null;
}
[Obsolete("IsAppRunning(string appName, ConnectInfo targetDevice)")]
public static bool IsAppRunning(string appName, string targetDevice)
{
return IsAppRunning(appName, new ConnectInfo(targetDevice, BuildDeployPrefs.DeviceUser, BuildDeployPrefs.DevicePassword));
}
/// <summary>
/// Determines if the target application is running on the target device.
/// </summary>
/// <param name="appName"></param>
/// <param name="targetDevice"></param>
/// <returns>True, if the application is running.</returns>
public static bool IsAppRunning(string appName, ConnectInfo targetDevice)
{
string response = WebRequestGet(string.Format(API_ProcessQuery, FinalizeUrl(targetDevice.IP)), GetBasicAuthHeader(targetDevice, true), false);
if (!string.IsNullOrEmpty(response))
{
var processList = JsonUtility.FromJson<ProcessList>(response);
for (int i = 0; i < processList.Processes.Length; ++i)
{
string processName = processList.Processes[i].ImageName;
if (processName.Contains(appName))
{
return true;
}
}
}
return false;
}
/// <summary>
/// Returns the <see cref="AppDetails"/> of the target application from the target device.
/// </summary>
/// <param name="packageFamilyName"></param>
/// <param name="targetDevice"></param>
/// <returns>null if application is not currently installed on the target device.</returns>
private static AppDetails QueryAppDetails(string packageFamilyName, ConnectInfo targetDevice)
{
string response = WebRequestGet(string.Format(API_PackagesQuery, FinalizeUrl(targetDevice.IP)), GetBasicAuthHeader(targetDevice, true), false);
if (!string.IsNullOrEmpty(response))
{
var appList = JsonUtility.FromJson<AppList>(response);
for (int i = 0; i < appList.InstalledPackages.Length; ++i)
{
string thisAppName = appList.InstalledPackages[i].PackageFamilyName;
if (thisAppName.Equals(packageFamilyName, StringComparison.OrdinalIgnoreCase))
{
return appList.InstalledPackages[i];
}
}
}
return null;
}
/// <summary>
/// Installs the target application on the target device.
/// </summary>
/// <param name="appFullPath"></param>
/// <param name="targetDevice"></param>
/// <param name="waitForDone">Should the thread wait until installation is complete?</param>
/// <returns>True, if Installation was a success.</returns>
public static bool InstallApp(string appFullPath, ConnectInfo targetDevice, bool waitForDone = true)
{
bool success = false;
try
{
// Calculate the cert and dependency paths
string fileName = Path.GetFileName(appFullPath);
string certFullPath = Path.ChangeExtension(appFullPath, ".cer");
string certName = Path.GetFileName(certFullPath);
string depPath = Path.GetDirectoryName(appFullPath) + @"\Dependencies\x86\";
// Post it using the REST API
var form = new WWWForm();
// APPX file
Debug.Assert(appFullPath != null);
using (var stream = new FileStream(appFullPath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var reader = new BinaryReader(stream))
{
form.AddBinaryData(fileName, reader.ReadBytes((int)reader.BaseStream.Length), fileName);
}
}
// CERT file
Debug.Assert(certFullPath != null);
using (var stream = new FileStream(certFullPath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var reader = new BinaryReader(stream))
{
form.AddBinaryData(certName, reader.ReadBytes((int)reader.BaseStream.Length), certName);
}
}
// Dependencies
FileInfo[] depFiles = new DirectoryInfo(depPath).GetFiles();
foreach (FileInfo dep in depFiles)
{
using (var stream = new FileStream(dep.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var reader = new BinaryReader(stream))
{
string depFilename = Path.GetFileName(dep.FullName);
form.AddBinaryData(depFilename, reader.ReadBytes((int)reader.BaseStream.Length), depFilename);
}
}
}
// Query
string query = string.Format(API_InstallQuery, FinalizeUrl(targetDevice.IP));
query += "?package=" + WWW.EscapeURL(fileName);
var response = WebRequestPost(query, form, GetBasicAuthHeader(targetDevice));
if (string.IsNullOrEmpty(response))
{
Debug.LogErrorFormat("Failed to install {0} on {1}.\n", fileName, targetDevice.MachineName);
return false;
}
// Wait for done (if requested)
DateTime waitStartTime = DateTime.Now;
while (waitForDone && (DateTime.Now - waitStartTime).TotalSeconds < MaxWaitTime)
{
EditorUtility.DisplayProgressBar("Connecting to Device Portal", "Installing...", (float)((DateTime.Now - waitStartTime).TotalSeconds / MaxWaitTime));
AppInstallStatus status = GetInstallStatus(targetDevice);
if (status == AppInstallStatus.InstallSuccess)
{
Debug.LogFormat("Successfully installed {0} on {1}.", fileName, targetDevice.MachineName);
success = true;
break;
}
if (status == AppInstallStatus.InstallFail)
{
Debug.LogErrorFormat("Failed to install {0} on {1}.\n", fileName, targetDevice.MachineName);
break;
}
// Wait a bit and we'll ask again
Thread.Sleep(1000);
}
EditorUtility.ClearProgressBar();
}
catch (Exception e)
{
Debug.LogException(e);
success = false;
}
return success;
}
private static AppInstallStatus GetInstallStatus(ConnectInfo targetDevice)
{
string response = WebRequestGet(string.Format(API_InstallStatusQuery, FinalizeUrl(targetDevice.IP)), GetBasicAuthHeader(targetDevice, true), false);
if (!string.IsNullOrEmpty(response))
{
var status = JsonUtility.FromJson<InstallStatus>(response);
if (status == null)
{
return AppInstallStatus.Installing;
}
if (status.Success)
{
return AppInstallStatus.InstallSuccess;
}
Debug.LogError(status.Reason + "(" + status.CodeText + ")");
}
else
{
return AppInstallStatus.Installing;
}
return AppInstallStatus.InstallFail;
}
[Obsolete("Use UninstallApp(string packageFamilyName, ConnectInfo targetDevice)")]
public static bool UninstallApp(string packageFamilyName, string targetIp)
{
return UninstallApp(packageFamilyName, new ConnectInfo(targetIp, BuildDeployPrefs.DeviceUser, BuildDeployPrefs.DevicePassword));
}
/// <summary>
/// Uninstalls the target application on the target device.
/// </summary>
/// <param name="packageFamilyName"></param>
/// <param name="targetDevice"></param>
/// <param name="showDialog"></param>
/// <returns>True, if uninstall was a success.</returns>
public static bool UninstallApp(string packageFamilyName, ConnectInfo targetDevice, bool showDialog = true)
{
AppDetails appDetails = QueryAppDetails(packageFamilyName, targetDevice);
if (appDetails == null)
{
Debug.Log(string.Format("Application '{0}' not found", packageFamilyName));
return false;
}
string query = string.Format("{0}?package={1}",
string.Format(API_InstallQuery, FinalizeUrl(targetDevice.IP)),
WWW.EscapeURL(appDetails.PackageFullName));
bool success = WebRequestDelete(query, GetBasicAuthHeader(targetDevice), showDialog);
MachineName targetMachine = GetMachineName(targetDevice);
if (success)
{
Debug.LogFormat("Successfully uninstalled {0} on {1}.", packageFamilyName, targetMachine.ComputerName);
}
else
{
Debug.LogErrorFormat("Failed to uninstall {0} on {1}", packageFamilyName, targetMachine.ComputerName);
}
return success;
}
/// <summary>
/// Launches the target application on the target device.
/// </summary>
/// <param name="packageFamilyName"></param>
/// <param name="targetDevice"></param>
/// <param name="showDialog"></param>
/// <returns>True, if application was successfully launched and is currently running on the target device.</returns>
public static bool LaunchApp(string packageFamilyName, ConnectInfo targetDevice, bool showDialog = true)
{
// Find the app description
AppDetails appDetails = QueryAppDetails(packageFamilyName, targetDevice);
if (appDetails == null)
{
Debug.LogWarning("Application not found");
return false;
}
string query = string.Format(API_AppQuery, FinalizeUrl(targetDevice.IP)) +
string.Format("?appid={0}&package={1}",
WWW.EscapeURL(EncodeTo64(appDetails.PackageRelativeId)),
WWW.EscapeURL(appDetails.PackageFullName));
WebRequestPost(query, null, GetBasicAuthHeader(targetDevice), false);
return IsAppRunning(PlayerSettings.productName, targetDevice);
}
[Obsolete("KillApp(string packageFamilyName, ConnectInfo targetDevice)")]
public static bool KillApp(string packageFamilyName, string targetIp)
{
return KillApp(packageFamilyName, new ConnectInfo(targetIp, BuildDeployPrefs.DeviceUser, BuildDeployPrefs.DevicePassword));
}
/// <summary>
/// Kills the target application on the target device.
/// </summary>
/// <param name="packageFamilyName"></param>
/// <param name="targetDevice"></param>
/// <param name="showDialog"></param>
/// <returns>true, if application was successfully stopped.</returns>
public static bool KillApp(string packageFamilyName, ConnectInfo targetDevice, bool showDialog = true)
{
AppDetails appDetails = QueryAppDetails(packageFamilyName, targetDevice);
if (appDetails == null)
{
Debug.LogError("Application not found");
return false;
}
string query = string.Format("{0}?package={1}",
string.Format(API_AppQuery, FinalizeUrl(targetDevice.IP)),
WWW.EscapeURL(EncodeTo64(appDetails.PackageFullName)));
bool success = WebRequestDelete(query, GetBasicAuthHeader(targetDevice), showDialog);
MachineName targetMachine = GetMachineName(targetDevice);
if (success)
{
Debug.LogFormat("Successfully stopped {0} on {1}.", packageFamilyName, targetMachine.ComputerName);
}
return success;
}
[Obsolete("DeviceLogFile_View(string packageFamilyName, ConnectInfo targetDevice)")]
public static bool DeviceLogFile_View(string packageFamilyName, string targetIp)
{
return DeviceLogFile_View(packageFamilyName, new ConnectInfo(targetIp, BuildDeployPrefs.DeviceUser, BuildDeployPrefs.DevicePassword));
}
/// <summary>
/// Downloads and launches the Log file for the target application on the target device.
/// </summary>
/// <param name="packageFamilyName"></param>
/// <param name="targetDevice"></param>
/// <returns>True, if download success.</returns>
public static bool DeviceLogFile_View(string packageFamilyName, ConnectInfo targetDevice)
{
EditorUtility.DisplayProgressBar("Download Log", "Downloading Log File for " + packageFamilyName, 0.25f);
AppDetails appDetails = QueryAppDetails(packageFamilyName, targetDevice);
if (appDetails == null)
{
Debug.LogWarningFormat("{0} not installed on target device", packageFamilyName);
EditorUtility.ClearProgressBar();
return false;
}
string logFile = string.Format("{0}/{1}_{2}{3}{4}{5}{6}{7}_deviceLog.txt",
Application.temporaryCachePath,
targetDevice.MachineName,
DateTime.Now.Year,
DateTime.Now.Month,
DateTime.Now.Day,
DateTime.Now.Hour,
DateTime.Now.Minute,
DateTime.Now.Second);
string response = WebRequestGet(string.Format(API_FileQuery, FinalizeUrl(targetDevice.IP), appDetails.PackageFullName), GetBasicAuthHeader(targetDevice, true));
bool success = !string.IsNullOrEmpty(response);
if (success)
{
File.WriteAllText(logFile, response);
Process.Start(logFile);
}
EditorUtility.ClearProgressBar();
return success;
}
/// <summary>
/// Returns the <see cref="NetworkInfo"/> for the target device.
/// </summary>
/// <param name="targetDevice"></param>
/// <returns></returns>
public static NetworkInfo GetNetworkInfo(ConnectInfo targetDevice)
{
string response = WebRequestGet(string.Format(API_IpConfigQuery, FinalizeUrl(targetDevice.IP)), GetBasicAuthHeader(targetDevice, true), false);
if (!string.IsNullOrEmpty(response))
{
return JsonUtility.FromJson<NetworkInfo>(response);
}
return null;
}
/// <summary>
/// This Utility method finalizes the URL and formats the HTTPS string if needed.
/// <remarks>Local Machine will be changed to 127.0.1:10080 for HoloLens connections.</remarks>
/// </summary>
/// <param name="targetUrl"></param>
/// <returns></returns>
private static string FinalizeUrl(string targetUrl)
{
string ssl = BuildDeployPrefs.UseSSL ? "s" : string.Empty;
if (targetUrl.Contains("Local Machine"))
{
targetUrl = "127.0.0.1:10080";
ssl = string.Empty;
}
return string.Format(@"http{0}://{1}", ssl, targetUrl);
}
private static string EncodeTo64(string toEncode)
{
byte[] toEncodeAsBytes = Encoding.ASCII.GetBytes(toEncode);
string returnValue = Convert.ToBase64String(toEncodeAsBytes);
return returnValue;
}
private static string DecodeFrom64(string encodedData)
{
byte[] encodedDataAsBytes = Convert.FromBase64String(encodedData);
string returnValue = Encoding.ASCII.GetString(encodedDataAsBytes);
return returnValue;
}
}
}

Просмотреть файл

@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 09ea77b2be8b62b4a9c86c123cd5ddbe
timeCreated: 1466615025
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,129 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
using System.IO;
using UnityEngine;
namespace HoloToolkit.Unity
{
public static class BuildDeployPrefs
{
// Constants
private const string EditorPrefs_BuildDir = "_BuildDeployWindow_BuildDir";
private const string EditorPrefs_BuildConfig = "_BuildDeployWindow_BuildConfig";
private const string EditorPrefs_BuildPlatform = "_BuildDeployWindow_BuildPlatform";
private const string EditorPrefs_ForceRebuild = "_BuildDeployWindow_ForceBuild";
private const string EditorPrefs_IncrementBuildVersion = "_BuildDeployWindow_IncrementBuildVersion";
private const string EditorPrefs_MSBuildVer = "_BuildDeployWindow_MSBuildVer";
private const string EditorPrefs_TargetIPs = "_BuildDeployWindow_DestIPs";
private const string EditorPrefs_ConnectInfos = "_BuildDeployWindow_ConnectInfos";
private const string EditorPrefs_DeviceUser = "_BuildDeployWindow_DeviceUser";
private const string EditorPrefs_DevicePwd = "_BuildDeployWindow_DevicePwd";
private const string EditorPrefs_FullReinstall = "_BuildDeployWindow_FullReinstall";
private const string EditorPrefs_UseSSL = "_BuildDeployWindow_UseSSL";
private const string EditorPrefs_ProcessAll = "_BuildDeployWindow_ProcessAll";
public static string BuildDirectory
{
get { return EditorPrefsUtility.GetEditorPref(EditorPrefs_BuildDir, "UWP"); }
set { EditorPrefsUtility.SetEditorPref(EditorPrefs_BuildDir, value); }
}
public static string AbsoluteBuildDirectory
{
get
{
string rootBuildDirectory = BuildDirectory;
int dirCharIndex = rootBuildDirectory.IndexOf("/", StringComparison.Ordinal);
if (dirCharIndex != -1)
{
rootBuildDirectory = rootBuildDirectory.Substring(0, dirCharIndex);
}
return Path.GetFullPath(Path.Combine(Path.Combine(Application.dataPath, ".."), rootBuildDirectory));
}
}
public static string MsBuildVersion
{
get { return EditorPrefsUtility.GetEditorPref(EditorPrefs_MSBuildVer, BuildDeployTools.DefaultMSBuildVersion); }
set { EditorPrefsUtility.SetEditorPref(EditorPrefs_MSBuildVer, value); }
}
public static string BuildConfig
{
get { return EditorPrefsUtility.GetEditorPref(EditorPrefs_BuildConfig, "Debug"); }
set { EditorPrefsUtility.SetEditorPref(EditorPrefs_BuildConfig, value); }
}
public static string BuildPlatform
{
get { return EditorPrefsUtility.GetEditorPref(EditorPrefs_BuildPlatform, "x86"); }
set { EditorPrefsUtility.SetEditorPref(EditorPrefs_BuildPlatform, value); }
}
public static bool ForceRebuild
{
get { return EditorPrefsUtility.GetEditorPref(EditorPrefs_ForceRebuild, false); }
set { EditorPrefsUtility.SetEditorPref(EditorPrefs_ForceRebuild, value); }
}
public static bool IncrementBuildVersion
{
get { return EditorPrefsUtility.GetEditorPref(EditorPrefs_IncrementBuildVersion, true); }
set { EditorPrefsUtility.SetEditorPref(EditorPrefs_IncrementBuildVersion, value); }
}
public static bool FullReinstall
{
get { return EditorPrefsUtility.GetEditorPref(EditorPrefs_FullReinstall, true); }
set { EditorPrefsUtility.SetEditorPref(EditorPrefs_FullReinstall, value); }
}
public static string DevicePortalConnections
{
get
{
return EditorPrefsUtility.GetEditorPref(
EditorPrefs_ConnectInfos,
JsonUtility.ToJson(
new DevicePortalConnections(
new ConnectInfo("127.0.0.1", string.Empty, string.Empty, "Local Machine"))));
}
set { EditorPrefsUtility.SetEditorPref(EditorPrefs_ConnectInfos, value); }
}
[Obsolete("Use DevicePortalConnections")]
public static string DeviceUser
{
get { return EditorPrefsUtility.GetEditorPref(EditorPrefs_DeviceUser, string.Empty); }
set { EditorPrefsUtility.SetEditorPref(EditorPrefs_DeviceUser, value); }
}
[Obsolete("Use DevicePortalConnections")]
public static string DevicePassword
{
get { return EditorPrefsUtility.GetEditorPref(EditorPrefs_DevicePwd, string.Empty); }
set { EditorPrefsUtility.SetEditorPref(EditorPrefs_DevicePwd, value); }
}
[Obsolete("Use DevicePortalConnections")]
public static string TargetIPs
{
get { return EditorPrefsUtility.GetEditorPref(EditorPrefs_TargetIPs, "127.0.0.1"); }
set { EditorPrefsUtility.SetEditorPref(EditorPrefs_TargetIPs, value); }
}
public static bool UseSSL
{
get { return EditorPrefsUtility.GetEditorPref(EditorPrefs_UseSSL, true); }
set { EditorPrefsUtility.SetEditorPref(EditorPrefs_UseSSL, value); }
}
public static bool TargetAllConnections
{
get { return EditorPrefsUtility.GetEditorPref(EditorPrefs_ProcessAll, false); }
set { EditorPrefsUtility.SetEditorPref(EditorPrefs_ProcessAll, value); }
}
}
}

Просмотреть файл

@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 6762008b7153ae94ab1f370faf6bbca0
timeCreated: 1468891604
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,390 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Microsoft.Win32;
using UnityEditor;
using UnityEngine;
using Debug = UnityEngine.Debug;
namespace HoloToolkit.Unity
{
/// <summary>
/// Contains utility functions for building for the device
/// </summary>
public class BuildDeployTools
{
public const string DefaultMSBuildVersion = "15.0";
public static bool CanBuild()
{
if (PlayerSettings.GetScriptingBackend(BuildTargetGroup.WSA) == ScriptingImplementation.IL2CPP &&
IsIl2CppAvailable())
{
return true;
}
return PlayerSettings.GetScriptingBackend(BuildTargetGroup.WSA) == ScriptingImplementation.WinRTDotNET &&
IsDotNetAvailable();
}
public static bool IsDotNetAvailable()
{
return Directory.Exists(EditorApplication.applicationContentsPath +
"\\PlaybackEngines\\MetroSupport\\Managed\\UAP");
}
public static bool IsIl2CppAvailable()
{
return Directory.Exists(EditorApplication.applicationContentsPath +
"\\PlaybackEngines\\MetroSupport\\Managed\\il2cpp");
}
/// <summary>
/// Displays a dialog if no scenes are present in the build and returns true if build can proceed.
/// </summary>
/// <returns></returns>
public static bool CheckBuildScenes()
{
if (EditorBuildSettings.scenes.Length == 0)
{
return EditorUtility.DisplayDialog("Attention!",
"No scenes are present in the build settings!\n\n Do you want to cancel and add one?",
"Continue Anyway", "Cancel Build");
}
return true;
}
/// <summary>
/// Do a build configured for Mixed Reality Applications, returns the error from BuildPipeline.BuildPlayer
/// </summary>
public static bool BuildSLN()
{
return BuildSLN(BuildDeployPrefs.BuildDirectory, false);
}
public static bool BuildSLN(string buildDirectory, bool showDialog = true)
{
// Use BuildSLNUtilities to create the SLN
bool buildSuccess = false;
if (CheckBuildScenes() == false)
{
return false;
}
var buildInfo = new BuildInfo
{
// These properties should all match what the Standalone.proj file specifies
OutputDirectory = buildDirectory,
Scenes = EditorBuildSettings.scenes.Where(scene => scene.enabled).Select(scene => scene.path),
BuildTarget = BuildTarget.WSAPlayer,
WSASdk = WSASDK.UWP,
WSAUWPBuildType = EditorUserBuildSettings.wsaUWPBuildType,
WSAUwpSdk = EditorUserBuildSettings.wsaUWPSDK,
// Configure a post build action that will compile the generated solution
PostBuildAction = (innerBuildInfo, buildError) =>
{
if (!string.IsNullOrEmpty(buildError))
{
//EditorUtility.DisplayDialog(PlayerSettings.productName + " WindowsStoreApp Build Failed!", buildError, "OK");
}
else
{
if (showDialog)
{
if (!EditorUtility.DisplayDialog(PlayerSettings.productName, "Build Complete", "OK",
"Build AppX"))
{
BuildAppxFromSLN(
PlayerSettings.productName,
BuildDeployPrefs.MsBuildVersion,
BuildDeployPrefs.ForceRebuild,
BuildDeployPrefs.BuildConfig,
BuildDeployPrefs.BuildPlatform,
BuildDeployPrefs.BuildDirectory,
BuildDeployPrefs.IncrementBuildVersion);
}
}
buildSuccess = true;
}
}
};
BuildSLNUtilities.RaiseOverrideBuildDefaults(ref buildInfo);
BuildSLNUtilities.PerformBuild(buildInfo);
return buildSuccess;
}
public static string CalcMSBuildPath(string msBuildVersion)
{
#if UNITY_WINDOWS
if (msBuildVersion.Equals("14.0"))
{
using (RegistryKey key =
Registry.LocalMachine.OpenSubKey(
string.Format(@"Software\Microsoft\MSBuild\ToolsVersions\{0}", msBuildVersion)))
{
if (key != null)
{
var msBuildBinFolder = (string)key.GetValue("MSBuildToolsPath");
return Path.Combine(msBuildBinFolder, "msbuild.exe");
}
}
}
#endif
// If we got this far then we don't have VS 2015 installed and need to use msBuild 15
msBuildVersion = "15.0";
// For MSBuild 15+ we should to use vswhere to give us the correct instance
string output = @"/C vswhere -version " + msBuildVersion +
" -products * -requires Microsoft.Component.MSBuild -property installationPath";
// get the right program files path based on whether the PC is x86 or x64
string programFiles = @"C:\Program Files (x86)\Microsoft Visual Studio\Installer";
var vswherePInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = false,
Arguments = output,
WorkingDirectory = programFiles
};
using (var vswhereP = new Process())
{
vswhereP.StartInfo = vswherePInfo;
vswhereP.Start();
output = vswhereP.StandardOutput.ReadToEnd();
vswhereP.WaitForExit();
}
string[] paths = output.Split(new[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries);
if (paths.Length > 0)
{
// if there are multiple 2017 installs,
// prefer enterprise, then pro, then community
string bestPath = paths.OrderBy(p => p.ToLower().Contains("enterprise"))
.ThenBy(p => p.ToLower().Contains("professional"))
.ThenBy(p => p.ToLower().Contains("community")).First();
return bestPath + @"\MSBuild\" + msBuildVersion + @"\Bin\MSBuild.exe";
}
Debug.LogError("Unable to find a valid path to Visual Studio Instance!");
return string.Empty;
}
public static bool RestoreNugetPackages(string nugetPath, string storePath)
{
Debug.Assert(File.Exists(nugetPath));
Debug.Assert(Directory.Exists(storePath));
var nugetPInfo = new ProcessStartInfo
{
FileName = nugetPath,
CreateNoWindow = true,
UseShellExecute = false,
Arguments = "restore \"" + storePath + "/project.json\""
};
using (var nugetP = new Process())
{
nugetP.StartInfo = nugetPInfo;
nugetP.Start();
nugetP.WaitForExit();
nugetP.Close();
nugetP.Dispose();
}
return File.Exists(storePath + "\\project.lock.json");
}
public static bool BuildAppxFromSLN(string productName, string msBuildVersion, bool forceRebuildAppx,
string buildConfig, string buildPlatform, string buildDirectory, bool incrementVersion,
bool showDialog = true)
{
EditorUtility.DisplayProgressBar("Build AppX", "Building AppX Package...", 0);
string slnFilename = Path.Combine(buildDirectory, PlayerSettings.productName + ".sln");
if (!File.Exists(slnFilename))
{
Debug.LogError("Unable to find Solution to build from!");
EditorUtility.ClearProgressBar();
return false;
}
// Get and validate the msBuild path...
var msBuildPath = CalcMSBuildPath(msBuildVersion);
if (!File.Exists(msBuildPath))
{
Debug.LogErrorFormat("MSBuild.exe is missing or invalid (path={0}).", msBuildPath);
EditorUtility.ClearProgressBar();
return false;
}
// Get the path to the NuGet tool
string unity = Path.GetDirectoryName(EditorApplication.applicationPath);
System.Diagnostics.Debug.Assert(unity != null, "unity != null");
string storePath = Path.GetFullPath(Path.Combine(Path.Combine(Application.dataPath, ".."), buildDirectory));
string solutionProjectPath = Path.GetFullPath(Path.Combine(storePath, productName + @".sln"));
// Bug in Unity editor that doesn't copy project.json and project.lock.json files correctly if solutionProjectPath is not in a folder named UWP.
if (!File.Exists(storePath + "\\project.json"))
{
File.Copy(unity + @"\Data\PlaybackEngines\MetroSupport\Tools\project.json",
storePath + "\\project.json");
}
string nugetPath = Path.Combine(unity, @"Data\PlaybackEngines\MetroSupport\Tools\NuGet.exe");
string assemblyCSharp = storePath + "/GeneratedProjects/UWP/Assembly-CSharp";
string assemblyCSharpFirstPass = storePath + "/GeneratedProjects/UWP/Assembly-CSharp-firstpass";
bool restoreFirstPass = Directory.Exists(assemblyCSharpFirstPass);
// Before building, need to run a nuget restore to generate a json.lock file. Failing to do
// this breaks the build in VS RTM
if (PlayerSettings.GetScriptingBackend(BuildTargetGroup.WSA) == ScriptingImplementation.WinRTDotNET &&
(!RestoreNugetPackages(nugetPath, storePath) ||
!RestoreNugetPackages(nugetPath, storePath + "\\" + productName) ||
!RestoreNugetPackages(nugetPath, assemblyCSharp) ||
restoreFirstPass &&
!RestoreNugetPackages(nugetPath, assemblyCSharpFirstPass)))
{
Debug.LogError("Failed to restore nuget packages");
EditorUtility.ClearProgressBar();
return false;
}
EditorUtility.DisplayProgressBar("Build AppX", "Building AppX Package...", 25);
// Ensure that the generated .appx version increments by modifying
// Package.appxmanifest
if (incrementVersion)
{
IncrementPackageVersion();
}
// Now do the actual build
var pInfo = new ProcessStartInfo
{
FileName = msBuildPath,
CreateNoWindow = false,
Arguments = string.Format("\"{0}\" /t:{1} /p:Configuration={2} /p:Platform={3} /verbosity:m",
solutionProjectPath,
forceRebuildAppx ? "Rebuild" : "Build",
buildConfig,
buildPlatform)
};
// Uncomment out to debug by copying into command window
//Debug.Log("\"" + vs + "\"" + " " + pInfo.Arguments);
var process = new Process {StartInfo = pInfo};
try
{
if (!process.Start())
{
Debug.LogError("Failed to start Cmd process!");
EditorUtility.ClearProgressBar();
return false;
}
process.WaitForExit();
EditorUtility.ClearProgressBar();
if (process.ExitCode == 0 &&
showDialog &&
!EditorUtility.DisplayDialog("Build AppX", "AppX Build Successful!", "OK", "Open AppX Folder"))
{
Process.Start("explorer.exe",
"/f /open," + Path.GetFullPath(BuildDeployPrefs.BuildDirectory + "/" +
PlayerSettings.productName + "/AppPackages"));
}
if (process.ExitCode != 0)
{
Debug.LogError("MSBuild error (code = " + process.ExitCode + ")");
EditorUtility.DisplayDialog(PlayerSettings.productName + " build Failed!",
"Failed to build appx from solution. Error code: " + process.ExitCode, "OK");
return false;
}
process.Close();
process.Dispose();
}
catch (Exception e)
{
Debug.LogError("Cmd Process EXCEPTION: " + e);
EditorUtility.ClearProgressBar();
return false;
}
return true;
}
private static void IncrementPackageVersion()
{
// Find the manifest, assume the one we want is the first one
string[] manifests = Directory.GetFiles(BuildDeployPrefs.AbsoluteBuildDirectory, "Package.appxmanifest",
SearchOption.AllDirectories);
if (manifests.Length == 0)
{
Debug.LogError("Unable to find Package.appxmanifest file for build (in path - " +
BuildDeployPrefs.AbsoluteBuildDirectory + ")");
return;
}
string manifest = manifests[0];
var rootNode = XElement.Load(manifest);
var identityNode = rootNode.Element(rootNode.GetDefaultNamespace() + "Identity");
if (identityNode == null)
{
Debug.LogError("Package.appxmanifest for build (in path - " + BuildDeployPrefs.AbsoluteBuildDirectory +
") is missing an <Identity /> node");
return;
}
// We use XName.Get instead of string -> XName implicit conversion because
// when we pass in the string "Version", the program doesn't find the attribute.
// Best guess as to why this happens is that implicit string conversion doesn't set the namespace to empty
var versionAttr = identityNode.Attribute(XName.Get("Version"));
if (versionAttr == null)
{
Debug.LogError("Package.appxmanifest for build (in path - " + BuildDeployPrefs.AbsoluteBuildDirectory +
") is missing a version attribute in the <Identity /> node.");
return;
}
// Assume package version always has a '.' between each number.
// According to https://msdn.microsoft.com/en-us/library/windows/apps/br211441.aspx
// Package versions are always of the form Major.Minor.Build.Revision.
// Note: Revision number reserved for Windows Store, and a value other than 0 will fail WACK.
var version = PlayerSettings.WSA.packageVersion;
var newVersion = new Version(version.Major, version.Minor, version.Build + 1, version.Revision);
PlayerSettings.WSA.packageVersion = newVersion;
versionAttr.Value = newVersion.ToString();
rootNode.Save(manifest);
}
}
}

Просмотреть файл

@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: bc185db46b00c9840b977f9e46183160
timeCreated: 1466615028
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 6d8b4a3eedcdf774bbc71cc2a08da79f
timeCreated: 1466615027
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,98 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace HoloToolkit.Unity
{
public class BuildInfo
{
public string OutputDirectory { get; set; }
public IEnumerable<string> Scenes { get; set; }
public IEnumerable<CopyDirectoryInfo> CopyDirectories { get; set; }
public Action<BuildInfo> PreBuildAction { get; set; }
public Action<BuildInfo, string> PostBuildAction { get; set; }
public BuildOptions BuildOptions { get; set; }
public BuildTarget BuildTarget { get; set; }
public WSASDK? WSASdk { get; set; }
public string WSAUwpSdk { get; set; }
public WSAUWPBuildType? WSAUWPBuildType { get; set; }
public bool? WSAGenerateReferenceProjects { get; set; }
public ColorSpace? ColorSpace { get; set; }
public bool IsCommandLine { get; set; }
public string BuildSymbols { get; private set; }
public BuildInfo()
{
BuildSymbols = string.Empty;
}
public void AppendSymbols(params string[] symbol)
{
AppendSymbols((IEnumerable<string>)symbol);
}
public void AppendSymbols(IEnumerable<string> symbols)
{
string[] toAdd = symbols.Except(BuildSymbols.Split(';'))
.Where(sym => !string.IsNullOrEmpty(sym)).ToArray();
if (!toAdd.Any())
{
return;
}
if (!string.IsNullOrEmpty(BuildSymbols))
{
BuildSymbols += ";";
}
BuildSymbols += string.Join(";", toAdd);
}
public bool HasAnySymbols(params string[] symbols)
{
return BuildSymbols.Split(';').Intersect(symbols).Any();
}
public bool HasConfigurationSymbol()
{
return HasAnySymbols(
BuildSLNUtilities.BuildSymbolDebug,
BuildSLNUtilities.BuildSymbolRelease,
BuildSLNUtilities.BuildSymbolMaster);
}
public static IEnumerable<string> RemoveConfigurationSymbols(string symbols)
{
return symbols.Split(';').Except(new[]
{
BuildSLNUtilities.BuildSymbolDebug,
BuildSLNUtilities.BuildSymbolRelease,
BuildSLNUtilities.BuildSymbolMaster
});
}
public bool HasAnySymbols(IEnumerable<string> symbols)
{
return BuildSymbols.Split(';').Intersect(symbols).Any();
}
}
}

Просмотреть файл

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 8641cc4d0d7648aca3b48f7d2302a094
timeCreated: 1497140920

Просмотреть файл

@ -1,448 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Xml;
using UnityEditor;
using UnityEngine;
namespace HoloToolkit.Unity
{
/// <summary>
/// Class containing various utility methods to build a WSA solution from a Unity project.
/// </summary>
public static class BuildSLNUtilities
{
/// <summary>
/// A method capable of configuring <see cref="BuildInfo"/> settings.
/// </summary>
/// <param name="toConfigure">The settings to configure.</param>
public delegate void BuildInfoConfigurationMethod(ref BuildInfo toConfigure);
/// <summary>
/// Add a handler to this event to override <see cref="BuildInfo"/> defaults before a build.
/// </summary>
/// <seealso cref="RaiseOverrideBuildDefaults"/>
public static event BuildInfoConfigurationMethod OverrideBuildDefaults;
/// <summary>
/// Call this method to give other code an opportunity to override <see cref="BuildInfo"/> defaults.
/// </summary>
/// <param name="toConfigure">>The settings to configure.</param>
/// <seealso cref="OverrideBuildDefaults"/>
public static void RaiseOverrideBuildDefaults(ref BuildInfo toConfigure)
{
if (OverrideBuildDefaults != null)
{
OverrideBuildDefaults(ref toConfigure);
}
}
// Build configurations. Exactly one of these should be defined for any given build.
public const string BuildSymbolDebug = "DEBUG";
public const string BuildSymbolRelease = "RELEASE";
public const string BuildSymbolMaster = "MASTER";
/// <summary>
/// Event triggered when a build starts.
/// </summary>
public static event Action<BuildInfo> BuildStarted;
/// <summary>
/// Event triggered when a build completes.
/// </summary>
public static event Action<BuildInfo, string> BuildCompleted;
public static void PerformBuild(BuildInfo buildInfo)
{
BuildTargetGroup buildTargetGroup = GetGroup(buildInfo.BuildTarget);
string oldBuildSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup);
if (!string.IsNullOrEmpty(oldBuildSymbols))
{
if (buildInfo.HasConfigurationSymbol())
{
buildInfo.AppendSymbols(BuildInfo.RemoveConfigurationSymbols(oldBuildSymbols));
}
else
{
buildInfo.AppendSymbols(oldBuildSymbols.Split(';'));
}
}
if ((buildInfo.BuildOptions & BuildOptions.Development) == BuildOptions.Development)
{
if (!buildInfo.HasConfigurationSymbol())
{
buildInfo.AppendSymbols(BuildSymbolDebug);
}
}
if (buildInfo.HasAnySymbols(BuildSymbolDebug))
{
buildInfo.BuildOptions |= BuildOptions.Development | BuildOptions.AllowDebugging;
}
if (buildInfo.HasAnySymbols(BuildSymbolRelease))
{
//Unity automatically adds the DEBUG symbol if the BuildOptions.Development flag is
//specified. In order to have debug symbols and the RELEASE symbols we have to
//inject the symbol Unity relies on to enable the /debug+ flag of csc.exe which is "DEVELOPMENT_BUILD"
buildInfo.AppendSymbols("DEVELOPMENT_BUILD");
}
BuildTarget oldBuildTarget = EditorUserBuildSettings.activeBuildTarget;
BuildTargetGroup oldBuildTargetGroup = GetGroup(oldBuildTarget);
EditorUserBuildSettings.SwitchActiveBuildTarget(buildTargetGroup, buildInfo.BuildTarget);
WSAUWPBuildType? oldWSAUWPBuildType = EditorUserBuildSettings.wsaUWPBuildType;
if (buildInfo.WSAUWPBuildType.HasValue)
{
EditorUserBuildSettings.wsaUWPBuildType = buildInfo.WSAUWPBuildType.Value;
}
var oldColorSpace = PlayerSettings.colorSpace;
if (buildInfo.ColorSpace.HasValue)
{
PlayerSettings.colorSpace = buildInfo.ColorSpace.Value;
}
if (buildInfo.BuildSymbols != null)
{
PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, buildInfo.BuildSymbols);
}
string buildError = "Error";
try
{
// For the WSA player, Unity builds into a target directory.
// For other players, the OutputPath parameter indicates the
// path to the target executable to build.
if (buildInfo.BuildTarget == BuildTarget.WSAPlayer)
{
Directory.CreateDirectory(buildInfo.OutputDirectory);
}
OnPreProcessBuild(buildInfo);
buildError = BuildPipeline.BuildPlayer(
buildInfo.Scenes.ToArray(),
buildInfo.OutputDirectory,
buildInfo.BuildTarget,
buildInfo.BuildOptions).ToString();
if (buildError.StartsWith("Error"))
{
throw new Exception(buildError);
}
}
finally
{
OnPostProcessBuild(buildInfo, buildError);
if (BuildTarget.WSAPlayer == buildInfo.BuildTarget)
{
UwpProjectPostProcess.Execute(buildInfo.OutputDirectory);
}
PlayerSettings.colorSpace = oldColorSpace;
PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, oldBuildSymbols);
if (oldWSAUWPBuildType.HasValue)
{
EditorUserBuildSettings.wsaUWPBuildType = oldWSAUWPBuildType.Value;
}
EditorUserBuildSettings.SwitchActiveBuildTarget(oldBuildTargetGroup, oldBuildTarget);
}
}
public static void ParseBuildCommandLine(ref BuildInfo buildInfo)
{
string[] arguments = Environment.GetCommandLineArgs();
buildInfo.IsCommandLine = true;
for (int i = 0; i < arguments.Length; ++i)
{
// Can't use -buildTarget which is something Unity already takes as an argument for something.
if (string.Equals(arguments[i], "-duskBuildTarget", StringComparison.InvariantCultureIgnoreCase))
{
buildInfo.BuildTarget = (BuildTarget)Enum.Parse(typeof(BuildTarget), arguments[++i]);
}
else if (string.Equals(arguments[i], "-wsaSDK", StringComparison.InvariantCultureIgnoreCase))
{
string wsaSdkArg = arguments[++i];
buildInfo.WSASdk = (WSASDK)Enum.Parse(typeof(WSASDK), wsaSdkArg);
}
else if (string.Equals(arguments[i], "-wsaUwpSdk", StringComparison.InvariantCultureIgnoreCase))
{
buildInfo.WSAUwpSdk = arguments[++i];
}
else if (string.Equals(arguments[i], "-wsaUWPBuildType", StringComparison.InvariantCultureIgnoreCase))
{
buildInfo.WSAUWPBuildType = (WSAUWPBuildType)Enum.Parse(typeof(WSAUWPBuildType), arguments[++i]);
}
else if (string.Equals(arguments[i], "-wsaGenerateReferenceProjects", StringComparison.InvariantCultureIgnoreCase))
{
buildInfo.WSAGenerateReferenceProjects = bool.Parse(arguments[++i]);
}
else if (string.Equals(arguments[i], "-buildOutput", StringComparison.InvariantCultureIgnoreCase))
{
buildInfo.OutputDirectory = arguments[++i];
}
else if (string.Equals(arguments[i], "-buildDesc", StringComparison.InvariantCultureIgnoreCase))
{
ParseBuildDescriptionFile(arguments[++i], ref buildInfo);
}
else if (string.Equals(arguments[i], "-unityBuildSymbols", StringComparison.InvariantCultureIgnoreCase))
{
string newBuildSymbols = arguments[++i];
buildInfo.AppendSymbols(newBuildSymbols.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries));
}
}
}
public static void PerformBuild_CommandLine()
{
var buildInfo = new BuildInfo
{
// Use scenes from the editor build settings.
Scenes = EditorBuildSettings.scenes.Where(scene => scene.enabled).Select(scene => scene.path),
// Configure a post build action to throw appropriate error code.
PostBuildAction = (innerBuildInfo, buildError) =>
{
if (!string.IsNullOrEmpty(buildError))
{
EditorApplication.Exit(1);
}
}
};
RaiseOverrideBuildDefaults(ref buildInfo);
ParseBuildCommandLine(ref buildInfo);
PerformBuild(buildInfo);
}
public static void ParseBuildDescriptionFile(string filename, ref BuildInfo buildInfo)
{
Debug.Log(string.Format(CultureInfo.InvariantCulture, "Build: Using \"{0}\" as build description", filename));
// Parse the XML file
var reader = new XmlTextReader(filename);
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (string.Equals(reader.Name, "SceneList", StringComparison.InvariantCultureIgnoreCase))
{
// Set the scenes we want to build
buildInfo.Scenes = ReadSceneList(reader);
}
else if (string.Equals(reader.Name, "CopyList", StringComparison.InvariantCultureIgnoreCase))
{
// Set the directories we want to copy
buildInfo.CopyDirectories = ReadCopyList(reader);
}
break;
}
}
}
private static BuildTargetGroup GetGroup(BuildTarget buildTarget)
{
switch (buildTarget)
{
case BuildTarget.WSAPlayer:
return BuildTargetGroup.WSA;
case BuildTarget.StandaloneWindows:
case BuildTarget.StandaloneWindows64:
return BuildTargetGroup.Standalone;
default:
return BuildTargetGroup.Unknown;
}
}
private static IEnumerable<string> ReadSceneList(XmlTextReader reader)
{
var result = new List<string>();
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (string.Equals(reader.Name, "Scene", StringComparison.InvariantCultureIgnoreCase))
{
while (reader.MoveToNextAttribute())
{
if (string.Equals(reader.Name, "Name", StringComparison.InvariantCultureIgnoreCase))
{
result.Add(reader.Value);
Debug.Log(string.Format(CultureInfo.InvariantCulture, "Build: Adding scene \"{0}\"", reader.Value));
}
}
}
break;
case XmlNodeType.EndElement:
if (string.Equals(reader.Name, "SceneList", StringComparison.InvariantCultureIgnoreCase))
{
return result;
}
break;
}
}
return result;
}
private static IEnumerable<CopyDirectoryInfo> ReadCopyList(XmlTextReader reader)
{
var result = new List<CopyDirectoryInfo>();
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (string.Equals(reader.Name, "Copy", StringComparison.InvariantCultureIgnoreCase))
{
string source = null;
string dest = null;
string filter = null;
bool recursive = false;
while (reader.MoveToNextAttribute())
{
if (string.Equals(reader.Name, "Source", StringComparison.InvariantCultureIgnoreCase))
{
source = reader.Value;
}
else if (string.Equals(reader.Name, "Destination", StringComparison.InvariantCultureIgnoreCase))
{
dest = reader.Value;
}
else if (string.Equals(reader.Name, "Recursive", StringComparison.InvariantCultureIgnoreCase))
{
recursive = Convert.ToBoolean(reader.Value);
}
else if (string.Equals(reader.Name, "Filter", StringComparison.InvariantCultureIgnoreCase))
{
filter = reader.Value;
}
}
if (source != null)
{
// Either the file specifies the Destination as well, or else CopyDirectory will use Source for Destination
var info = new CopyDirectoryInfo { Source = source };
if (dest != null)
{
info.Destination = dest;
}
if (filter != null)
{
info.Filter = filter;
}
info.Recursive = recursive;
Debug.Log(string.Format(CultureInfo.InvariantCulture, @"Build: Adding {0}copy ""{1}\{2}"" => ""{3}""", info.Recursive ? "Recursive " : "", info.Source, info.Filter, info.Destination ?? info.Source));
result.Add(info);
}
}
break;
case XmlNodeType.EndElement:
if (string.Equals(reader.Name, "CopyList", StringComparison.InvariantCultureIgnoreCase))
return result;
break;
}
}
return result;
}
public static void CopyDirectory(string sourceDirectoryPath, string destinationDirectoryPath, CopyDirectoryInfo directoryInfo)
{
sourceDirectoryPath = Path.Combine(sourceDirectoryPath, directoryInfo.Source);
destinationDirectoryPath = Path.Combine(destinationDirectoryPath, directoryInfo.Destination ?? directoryInfo.Source);
Debug.Log(string.Format(CultureInfo.InvariantCulture, @"{0} ""{1}\{2}"" to ""{3}""", directoryInfo.Recursive ? "Recursively copying" : "Copying", sourceDirectoryPath, directoryInfo.Filter, destinationDirectoryPath));
foreach (string sourceFilePath in Directory.GetFiles(sourceDirectoryPath, directoryInfo.Filter, directoryInfo.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly))
{
string destinationFilePath = sourceFilePath.Replace(sourceDirectoryPath, destinationDirectoryPath);
try
{
Directory.CreateDirectory(Path.GetDirectoryName(destinationFilePath));
if (File.Exists(destinationFilePath))
{
File.SetAttributes(destinationFilePath, FileAttributes.Normal);
}
File.Copy(sourceFilePath, destinationFilePath, true);
File.SetAttributes(destinationFilePath, FileAttributes.Normal);
}
catch (Exception exception)
{
Debug.LogError(string.Format(CultureInfo.InvariantCulture, "Failed to copy \"{0}\" to \"{1}\" with \"{2}\"", sourceFilePath, destinationFilePath, exception));
}
}
}
private static void OnPreProcessBuild(BuildInfo buildInfo)
{
// Raise the global event for listeners
BuildStarted.RaiseEvent(buildInfo);
// Call the pre-build action, if any
if (buildInfo.PreBuildAction != null)
{
buildInfo.PreBuildAction(buildInfo);
}
}
private static void OnPostProcessBuild(BuildInfo buildInfo, string buildError)
{
if (string.IsNullOrEmpty(buildError))
{
if (buildInfo.CopyDirectories != null)
{
string inputProjectDirectoryPath = GetProjectPath();
string outputProjectDirectoryPath = Path.Combine(GetProjectPath(), buildInfo.OutputDirectory);
foreach (var directory in buildInfo.CopyDirectories)
{
CopyDirectory(inputProjectDirectoryPath, outputProjectDirectoryPath, directory);
}
}
}
// Raise the global event for listeners
BuildCompleted.RaiseEvent(buildInfo, buildError);
// Call the post-build action, if any
if (buildInfo.PostBuildAction != null)
{
buildInfo.PostBuildAction(buildInfo, buildError);
}
}
public static string GetProjectPath()
{
return Path.GetDirectoryName(Path.GetFullPath(Application.dataPath));
}
}
}

Просмотреть файл

@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: b404a9703a0c1784b9c8f2de897cae3b
timeCreated: 1466615028
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,10 +0,0 @@
fileFormatVersion: 2
guid: 183ec72b0e46f5d4a974ffbe5d11fe95
folderAsset: yes
timeCreated: 1511727687
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,20 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
namespace HoloToolkit.Unity
{
[Serializable]
public class AdapterInfo
{
public string Description;
public string HardwareAddress;
public int Index;
public string Name;
public string Type;
public DHCPInfo DHCP;
public IpAddressInfo[] Gateways;
public IpAddressInfo[] IpAddresses;
}
}

Просмотреть файл

@ -1,13 +0,0 @@
fileFormatVersion: 2
guid: e9e582b5e23c1ce4db5af4795de2ea11
timeCreated: 1511921435
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,18 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
namespace HoloToolkit.Unity
{
[Serializable]
public class AppDetails
{
public string Name;
public string PackageFamilyName;
public string PackageFullName;
public int PackageOrigin;
public string PackageRelativeId;
public string Publisher;
}
}

Просмотреть файл

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 78d89e4089fc412fbd92cf88db9abb54
timeCreated: 1505630361

Просмотреть файл

@ -1,13 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
namespace HoloToolkit.Unity
{
[Serializable]
public class AppList
{
public AppDetails[] InstalledPackages;
}
}

Просмотреть файл

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 1b08d6ba78f3428e9ea3dbfd1dec00f3
timeCreated: 1505630361

Просмотреть файл

@ -1,24 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
namespace HoloToolkit.Unity
{
[Serializable]
public struct ConnectInfo
{
public ConnectInfo(string ip, string user, string password, string machineName = "")
{
IP = ip;
User = user;
Password = password;
MachineName = string.IsNullOrEmpty(machineName) ? ip : machineName;
}
public string IP;
public string User;
public string Password;
public string MachineName;
}
}

Просмотреть файл

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: e2f1a5e5a63040eb99e1c07b389abef6
timeCreated: 1505630244

Просмотреть файл

@ -1,21 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
namespace HoloToolkit.Unity
{
public class CopyDirectoryInfo
{
public string Source { get; set; }
public string Destination { get; set; }
public string Filter { get; set; }
public bool Recursive { get; set; }
public CopyDirectoryInfo()
{
Source = null;
Destination = null;
Filter = "*";
Recursive = false;
}
}
}

Просмотреть файл

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 23511800bce94604830cfd49251a3746
timeCreated: 1497140939

Просмотреть файл

@ -1,15 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
namespace HoloToolkit.Unity
{
[Serializable]
public class DHCPInfo
{
public int LeaseExpires;
public int LeaseObtained;
public IpAddressInfo Address;
}
}

Просмотреть файл

@ -1,13 +0,0 @@
fileFormatVersion: 2
guid: b9f4adcf165401e44b8dd0fdc1f01406
timeCreated: 1511921662
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,19 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
using System.Collections.Generic;
namespace HoloToolkit.Unity
{
[Serializable]
public class DevicePortalConnections
{
public List<ConnectInfo> Connections = new List<ConnectInfo>(0);
public DevicePortalConnections(ConnectInfo connectInfo)
{
Connections.Add(connectInfo);
}
}
}

Просмотреть файл

@ -1,13 +0,0 @@
fileFormatVersion: 2
guid: d9fa39adff61e294d9fac017583d4dfa
timeCreated: 1511774995
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,16 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
namespace HoloToolkit.Unity
{
[Serializable]
public class InstallStatus
{
public int Code;
public string CodeText;
public string Reason;
public bool Success;
}
}

Просмотреть файл

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 3bac05516c6546fc9692f8e3575e5bc4
timeCreated: 1505630361

Просмотреть файл

@ -1,14 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
namespace HoloToolkit.Unity
{
[Serializable]
public class IpAddressInfo
{
public string IpAddress;
public string Mask;
}
}

Просмотреть файл

@ -1,13 +0,0 @@
fileFormatVersion: 2
guid: 89cbcc9bf958da744ac19dfb03b05f36
timeCreated: 1511923796
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,13 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
namespace HoloToolkit.Unity
{
[Serializable]
public class MachineName
{
public string ComputerName;
}
}

Просмотреть файл

@ -1,13 +0,0 @@
fileFormatVersion: 2
guid: 6b38e86f792363c45afa2e3aba61e715
timeCreated: 1511828513
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,13 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
namespace HoloToolkit.Unity
{
[Serializable]
public class NetworkInfo
{
public AdapterInfo[] Adapters;
}
}

Просмотреть файл

@ -1,13 +0,0 @@
fileFormatVersion: 2
guid: 34cde40c31747a94e901220591f0a238
timeCreated: 1511921270
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,21 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
namespace HoloToolkit.Unity
{
[Serializable]
public class ProcessDesc
{
public float CPUUsage;
public string ImageName;
public float PageFileUsage;
public int PrivateWorkingSet;
public int ProcessId;
public int SessionId;
public string UserName;
public int VirtualSize;
public int WorkingSetSize;
}
}

Просмотреть файл

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 444b49b99f6c486a9f94123fefa890c8
timeCreated: 1505630361

Просмотреть файл

@ -1,13 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
namespace HoloToolkit.Unity
{
[Serializable]
public class ProcessList
{
public ProcessDesc[] Processes;
}
}

Просмотреть файл

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: bb334efdb39a4bf4902fa71524072b4a
timeCreated: 1505630361

Просмотреть файл

@ -1,13 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
namespace HoloToolkit.Unity
{
[Serializable]
public class Response
{
public string Reason;
}
}

Просмотреть файл

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 3ba58874bb124faa8037fb6733e6475f
timeCreated: 1505630361

Просмотреть файл

@ -1,75 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using UnityEditor;
using UnityEngine;
namespace HoloToolkit.Unity
{
public static class EditorPrefsUtility
{
public static void SetEditorPref(string key, string value)
{
EditorPrefs.SetString(Application.productName + key, value);
}
public static void SetEditorPref(string key, bool value)
{
EditorPrefs.SetBool(Application.productName + key, value);
}
public static void SetEditorPref(string key, float value)
{
EditorPrefs.SetFloat(Application.productName + key, value);
}
public static void SetEditorPref(string key, int value)
{
EditorPrefs.SetInt(Application.productName + key, value);
}
public static string GetEditorPref(string key, string defaultValue)
{
if (EditorPrefs.HasKey(Application.productName + key))
{
return EditorPrefs.GetString(Application.productName + key);
}
EditorPrefs.SetString(Application.productName + key, defaultValue);
return defaultValue;
}
public static bool GetEditorPref(string key, bool defaultValue)
{
if (EditorPrefs.HasKey(Application.productName + key))
{
return EditorPrefs.GetBool(Application.productName + key);
}
EditorPrefs.SetBool(Application.productName + key, defaultValue);
return defaultValue;
}
public static float GetEditorPref(string key, float defaultValue)
{
if (EditorPrefs.HasKey(Application.productName + key))
{
return EditorPrefs.GetFloat(Application.productName + key);
}
EditorPrefs.SetFloat(Application.productName + key, defaultValue);
return defaultValue;
}
public static int GetEditorPref(string key, int defaultValue)
{
if (EditorPrefs.HasKey(Application.productName + key))
{
return EditorPrefs.GetInt(Application.productName + key);
}
EditorPrefs.SetInt(Application.productName + key, defaultValue);
return defaultValue;
}
}
}

Просмотреть файл

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: eb5e6e8f269f74d439c58d77b1aea33b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,56 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
using UnityEditor;
namespace HoloToolkit.Unity
{
/// <summary>
/// Implements functionality for building HoloLens applications
/// </summary>
public static class HoloToolkitCommands
{
/// <summary>
/// Do a build configured for the HoloLens, returns the error from BuildPipeline.BuildPlayer
/// </summary>
[Obsolete("Use BuildDeployTools.BuildSLN")]
public static bool BuildSLN()
{
return BuildDeployTools.BuildSLN(BuildDeployPrefs.BuildDirectory, false);
}
public static bool BuildAPPX(string buildDirectory = "")
{
if(buildDirectory == string.Empty)
{
buildDirectory = BuildDeployPrefs.BuildDirectory;
}
return BuildDeployTools.BuildAppxFromSLN(
PlayerSettings.productName,
BuildDeployTools.DefaultMSBuildVersion,
BuildDeployPrefs.ForceRebuild,
BuildDeployPrefs.BuildConfig,
BuildDeployPrefs.BuildPlatform,
buildDirectory,
BuildDeployPrefs.IncrementBuildVersion);
}
public static void BuildSLNAndAPPX(string path)
{
var slnResult = BuildDeployTools.BuildSLN(path, false);
var appxResult = BuildAPPX(path);
}
public static bool InstallAPPX()
{
ConnectInfo connectInfo = new ConnectInfo("10.1.18.9", "1234", "12341234", "HoloLens");
BuildDeployWindow.InstallOnTargetDevice(BuildDeployPrefs.BuildDirectory, connectInfo);
return BuildDeployWindow.AppxInstallSucces;
}
}
}

Просмотреть файл

@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 85636330e25a7ac4c81b19530c5b8282
timeCreated: 1464366824
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,10 +0,0 @@
fileFormatVersion: 2
guid: 080001477ab9a6248b3cd5c3c4bfbff4
folderAsset: yes
timeCreated: 1512167852
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,31 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
using UnityEngine;
namespace HoloToolkit.Unity
{
[Serializable]
public class USBDeviceInfo
{
public USBDeviceInfo(int vendorId, string udid, int productId, string name, int revision)
{
VendorId = vendorId;
Udid = udid;
ProductId = productId;
Name = name;
Revision = revision;
}
public int VendorId { get; private set; }
public string Udid { get; private set; }
public int ProductId { get; private set; }
public string Name { get; private set; }
public int Revision { get; private set; }
}
}

Просмотреть файл

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: c5e55757366a403cb092abaff6b6a15d
timeCreated: 1497305870

Просмотреть файл

@ -1,45 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.Hardware;
using UnityEngine;
namespace HoloToolkit.Unity
{
[InitializeOnLoad]
public class USBDeviceListener
{
[SerializeField]
public static USBDeviceInfo[] USBDevices;
public delegate void OnUsbDevicesChanged(UsbDevice[] usbDevices);
public static event OnUsbDevicesChanged UsbDevicesChanged;
private static List<USBDeviceInfo> usbDevicesList = new List<USBDeviceInfo>(0);
static USBDeviceListener()
{
Usb.DevicesChanged += NotifyUsbDevicesChanged;
}
private static void NotifyUsbDevicesChanged(UsbDevice[] devices)
{
if (UsbDevicesChanged != null)
{
UsbDevicesChanged.Invoke(devices);
}
usbDevicesList.Clear();
foreach (UsbDevice device in devices)
{
usbDevicesList.Add(new USBDeviceInfo(device.vendorId, device.udid, device.productId, device.name, device.revision));
}
USBDevices = usbDevicesList.ToArray();
}
}
}

Просмотреть файл

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: fc26d07c1945497f97ae60db9eb11a91
timeCreated: 1497297319

Просмотреть файл

@ -1,133 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml;
namespace HoloToolkit.Unity
{
/// <summary>
/// This class is designed to post process the UWP Assembly-CSharp projects to ensure that the defaults and defines are set correctly.
/// </summary>
public static class UwpProjectPostProcess
{
private static readonly Regex PlatformRegex = new Regex(@"'\$\(Configuration\)\|\$\(Platform\)' == '(?<Configuration>.*)\|(?<Platform>.*)'");
/// <summary>
/// Executes the Post Processes on the C# Projects generated as part of the UWP build.
/// </summary>
/// <param name="buildRootPath">The root path of the UWP build output.</param>
public static void Execute(string buildRootPath)
{
UpdateProjectFile(Path.Combine(buildRootPath, @"GeneratedProjects\UWP\Assembly-CSharp\Assembly-CSharp.csproj"));
UpdateProjectFile(Path.Combine(buildRootPath, @"GeneratedProjects\UWP\Assembly-CSharp-firstpass\Assembly-CSharp-firstpass.csproj"));
}
/// <summary>
/// Updates the project file to ensure that certain requirements are met.
/// </summary>
/// <param name="filename">The filename of the project to update.</param>
/// <remarks>This is manually parsing the Unity generated MSBuild projects, which means it will be fragile to changes.</remarks>
private static void UpdateProjectFile(string filename)
{
if (!File.Exists(filename))
{
UnityEngine.Debug.LogWarningFormat("Unable to find file \"{0}\", double check that the build succeeded and that the C# Projects are set to be generated.", filename);
return;
}
var projectDocument = new XmlDocument();
projectDocument.Load(filename);
if (projectDocument.DocumentElement == null)
{
UnityEngine.Debug.LogWarningFormat("Unable to load file \"{0}\", double check that the build succeeded and that the C# Projects are set to be generated.", filename);
return;
}
if (projectDocument.DocumentElement.Name != "Project")
{
UnityEngine.Debug.LogWarningFormat("The loaded project \"{0}\", does not appear to be a MSBuild Project file.", filename);
return;
}
foreach (XmlNode node in projectDocument.DocumentElement.ChildNodes)
{
// Everything we are looking for is inside a PropertyGroup...
if (node.Name != "PropertyGroup" || node.Attributes == null)
{
continue;
}
if (node.Attributes.Count == 0 && node["Configuration"] != null && node["Platform"] != null)
{
// Update the defaults to Release and x86 so that we can run NuGet restore.
node["Configuration"].InnerText = "Release";
node["Platform"].InnerText = "x86";
}
else if (node.Attributes["Condition"] != null)
{
// Update the DefineConstants to include the configuration allowing us to conditionally compile code based on the configuration.
Match match = PlatformRegex.Match(node.Attributes["Condition"].InnerText);
if (match.Success)
{
UpdateDefineConstants(node["DefineConstants"], match.Groups["Configuration"].Value, match.Groups["Platform"].Value);
}
}
}
WriteXmlDocumentToFile(projectDocument, filename);
}
private static void UpdateDefineConstants(XmlNode defineConstants, string configuration, string platform)
{
if (defineConstants == null)
{
return;
}
IEnumerable<string> symbols = defineConstants.InnerText.Split(';').Except(new[]
{
string.Empty,
BuildSLNUtilities.BuildSymbolDebug,
BuildSLNUtilities.BuildSymbolRelease,
BuildSLNUtilities.BuildSymbolMaster
}).Union(new[] { configuration.ToUpperInvariant() });
defineConstants.InnerText = string.Join(";", symbols.ToArray());
//UnityEngine.Debug.LogFormat("Updating defines for Configuration|Platform: {0}|{1} => {2}", configuration, platform, defineConstants.InnerText);
}
private static void WriteXmlDocumentToFile(XmlNode document, string fullPath)
{
FileStream fileStream = null;
try
{
fileStream = File.Open(fullPath, FileMode.Create);
var settings = new XmlWriterSettings
{
Indent = true,
CloseOutput = true
};
using (XmlWriter writer = XmlWriter.Create(fileStream, settings))
{
fileStream = null;
document.WriteTo(writer);
}
}
finally
{
if (fileStream != null)
{
fileStream.Dispose();
}
}
}
}
}

Просмотреть файл

@ -1,13 +0,0 @@
fileFormatVersion: 2
guid: 740afdacd94cd8d49a0fbdf8bfed2c1f
timeCreated: 1484171169
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,164 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Copyright (c) Rafael Rivera.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading;
namespace HoloToolkit.Unity
{
/// <summary>
/// Emulator Utility Class
/// </summary>
public static class XdeGuestLocator
{
[StructLayout(LayoutKind.Sequential, Pack = 4)]
struct XdePeerHostIdentifier
{
public Guid GuestDiscoveryGUID;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[] GuestMACAddress;
public int PeerDiscoveryPort;
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
struct XdePeerGuestIdentifier
{
public Guid GuestDiscoveryGUID;
public int GuestTcpPort;
public int GuestSvcVersion;
}
public static bool IsSearching { get; private set; }
public static bool HasData { get; private set; }
public static IPAddress GuestIpAddress { get; private set; }
static XdeGuestLocator()
{
HasData = false;
IsSearching = false;
}
public static void FindGuestAddressAsync()
{
if (IsSearching)
{
return;
}
ThreadPool.QueueUserWorkItem(FindGuestAddress);
}
private static void FindGuestAddress(object state)
{
IsSearching = true;
HasData = false;
GuestIpAddress = IPAddress.None;
UnicastIPAddressInformation internalSwitchAddressInfo = null;
try
{
internalSwitchAddressInfo = GetInternalSwitchAddressInfo();
}
catch (Exception)
{
UnityEngine.Debug.LogError("Failed to locate internal switch adapter");
}
if (internalSwitchAddressInfo != null)
{
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
{
try
{
// Bind to next available UDP port for a listen operation
socket.Blocking = true;
socket.ReceiveTimeout = (int)TimeSpan.FromSeconds(5).TotalMilliseconds;
socket.Bind(new IPEndPoint(internalSwitchAddressInfo.Address, 0));
var localPort = (socket.LocalEndPoint as IPEndPoint).Port;
// Send out a probe to 'devices' connected to the internal switch
// listening on port 3553 (Microsoft Device Emulator specific)
var broadcastAddress = GetBroadcastAddressForAddress(internalSwitchAddressInfo.Address, internalSwitchAddressInfo.IPv4Mask);
var broadcastTarget = new IPEndPoint(broadcastAddress, 3553);
//
// WORKAROUND: We don't have easy access to WMI to go querying
// for virtual machine information so we just cover finding
// the first 255 potential candidates xx 00 - xx FF.
//
// It sounds like a lot but we're talking super tiny
// payloads on an internal interface. It's very fast.
//
for (int i = 0; i <= 0xFF; i++)
{
var probe = GenerateProbe(localPort, i);
socket.SendTo(probe, broadcastTarget);
}
// Return the endpoint information for the first 'device' that replies
// (we don't necessarily care about the returned identifier info)
var responseBytes = new byte[Marshal.SizeOf(typeof(XdePeerGuestIdentifier))];
EndPoint guestEndpoint = new IPEndPoint(broadcastAddress, 0);
socket.ReceiveFrom(responseBytes, ref guestEndpoint);
GuestIpAddress = (guestEndpoint as IPEndPoint).Address;
HasData = true;
}
catch (SocketException)
{
// Do nothing, our probe went unanswered or failed
}
}
}
IsSearching = false;
}
private static UnicastIPAddressInformation GetInternalSwitchAddressInfo()
{
var internalSwitch = GetInternalNetworkSwitchInterface();
return internalSwitch.GetIPProperties().UnicastAddresses.Where(a => a.Address.AddressFamily == AddressFamily.InterNetwork).FirstOrDefault();
}
private static NetworkInterface GetInternalNetworkSwitchInterface()
{
return NetworkInterface.GetAllNetworkInterfaces().Where(i => i.Name.Contains("Windows Phone Emulator")).FirstOrDefault();
}
private static IPAddress GetBroadcastAddressForAddress(IPAddress address, IPAddress mask)
{
var addressInt = BitConverter.ToInt32(address.GetAddressBytes(), 0);
var maskInt = BitConverter.ToInt32(mask.GetAddressBytes(), 0);
return new IPAddress(BitConverter.GetBytes((addressInt | ~maskInt)));
}
private static byte[] GenerateProbe(int port, int machineIndex)
{
var identifier = new XdePeerHostIdentifier();
identifier.PeerDiscoveryPort = port;
identifier.GuestDiscoveryGUID = new Guid("{963ef858-2efe-4eb4-8d2d-fed5408e6441}");
identifier.GuestMACAddress = new byte[] { 0x02, 0xDE, 0xDE, 0xDE, 0xDE, (byte)machineIndex };
return GetStructureBytes(identifier);
}
private static byte[] GetStructureBytes(object obj)
{
var bytes = new byte[Marshal.SizeOf(obj)];
var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
Marshal.StructureToPtr(obj, handle.AddrOfPinnedObject(), false);
handle.Free();
return bytes;
}
}
}

Просмотреть файл

@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 05d1324a6d6a0d248848b4042ad6d6bf
timeCreated: 1471035499
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -8,7 +8,7 @@ public class AudioSourceTests : XrFunctionalTestBase
{ {
private AudioSource audioSource; private AudioSource audioSource;
private readonly int audioPlaySkipFrameCountWait = 2 * OneSecOfFramesWaitTime; private readonly int audioPlaySkipFrameCountWait = 2;
private readonly float audioTolerance = .01f; private readonly float audioTolerance = .01f;
[SetUp] [SetUp]
@ -34,7 +34,7 @@ public class AudioSourceTests : XrFunctionalTestBase
public IEnumerator VerifyAudioSource_Play() public IEnumerator VerifyAudioSource_Play()
{ {
// Act // Act
yield return null; yield return SkipFrame(DefaultFrameSkipCount);
audioSource.Play(); audioSource.Play();
yield return SkipFrame(audioPlaySkipFrameCountWait); yield return SkipFrame(audioPlaySkipFrameCountWait);
@ -47,7 +47,7 @@ public class AudioSourceTests : XrFunctionalTestBase
public IEnumerator VerifyAudioSource_Pause() public IEnumerator VerifyAudioSource_Pause()
{ {
// Arrange // Arrange
yield return null; yield return SkipFrame(DefaultFrameSkipCount);
audioSource.Play(); audioSource.Play();
yield return SkipFrame(audioPlaySkipFrameCountWait); yield return SkipFrame(audioPlaySkipFrameCountWait);
@ -64,7 +64,7 @@ public class AudioSourceTests : XrFunctionalTestBase
public IEnumerator VerifyAudioSource_UnPause() public IEnumerator VerifyAudioSource_UnPause()
{ {
// Arrange // Arrange
yield return null; yield return SkipFrame(DefaultFrameSkipCount);
audioSource.Play(); audioSource.Play();
yield return SkipFrame(audioPlaySkipFrameCountWait); yield return SkipFrame(audioPlaySkipFrameCountWait);
@ -84,14 +84,14 @@ public class AudioSourceTests : XrFunctionalTestBase
public IEnumerator VerifyAudioSource_Stop() public IEnumerator VerifyAudioSource_Stop()
{ {
// Arrange // Arrange
yield return null; yield return SkipFrame(DefaultFrameSkipCount);
audioSource.Play(); audioSource.Play();
yield return SkipFrame(audioPlaySkipFrameCountWait); yield return SkipFrame(audioPlaySkipFrameCountWait);
// Act // Act
audioSource.Stop(); audioSource.Stop();
yield return null; yield return SkipFrame(DefaultFrameSkipCount);
// Assert // Assert
Assert.AreEqual(audioSource.isPlaying, false, "Audio failed to stop"); Assert.AreEqual(audioSource.isPlaying, false, "Audio failed to stop");
@ -101,7 +101,7 @@ public class AudioSourceTests : XrFunctionalTestBase
public IEnumerator VerifyAudioSource_Adjust_SpatialBlend() public IEnumerator VerifyAudioSource_Adjust_SpatialBlend()
{ {
// Arrange // Arrange
yield return null; yield return SkipFrame(DefaultFrameSkipCount);
audioSource.spatialize = true; audioSource.spatialize = true;
Debug.Log("Enabling Spatialized Audio"); Debug.Log("Enabling Spatialized Audio");
@ -129,7 +129,7 @@ public class AudioSourceTests : XrFunctionalTestBase
public IEnumerator VerifyAudioSource_Adjust_Volume() public IEnumerator VerifyAudioSource_Adjust_Volume()
{ {
// Arrange // Arrange
yield return null; yield return SkipFrame(DefaultFrameSkipCount);
audioSource.Play(); audioSource.Play();
Debug.Log("Starting Audio"); Debug.Log("Starting Audio");
@ -137,7 +137,7 @@ public class AudioSourceTests : XrFunctionalTestBase
audioSource.volume = 0f; audioSource.volume = 0f;
Assert.AreEqual(0f, audioSource.volume, "Volume was not set to 0;"); Assert.AreEqual(0f, audioSource.volume, "Volume was not set to 0;");
yield return null; yield return SkipFrame(DefaultFrameSkipCount);
var volumeAmount = 0f; var volumeAmount = 0f;

Просмотреть файл

@ -41,7 +41,7 @@ public class CameraTests : XrFunctionalTestBase
[UnityTest] [UnityTest]
public IEnumerator CameraCheckForMultiPass() public IEnumerator CameraCheckForMultiPass()
{ {
yield return SkipFrame(OneSecOfFramesWaitTime); yield return SkipFrame(DefaultFrameSkipCount);
XrFunctionalTestHelpers.TestStageSetup(TestStageConfig.MultiPass); XrFunctionalTestHelpers.TestStageSetup(TestStageConfig.MultiPass);
Assert.AreEqual(XRSettings.stereoRenderingMode, UnityEditor.PlayerSettings.stereoRenderingPath, "Expected StereoRenderingPath to be Multi pass"); Assert.AreEqual(XRSettings.stereoRenderingMode, UnityEditor.PlayerSettings.stereoRenderingPath, "Expected StereoRenderingPath to be Multi pass");
@ -52,7 +52,7 @@ public class CameraTests : XrFunctionalTestBase
[UnityTest] [UnityTest]
public IEnumerator CameraCheckForInstancing() public IEnumerator CameraCheckForInstancing()
{ {
yield return SkipFrame(OneSecOfFramesWaitTime); yield return SkipFrame(DefaultFrameSkipCount);
XrFunctionalTestHelpers.TestStageSetup(TestStageConfig.Instancing); XrFunctionalTestHelpers.TestStageSetup(TestStageConfig.Instancing);
Assert.AreEqual(XRSettings.stereoRenderingMode, UnityEditor.PlayerSettings.stereoRenderingPath, "Expected StereoRenderingPath to be Instancing"); Assert.AreEqual(XRSettings.stereoRenderingMode, UnityEditor.PlayerSettings.stereoRenderingPath, "Expected StereoRenderingPath to be Instancing");
@ -62,7 +62,7 @@ public class CameraTests : XrFunctionalTestBase
[UnityTest] [UnityTest]
public IEnumerator VerifyRefreshRate() public IEnumerator VerifyRefreshRate()
{ {
yield return SkipFrame(OneSecOfFramesWaitTime); yield return SkipFrame(DefaultFrameSkipCount);
var refreshRate = XRDevice.refreshRate; var refreshRate = XRDevice.refreshRate;
if (IsMobilePlatform()) if (IsMobilePlatform())
@ -77,7 +77,7 @@ public class CameraTests : XrFunctionalTestBase
[UnityTest] [UnityTest]
public IEnumerator VerifyAdjustRenderViewportScale() public IEnumerator VerifyAdjustRenderViewportScale()
{ {
yield return SkipFrame(OneSecOfFramesWaitTime); yield return SkipFrame(DefaultFrameSkipCount);
XRSettings.renderViewportScale = 1f; XRSettings.renderViewportScale = 1f;
Assert.AreEqual(1f, XRSettings.renderViewportScale, "Render viewport scale is not being respected"); Assert.AreEqual(1f, XRSettings.renderViewportScale, "Render viewport scale is not being respected");
@ -93,29 +93,31 @@ public class CameraTests : XrFunctionalTestBase
[UnityTest] [UnityTest]
public IEnumerator VerifyAdjustEyeTextureResolutionScale() public IEnumerator VerifyAdjustEyeTextureResolutionScale()
{ {
yield return SkipFrame(OneSecOfFramesWaitTime); yield return SkipFrame(DefaultFrameSkipCount);
var scale = 0.1f; var scale = 0.1f;
var scaleCount = 0.1f; var scaleIncrement = 0.1f;
var scaleLimit = 2f;
for (var i = 0.1f; i < 2; i++) do
{ {
scale = scale + 0.1f;
scaleCount = scaleCount + 0.1f; scale = scale + scaleIncrement;
XRSettings.eyeTextureResolutionScale = scale; XRSettings.eyeTextureResolutionScale = scale;
yield return null; yield return SkipFrame(DefaultFrameSkipCount);
Debug.Log("VerifyAdjustEyeTextureResolutionScale = " + scale); Debug.Log("VerifyAdjustEyeTextureResolutionScale = " + scale);
Assert.AreEqual(scaleCount, XRSettings.eyeTextureResolutionScale, "Eye texture resolution scale is not being respected"); Assert.AreEqual(scale, XRSettings.eyeTextureResolutionScale, "Eye texture resolution scale is not being respected");
} }
while (scale < scaleLimit) ;
} }
[UnityTest] [UnityTest]
public IEnumerator VerifyAdjustDeviceZoom() public IEnumerator VerifyAdjustDeviceZoom()
{ {
yield return SkipFrame(OneSecOfFramesWaitTime); yield return SkipFrame(DefaultFrameSkipCount);
var zoomAmount = 0f; var zoomAmount = 0f;
var zoomCount = 0f; var zoomCount = 0f;
@ -127,7 +129,7 @@ public class CameraTests : XrFunctionalTestBase
XRDevice.fovZoomFactor = zoomAmount; XRDevice.fovZoomFactor = zoomAmount;
yield return null; yield return SkipFrame(DefaultFrameSkipCount);
Debug.Log("fovZoomFactor = " + zoomAmount); Debug.Log("fovZoomFactor = " + zoomAmount);
Assert.AreEqual(zoomCount, XRDevice.fovZoomFactor, "Zoom Factor is not being respected"); Assert.AreEqual(zoomCount, XRDevice.fovZoomFactor, "Zoom Factor is not being respected");
@ -137,7 +139,7 @@ public class CameraTests : XrFunctionalTestBase
[UnityTest] [UnityTest]
public IEnumerator TakeScreenShot() public IEnumerator TakeScreenShot()
{ {
yield return SkipFrame(2 * OneSecOfFramesWaitTime); yield return SkipFrame(2);
try try
{ {

Просмотреть файл

@ -64,11 +64,10 @@ public class DllNativePluginTests : XrFunctionalTestBase
sceneObjectsLoaded = true; sceneObjectsLoaded = true;
} }
[UnityTest] [Test]
public IEnumerator VerifySceneObjectsLoaded() public void VerifySceneObjectsLoaded()
{ {
Assert.IsTrue(sceneObjectsLoaded, "Scene Objects was not created"); Assert.IsTrue(sceneObjectsLoaded, "Scene Objects was not created");
yield return null;
} }
[UnityTest] [UnityTest]
@ -82,7 +81,7 @@ public class DllNativePluginTests : XrFunctionalTestBase
[UnityTest] [UnityTest]
public IEnumerator VerifyRenderingFps() public IEnumerator VerifyRenderingFps()
{ {
yield return SkipFrame(2 * OneSecOfFramesWaitTime); yield return SkipFrame(2);
Assert.AreEqual(0, nonPerformantFrameCount, "Failed to keep every frame inside the target frame time for the tested window"); Assert.AreEqual(0, nonPerformantFrameCount, "Failed to keep every frame inside the target frame time for the tested window");
} }
@ -96,6 +95,7 @@ public class DllNativePluginTests : XrFunctionalTestBase
filter = true; filter = true;
} }
// TODO pull these magic numbers (256) into readonly vars with description
if(renderPlane.GetComponent<Renderer>().material.mainTexture.height == 256 && renderPlane.GetComponent<Renderer>().material.mainTexture.width == 256) if(renderPlane.GetComponent<Renderer>().material.mainTexture.height == 256 && renderPlane.GetComponent<Renderer>().material.mainTexture.width == 256)
{ {
textsize = true; textsize = true;

Просмотреть файл

@ -10,7 +10,7 @@ public class EyeCameraTests : XrFunctionalTestBase
[UnityTest] [UnityTest]
public IEnumerator VerifyEyesParallelWithHead() public IEnumerator VerifyEyesParallelWithHead()
{ {
yield return null; yield return SkipFrame(DefaultFrameSkipCount);
Assert.IsTrue(EyesParallelWithHead(), "Eyes are not parallel with the head"); Assert.IsTrue(EyesParallelWithHead(), "Eyes are not parallel with the head");
} }

Просмотреть файл

@ -45,10 +45,10 @@ public class PhysicsTests : XrFunctionalTestBase
[UnityTest] [UnityTest]
public IEnumerator GazeCheck() public IEnumerator GazeCheck()
{ {
yield return SkipFrame(OneSecOfFramesWaitTime); yield return SkipFrame(DefaultFrameSkipCount);
InputTracking.GetNodeStates(xrNodeList); InputTracking.GetNodeStates(xrNodeList);
yield return SkipFrame(OneSecOfFramesWaitTime); yield return SkipFrame(DefaultFrameSkipCount);
if (xrNodeList.Count != 0) if (xrNodeList.Count != 0)
{ {
@ -64,7 +64,7 @@ public class PhysicsTests : XrFunctionalTestBase
Ray ray = new Ray(xrCenterNodePos, XrFunctionalTestHelpers.Camera.GetComponent<Camera>().transform.forward); Ray ray = new Ray(xrCenterNodePos, XrFunctionalTestHelpers.Camera.GetComponent<Camera>().transform.forward);
Physics.Raycast(ray, 10f); Physics.Raycast(ray, 10f);
yield return null; yield return SkipFrame(DefaultFrameSkipCount);
if (ray.origin == xrCenterNodePos) if (ray.origin == xrCenterNodePos)
{ {

Просмотреть файл

@ -56,7 +56,7 @@ public class RenderingChecks : XrFunctionalTestBase
// 100 frames ~= 1 or 2 seconds // 100 frames ~= 1 or 2 seconds
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
yield return null; yield return SkipFrame(DefaultFrameSkipCount);
} }
// TODO We need to refactor this so that we have a clear arrange/act/assert // TODO We need to refactor this so that we have a clear arrange/act/assert
@ -66,7 +66,7 @@ public class RenderingChecks : XrFunctionalTestBase
while (!stopTest) while (!stopTest)
{ {
DoTest(); DoTest();
yield return SkipFrame(2 * OneSecOfFramesWaitTime); yield return SkipFrame(2);
} }
} }

Просмотреть файл

@ -23,7 +23,7 @@ public class SimplePerformanceTests : XrFunctionalTestBase
public IEnumerator SimpleFpsTest() public IEnumerator SimpleFpsTest()
{ {
XrFunctionalTestHelpers.TestCubeSetup(TestCubesConfig.TestCube); XrFunctionalTestHelpers.TestCubeSetup(TestCubesConfig.TestCube);
yield return null; yield return SkipFrame(DefaultFrameSkipCount);
Assert.AreEqual(0, nonPerformantFrameCount, "Failed to keep every frame inside the target frame time for the tested window"); Assert.AreEqual(0, nonPerformantFrameCount, "Failed to keep every frame inside the target frame time for the tested window");
} }
@ -32,7 +32,7 @@ public class SimplePerformanceTests : XrFunctionalTestBase
public IEnumerator SimpleFpsTestWithFocalPoint() public IEnumerator SimpleFpsTestWithFocalPoint()
{ {
XrFunctionalTestHelpers.TestCubeSetup(TestCubesConfig.TestCube); XrFunctionalTestHelpers.TestCubeSetup(TestCubesConfig.TestCube);
yield return null; yield return SkipFrame(DefaultFrameSkipCount);
Assert.AreEqual(0, nonPerformantFrameCount, "Failed to keep every frame inside the target frame time for the tested window"); Assert.AreEqual(0, nonPerformantFrameCount, "Failed to keep every frame inside the target frame time for the tested window");
} }
@ -42,7 +42,7 @@ public class SimplePerformanceTests : XrFunctionalTestBase
{ {
XrFunctionalTestHelpers.TestCubeSetup(TestCubesConfig.PerformanceMassObjects); XrFunctionalTestHelpers.TestCubeSetup(TestCubesConfig.PerformanceMassObjects);
yield return null; yield return SkipFrame(DefaultFrameSkipCount);
Assert.AreEqual(0, nonPerformantFrameCount, "Failed to keep every frame inside the target frame time for the tested window"); Assert.AreEqual(0, nonPerformantFrameCount, "Failed to keep every frame inside the target frame time for the tested window");
} }
@ -52,7 +52,7 @@ public class SimplePerformanceTests : XrFunctionalTestBase
{ {
XrFunctionalTestHelpers.TestCubeSetup(TestCubesConfig.PerformanceMassFloorObjects); XrFunctionalTestHelpers.TestCubeSetup(TestCubesConfig.PerformanceMassFloorObjects);
yield return null; yield return SkipFrame(DefaultFrameSkipCount);
Assert.AreEqual(0, nonPerformantFrameCount, "Failed to keep every frame inside the target frame time for the tested window"); Assert.AreEqual(0, nonPerformantFrameCount, "Failed to keep every frame inside the target frame time for the tested window");
} }

Просмотреть файл

@ -1,6 +1,4 @@
using System.Collections; using System.Collections;
using UnityEngine.Experimental.XR;
using UnityEngine;
using UnityEngine.XR; using UnityEngine.XR;
using NUnit.Framework; using NUnit.Framework;
using UnityEngine.TestTools; using UnityEngine.TestTools;
@ -10,7 +8,7 @@ public class TrackingSpaceTests : XrFunctionalTestBase
[UnityTest] [UnityTest]
public IEnumerator VerifyXRDevice_GetCurrentTrackingSpace() public IEnumerator VerifyXRDevice_GetCurrentTrackingSpace()
{ {
yield return SkipFrame(2 * OneSecOfFramesWaitTime); yield return SkipFrame(2);
var trackingSpace = XRDevice.GetTrackingSpaceType(); var trackingSpace = XRDevice.GetTrackingSpaceType();
Assert.IsNotNull(trackingSpace, "Tracking space is not reading correctly"); Assert.IsNotNull(trackingSpace, "Tracking space is not reading correctly");

Просмотреть файл

@ -6,79 +6,107 @@ using UnityEngine.XR;
public class XrApiTests : XrFunctionalTestBase public class XrApiTests : XrFunctionalTestBase
{ {
[UnityTest] [UnityPlatform(include = new[] { RuntimePlatform.Android, RuntimePlatform.IPhonePlayer })]
public IEnumerator VerifyApplication_IsMobilePlatform() [Test]
public void VerifyApplication_IsMobilePlatform()
{ {
if (IsMobilePlatform()) Assert.IsTrue(Application.isMobilePlatform, "SDK returned as a non mobile platform ");
{
Assert.IsTrue(Application.isMobilePlatform, "SDK returned as a non mobile platform ");
}
else
{
Assert.IsFalse(Application.isMobilePlatform, "SDK returned as a mobile platform");
}
yield return null;
} }
[UnityTest] [Test]
public IEnumerator VerifyXrDevice_IsPresent() public void VerifyXrDevice_IsPresent()
{ {
Assert.IsTrue(XRDevice.isPresent, "XR Device is not present"); Assert.IsTrue(XRDevice.isPresent, "XR Device is not present");
yield return null;
} }
[UnityPlatform(exclude = new[] { RuntimePlatform.Android })] [UnityPlatform(exclude = new[] { RuntimePlatform.Android, RuntimePlatform.IPhonePlayer })]
[UnityTest] [Test]
public IEnumerator VerifyXRDevice_userPresence_isPresent() public void VerifyXRDevice_userPresence_isPresent()
{ {
if (Settings.EnabledXrTarget != "MockHMD") if (Settings.EnabledXrTarget != "MockHMD")
{ {
var expUserPresenceState = UserPresenceState.Present; var expUserPresenceState = UserPresenceState.Present;
Assert.AreEqual(XRDevice.userPresence, expUserPresenceState, string.Format("Not mobile platform. Expected XRDevice.userPresence to be {0}, but is {1}.", expUserPresenceState, XRDevice.userPresence)); Assert.AreEqual(XRDevice.userPresence, expUserPresenceState, string.Format("Not mobile platform. Expected XRDevice.userPresence to be {0}, but is {1}.", expUserPresenceState, XRDevice.userPresence));
} }
yield return null;
} }
[UnityTest] [Test]
public IEnumerator VerifyXrSettings_IsDeviceActive() public void VerifyXrSettings_IsDeviceActive()
{ {
Assert.IsTrue(XRSettings.isDeviceActive, "XR Device is not active"); Assert.IsTrue(XRSettings.isDeviceActive, "XR Device is not active");
yield return null;
} }
[UnityTest] [Test]
public IEnumerator VerifyXrSettings_LoadedDeviceName() public void VerifyXrSettings_LoadedDeviceName()
{ {
yield return null;
Assert.AreEqual( Assert.AreEqual(
Settings.EnabledXrTarget, Settings.EnabledXrTarget,
XRSettings.loadedDeviceName, XRSettings.loadedDeviceName,
string.Format("Expected {0}, but is {1}.", Settings.EnabledXrTarget, XRSettings.loadedDeviceName)); string.Format("Expected {0}, but is {1}.", Settings.EnabledXrTarget, XRSettings.loadedDeviceName));
} }
[UnityTest] [Test]
public IEnumerator VerifyXrModelNotEmpty() public void VerifyXrModelNotEmpty()
{ {
var model = XRDevice.model; Assert.IsNotEmpty(XRDevice.model, "Model is empty");
Assert.IsNotEmpty(model, "Model is empty");
yield return null;
} }
[UnityTest] [Test]
public IEnumerator VerifyXrDevice_NativePtr_IsNotEmpty() public void VerifyXrDevice_NativePtr_IsNotEmpty()
{ {
var ptr = XRDevice.GetNativePtr().ToString(); var ptr = XRDevice.GetNativePtr().ToString();
Assert.IsNotEmpty(ptr, "Native Ptr is empty"); Assert.IsNotEmpty(ptr, "Native Ptr is empty");
yield return null;
} }
[UnityTest] [Test]
public IEnumerator VerifyRefreshRateGreaterThan0() public void VerifyRefreshRateGreaterThan0()
{ {
var refreshRate = XRDevice.refreshRate; Assert.AreNotEqual(XRDevice.refreshRate, 0, "Refresh is 0; should be greater than 0.");
Assert.AreNotEqual(refreshRate, 0, "Refresh is 0; should be greater than 0."); }
yield return null;
[Test]
public void VerifyXrSettings_EyeTextureHeight_GreaterThan0()
{
Assert.IsTrue(XRSettings.eyeTextureHeight > 0f);
}
[Test]
public void VerifyXrSettings_EyeTextureWidth_GreaterThan0()
{
Assert.IsTrue(XRSettings.eyeTextureWidth > 0f);
}
[Test]
public void VerifyXrSettings_EyeTextureResolutionScale_GreaterThan0()
{
Assert.IsTrue(XRSettings.eyeTextureResolutionScale > 0f);
}
[Test]
public void VerifyXrSettings_RenderViewportScale_GreaterThan0()
{
Assert.IsTrue(XRSettings.renderViewportScale > 0f);
}
[Test]
public void VerifyXrSettings_UseOcclusionMesh()
{
Assert.IsTrue(XRSettings.useOcclusionMesh);
}
#if !UNITY_EDITOR
[Test]
public void XrApVerifyXrSettings_StereoRenderingMode()
{
Assert.IsTrue(XRSettings.stereoRenderingMode.ToString().Contains(Settings.StereoRenderingMode.ToString()), $"{XRSettings.stereoRenderingMode} != {Settings.StereoRenderingMode}");
}
#endif
[UnityTest]
[Ignore("Inconsistent results for test. For example, this doesn't work on GearVR.")]
public IEnumerator CanDisableAndEnableXr()
{
yield return new MonoBehaviourTest<SwapXrEnabled>();
} }
} }

Просмотреть файл

@ -20,7 +20,7 @@ public class XrFunctionalTestBase
{ {
protected XrFunctionalTestHelpers XrFunctionalTestHelpers; protected XrFunctionalTestHelpers XrFunctionalTestHelpers;
protected CurrentSettings Settings; protected CurrentSettings Settings;
protected static int OneSecOfFramesWaitTime = 1; protected static int DefaultFrameSkipCount = 1;
public GameObject Camera; public GameObject Camera;
public GameObject Light; public GameObject Light;

Просмотреть файл

@ -36,7 +36,7 @@ internal class XrNodesTests : XrFunctionalTestBase
public IEnumerator XrNodesHeadTracking() public IEnumerator XrNodesHeadTracking()
{ {
InputTracking.GetNodeStates(nodeList); InputTracking.GetNodeStates(nodeList);
yield return SkipFrame(OneSecOfFramesWaitTime); yield return SkipFrame(DefaultFrameSkipCount);
var headNodes = nodeList.Where(n => n.nodeType == XRNode.Head); var headNodes = nodeList.Where(n => n.nodeType == XRNode.Head);
Assert.True(headNodes.Any(), "Failed to find XRNode.Head node type."); Assert.True(headNodes.Any(), "Failed to find XRNode.Head node type.");
@ -47,7 +47,7 @@ internal class XrNodesTests : XrFunctionalTestBase
public IEnumerator XrNodesEyeTracking() public IEnumerator XrNodesEyeTracking()
{ {
InputTracking.GetNodeStates(nodeList); InputTracking.GetNodeStates(nodeList);
yield return SkipFrame(OneSecOfFramesWaitTime); yield return SkipFrame(DefaultFrameSkipCount);
// Verify left eye node // Verify left eye node
var leftEyeNodes = nodeList.Where(n => n.nodeType == XRNode.LeftEye); var leftEyeNodes = nodeList.Where(n => n.nodeType == XRNode.LeftEye);

Просмотреть файл

@ -1,60 +0,0 @@
using System.Collections;
using NUnit.Framework;
using UnityEngine.TestTools;
using UnityEngine.XR;
using Assert = UnityEngine.Assertions.Assert;
internal class XrSmokeXrFunctionalTest : XrFunctionalTestBase
{
[UnityTest]
public IEnumerator VerifyXrSettings_EyeTextureHeight_GreaterThan0()
{
Assert.IsTrue(XRSettings.eyeTextureHeight > 0f);
yield return null;
}
[UnityTest]
public IEnumerator VerifyXrSettings_EyeTextureWidth_GreaterThan0()
{
Assert.IsTrue(XRSettings.eyeTextureWidth > 0f);
yield return null;
}
[UnityTest]
public IEnumerator VerifyXrSettings_EyeTextureResolutionScale_GreaterThan0()
{
Assert.IsTrue(XRSettings.eyeTextureResolutionScale > 0f);
yield return null;
}
[UnityTest]
public IEnumerator VerifyXrSettings_RenderViewportScale_GreaterThan0()
{
Assert.IsTrue(XRSettings.renderViewportScale > 0f);
yield return null;
}
[UnityTest]
public IEnumerator VerifyXrSettings_UseOcclusionMesh()
{
Assert.IsTrue(XRSettings.useOcclusionMesh);
yield return null;
}
#if !UNITY_EDITOR
[UnityTest]
public IEnumerator XrApVerifyXrSettings_StereoRenderingMode()
{
Assert.IsTrue(XRSettings.stereoRenderingMode.ToString().Contains(Settings.StereoRenderingMode.ToString()), $"{XRSettings.stereoRenderingMode} != {Settings.StereoRenderingMode}");
yield return null;
}
#endif
[UnityTest]
[Ignore("Inconsistent results for test. For example, this doesn't work on GearVR.")]
public IEnumerator CanDisableAndEnableXr()
{
yield return new MonoBehaviourTest<SwapXrEnabled>();
}
}

Просмотреть файл

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 1e24ec30759d27c4d8c3379b486701b3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -8,7 +8,7 @@
"com.unity.ide.vscode": "1.0.6", "com.unity.ide.vscode": "1.0.6",
"com.unity.package-manager-ui": "2.2.0", "com.unity.package-manager-ui": "2.2.0",
"com.unity.purchasing": "2.0.6", "com.unity.purchasing": "2.0.6",
"com.unity.test-framework": "1.0.11", "com.unity.test-framework": "1.0.12",
"com.unity.textmeshpro": "1.3.0", "com.unity.textmeshpro": "1.3.0",
"com.unity.timeline": "1.0.0", "com.unity.timeline": "1.0.0",
"com.unity.xr.legacyinputhelpers": "2.0.2", "com.unity.xr.legacyinputhelpers": "2.0.2",