/// <summary> /// Gets the <see cref="Microsoft.MixedReality.Toolkit.WindowsDevicePortal.AvailableWiFiNetworks"/> of the target device. /// </summary> /// <param name="interfaceInfo">The GUID for the network interface to use to search for wireless networks, without brackets.</param> /// <returns><see cref="Microsoft.MixedReality.Toolkit.WindowsDevicePortal.AvailableWiFiNetworks"/></returns> public static async Task <AvailableWiFiNetworks> GetAvailableWiFiNetworksAsync(DeviceInfo targetDevice, InterfaceInfo interfaceInfo) { var isAuth = await EnsureAuthenticationAsync(targetDevice); if (!isAuth) { return(null); } string query = string.Format(WiFiNetworkQuery, FinalizeUrl(targetDevice.IP), $"s?interface={interfaceInfo.GUID}"); var response = await RestHelpers.Rest.GetAsync(query, targetDevice.Authorization, readResponseData : true, certificateHandler : DevicePortalCertificateHandler, disposeCertificateHandlerOnDispose : false); if (!response.Successful) { if (response.ResponseCode == 403 && await RefreshCsrfTokenAsync(targetDevice)) { return(await GetAvailableWiFiNetworksAsync(targetDevice, interfaceInfo)); } Debug.LogError(response.ResponseBody); return(null); } return(JsonUtility.FromJson <AvailableWiFiNetworks>(response.ResponseBody)); }
/// <summary> /// Opens the Device Portal for the target device. /// </summary> public static void OpenWebPortal(DeviceInfo targetDevice) { System.Diagnostics.Process.Start(FinalizeUrl(targetDevice.IP)); }
/// <summary> /// Installs the target application on the target device. /// </summary> /// <param name="waitForDone">Should the thread wait until installation is complete?</param> /// <returns>True, if Installation was a success.</returns> public static async Task <bool> InstallAppAsync(string appFullPath, DeviceInfo targetDevice, bool waitForDone = true) { Debug.Assert(!string.IsNullOrEmpty(appFullPath)); var isAuth = await EnsureAuthenticationAsync(targetDevice); if (!isAuth) { return(false); } Debug.Log($"Starting app install on {targetDevice.ToString()}..."); // Calculate the cert and dependency paths string fileName = Path.GetFileName(appFullPath); string certFullPath = Path.ChangeExtension(appFullPath, ".cer"); string certName = Path.GetFileName(certFullPath); string arch = "ARM"; if (appFullPath.Contains("x86")) { arch = "x86"; } else if (appFullPath.Contains("ARM64")) { arch = "ARM64"; } string depPath = $@"{Path.GetDirectoryName(appFullPath)}\Dependencies\{arch}\"; var form = new WWWForm(); try { // 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 IOFileInfo[] depFiles = new DirectoryInfo(depPath).GetFiles(); foreach (IOFileInfo 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); } } } } catch (Exception e) { Debug.LogException(e); return(false); } // Query string query = $"{string.Format(InstallQuery, FinalizeUrl(targetDevice.IP))}?package={UnityWebRequest.EscapeURL(fileName)}"; var response = await RestHelpers.Rest.PostAsync(query, form, targetDevice.Authorization, certificateHandler : DevicePortalCertificateHandler, disposeCertificateHandlerOnDispose : false); if (!response.Successful) { if (response.ResponseCode == 403 && await RefreshCsrfTokenAsync(targetDevice)) { return(await InstallAppAsync(appFullPath, targetDevice, waitForDone)); } Debug.LogError($"Failed to install {fileName} on {targetDevice.ToString()}."); return(false); } var status = AppInstallStatus.Installing; // Wait for done (if requested) while (waitForDone && status == AppInstallStatus.Installing) { status = await GetInstallStatusAsync(targetDevice); switch (status) { case AppInstallStatus.InstallSuccess: Debug.Log($"Successfully installed {fileName} on {targetDevice.ToString()}."); return(true); case AppInstallStatus.InstallFail: Debug.LogError($"Failed to install {fileName} on {targetDevice.ToString()}."); return(false); } } return(true); }
/// <summary> /// Gets the <see cref="Microsoft.MixedReality.Toolkit.WindowsDevicePortal.ApplicationInfo"/> of the target application on the target device. /// </summary> /// <returns>Returns the <see cref="Microsoft.MixedReality.Toolkit.WindowsDevicePortal.ApplicationInfo"/> of the target application from the target device.</returns> private static async Task <ApplicationInfo> GetApplicationInfoAsync(string packageName, DeviceInfo targetDevice) { Debug.Assert(!string.IsNullOrEmpty(packageName)); var appList = await GetAllInstalledAppsAsync(targetDevice); for (int i = 0; i < appList?.InstalledPackages.Length; ++i) { if (appList.InstalledPackages[i].PackageFullName.Equals(packageName, StringComparison.OrdinalIgnoreCase)) { return(appList.InstalledPackages[i]); } if (appList.InstalledPackages[i].PackageFamilyName.Equals(packageName, StringComparison.OrdinalIgnoreCase)) { return(appList.InstalledPackages[i]); } } return(null); }
/// <summary> /// Determines if the target application is currently running on the target device. /// </summary> /// <returns>True, if application is currently installed on device.</returns> public static async Task <bool> IsAppInstalledAsync(string packageName, DeviceInfo targetDevice) { Debug.Assert(!string.IsNullOrEmpty(packageName)); return(await GetApplicationInfoAsync(packageName, targetDevice) != null); }
/// <summary> /// Makes sure the Authentication Headers and CSRF Tokens are set. /// </summary> /// <param name="targetDevice"></param> /// <returns>True if Authentication is successful, otherwise false.</returns> public static async Task <bool> EnsureAuthenticationAsync(DeviceInfo targetDevice) { string auth = Rest.GetBasicAuthentication(targetDevice.User, targetDevice.Password); if (targetDevice.Authorization.ContainsKey("Authorization")) { targetDevice.Authorization["Authorization"] = auth; } else { targetDevice.Authorization.Add("Authorization", auth); } bool success; if (!targetDevice.Authorization.ContainsKey("cookie")) { var response = await DevicePortalAuthorizationAsync(targetDevice); success = response.Successful; if (success) { targetDevice.CsrfToken = response.ResponseBody; // Strip the beginning of the cookie header targetDevice.CsrfToken = targetDevice.CsrfToken.Replace("CSRF-Token=", string.Empty); } else { Debug.LogError($"Authentication failed! {response.ResponseBody}"); } if (!string.IsNullOrEmpty(targetDevice.CsrfToken)) { if (!targetDevice.Authorization.ContainsKey("cookie")) { targetDevice.Authorization.Add("cookie", targetDevice.CsrfToken); } else { targetDevice.Authorization["cookie"] = targetDevice.CsrfToken; } if (targetDevice.Authorization.ContainsKey("x-csrf-token")) { targetDevice.Authorization["x-csrf-token"] = targetDevice.CsrfToken; } else { targetDevice.Authorization.Add("x-csrf-token", targetDevice.CsrfToken); } } } else { success = true; } return(success); }
/// <summary> /// Initialize /// </summary> public DevicePortalConnections(DeviceInfo deviceInfo) { Connections.Add(deviceInfo); }