Skip to content

Commit

Permalink
实现fastboot getvar all的包装
Browse files Browse the repository at this point in the history
  • Loading branch information
zsh2401 committed Aug 20, 2020
1 parent 9ffcc6b commit cdd4e0e
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 6 deletions.
76 changes: 76 additions & 0 deletions src/AutumnBox.Basic.Shared/Calling/CommandExecutorExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
using AutumnBox.Basic.Device;
using AutumnBox.Basic.Exceptions;
using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Schema;

namespace AutumnBox.Basic.Calling
{
Expand Down Expand Up @@ -94,6 +97,26 @@ public static async Task<CommandResult> FastbootAsync(this ICommandExecutor exec
});
}

/// <summary>
/// 异步执行FastbootWithRetry
/// </summary>
/// <param name="executor"></param>
/// <param name="args"></param>
/// <param name="device"></param>
/// <param name="retryTimes"></param>
/// <param name="maxTimeout"></param>
/// <exception cref="TimeoutException">超过重试次数</exception>
/// <exception cref="ArgumentException">参数不合理</exception>
/// <returns></returns>
public static Task<CommandResult> FastbootWithRetryAsync(this ICommandExecutor executor, string args
, IDevice device, int retryTimes = 10, int maxTimeout = 300)
{
return Task.Run(() =>
{
return FastbootWithRetry(executor, args, device, retryTimes, maxTimeout);
});
}

/// <summary>
/// 异步执行ADB命令
/// </summary>
Expand Down Expand Up @@ -211,6 +234,59 @@ public static CommandResult Fastboot(this ICommandExecutor executor, params stri
return executor.Execute("fastboot.exe", compCommand);
}

/// <summary>
/// 带有超时重试功能的fastboot指令执行器
/// </summary>
/// <param name="executor"></param>
/// <param name="args"></param>
/// <param name="retryTimes"></param>
/// <param name="maxTimeout"></param>
/// <exception cref="TimeoutException">超过重试次数</exception>
/// <exception cref="ArgumentException">参数不合理</exception>
/// <returns></returns>
public static CommandResult FastbootWithRetry(this ICommandExecutor executor, string args,
IDevice? device = null, int retryTimes = 10, int maxTimeout = 300)
{
if (retryTimes * maxTimeout <= 0)
{
throw new ArgumentException("retryTimes and maxTimeout should not be smaller than 0");
}
const int INTERVAL_BETWEEN_PER_RETRY = 20;
/*
* 由于某些原因,部分设备上的fastboot指令会有玄学问题
*因此此处实现了一个重试机制,尽可能获取到正确的值
*/
CommandResult? result = null;
for (int crtTime = 1; crtTime <= retryTimes; crtTime++)
{
CommandResult routine()
{
return device == null ? executor.Fastboot(args) : executor.Fastboot(device, args);
}
Task.Run(() =>
{
result = routine();
});

Thread.Sleep((int)maxTimeout);

if (result != null && !result.Output.Contains("GetVar Variable Not found"))
{
break;
}
else
{
executor.CancelCurrent();
Thread.Sleep(INTERVAL_BETWEEN_PER_RETRY);
}
}
if (result == null)
{
throw new TimeoutException();
}
return result;
}

/// <summary>
/// 执行非针对设备的adb命令
/// </summary>
Expand Down
55 changes: 49 additions & 6 deletions src/AutumnBox.Basic.Shared/Device/DeviceExtension.Management.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
using AutumnBox.Basic.Exceptions;
using AutumnBox.Basic.Util;
using AutumnBox.Logging;
using AutumnBox.OpenFramework.Exceptions;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading;
Expand Down Expand Up @@ -59,14 +62,15 @@ partial class DeviceExtension
/// <param name="device"></param>
/// <param name="key"></param>
/// <exception cref="CommandErrorException">命令执行失败</exception>
/// <exception cref="InvalidOperationException">设备状态有误</exception>
/// <exception cref="DeviceStateIsNotCorrectException">设备状态有误</exception>
/// <exception cref="KeyNotFoundException">未找到对应键的值</exception>
/// <returns></returns>
public static string GetVar(this IDevice device, string key)
{
if (device.State != DeviceState.Fastboot)
{
throw new InvalidOperationException("Device's state not correct: should be bootloader mode");
throw new DeviceStateIsNotCorrectException(
DeviceState.Fastboot, device.State);
}
string command = $"getvar {key}";
using var hestExecutor = new HestExecutor(BasicBooter.CommandProcedureManager);
Expand Down Expand Up @@ -99,7 +103,7 @@ public static string GetVar(this IDevice device, string key)
}
}

//达到尝试上线或已经获取到正确结果
//达到尝试上限或已经获取到正确结果

if (result == null)
{
Expand All @@ -115,10 +119,10 @@ public static string GetVar(this IDevice device, string key)
}
else
{
var match = Regex.Match(result.Output, key + @":\s(?<value>[\w|\d]+)");
if (match.Success)
var matches = Regex.Matches(result.Output, key + @":\s(?<value>[\w|\d]+)");
if (matches.FirstOrDefault().Success)
{
return match.Result("${value}");
return matches.FirstOrDefault().Result("${value}");
}
else
{
Expand All @@ -127,6 +131,45 @@ public static string GetVar(this IDevice device, string key)
}
}


private static readonly Regex regexAllVar = new Regex(@"(?<key>[\w|\d|-|_]+):(?<value>.+)$"
, RegexOptions.Multiline | RegexOptions.Compiled);

/// <summary>
/// 在fastboot模式下获取所有变量
/// </summary>
/// <param name="device"></param>
/// <exception cref="TimeoutException">内部获取命令超时</exception>
/// <exception cref="CommandErrorException">命令执行,但最终结果是失败的</exception>
/// <exception cref="DeviceStateIsNotCorrectException">设备状态不正确</exception>
/// <returns></returns>
public static IReadOnlyDictionary<string, string> GetAllVar(this IDevice device)
{
if (device.State != DeviceState.Fastboot)
{
throw new DeviceStateIsNotCorrectException(
DeviceState.Fastboot, device.State);
}

using var hestExecutor = new HestExecutor(BasicBooter.CommandProcedureManager);
var result = hestExecutor.FastbootWithRetry("getvar all", device).ThrowIfExitCodeIsNotZero();

//return (from match in regexAllVar.Matches(result.Output.ToString())
// where match.Success
// select match)
// .ToDictionary(m => m.Result("${key}"), m => m.Result("${value}"));

var matches = (from match in regexAllVar.Matches(result.Output.ToString())
where match.Success
select match);
var dictionary = new Dictionary<string, string>();
foreach (var match in matches)
{
dictionary[match.Result("${key}")] = match.Result("${value}");
}
return dictionary;
}

/// <summary>
/// 获取AB槽位信息
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ENetDeviceConnecter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ENetDeviceDisconnecter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\EPSLauncher.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ETest.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Resources\Icons\cmd.png" />
Expand Down
47 changes: 47 additions & 0 deletions src/AutumnBox.Extensions.Essentials.Shared/Extensions/ETest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* ==============================================================================
*
* Filename: ETest
* Description: 
*
* Version: 1.0
* Created: 2020/8/20 18:02:55
* Compiler: Visual Studio 2019
*
* Author: zsh2401
*
* ==============================================================================
*/
using AutumnBox.Basic.Device;
using AutumnBox.OpenFramework.Extension;
using AutumnBox.OpenFramework.Extension.Leaf;
using AutumnBox.OpenFramework.Open;
using AutumnBox.OpenFramework.Open.LKit;

namespace AutumnBox.Extensions.Essentials.Extensions
{

#if !DEBUG
[ExtHidden()]
#endif
[ExtName("测试模块")]
[ExtRequiredDeviceStates(DeviceState.Fastboot)]
class ETest : LeafExtensionBase
{
[LMain]
public void Main(IDevice device, IUx ux, ILeafUI ui)
{
using (ui)
{
ui.Show();
foreach (var kv in device.GetAllVar())
{
ui.Println($"{kv.Key}:{kv.Value}");
}
ui.Finish();
}

}
}
}

0 comments on commit cdd4e0e

Please sign in to comment.