public static WrappedTask <RedirectedProcessResult, AssemblyConfig> UploadAsync(AssemblyConfig config) { var source = new CancellationTokenSource(); var token = source.Token; var args = new List <string> { "cloud", "upload", config.AssemblyName, "--project_name", config.ProjectName, "--json_output", "--enable_pre_upload_check=false", }; if (config.ShouldForceUpload) { args.Add("--force"); } var task = Task.Run(async() => await RedirectedProcess.Command(Tools.Common.SpatialBinary) .InDirectory(Tools.Common.SpatialProjectRootDir) .WithArgs(args.ToArray()) .RedirectOutputOptions(OutputRedirectBehaviour.RedirectStdOut | OutputRedirectBehaviour.RedirectStdErr | OutputRedirectBehaviour.ProcessSpatialOutput) .RunAsync(token)); return(new WrappedTask <RedirectedProcessResult, AssemblyConfig> { Task = task, CancelSource = source, Context = config.DeepCopy() }); }
public static Dictionary <string, string> RetrieveAvailableiOSSimulators() { var availableSimulators = new Dictionary <string, string>(); // Check if we have a physical device connected var exitCode = RedirectedProcess.Command("instruments") .WithArgs("-s", "devices") .AddOutputProcessing(message => { // get all simulators if (message.Contains("iPhone") || message.Contains("iPad")) { if (simulatorUIDRegex.IsMatch(message)) { var simulatorUID = simulatorUIDRegex.Match(message).Groups[1].Value; availableSimulators[nameRegex.Match(message).Groups[1].Value] = simulatorUID; } } }) .RedirectOutputOptions(OutputRedirectBehaviour.None) .Run(); if (exitCode != 0) { Debug.LogError("Failed to find iOS Simulators. Make sure you have the Command line tools for XCode (https://developer.apple.com/download/more/) installed and check the logs."); } return(availableSimulators); }
private async Task <bool> TriggerUploadAssemblyAsync() { if (!Tools.Common.CheckDependencies()) { return(false); } var arguments = new string[] { "cloud", "upload", uploadAssemblyName, "--project_name", projectName, forceUploadAssembly ? "--json_output --force" : "--json_output" }; var processResult = await RedirectedProcess.Command(Tools.Common.SpatialBinary).WithArgs(arguments) .RedirectOutputOptions(OutputRedirectBehaviour.RedirectStdOut | OutputRedirectBehaviour.RedirectStdErr | OutputRedirectBehaviour.ProcessSpatialOutput) .InDirectory(ProjectRootPath) .RunAsync(); if (processResult.ExitCode == 0) { Debug.Log($"Uploaded assembly {uploadAssemblyName} to project {projectName} successfully."); return(true); } Debug.LogError($"Failed to upload assembly {uploadAssemblyName} to project {projectName}."); return(false); }
public static (List <DeviceLaunchConfig> emulators, List <DeviceLaunchConfig> devices) RetrieveAvailableEmulatorsAndDevices() { var availableEmulators = new List <DeviceLaunchConfig>(); var availableDevices = new List <DeviceLaunchConfig>(); if (!TryGetAdbPath(out var adbPath)) { Debug.LogError( $"Could not find Android SDK. Please set the SDK location in your editor preferences."); return(availableEmulators, availableDevices); } // List connected devices // adb devices -l var result = RedirectedProcess.Command(adbPath) .WithArgs("devices", "-l") .AddOutputProcessing(message => { if (!DeviceMatchRegex.IsMatch(message)) { return; } var match = DeviceMatchRegex.Match(message); var deviceId = match.Groups["id"].Value; if (deviceId.Contains("emulator")) { availableEmulators.Add(new DeviceLaunchConfig( deviceName: $"{match.Groups["product"].Value} ({deviceId})", deviceId: deviceId, deviceType: DeviceType.AndroidEmulator, launchAction: Launch)); } else { availableDevices.Add(new DeviceLaunchConfig( deviceName: $"{match.Groups["model"].Value} ({deviceId})", deviceId: deviceId, deviceType: DeviceType.AndroidDevice, launchAction: Launch)); } }) .RedirectOutputOptions(OutputRedirectBehaviour.None) .Run(); if (result.ExitCode == 0) { return(availableEmulators, availableDevices); } Debug.LogError($"Failed to find Android emulators or devices:\n {string.Join("\n", result.Stderr)}"); availableEmulators.Clear(); availableDevices.Clear(); return(availableEmulators, availableDevices); }
public static void Launch(bool shouldConnectLocally, string deviceId, string runtimeIp, bool useSimulator) { try { EditorUtility.DisplayProgressBar("Preparing your Mobile Client", "Preparing launch arguments", 0.0f); if (!TryGetXCTestRunPath(useSimulator, out var xcTestRunPath)) { Debug.LogError( "Unable to find a xctestrun file for the correct architecture. Did you build your client using the correct Target SDK? " + "Go to Project Settings > Player > iOS > Other Settings > Target SDK to select the correct one before building your iOS worker."); return; } var arguments = MobileLaunchUtils.PrepareArguments(shouldConnectLocally, runtimeIp); if (!TryModifyEnvironmentVariables(xcTestRunPath, arguments)) { Debug.LogError($"Was unable to read and modify {xcTestRunPath}."); return; } if (useSimulator) { EditorUtility.DisplayProgressBar("Launching Mobile Client", "Start iOS Simulator", 0.5f); // Start simulator if (RedirectedProcess.Command("xcrun") .WithArgs("instruments", "-w", deviceId, "-t", "Blank") .Run() != 0) { Debug.LogError("Was unable to start iOS Simulator."); return; } } EditorUtility.DisplayProgressBar("Launching Mobile Client", "Installing your app", 0.7f); if (!TryLaunchApplication(deviceId, xcTestRunPath)) { Debug.LogError("Failed to start app on iOS device."); } EditorUtility.DisplayProgressBar("Launching Mobile Client", "Done", 1.0f); } finally { var traceDirectories = Directory .GetDirectories(Path.Combine(Application.dataPath, ".."), "*.trace") .Where(s => s.EndsWith(".trace")); foreach (var directory in traceDirectories) { Directory.Delete(directory, true); } EditorUtility.ClearProgressBar(); } }
public static (List <DeviceLaunchConfig> emulators, List <DeviceLaunchConfig> devices) RetrieveAvailableEmulatorsAndDevices() { var availableSimulators = new List <DeviceLaunchConfig>(); var availableDevices = new List <DeviceLaunchConfig>(); // List connected devices // instruments -s devices var result = RedirectedProcess.Command("instruments") .WithArgs("-s", "devices") .AddOutputProcessing(message => { // Simulators if (message.Contains("iPhone") || message.Contains("iPad")) { if (SimulatorUidRegex.IsMatch(message)) { var simulatorName = NameRegex.Match(message).Groups[1].Value; var simulatorUid = SimulatorUidRegex.Match(message).Groups[1].Value; availableSimulators.Add(new DeviceLaunchConfig( deviceName: simulatorName, deviceId: simulatorUid, deviceType: DeviceType.iOSSimulator, launchAction: Launch)); return; } } // Devices if (DeviceUidRegex.IsMatch(message)) { var deviceName = NameRegex.Match(message).Groups[1].Value; var deviceUid = DeviceUidRegex.Match(message).Groups[1].Value; availableDevices.Add(new DeviceLaunchConfig( deviceName: deviceName, deviceId: deviceUid, deviceType: DeviceType.iOSDevice, launchAction: Launch)); } }) .RedirectOutputOptions(OutputRedirectBehaviour.None) .Run(); if (result.ExitCode == 0) { return(availableSimulators, availableDevices); } Debug.LogError("Failed to find iOS Simulators or devices. " + "Make sure you have the Command line tools for XCode (https://developer.apple.com/download/more/) " + $"installed and check the logs:\n {string.Join("\n", result.Stderr)}"); availableSimulators.Clear(); availableDevices.Clear(); return(availableSimulators, availableDevices); }
private static bool TryBuildXCodeProject(string developmentTeamId) { return(RedirectedProcess.Command("xcodebuild") .WithArgs("build-for-testing", "-project", Path.Combine(XCodeProjectPath, XCodeProjectFile), "-derivedDataPath", DerivedDataPath, "-scheme", "Unity-iPhone", $"DEVELOPMENT_TEAM={developmentTeamId}", "-allowProvisioningUpdates") .Run() == 0); }
private static void Zip(string zipAbsolutePath, string basePath, bool useCompression) { using (new ShowProgressBarScope($"Package {basePath}")) { RedirectedProcess.Command(Common.SpatialBinary) .WithArgs("file", "zip", $"--output=\"{Path.GetFullPath(zipAbsolutePath)}\"", $"--basePath=\"{Path.GetFullPath(basePath)}\"", "\"**\"", $"--compression={useCompression}") .Run(); } }
/// <summary> /// Starts a local deployment asynchronously. /// </summary> /// <param name="name">The name for the local deployment.</param> /// <param name="deploymentJsonPath"> /// The path to the launch configuration JSON relative to the root of the SpatialOS project. /// </param> /// <param name="snapshotFileName"> /// The name of the snapshot to use for this deployment. Must be in the snapshots directory of your /// SpatialOS project. /// </param> /// <returns>A task which represents the deployment that was started.</returns> /// <exception cref="ArgumentException">Thrown if <see cref="deploymentJsonPath"/> does not exist.</exception> /// <exception cref="Exception">Thrown if the deployment fails to start.</exception> public async Task <LocalDeployment> StartLocalDeployment(string name, string deploymentJsonPath, string snapshotFileName = "default.snapshot") { var fullJsonPath = Path.Combine(Common.SpatialProjectRootDir, deploymentJsonPath); if (!File.Exists(fullJsonPath)) { throw new ArgumentException($"Could not find launch config file at {fullJsonPath}"); } var fullSnapshotPath = Path.Combine(Common.SpatialProjectRootDir, "snapshots", snapshotFileName); if (!File.Exists(fullSnapshotPath)) { throw new ArgumentException($"Could not find launch config file at {fullSnapshotPath}"); } var buildConfigResult = await RedirectedProcess .Spatial("build", "build-config") .InDirectory(Common.SpatialProjectRootDir) .RedirectOutputOptions(OutputRedirectBehaviour.None) .RunAsync() .ConfigureAwait(false); if (buildConfigResult.ExitCode != 0) { throw new Exception($"Failed to build worker configs with error:\n {string.Join("\n", buildConfigResult.Stderr)}"); } var snapshotFile = Path.GetFileNameWithoutExtension(snapshotFileName); var result = await RedirectedProcess.Command(SpotBinary) .WithArgs("alpha", "deployment", "create", "-p", ProjectName, "-n", name, "-c", $"\"{fullJsonPath}\"", "-s", snapshotFile, "--json") .InDirectory(Common.SpatialProjectRootDir) .RedirectOutputOptions(OutputRedirectBehaviour.None) .RunAsync() .ConfigureAwait(false); if (result.ExitCode != 0) { throw new Exception($"Failed to start deployment with error:\n {string.Join("\n", result.Stderr)}"); } var deploymentData = Json.Deserialize(string.Join("", result.Stdout)); if (deploymentData == null) { throw new Exception($"Failed to create deployment because there was no output. Error: \n {string.Join("\n", result.Stderr)}"); } var content = (Dictionary <string, object>)deploymentData["content"]; var id = (string)content["id"]; return(new LocalDeployment(this, id, name, ProjectName)); }
private async Task <bool> TriggerLaunchDeploymentAsync() { try { EditorApplication.LockReloadAssemblies(); if (!Tools.Common.CheckDependencies()) { return(false); } var arguments = new List <string> { "create", projectName, assemblyName, deploymentName, Path.Combine(ProjectRootPath, mainLaunchJson), Path.Combine(ProjectRootPath, snapshotPath), deploymentRegionCode.ToString() }; if (simPlayerDeploymentEnabled) { arguments.AddRange(new List <string> { simPlayerDeploymentName, Path.Combine(ProjectRootPath, simPlayerLaunchJson) }); } var processResult = await RedirectedProcess.Command(Tools.Common.DotNetBinary) .WithArgs(ConstructArguments(arguments)) .RedirectOutputOptions(OutputRedirectBehaviour.RedirectStdOut | OutputRedirectBehaviour.RedirectStdErr) .InDirectory(DotNetWorkingDirectory) .RunAsync(); if (processResult.ExitCode == 0) { Application.OpenURL(string.Format(ConsoleURLFormat, projectName, deploymentName)); if (simPlayerDeploymentEnabled) { Application.OpenURL(string.Format(ConsoleURLFormat, projectName, simPlayerDeploymentName)); } } return(processResult.ExitCode != 0); } finally { EditorApplication.UnlockReloadAssemblies(); } }
private async Task <RedirectedProcessResult> RunDeploymentLauncherHelperAsync(List <string> args, bool redirectStdout = false) { var outputOptions = OutputRedirectBehaviour.RedirectStdErr; if (redirectStdout) { outputOptions |= OutputRedirectBehaviour.RedirectStdOut; } var processResult = await RedirectedProcess.Command(Tools.Common.DotNetBinary) .WithArgs(ConstructArguments(args)) .RedirectOutputOptions(outputOptions) .InDirectory(DotNetWorkingDirectory) .RunAsync(); if (processResult.ExitCode == 0) { return(processResult); } // Examine the failure reason. var failureReason = processResult.Stdout.Count > 0 ? processResult.Stdout[0] : ""; if (failureReason == "<error:unauthenticated>") { // The reason this task failed is because we are authenticated. Try authenticating. Debug.Log( "Failed to connect to the SpatialOS platform due to being unauthenticated. Running `spatial auth login` then retrying the last operation..."); var spatialAuthLoginResult = await RedirectedProcess.Command(Tools.Common.SpatialBinary) .WithArgs(new string[] { "auth", "login", "--json_output" }) .RedirectOutputOptions(OutputRedirectBehaviour.RedirectStdErr | OutputRedirectBehaviour.ProcessSpatialOutput) .InDirectory(DotNetWorkingDirectory) .RunAsync(); if (spatialAuthLoginResult.ExitCode == 0) { // Re-run the task. processResult = await RedirectedProcess.Command(Tools.Common.DotNetBinary) .WithArgs(ConstructArguments(args)) .RedirectOutputOptions(OutputRedirectBehaviour.RedirectStdErr) .InDirectory(DotNetWorkingDirectory) .RunAsync(); } else { Debug.Log("Failed to run `spatial auth login`."); } } return(processResult); }
public void Spatiald_is_running_after_Start() { using (SpatialdManager.Start().Result) { var result = RedirectedProcess.Command(Common.SpatialBinary) .WithArgs("service", "status") .InDirectory(Common.SpatialProjectRootDir) .RedirectOutputOptions(OutputRedirectBehaviour.None) .RunAsync() .Result; Assert.IsTrue(result.Stdout.Any(line => line.Contains("Local API service is running"))); } }
public void Dispose() { var result = RedirectedProcess.Command(Common.SpatialBinary) .WithArgs("service", "stop") .InDirectory(Common.SpatialProjectRootDir) .RedirectOutputOptions(OutputRedirectBehaviour.None) .RunAsync() .Result; if (result.ExitCode != 0) { Debug.LogWarning($"Failed to stop spatiald with error:\n {string.Join("\n", result.Stderr)}"); } }
/// <summary> /// Stops a local deployment asynchronously. /// </summary> /// <param name="deployment">The deployment to stop.</param> /// <returns>A task which represents the operation to stop the deployment.</returns> /// <exception cref="Exception">Thrown if the deployment fails to be stopped.</exception> public async Task StopLocalDeployment(LocalDeployment deployment) { var result = await RedirectedProcess.Command(SpotBinary) .WithArgs("alpha", "deployment", "delete", "-i", deployment.Id) .InDirectory(Common.SpatialProjectRootDir) .RedirectOutputOptions(OutputRedirectBehaviour.None) .RunAsync() .ConfigureAwait(false); if (result.ExitCode != 0) { throw new Exception($"Failed to stop deployment with error:\n {string.Join("\n", result.Stderr)}"); } }
private static void Package(string packageName, bool useCompression) { var zipPath = Path.Combine(EditorPaths.PlayerBuildDirectory, packageName); var basePath = Path.Combine(Common.BuildScratchDirectory, packageName); using (new ShowProgressBarScope($"Package {basePath}")) { RedirectedProcess.Command(Common.SpatialBinary) .InDirectory(Path.GetFullPath(Path.Combine(Application.dataPath, ".."))) .WithArgs("file", "zip", $"--output=\"{Path.GetFullPath(zipPath)}\"", $"--basePath=\"{Path.GetFullPath(basePath)}\"", "\"**\"", $"--compression={useCompression}") .Run(); } }
/// <summary> /// Gets the details of currently running deployments asynchronously. /// </summary> /// <returns>A task which represents list of</returns> public async Task <List <LocalDeployment> > GetRunningDeployments() { var result = await RedirectedProcess.Command(SpotBinary) .WithArgs("alpha", "deployment", "list", "-p", ProjectName, "-f", "NOT_STOPPED_DEPLOYMENTS", "--json") .InDirectory(Common.SpatialProjectRootDir) .RedirectOutputOptions(OutputRedirectBehaviour.None) .RunAsync() .ConfigureAwait(false); if (result.ExitCode != 0) { throw new Exception($"Failed to list deployments with error:\n {string.Join("\n", result.Stderr)}"); } var json = Json.Deserialize(string.Join("", result.Stdout)); if (json == null) { throw new Exception($"Failed to list deployments because there was no output. Error: \n {string.Join("\n", result.Stderr)}"); } var content = (Dictionary <string, object>)json["content"]; if (!content.TryGetValue("deployments", out var deploymentsObj)) { return(new List <LocalDeployment>()); } var deploymentData = (List <object>)deploymentsObj; return(deploymentData .OfType <Dictionary <string, object> >() .Select(data => { var id = (string)data["id"]; var name = (string)data["name"]; if (!data.TryGetValue("tag", out var tagsObj)) { tagsObj = new List <object>(); } var tags = (List <object>)tagsObj; return new LocalDeployment(this, id, name, ProjectName, tags.Cast <string>().ToArray()); }) .ToList()); }
/// <summary> /// Adds the "dev_login" tag to this deployment asynchronously. /// </summary> /// <returns>A task which represents the underlying operation to add the tag.</returns> /// <exception cref="InvalidOperationException">Thrown if the operation to set the tag fails.</exception> public async Task AddDevLoginTag() { // TODO: Remove shim once tag functionality is added to `spot`: UTY-2212 to track. var result = await RedirectedProcess.Command(Common.DotNetBinary) .WithArgs("run", Id, Name, ProjectName) .InDirectory(SpotShimPath) .RedirectOutputOptions(OutputRedirectBehaviour.None) .RunAsync() .ConfigureAwait(false); if (result.ExitCode != 0) { throw new InvalidOperationException($"Failed to set deployment tag with error:\n {string.Join("\n", result.Stderr)}"); } Tags.Add("dev_login"); }
public static WrappedTask <RedirectedProcessResult, int> Authenticate() { var source = new CancellationTokenSource(); var token = source.Token; var task = Task.Run(async() => await RedirectedProcess.Command(Tools.Common.SpatialBinary) .InDirectory(Tools.Common.SpatialProjectRootDir) .WithArgs(AuthArgs) .RedirectOutputOptions(OutputRedirectBehaviour.RedirectStdOut | OutputRedirectBehaviour.RedirectStdErr | OutputRedirectBehaviour.ProcessSpatialOutput) .RunAsync(token)); return(new WrappedTask <RedirectedProcessResult, int> { Task = task, CancelSource = source, Context = 0 }); }
private static bool TryBuildXCodeProject(string developmentTeamId, out IEnumerable <string> xcBuildErrors) { var teamIdArgs = string.Empty; if (!string.IsNullOrEmpty(developmentTeamId)) { teamIdArgs = $"DEVELOPMENT_TEAM={developmentTeamId}"; } var result = RedirectedProcess.Command("xcodebuild") .WithArgs("build-for-testing", "-project", Path.Combine(XCodeProjectPath, XCodeProjectFile), "-derivedDataPath", DerivedDataPath, "-scheme", "Unity-iPhone", teamIdArgs, "-allowProvisioningUpdates") .Run(); xcBuildErrors = result.Stderr; return(result.ExitCode == 0); }
public static Dictionary <string, string> RetrieveAvailableiOSDevices() { var availableDevices = new Dictionary <string, string>(); var exitCode = RedirectedProcess.Command("instruments") .WithArgs("-s", "devices") .AddOutputProcessing(message => { if (deviceUIDRegex.IsMatch(message)) { var deviceUID = deviceUIDRegex.Match(message).Groups[1].Value; availableDevices[nameRegex.Match(message).Groups[1].Value] = deviceUID; } }) .RedirectOutputOptions(OutputRedirectBehaviour.None) .Run(); if (exitCode != 0) { Debug.LogError("Failed to find connected iOS devices. Make sure you have the Command line tools for XCode (https://developer.apple.com/download/more/) installed and check the logs."); } return(availableDevices); }
/// <summary> /// Starts SpatialD. /// </summary> /// <remarks> /// If SpatialD is already running, it will stop that instance and start a new one. /// </remarks> /// <exception cref="Exception">Thrown if this fails to start SpatialD.</exception> public static async Task <SpatialdManager> Start() { await RedirectedProcess.Command(Common.SpatialBinary) .WithArgs("service", "stop") .InDirectory(Common.SpatialProjectRootDir) .RedirectOutputOptions(OutputRedirectBehaviour.None) .RunAsync() .ConfigureAwait(false); var result = await RedirectedProcess.Command(Common.SpatialBinary) .WithArgs("service", "start") .InDirectory(Common.SpatialProjectRootDir) .RedirectOutputOptions(OutputRedirectBehaviour.None) .RunAsync() .ConfigureAwait(false); if (result.ExitCode != 0) { throw new Exception($"Could not start spatiald with error:\n {string.Join("\n", result.Stderr)}"); } return(new SpatialdManager()); }
private static void LaunchMobileClient() { try { // Find ADB tool var sdkRootPath = EditorPrefs.GetString("AndroidSdkRoot"); if (string.IsNullOrEmpty(sdkRootPath)) { Debug.LogError($"Could not find Android SDK. Please set the SDK location in your editor preferences."); return; } var adbPath = Path.Combine(sdkRootPath, "platform-tools", "adb"); EditorUtility.DisplayProgressBar("Launching Mobile Client", "Installing APK", 0.3f); // Find apk to install if (!TryGetApkPath(AbsoluteApkPath, out var apkPath)) { Debug.LogError($"Could not find a built out Android binary in \"{AbsoluteApkPath}\" to launch."); return; } // Ensure an android device/emulator is present if (RedirectedProcess.Command(adbPath).WithArgs("get-state").Run() != 0) { Debug.LogError("No Android device/emulator detected."); return; } // Install apk on connected phone / emulator if (RedirectedProcess.Command(adbPath).WithArgs("install", "-r", $"\"{apkPath}\"").Run() != 0) { Debug.LogError("Failed to install the apk on the device/emulator. If the application is already installed on your device/emulator, " + "try uninstalling it before launching the mobile client."); return; } EditorUtility.DisplayProgressBar("Launching Mobile Client", "Launching Client", 0.9f); // Optional arguments to be passed, same as standalone // Use this to pass through the local ip to connect to var runtimeIp = GdkToolsConfiguration.GetOrCreateInstance().RuntimeIp; var arguments = new StringBuilder(); if (!string.IsNullOrEmpty(runtimeIp)) { arguments.Append($"+{RuntimeConfigNames.ReceptionistHost} {runtimeIp}"); } // Get chosen android package id and launch var bundleId = PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.Android); RedirectedProcess.Command(adbPath) .WithArgs("shell", "am", "start", "-S", "-n", $"{bundleId}/com.unity3d.player.UnityPlayerActivity", "-e", "\"arguments\"", $"\\\"{arguments.ToString()}\\\"") .Run(); EditorUtility.DisplayProgressBar("Launching Mobile Client", "Done", 1.0f); } finally { EditorUtility.ClearProgressBar(); } }
public static void Launch(DeviceLaunchConfig deviceLaunchConfig, MobileLaunchConfig mobileLaunchConfig) { // Throw if device type is neither iOSDevice nor iOSSimulator if (deviceLaunchConfig.IsAndroid) { throw new ArgumentException($"Device must of be of type {DeviceType.iOSDevice} or {DeviceType.iOSSimulator}."); } try { var useEmulator = deviceLaunchConfig.DeviceType == DeviceType.iOSSimulator; EditorUtility.DisplayProgressBar("Preparing your Mobile Client", "Preparing launch arguments", 0.0f); if (!TryGetXCodeTestRunPath(useEmulator, out var xcTestRunPath)) { Debug.LogError( "Unable to find a xctestrun file for the correct architecture. Did you build your client using the correct Target SDK? " + "Go to Project Settings > Player > iOS > Other Settings > Target SDK to select the correct one before building your iOS worker."); return; } var arguments = mobileLaunchConfig.ToLaunchArgs(); if (!TryModifyEnvironmentVariables(xcTestRunPath, arguments)) { Debug.LogError($"Was unable to read and modify {xcTestRunPath}."); return; } if (useEmulator) { EditorUtility.DisplayProgressBar("Launching Mobile Client", "Start iOS Simulator", 0.5f); // Need to start Simulator before launching application on it // instruments -w <device id> -t <profiling template> var result = RedirectedProcess.Command("xcrun") .WithArgs("instruments", "-w", deviceLaunchConfig.DeviceId, "-t", "Blank") .Run(); if (result.ExitCode != 0) { Debug.LogError($"Unable to start iOS Simulator:\n{string.Join("\n", result.Stderr)}"); return; } } EditorUtility.DisplayProgressBar("Launching Mobile Client", "Installing your app", 0.7f); if (!TryLaunchApplication(deviceLaunchConfig.DeviceId, xcTestRunPath)) { Debug.LogError("Failed to start app on iOS device."); } EditorUtility.DisplayProgressBar("Launching Mobile Client", "Done", 1.0f); } finally { var traceDirectories = Directory .GetDirectories(Path.Combine(Application.dataPath, ".."), "*.trace") .Where(s => s.EndsWith(".trace")); foreach (var directory in traceDirectories) { Directory.Delete(directory, true); } EditorUtility.ClearProgressBar(); } }
public static void Launch(bool shouldConnectLocally, string runtimeIp) { try { // Find ADB tool var sdkRootPath = EditorPrefs.GetString("AndroidSdkRoot"); if (string.IsNullOrEmpty(sdkRootPath)) { Debug.LogError( $"Could not find Android SDK. Please set the SDK location in your editor preferences."); return; } var adbPath = Path.Combine(sdkRootPath, "platform-tools", "adb"); EditorUtility.DisplayProgressBar("Launching Mobile Client", "Installing APK", 0.3f); // Find apk to install if (!TryGetApkPath(Common.BuildScratchDirectory, out var apkPath)) { Debug.LogError($"Could not find a built out Android binary in \"{Common.BuildScratchDirectory}\" to launch."); return; } // Ensure an android device/emulator is present if (RedirectedProcess.Command(adbPath) .InDirectory(Path.GetFullPath(Path.Combine(Application.dataPath, ".."))) .WithArgs("get-state").Run() != 0) { Debug.LogError("No Android device/emulator detected."); return; } // Install apk on connected phone / emulator if (RedirectedProcess.Command(adbPath) .InDirectory(Path.GetFullPath(Path.Combine(Application.dataPath, ".."))) .WithArgs("install", "-r", $"\"{apkPath}\"").Run() != 0) { Debug.LogError( "Failed to install the apk on the device/emulator. If the application is already installed on your device/emulator, " + "try uninstalling it before launching the mobile client."); return; } EditorUtility.DisplayProgressBar("Launching Mobile Client", "Launching Client", 0.9f); var arguments = MobileLaunchUtils.PrepareArguments(shouldConnectLocally, runtimeIp); // Get chosen android package id and launch var bundleId = PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.Android); RedirectedProcess.Command(adbPath) .WithArgs("shell", "am", "start", "-S", "-n", $"{bundleId}/com.unity3d.player.UnityPlayerActivity", "-e", "\"arguments\"", $"\\\"{arguments}\\\"") .InDirectory(Path.GetFullPath(Path.Combine(Application.dataPath, ".."))) .Run(); EditorUtility.DisplayProgressBar("Launching Mobile Client", "Done", 1.0f); } finally { EditorUtility.ClearProgressBar(); } }
public static void Launch(DeviceLaunchConfig deviceLaunchConfig, MobileLaunchConfig mobileLaunchConfig) { // Throw if device type is neither AndroidDevice nor AndroidEmulator if (!deviceLaunchConfig.IsAndroid) { throw new ArgumentException($"Device must of be of type {DeviceType.AndroidDevice} or {DeviceType.AndroidEmulator}."); } try { // Find adb if (!TryGetAdbPath(out var adbPath)) { Debug.LogError( $"Could not find Android SDK. Please set the SDK location in your editor preferences."); return; } EditorUtility.DisplayProgressBar("Launching Mobile Client", "Installing APK", 0.3f); // Find apk to install if (!TryGetApkPath(Common.BuildScratchDirectory, out var apkPath)) { Debug.LogError($"Could not find a built out Android binary in \"{Common.BuildScratchDirectory}\" to launch."); return; } // Check if chosen emulator/device is connected // adb -s <device id> get-state if (RedirectedProcess.Command(adbPath) .InDirectory(Path.GetFullPath(Path.Combine(Application.dataPath, ".."))) .WithArgs($"-s {deviceLaunchConfig.DeviceId}", "get-state").Run().ExitCode != 0) { Debug.LogError($"Chosen {deviceLaunchConfig.PrettyDeviceType} ({deviceLaunchConfig.DeviceId}) not found."); return; } // Install apk on chosen emulator/device // adb -s <device id> install -r <apk> if (RedirectedProcess.Command(adbPath) .InDirectory(Path.GetFullPath(Path.Combine(Application.dataPath, ".."))) .WithArgs($"-s {deviceLaunchConfig.DeviceId}", "install", "-r", $"\"{apkPath}\"").Run().ExitCode != 0) { Debug.LogError( $"Failed to install the apk on the {deviceLaunchConfig.PrettyDeviceType}. " + $"If the application is already installed on your {deviceLaunchConfig.PrettyDeviceType}, " + "try uninstalling it before launching the mobile client."); return; } EditorUtility.DisplayProgressBar("Launching Mobile Client", "Launching Client", 0.9f); // Get GDK-related mobile launch arguments var arguments = mobileLaunchConfig.ToLaunchArgs(); // Get bundle identifier var bundleId = PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.Android); // Launch the bundle on chosen device // Use -S force stops target app before launching again // adb -s <device id> // shell am start -S -n <unity package path> -e arguments <mobile launch arguments> RedirectedProcess.Command(adbPath) .WithArgs($"-s {deviceLaunchConfig.DeviceId}", "shell", "am", "start", "-S", "-n", $"{bundleId}/com.unity3d.player.UnityPlayerActivity", "-e", "\"arguments\"", $"\\\"{arguments}\\\"") .InDirectory(Path.GetFullPath(Path.Combine(Application.dataPath, ".."))) .Run(); EditorUtility.DisplayProgressBar("Launching Mobile Client", "Done", 1.0f); } finally { EditorUtility.ClearProgressBar(); } }