public static bool UninstallAPK() { OVRBundleTool.PrintLog("Uninstalling Application . . ."); OVRADBTool adbTool = new OVRADBTool(OVRConfig.Instance.GetAndroidSDKPath()); if (adbTool.isReady) { string output, error; string appPackagename = PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.Android) + GetTransitionApkOptionalIdentifier(); string[] appStartCommand = { "-d shell", "pm uninstall", appPackagename }; if (adbTool.RunCommand(appStartCommand, null, out output, out error) == 0) { OVRBundleTool.PrintSuccess(); OVRBundleTool.PrintLog("App package " + appPackagename + " is uninstalled."); return(true); } OVRBundleTool.PrintError("Failed to uninstall APK."); } else { OVRBundleTool.PrintError(ADB_TOOL_INITIALIZE_ERROR); } return(false); }
private static bool CheckADBDevices() { // Check if there are any ADB devices connected before starting the build process var adbTool = new OVRADBTool(OVRConfig.Instance.GetAndroidSDKPath()); if (adbTool.isReady) { List <string> devices = adbTool.GetDevices(); if (devices.Count == 0) { OVRPlugin.SendEvent("no_adb_devices", "", "ovrbuild"); UnityEngine.Debug.LogError("No ADB devices connected. Cannot perform OVR Build and Run."); return(false); } else if (devices.Count > 1) { OVRPlugin.SendEvent("multiple_adb_devices", "", "ovrbuild"); UnityEngine.Debug.LogError("Multiple ADB devices connected. Cannot perform OVR Build and Run."); return(false); } } else { OVRPlugin.SendEvent("ovr_adbtool_initialize_failure", "", "ovrbuild"); UnityEngine.Debug.LogError("OVR ADB Tool failed to initialize. Check the Android SDK path in [Edit -> Preferences -> External Tools]"); return(false); } return(true); }
public static bool LaunchApplication() { OVRBundleTool.PrintLog("Launching Application . . . "); OVRADBTool adbTool = new OVRADBTool(OVRConfig.Instance.GetAndroidSDKPath()); if (adbTool.isReady) { string output, error; string appPackagename = PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.Android) + GetTransitionApkOptionalIdentifier(); string playerActivityName = "\"" + appPackagename + "/com.unity3d.player.UnityPlayerActivity\""; string[] appStartCommand = { "-d shell", "am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -S -f 0x10200000 -n", playerActivityName }; if (adbTool.RunCommand(appStartCommand, null, out output, out error) == 0) { OVRBundleTool.PrintSuccess(); OVRBundleTool.PrintLog("App package " + appPackagename + " is launched."); return(true); } string completeError = "Failed to launch application. Try launching it manually through the device.\n" + (string.IsNullOrEmpty(error) ? output : error); OVRBundleTool.PrintError(completeError); } else { OVRBundleTool.PrintError(ADB_TOOL_INITIALIZE_ERROR); } return(false); }
private static bool CheckADBDevices(out string connectedDeviceName) { // Check if there are any ADB devices connected before starting the build process var adbTool = new OVRADBTool(OVRConfig.Instance.GetAndroidSDKPath()); connectedDeviceName = null; if (adbTool.isReady) { List <string> devices = adbTool.GetDevices(); if (devices.Count == 0) { UnityEngine.Debug.LogError("No ADB devices connected. Connect a device to this computer to run APK."); return(false); } else if (devices.Count > 1) { UnityEngine.Debug.LogError("Multiple ADB devices connected. Disconnect extra devices from this computer to run APK."); return(false); } else { connectedDeviceName = devices[0]; return(true); } } else { UnityEngine.Debug.LogError("OVR ADB Tool failed to initialize. Check the Android SDK path in [Edit -> Preferences -> External Tools]"); return(false); } }
public static void DeleteRemoteAssetBundles() { OVRADBTool adbTool = new OVRADBTool(OVRConfig.Instance.GetAndroidSDKPath()); if (adbTool.isReady) { bool failure = false; string fileExistsError = "No such file or directory"; OVRBundleTool.PrintLog("Deleting device bundles . . . "); string output, error; string[] deleteBundleCommand = { "-d shell", "rm -r", externalSceneCache }; if (adbTool.RunCommand(deleteBundleCommand, null, out output, out error) != 0) { if (!(output.Contains(fileExistsError) || error.Contains(fileExistsError))) { failure = true; } } if (failure) { OVRBundleTool.PrintError(string.IsNullOrEmpty(error) ? output : error); OVRBundleTool.PrintError("Failed to delete scene bundle cache directory."); } else { OVRBundleTool.PrintSuccess(); } } else { OVRBundleTool.PrintError(ADB_TOOL_INITIALIZE_ERROR); } }
public static bool UninstallAPK() { OVRBundleTool.PrintLog("Uninstalling Application . . ."); OVRADBTool adbTool = new OVRADBTool(OVRConfig.Instance.GetAndroidSDKPath()); if (adbTool.isReady) { string output, error; string packageName = Application.identifier + ".transition"; string[] appStartCommand = { "-d shell", "pm uninstall", packageName }; if (adbTool.RunCommand(appStartCommand, null, out output, out error) == 0) { OVRBundleTool.PrintSuccess(); return(true); } OVRBundleTool.PrintError("Failed to uninstall APK."); } else { OVRBundleTool.PrintError(ADB_TOOL_INITIALIZE_ERROR); } return(false); }
public static string[] ListRemoteAssetBundleNames() { OVRADBTool adbTool = new OVRADBTool(OVRConfig.Instance.GetAndroidSDKPath()); if (adbTool.isReady) { externalSceneCache = EXTERNAL_STORAGE_PATH + "/" + PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.Android) + GetTransitionApkOptionalIdentifier() + "/cache/scenes"; string output, error; string[] listBundlesCommand = { "-d shell", "ls", externalSceneCache }; if (adbTool.RunCommand(listBundlesCommand, null, out output, out error) == 0) { return(output.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)); } } return(null); }
public static void DeleteRemoteAssetBundles() { OVRADBTool adbTool = new OVRADBTool(OVRConfig.Instance.GetAndroidSDKPath()); if (adbTool.isReady) { externalSceneCache = EXTERNAL_STORAGE_PATH + "/" + PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.Android) + GetTransitionApkOptionalIdentifier() + "/cache/scenes"; bool failure = false; string fileExistsError = "No such file or directory"; OVRBundleTool.PrintLog("Deleting device bundles . . . "); string output, error; string[] deleteBundleCommand = { "-d shell", "rm -r", externalSceneCache }; if (adbTool.RunCommand(deleteBundleCommand, null, out output, out error) != 0) { if (!(output.Contains(fileExistsError) || error.Contains(fileExistsError))) { failure = true; } } if (failure) { OVRBundleTool.PrintError(string.IsNullOrEmpty(error) ? output : error); OVRBundleTool.PrintError("Failed to delete scene bundle cache directory."); } else { OVRBundleTool.PrintSuccess(); } } else { OVRBundleTool.PrintError(ADB_TOOL_INITIALIZE_ERROR); } }
// The actual window code goes here void OnGUI() { showAndroidOptions = EditorGUILayout.Foldout(showAndroidOptions, "Android Tools"); if (showAndroidOptions) { GUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Android SDK root path: ", androidSdkRootPath); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Button("Start Server")) { if (adbTool == null) { adbTool = new OVRADBTool(androidSdkRootPath); } if (adbTool.isReady) { int exitCode = adbTool.StartServer(null); EditorUtility.DisplayDialog("ADB StartServer", (exitCode == 0 ? "Success" : "Failure. ExitCode = " + exitCode.ToString()), "Ok"); } else { EditorUtility.DisplayDialog("Can't locate ADBTool", adbTool.adbPath, "Ok"); } } if (GUILayout.Button("Kill Server")) { if (adbTool == null) { adbTool = new OVRADBTool(androidSdkRootPath); } if (adbTool.isReady) { int exitCode = adbTool.KillServer(null); EditorUtility.DisplayDialog("ADB KillServer", (exitCode == 0 ? "Success" : "Failure. ExitCode = " + exitCode.ToString()), "Ok"); } else { EditorUtility.DisplayDialog("Can't locate ADBTool", adbTool.adbPath, "Ok"); } } if (GUILayout.Button("Forward Port")) { if (adbTool == null) { adbTool = new OVRADBTool(androidSdkRootPath); } if (adbTool.isReady) { int exitCode = adbTool.ForwardPort(remoteListeningPort, null); EditorUtility.DisplayDialog("ADB ForwardPort", (exitCode == 0 ? "Success" : "Failure. ExitCode = " + exitCode.ToString()), "Ok"); OVRPlugin.SendEvent("device_metrics_profiler", (exitCode == 0 ? "adb_forward_success" : "adb_forward_failure")); } else { EditorUtility.DisplayDialog("Can't locate ADBTool", adbTool.adbPath, "Ok"); } } if (GUILayout.Button("Release Port")) { if (adbTool == null) { adbTool = new OVRADBTool(androidSdkRootPath); } if (adbTool.isReady) { int exitCode = adbTool.ReleasePort(remoteListeningPort, null); EditorUtility.DisplayDialog("ADB ReleasePort", (exitCode == 0 ? "Success" : "Failure. ExitCode = " + exitCode.ToString()), "Ok"); } else { EditorUtility.DisplayDialog("Can't locate ADBTool", adbTool.adbPath, "Ok"); } } GUILayout.EndHorizontal(); } EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); GUILayout.BeginHorizontal(); remoteListeningPort = EditorGUILayout.DelayedIntField("Remote Port", remoteListeningPort); if (tcpClient.connectionState == OVRNetwork.OVRNetworkTcpClient.ConnectionState.Disconnected) { if (GUILayout.Button("Connect")) { ConnectPerfMetricsTcpServer(); pauseReceiveMetrics = false; OVRPlugin.SendEvent("device_metrics_profiler", "connect"); } } else { if (tcpClient.connectionState == OVRNetwork.OVRNetworkTcpClient.ConnectionState.Connecting) { if (GUILayout.Button("Connecting ... Click again to Cancel")) { DisconnectPerfMetricsTcpServer(); OVRPlugin.SendEvent("device_metrics_profiler", "cancel"); } } else { if (GUILayout.Button("Disconnect")) { DisconnectPerfMetricsTcpServer(); OVRPlugin.SendEvent("device_metrics_profiler", "disconnect"); } if (GUILayout.Button(pauseReceiveMetrics ? "Continue" : "Pause")) { pauseReceiveMetrics = !pauseReceiveMetrics; } } } GUILayout.EndHorizontal(); EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); lock (receivedMetricsList) { PresentIntProperty("Frame Count", "frameCount"); PresentIntProperty("Dropped Frame Count", "compositorDroppedFrameCount"); float?avgFrameTime = GetAveragePerfValueFloat("deltaFrameTime"); if (avgFrameTime.HasValue) { float fps = 1.0f / avgFrameTime.Value; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("FPS", GUILayout.Width(labelWidth)); EditorGUILayout.LabelField(string.Format("{0:F1}", fps)); EditorGUILayout.EndHorizontal(); } int? deviceCpuClockLevel = GetLatestPerfValueInt("deviceCpuClockLevel"); int? deviceGpuClockLevel = GetLatestPerfValueInt("deviceGpuClockLevel"); float?deviceCpuClockFrequencyInMHz = GetLatestPerfValueFloat("deviceCpuClockFrequencyInMHz"); float?deviceGpuClockFrequencyInMHz = GetLatestPerfValueFloat("deviceGpuClockFrequencyInMHz"); if (deviceCpuClockLevel.HasValue || deviceCpuClockFrequencyInMHz.HasValue) { string cpuLabel; string cpuText; if (deviceCpuClockLevel.HasValue && deviceCpuClockFrequencyInMHz.HasValue) { cpuLabel = "CPU Level (Freq)"; cpuText = string.Format("{0} ({1:F0} MHz)", deviceCpuClockLevel, deviceCpuClockFrequencyInMHz); } else if (deviceCpuClockLevel.HasValue) { cpuLabel = "CPU Level"; cpuText = string.Format("{0}", deviceCpuClockLevel); } else { cpuLabel = "CPU Frequency"; cpuText = string.Format("{0:F0} MHz", deviceCpuClockFrequencyInMHz); } PresentText(cpuLabel, cpuText); } if (deviceGpuClockLevel.HasValue || deviceGpuClockFrequencyInMHz.HasValue) { string cpuLabel; string cpuText; if (deviceGpuClockLevel.HasValue && deviceGpuClockFrequencyInMHz.HasValue) { cpuLabel = "GPU Level (Freq)"; cpuText = string.Format("{0} ({1:F0} MHz)", deviceGpuClockLevel, deviceGpuClockFrequencyInMHz); } else if (deviceGpuClockLevel.HasValue) { cpuLabel = "GPU Level"; cpuText = string.Format("{0}", deviceGpuClockLevel); } else { cpuLabel = "GPU Frequency"; cpuText = string.Format("{0:F0} MHz", deviceGpuClockFrequencyInMHz); } PresentText(cpuLabel, cpuText); } PresentColumnTitles("Current", "Average", "Peak"); PresentFloatTimeInMs("Frame Time", "deltaFrameTime", 0.020f, true, true); PresentFloatTimeInMs("App CPU Time", "appCpuTime", 0.020f, true, true); PresentFloatTimeInMs("App GPU Time", "appGpuTime", 0.020f, true, true); PresentFloatTimeInMs("Compositor CPU Time", "compositorCpuTime", 0.020f, true, true); PresentFloatTimeInMs("Compositor GPU Time", "compositorGpuTime", 0.020f, true, true); PresentFloatPercentage("CPU Util (Average)", "systemCpuUtilAveragePercentage", false, false); PresentFloatPercentage("CPU Util (Worst Core)", "systemCpuUtilWorstPercentage", false, false); PresentFloatPercentage("GPU Util", "systemGpuUtilPercentage", false, false); } }
private static bool TransferSceneBundles(OVRADBTool adbTool, string absoluteTempPath, string externalSceneCache) { List <string> bundlesToTransfer = new List <string>(); List <string> bundlesToDelete = new List <string>(); string manifestFilePath = externalSceneCache + "/" + BUNDLE_MANAGER_MASTER_BUNDLE; string[] pullManifestCommand = { "-d pull", "\"" + manifestFilePath + "\"", "\"" + absoluteTempPath + "\"" }; string output, error; if (adbTool.RunCommand(pullManifestCommand, null, out output, out error) == 0) { // An existing manifest file was found on device. Load hashes and upload bundles that have changed hashes. Debug.Log("[OVRBundleManager] - Scene bundle manifest file found. Decoding changes . . ."); // Load hashes from remote manifest AssetBundle remoteBundle = AssetBundle.LoadFromFile(Path.Combine(absoluteTempPath, BUNDLE_MANAGER_MASTER_BUNDLE)); if (remoteBundle == null) { OVRBundleTool.PrintError("Failed to load remote asset bundle manifest file."); return(false); } AssetBundleManifest remoteManifest = remoteBundle.LoadAsset <AssetBundleManifest>("AssetBundleManifest"); Dictionary <string, Hash128> remoteBundleToHash = new Dictionary <string, Hash128>(); if (remoteManifest != null) { string[] assetBundles = remoteManifest.GetAllAssetBundles(); foreach (string bundleName in assetBundles) { remoteBundleToHash[bundleName] = remoteManifest.GetAssetBundleHash(bundleName); } } remoteBundle.Unload(true); // Load hashes from local manifest AssetBundle localBundle = AssetBundle.LoadFromFile(BUNDLE_MANAGER_OUTPUT_PATH + "\\" + BUNDLE_MANAGER_MASTER_BUNDLE + "\\" + BUNDLE_MANAGER_MASTER_BUNDLE); if (localBundle == null) { OVRBundleTool.PrintError("<color=red>Failed to load local asset bundle manifest file.\n</color>"); return(false); } AssetBundleManifest localManifest = localBundle.LoadAsset <AssetBundleManifest>("AssetBundleManifest"); if (localManifest != null) { Hash128 zeroHash = new Hash128(0, 0, 0, 0); // Build a list of dirty bundles that will have to be transfered string relativeSceneBundlesPath = Path.Combine(BUNDLE_MANAGER_OUTPUT_PATH, BUNDLE_MANAGER_MASTER_BUNDLE); bundlesToTransfer.Add(Path.Combine(relativeSceneBundlesPath, BUNDLE_MANAGER_MASTER_BUNDLE)); string[] assetBundles = localManifest.GetAllAssetBundles(); foreach (string bundleName in assetBundles) { if (!remoteBundleToHash.ContainsKey(bundleName)) { bundlesToTransfer.Add(Path.Combine(relativeSceneBundlesPath, bundleName)); } else { if (remoteBundleToHash[bundleName] != localManifest.GetAssetBundleHash(bundleName)) { bundlesToTransfer.Add(Path.Combine(relativeSceneBundlesPath, bundleName)); } remoteBundleToHash[bundleName] = zeroHash; } } OVRBundleTool.PrintLog(bundlesToTransfer.Count + " dirty bundle(s) will be transfered.\n"); } } else { if (output.Contains("does not exist") || output.Contains("No such file or directory")) { // Fresh install of asset bundles, transfer all asset bundles OVRBundleTool.PrintLog("Manifest file not found. Transfering all bundles . . . "); string[] mkdirCommand = { "-d shell", "mkdir -p", "\"" + externalSceneCache + "\"" }; if (adbTool.RunCommand(mkdirCommand, null, out output, out error) == 0) { string absoluteSceneBundlePath = Path.Combine(Path.Combine(Application.dataPath, ".."), Path.Combine(BUNDLE_MANAGER_OUTPUT_PATH, BUNDLE_MANAGER_MASTER_BUNDLE)); string[] assetBundlePaths = Directory.GetFiles(absoluteSceneBundlePath); if (assetBundlePaths.Length != 0) { foreach (string path in assetBundlePaths) { if (!path.Contains(".manifest")) { bundlesToTransfer.Add(path); } } } else { OVRBundleTool.PrintError("Failed to locate scene bundles to transfer."); return(false); } } } } // If any adb error occured during manifest calculation, print it and return false if (!string.IsNullOrEmpty(error) || output.Contains("error")) { OVRBundleTool.PrintError(string.IsNullOrEmpty(error) ? output : error); return(false); } // Transfer bundles to device DateTime transferStart = DateTime.Now; foreach (string bundle in bundlesToTransfer) { string absoluteBundlePath = Path.Combine(Path.Combine(Application.dataPath, ".."), bundle); string[] pushBundleCommand = { "-d push", "\"" + absoluteBundlePath + "\"", "\"" + externalSceneCache + "\"" }; adbTool.RunCommandAsync(pushBundleCommand, null); } Debug.Log("[OVRBundleManager] - Transfer took " + (DateTime.Now - transferStart).TotalSeconds + " seconds."); // Delete stale bundles on device if (bundlesToDelete.Count > 0) { foreach (string bundle in bundlesToDelete) { string bundlePath = externalSceneCache + "/" + bundle; string[] deleteBundleCommand = { "-d shell", "rm", "\"" + bundlePath + "\"" }; adbTool.RunCommandAsync(deleteBundleCommand, null); } OVRBundleTool.PrintLog("Deleted " + bundlesToDelete.Count + " bundle(s) that were stale"); } return(true); }
public void OnPostprocessBuild(BuildReport report) { #if UNITY_ANDROID if (autoIncrementVersion) { if ((report.summary.options & BuildOptions.Development) == 0) { PlayerSettings.Android.bundleVersionCode++; UnityEngine.Debug.Log("Incrementing version code to " + PlayerSettings.Android.bundleVersionCode); } } bool isExporting = true; foreach (var step in report.steps) { if (step.name.Contains("Compile scripts") || step.name.Contains("Building scenes") || step.name.Contains("Writing asset files") || step.name.Contains("Preparing APK resources") || step.name.Contains("Creating Android manifest") || step.name.Contains("Processing plugins") || step.name.Contains("Exporting project") || step.name.Contains("Building Gradle project")) { OVRPlugin.SendEvent("build_step_" + step.name.ToLower().Replace(' ', '_'), step.duration.TotalSeconds.ToString(), "ovrbuild"); #if BUILDSESSION UnityEngine.Debug.LogFormat("build_step_" + step.name.ToLower().Replace(' ', '_') + ": {0}", step.duration.TotalSeconds.ToString()); #endif if (step.name.Contains("Building Gradle project")) { isExporting = false; } } } OVRPlugin.AddCustomMetadata("build_step_count", report.steps.Length.ToString()); if (report.summary.outputPath.Contains("apk")) // Exclude Gradle Project Output { var fileInfo = new System.IO.FileInfo(report.summary.outputPath); OVRPlugin.AddCustomMetadata("build_output_size", fileInfo.Length.ToString()); } #endif if (!report.summary.outputPath.Contains("OVRGradleTempExport")) { OVRPlugin.SendEvent("build_complete", (System.DateTime.Now - buildStartTime).TotalSeconds.ToString(), "ovrbuild"); #if BUILDSESSION UnityEngine.Debug.LogFormat("build_complete: {0}", (System.DateTime.Now - buildStartTime).TotalSeconds.ToString()); #endif } #if UNITY_ANDROID if (!isExporting) { // Get the hosts path to Android SDK if (adbTool == null) { adbTool = new OVRADBTool(OVRConfig.Instance.GetAndroidSDKPath(false)); } if (adbTool.isReady) { // Check to see if there are any ADB devices connected before continuing. List <string> devices = adbTool.GetDevices(); if (devices.Count == 0) { return; } // Clear current logs on device Process adbClearProcess; adbClearProcess = adbTool.RunCommandAsync(new string[] { "logcat --clear" }, null); // Add a timeout if we cannot get a response from adb logcat --clear in time. Stopwatch timeout = new Stopwatch(); timeout.Start(); while (!adbClearProcess.WaitForExit(100)) { if (timeout.ElapsedMilliseconds > 2000) { adbClearProcess.Kill(); return; } } // Check if existing ADB process is still running, kill if needed if (adbProcess != null && !adbProcess.HasExited) { adbProcess.Kill(); } // Begin thread to time upload and install var thread = new Thread(delegate() { TimeDeploy(); }); thread.Start(); } } #endif }
public static bool IsAndroidSdkRootValid(string androidSdkRoot) { OVRADBTool tool = new OVRADBTool(androidSdkRoot); return(tool.isReady); }
public static bool DeployAPK() { // Create new instance of ADB Tool var adbTool = new OVRADBTool(androidSdkPath); if (adbTool.isReady) { string apkPathLocal; string gradleExportFolder = Path.Combine(Path.Combine(gradleExport, productName), "build\\outputs\\apk\\debug"); // Check to see if gradle output directory exists gradleExportFolder = gradleExportFolder.Replace("/", "\\"); if (!Directory.Exists(gradleExportFolder)) { UnityEngine.Debug.LogError("Could not find the gradle project at the expected path: " + gradleExportFolder); return(false); } // Search for output APK in gradle output directory apkPathLocal = Path.Combine(gradleExportFolder, productName + "-debug.apk"); if (!System.IO.File.Exists(apkPathLocal)) { UnityEngine.Debug.LogError(string.Format("Could not find {0} in the gradle project.", productName + "-debug.apk")); return(false); } string output, error; DateTime timerStart; // Ensure that the Oculus temp directory is on the device by making it IncrementProgressBar("Making Temp directory on device"); string[] mkdirCommand = { "-d shell", "mkdir -p", REMOTE_APK_PATH }; if (adbTool.RunCommand(mkdirCommand, null, out output, out error) != 0) { return(false); } // Push APK to device, also time how long it takes timerStart = System.DateTime.Now; IncrementProgressBar("Pushing APK to device . . ."); string[] pushCommand = { "-d push", "\"" + apkPathLocal + "\"", REMOTE_APK_PATH }; if (adbTool.RunCommand(pushCommand, null, out output, out error) != 0) { return(false); } // Calculate the transfer speed and determine if user is using USB 2.0 or 3.0 TimeSpan pushTime = System.DateTime.Now - timerStart; FileInfo apkInfo = new System.IO.FileInfo(apkPathLocal); double transferSpeed = (apkInfo.Length / pushTime.TotalSeconds) / BYTES_TO_MEGABYTES; bool informLog = transferSpeed < USB_TRANSFER_SPEED_THRES; UnityEngine.Debug.Log("OVRADBTool: Push Success"); // Install the APK package on the device IncrementProgressBar("Installing APK . . ."); string apkPath = REMOTE_APK_PATH + "/" + productName + "-debug.apk"; apkPath = apkPath.Replace(" ", "\\ "); string[] installCommand = { "-d shell", "pm install -r", apkPath }; timerStart = System.DateTime.Now; if (adbTool.RunCommand(installCommand, null, out output, out error) != 0) { return(false); } TimeSpan installTime = System.DateTime.Now - timerStart; UnityEngine.Debug.Log("OVRADBTool: Install Success"); // Start the application on the device IncrementProgressBar("Launching application on device . . ."); #if UNITY_2019_3_OR_NEWER string playerActivityName = "\"" + applicationIdentifier + "/com.unity3d.player.UnityPlayerActivity\""; #else string playerActivityName = "\"" + applicationIdentifier + "/" + applicationIdentifier + ".UnityPlayerActivity\""; #endif string[] appStartCommand = { "-d shell", "am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -S -f 0x10200000 -n", playerActivityName }; if (adbTool.RunCommand(appStartCommand, null, out output, out error) != 0) { return(false); } UnityEngine.Debug.Log("OVRADBTool: Application Start Success"); // Send back metrics on push and install steps OVRPlugin.AddCustomMetadata("transfer_speed", transferSpeed.ToString()); OVRPlugin.SendEvent("build_step_push_apk", pushTime.TotalSeconds.ToString(), "ovrbuild"); OVRPlugin.SendEvent("build_step_install_apk", installTime.TotalSeconds.ToString(), "ovrbuild"); IncrementProgressBar("Success!"); // If the user is using a USB 2.0 cable, inform them about improved transfer speeds and estimate time saved if (informLog) { var usb3Time = apkInfo.Length / (USB_3_TRANSFER_SPEED * BYTES_TO_MEGABYTES); UnityEngine.Debug.Log(string.Format("OVRBuild has detected slow transfer speeds. A USB 3.0 cable is recommended to reduce the time it takes to deploy your project by approximatly {0:0.0} seconds", pushTime.TotalSeconds - usb3Time)); return(true); } } else { UnityEngine.Debug.LogError("Could not find the ADB executable in the specified Android SDK directory."); } return(false); }
private static void CheckForTransitionAPK() { OVRADBTool adbTool = new OVRADBTool(OVRConfig.Instance.GetAndroidSDKPath()); if (adbTool.isReady) { string matchedPackageList, error; var transitionPackageName = PlayerSettings.applicationIdentifier; if (useOptionalTransitionApkPackage) { transitionPackageName += ".transition"; } string[] packageCheckCommand = new string[] { "-d shell pm list package", transitionPackageName }; if (adbTool.RunCommand(packageCheckCommand, null, out matchedPackageList, out error) == 0) { if (string.IsNullOrEmpty(matchedPackageList)) { currentApkStatus = ApkStatus.NOT_INSTALLED; } else { // adb "list package" command returns all package names that contains the given query package name // Need to check if the transition package name is matched exactly if (matchedPackageList.Contains("package:" + transitionPackageName + "\r\n")) { if (useOptionalTransitionApkPackage) { // If optional package name is used, it is deterministic that the transition apk is installed currentApkStatus = ApkStatus.OK; } else { // get package info to check for TRANSITION_APK_VERSION_NAME string[] dumpPackageInfoCommand = new string[] { "-d shell dumpsys package", transitionPackageName }; string packageInfo; if (adbTool.RunCommand(dumpPackageInfoCommand, null, out packageInfo, out error) == 0 && !string.IsNullOrEmpty(packageInfo) && packageInfo.Contains(OVRBundleManager.TRANSITION_APK_VERSION_NAME)) { // Matched package name found, and the package info contains TRANSITION_APK_VERSION_NAME currentApkStatus = ApkStatus.OK; } else { currentApkStatus = ApkStatus.NOT_INSTALLED; } } } else { // No matached package name returned currentApkStatus = ApkStatus.NOT_INSTALLED; } } } else if (error.Contains("no devices found")) { currentApkStatus = ApkStatus.DEVICE_NOT_CONNECTED; } else { currentApkStatus = ApkStatus.UNKNOWN; } } }
private static bool DeploySceneBundles(List <OVRBundleTool.EditorSceneInfo> sceneList) { // Create Temp directory on local machine if it does not exist string tempDirectory = Path.Combine(BUNDLE_MANAGER_OUTPUT_PATH, "Temp"); if (!Directory.Exists(tempDirectory)) { Directory.CreateDirectory(tempDirectory); } string absoluteTempPath = Path.Combine(Path.Combine(Application.dataPath, ".."), tempDirectory); OVRBundleTool.PrintLog("Deploying scene bundles to device . . . "); OVRADBTool adbTool = new OVRADBTool(OVRConfig.Instance.GetAndroidSDKPath()); if (adbTool.isReady) { DateTime transferStart = DateTime.Now; for (int i = 0; i < sceneList.Count; ++i) { if (!sceneList[i].shouldDeploy) { continue; } OVRBundleTool.UpdateSceneBuildStatus(OVRBundleTool.SceneBundleStatus.TRANSFERRING, i); } // Transfer all scene bundles that are relavent if (!TransferSceneBundles(adbTool, absoluteTempPath, externalSceneCache)) { return(false); } for (int i = 0; i < sceneList.Count; ++i) { if (!sceneList[i].shouldDeploy) { continue; } OVRBundleTool.UpdateSceneBuildStatus(OVRBundleTool.SceneBundleStatus.DEPLOYED, i); } // Create file to tell transition scene APK which scene to load and push it to the device string sceneLoadDataPath = Path.Combine(tempDirectory, OVRSceneLoader.sceneLoadDataName); if (File.Exists(sceneLoadDataPath)) { File.Delete(sceneLoadDataPath); } StreamWriter writer = new StreamWriter(sceneLoadDataPath, true); // Write version and scene names long unixTime = (int)(DateTimeOffset.UtcNow.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds; writer.WriteLine(unixTime.ToString()); for (int i = 0; i < sceneList.Count; i++) { if (!sceneList[i].shouldDeploy) { continue; } writer.WriteLine(Path.GetFileNameWithoutExtension(sceneList[i].scenePath)); } writer.Close(); string absoluteSceneLoadDataPath = Path.Combine(absoluteTempPath, OVRSceneLoader.sceneLoadDataName); string[] pushCommand = { "-d push", "\"" + absoluteSceneLoadDataPath + "\"", "\"" + externalSceneCache + "\"" }; string output, error; if (adbTool.RunCommand(pushCommand, null, out output, out error) == 0) { Debug.Log("[OVRBundleManager] Scene Load Data Pushed to Device."); return(true); } OVRBundleTool.PrintError(string.IsNullOrEmpty(error) ? output : error); } else { OVRBundleTool.PrintError(ADB_TOOL_INITIALIZE_ERROR); } return(false); }
// The actual window code goes here void OnGUI() { if (odhCalloutBackgroundStyle == null) { odhCalloutBackgroundStyle = new GUIStyle(EditorStyles.helpBox); var odhCalloutBackgroundStyleTex = new Texture2D(1, 1); odhCalloutBackgroundStyleTex.SetPixel(0, 0, new Color(0.9f, 0.8f, 0.2f, 0.2f)); odhCalloutBackgroundStyleTex.Apply(); odhCalloutBackgroundStyle.normal.background = odhCalloutBackgroundStyleTex; } if (odhCalloutTextStyle == null) { odhCalloutTextStyle = new GUIStyle(EditorStyles.label); odhCalloutTextStyle.richText = true; odhCalloutTextStyle.wordWrap = true; } // ODH Callout Section GUILayout.BeginHorizontal(odhCalloutBackgroundStyle); var script = MonoScript.FromScriptableObject(this); string assetPath = AssetDatabase.GetAssetPath(script); string editorPath = Path.GetDirectoryName(assetPath); string odhIconPath = Path.Combine(editorPath, "Textures\\odh_icon.png"); Texture ODHIcon = (Texture)EditorGUIUtility.Load(odhIconPath); GUILayout.Box(ODHIcon, GUILayout.Width(60.0f), GUILayout.Height(60.0f)); GUILayout.BeginVertical(); EditorGUILayout.LabelField("<b>This tool is deprecated.</b> Oculus recommends profiling builds through the Metrics section of " + "<b>Oculus Developer Hub</b>, a desktop companion tool that streamlines the Quest development workflow.", odhCalloutTextStyle); GUIContent ODHLabel = new GUIContent("Download Oculus Developer Hub"); #if UNITY_2021_1_OR_NEWER if (EditorGUILayout.LinkButton(ODHLabel)) #else if (GUILayout.Button(ODHLabel, GUILayout.ExpandWidth(false))) #endif { #if UNITY_EDITOR_WIN Application.OpenURL("https://developer.oculus.com/downloads/package/oculus-developer-hub-win/?source=unity"); #elif UNITY_EDITOR_OSX Application.OpenURL("https://developer.oculus.com/downloads/package/oculus-developer-hub-mac/?source=unity"); #endif } GUILayout.EndVertical(); GUILayout.EndHorizontal(); GUILayout.Space(15.0f); showAndroidOptions = EditorGUILayout.Foldout(showAndroidOptions, "Android Tools"); if (showAndroidOptions) { GUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Android SDK root path: ", androidSdkRootPath); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Button("Start Server")) { if (adbTool == null) { adbTool = new OVRADBTool(androidSdkRootPath); } if (adbTool.isReady) { int exitCode = adbTool.StartServer(null); EditorUtility.DisplayDialog("ADB StartServer", (exitCode == 0 ? "Success" : "Failure. ExitCode = " + exitCode.ToString()), "Ok"); } else { EditorUtility.DisplayDialog("Can't locate ADBTool", adbTool.adbPath, "Ok"); } } if (GUILayout.Button("Kill Server")) { if (adbTool == null) { adbTool = new OVRADBTool(androidSdkRootPath); } if (adbTool.isReady) { int exitCode = adbTool.KillServer(null); EditorUtility.DisplayDialog("ADB KillServer", (exitCode == 0 ? "Success" : "Failure. ExitCode = " + exitCode.ToString()), "Ok"); } else { EditorUtility.DisplayDialog("Can't locate ADBTool", adbTool.adbPath, "Ok"); } } if (GUILayout.Button("Forward Port")) { if (adbTool == null) { adbTool = new OVRADBTool(androidSdkRootPath); } if (adbTool.isReady) { int exitCode = adbTool.ForwardPort(remoteListeningPort, null); EditorUtility.DisplayDialog("ADB ForwardPort", (exitCode == 0 ? "Success" : "Failure. ExitCode = " + exitCode.ToString()), "Ok"); OVRPlugin.SendEvent("device_metrics_profiler", (exitCode == 0 ? "adb_forward_success" : "adb_forward_failure")); } else { EditorUtility.DisplayDialog("Can't locate ADBTool", adbTool.adbPath, "Ok"); } } if (GUILayout.Button("Release Port")) { if (adbTool == null) { adbTool = new OVRADBTool(androidSdkRootPath); } if (adbTool.isReady) { int exitCode = adbTool.ReleasePort(remoteListeningPort, null); EditorUtility.DisplayDialog("ADB ReleasePort", (exitCode == 0 ? "Success" : "Failure. ExitCode = " + exitCode.ToString()), "Ok"); } else { EditorUtility.DisplayDialog("Can't locate ADBTool", adbTool.adbPath, "Ok"); } } GUILayout.EndHorizontal(); } EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); GUILayout.BeginHorizontal(); remoteListeningPort = EditorGUILayout.DelayedIntField("Remote Port", remoteListeningPort); if (tcpClient.connectionState == OVRNetwork.OVRNetworkTcpClient.ConnectionState.Disconnected) { if (GUILayout.Button("Connect")) { ConnectPerfMetricsTcpServer(); pauseReceiveMetrics = false; OVRPlugin.SendEvent("device_metrics_profiler", "connect"); } } else { if (tcpClient.connectionState == OVRNetwork.OVRNetworkTcpClient.ConnectionState.Connecting) { if (GUILayout.Button("Connecting ... Click again to Cancel")) { DisconnectPerfMetricsTcpServer(); OVRPlugin.SendEvent("device_metrics_profiler", "cancel"); } } else { if (GUILayout.Button("Disconnect")) { DisconnectPerfMetricsTcpServer(); OVRPlugin.SendEvent("device_metrics_profiler", "disconnect"); } if (GUILayout.Button(pauseReceiveMetrics ? "Continue" : "Pause")) { pauseReceiveMetrics = !pauseReceiveMetrics; } } } GUILayout.EndHorizontal(); EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); lock (receivedMetricsList) { PresentIntProperty("Frame Count", "frameCount"); PresentIntProperty("Dropped Frame Count", "compositorDroppedFrameCount"); float?avgFrameTime = GetAveragePerfValueFloat("deltaFrameTime"); if (avgFrameTime.HasValue) { float fps = 1.0f / avgFrameTime.Value; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("FPS", GUILayout.Width(labelWidth)); EditorGUILayout.LabelField(string.Format("{0:F1}", fps)); EditorGUILayout.EndHorizontal(); } int? deviceCpuClockLevel = GetLatestPerfValueInt("deviceCpuClockLevel"); int? deviceGpuClockLevel = GetLatestPerfValueInt("deviceGpuClockLevel"); float?deviceCpuClockFrequencyInMHz = GetLatestPerfValueFloat("deviceCpuClockFrequencyInMHz"); float?deviceGpuClockFrequencyInMHz = GetLatestPerfValueFloat("deviceGpuClockFrequencyInMHz"); if (deviceCpuClockLevel.HasValue || deviceCpuClockFrequencyInMHz.HasValue) { string cpuLabel; string cpuText; if (deviceCpuClockLevel.HasValue && deviceCpuClockFrequencyInMHz.HasValue) { cpuLabel = "CPU Level (Freq)"; cpuText = string.Format("{0} ({1:F0} MHz)", deviceCpuClockLevel, deviceCpuClockFrequencyInMHz); } else if (deviceCpuClockLevel.HasValue) { cpuLabel = "CPU Level"; cpuText = string.Format("{0}", deviceCpuClockLevel); } else { cpuLabel = "CPU Frequency"; cpuText = string.Format("{0:F0} MHz", deviceCpuClockFrequencyInMHz); } PresentText(cpuLabel, cpuText); } if (deviceGpuClockLevel.HasValue || deviceGpuClockFrequencyInMHz.HasValue) { string cpuLabel; string cpuText; if (deviceGpuClockLevel.HasValue && deviceGpuClockFrequencyInMHz.HasValue) { cpuLabel = "GPU Level (Freq)"; cpuText = string.Format("{0} ({1:F0} MHz)", deviceGpuClockLevel, deviceGpuClockFrequencyInMHz); } else if (deviceGpuClockLevel.HasValue) { cpuLabel = "GPU Level"; cpuText = string.Format("{0}", deviceGpuClockLevel); } else { cpuLabel = "GPU Frequency"; cpuText = string.Format("{0:F0} MHz", deviceGpuClockFrequencyInMHz); } PresentText(cpuLabel, cpuText); } PresentColumnTitles("Current", "Average", "Peak"); PresentFloatTimeInMs("Frame Time", "deltaFrameTime", 0.020f, true, true); PresentFloatTimeInMs("App CPU Time", "appCpuTime", 0.020f, true, true); PresentFloatTimeInMs("App GPU Time", "appGpuTime", 0.020f, true, true); PresentFloatTimeInMs("Compositor CPU Time", "compositorCpuTime", 0.020f, true, true); PresentFloatTimeInMs("Compositor GPU Time", "compositorGpuTime", 0.020f, true, true); PresentFloatPercentage("CPU Util (Average)", "systemCpuUtilAveragePercentage", false, false); PresentFloatPercentage("CPU Util (Worst Core)", "systemCpuUtilWorstPercentage", false, false); PresentFloatPercentage("GPU Util", "systemGpuUtilPercentage", false, false); } }
public static bool DeployAPK() { // Create new instance of ADB Tool var adbTool = new OVRADBTool(androidSdkPath); if (adbTool.isReady) { string apkPathLocal; string buildFlavor = isDevelopmentBuild ? "debug" : "release"; string gradleExportFolder = Path.Combine(gradleExport, productName, $"build\\outputs\\apk\\{buildFlavor}"); // Check to see if gradle output directory exists gradleExportFolder = gradleExportFolder.Replace("/", "\\"); if (!Directory.Exists(gradleExportFolder)) { UnityEngine.Debug.LogError("Could not find the gradle project at the expected path: " + gradleExportFolder); return(false); } // Search for output APK in gradle output directory apkPathLocal = Path.Combine(gradleExportFolder, productName + $"-{buildFlavor}.apk"); if (!System.IO.File.Exists(apkPathLocal)) { UnityEngine.Debug.LogError(string.Format("Could not find {0} in the gradle project.", productName + $"-{buildFlavor}.apk")); return(false); } string output, error; DateTime timerStart; // Ensure that the Oculus temp directory is on the device by making it IncrementProgressBar("Making Temp directory on device"); string[] mkdirCommand = { "-d shell", "mkdir -p", REMOTE_APK_PATH }; if (adbTool.RunCommand(mkdirCommand, null, out output, out error) != 0) { return(false); } // Push APK to device, also time how long it takes timerStart = System.DateTime.Now; IncrementProgressBar("Pushing APK to device . . ."); string[] pushCommand = { "-d push", "\"" + apkPathLocal + "\"", REMOTE_APK_PATH }; if (adbTool.RunCommand(pushCommand, null, out output, out error) != 0) { return(false); } // Calculate the transfer speed and determine if user is using USB 2.0 or 3.0 // Only bother informing the user on non-trivial transfers, as for very short // periods of time, things like process creation overhead can dwarf the actual // transfer time. TimeSpan pushTime = System.DateTime.Now - timerStart; bool trivialPush = pushTime.TotalSeconds < TRANSFER_SPEED_CHECK_THRESHOLD; long? apkSize = (trivialPush ? (long?)null : new System.IO.FileInfo(apkPathLocal).Length); double? transferSpeed = (apkSize / pushTime.TotalSeconds) / BYTES_TO_MEGABYTES; bool informLog = transferSpeed.HasValue && transferSpeed.Value < USB_TRANSFER_SPEED_THRES; UnityEngine.Debug.Log("OVRADBTool: Push Success"); // Install the APK package on the device IncrementProgressBar("Installing APK . . ."); string apkPath = REMOTE_APK_PATH + "/" + productName + "-debug.apk"; apkPath = apkPath.Replace(" ", "\\ "); string[] installCommand = { "-d shell", "pm install -r", apkPath }; timerStart = System.DateTime.Now; if (adbTool.RunCommand(installCommand, null, out output, out error) != 0) { return(false); } TimeSpan installTime = System.DateTime.Now - timerStart; UnityEngine.Debug.Log("OVRADBTool: Install Success"); // Start the application on the device IncrementProgressBar("Launching application on device . . ."); #if UNITY_2019_3_OR_NEWER string playerActivityName = "\"" + applicationIdentifier + "/com.unity3d.player.UnityPlayerActivity\""; #else string playerActivityName = "\"" + applicationIdentifier + "/" + applicationIdentifier + ".UnityPlayerActivity\""; #endif string[] appStartCommand = { "-d shell", "am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -S -f 0x10200000 -n", playerActivityName }; if (adbTool.RunCommand(appStartCommand, null, out output, out error) != 0) { return(false); } UnityEngine.Debug.Log("OVRADBTool: Application Start Success"); IncrementProgressBar("Success!"); // If the user is using a USB 2.0 cable, inform them about improved transfer speeds and estimate time saved if (informLog) { float usb3Time = apkSize.Value / (USB_3_TRANSFER_SPEED * BYTES_TO_MEGABYTES); // `informLog` can't be true if `apkSize` is null. UnityEngine.Debug.Log(string.Format("OVRBuild has detected slow transfer speeds. A USB 3.0 cable is recommended to reduce the time it takes to deploy your project by approximatly {0:0.0} seconds", pushTime.TotalSeconds - usb3Time)); return(true); } } else { UnityEngine.Debug.LogError("Could not find the ADB executable in the specified Android SDK directory."); } return(false); }