diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
index 72b1f16..df75ce3 100644
--- a/.github/workflows/build-and-test.yml
+++ b/.github/workflows/build-and-test.yml
@@ -30,7 +30,7 @@ jobs:
fetch-depth: 0
- name: Setup .NET Core App
- uses: actions/setup-dotnet@v4
+ uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
@@ -46,7 +46,7 @@ jobs:
pack-and-publish:
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
needs: build-and-test
- runs-on: windows-latest
+ runs-on: windows-2025-vs2026
env:
Solution_Name: AdvancedSharpAdbClient/AdvancedSharpAdbClient.csproj
@@ -57,7 +57,7 @@ jobs:
fetch-depth: 0
- name: Setup .NET Core App
- uses: actions/setup-dotnet@v4
+ uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
@@ -67,10 +67,10 @@ jobs:
msbuild-architecture: x64
- name: Install Dependencies
- run: msbuild $env:Solution_Name /t:Restore /p:FullTargets=true
+ run: msbuild $env:Solution_Name /m /t:Restore /p:FullTargets=true
- name: Pack
- run: msbuild $env:Solution_Name /t:Pack /p:FullTargets=true /p:Configuration=Release /p:PackageOutputPath=../nugets /p:VersionSuffix=build.${{ github.run_number }}.${{ github.run_attempt }}
+ run: msbuild $env:Solution_Name /m /t:Pack /p:FullTargets=true /p:Configuration=Release /p:PackageOutputPath=../nugets /p:VersionSuffix=build.${{ github.run_number }}.${{ github.run_attempt }}
- name: Publish
if: ${{ github.event_name == 'push' && github.ref_name == 'main' }}
@@ -80,7 +80,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v6
with:
- name: Nuget Package
+ name: NuGet Package
path: nugets/**
diff --git a/.gitignore b/.gitignore
index 95ad761..533ca9e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@
*.user
*.userosscache
*.sln.docstates
+*.env
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
@@ -21,16 +22,36 @@ mono_crash.*
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
-x64/
-x86/
+
+[Dd]ebug/x64/
+[Dd]ebugPublic/x64/
+[Rr]elease/x64/
+[Rr]eleases/x64/
+bin/x64/
+obj/x64/
+
+[Dd]ebug/x86/
+[Dd]ebugPublic/x86/
+[Rr]elease/x86/
+[Rr]eleases/x86/
+bin/x86/
+obj/x86/
+
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
+[Aa][Rr][Mm]64[Ee][Cc]/
bld/
-[Bb]in/
[Oo]bj/
+[Oo]ut/
[Ll]og/
-#[Ll]ogs/
+[Ll]ogs/
+
+# Build results on 'Bin' directories
+**/[Bb]in/*
+# Uncomment if you have tasks that rely on *.refresh files to move binaries
+# (https://github.com/github/gitignore/pull/3736)
+#!**/[Bb]in/*.refresh
# Visual Studio 2015/2017 cache/options directory
.vs/
@@ -43,12 +64,16 @@ Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
+*.trx
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
+# Approval Tests result files
+*.received.*
+
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
@@ -75,6 +100,7 @@ StyleCopReport.xml
*.ilk
*.meta
*.obj
+*.idb
*.iobj
*.pch
*.pdb
@@ -155,6 +181,7 @@ coverage*.info
# NCrunch
_NCrunch_*
+.NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
@@ -296,9 +323,6 @@ node_modules/
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
-# Visual Studio 6 auto-generated project file (contains which files were open etc.)
-*.vbp
-
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
@@ -316,22 +340,22 @@ node_modules/
_Pvt_Extensions
# Paket dependency manager
-.paket/paket.exe
+**/.paket/paket.exe
paket-files/
# FAKE - F# Make
-.fake/
+**/.fake/
# CodeRush personal settings
-.cr/personal
+**/.cr/personal
# Python Tools for Visual Studio (PTVS)
-__pycache__/
+**/__pycache__/
*.pyc
# Cake - Uncomment if you are using it
-# tools/**
-# !tools/packages.config
+#tools/**
+#!tools/packages.config
# Tabs Studio
*.tss
@@ -353,15 +377,19 @@ ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
+MSBuild_Logs/
+
+# AWS SAM Build and Temporary Artifacts folder
+.aws-sam
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
-.mfractor/
+**/.mfractor/
# Local History for Visual Studio
-.localhistory/
+**/.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
@@ -373,7 +401,7 @@ healthchecksdb
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
-.ionide/
+**/.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
@@ -384,11 +412,14 @@ FodyWeavers.xsd
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
-*.code-workspace
+!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
+# Built Visual Studio Code Extensions
+*.vsix
+
# Windows Installer files from build outputs
*.cab
*.msi
@@ -396,5 +427,5 @@ FodyWeavers.xsd
*.msm
*.msp
-# JetBrains Rider
-*.sln.iml
\ No newline at end of file
+# VS Code C# Dev Kit
+*.lscache
diff --git a/AdvancedSharpAdbClient.Tests/AdvancedSharpAdbClient.Tests.csproj b/AdvancedSharpAdbClient.Tests/AdvancedSharpAdbClient.Tests.csproj
index 869f801..e22ea8f 100644
--- a/AdvancedSharpAdbClient.Tests/AdvancedSharpAdbClient.Tests.csproj
+++ b/AdvancedSharpAdbClient.Tests/AdvancedSharpAdbClient.Tests.csproj
@@ -9,7 +9,7 @@
- net10.0-windows10.0.17763.0
+ net10.0-windows10.0.26100.0
@@ -20,15 +20,15 @@
-
+ runtime; build; native; contentfiles; analyzers; buildtransitive
-
+ runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/AdvancedSharpAdbClient.Tests/Models/FramebufferHeaderTests.cs b/AdvancedSharpAdbClient.Tests/Models/FramebufferHeaderTests.cs
index d184a74..5d23e23 100644
--- a/AdvancedSharpAdbClient.Tests/Models/FramebufferHeaderTests.cs
+++ b/AdvancedSharpAdbClient.Tests/Models/FramebufferHeaderTests.cs
@@ -42,7 +42,7 @@ public void ReadFramebufferTest()
}
///
- /// Tests the method.
+ /// Tests the method.
///
[Fact]
public void ReadFramebufferBySpanTest()
@@ -104,7 +104,7 @@ public void ReadFramebufferV2Test()
}
///
- /// Tests the method.
+ /// Tests the method.
///
[Fact]
public void ReadFramebufferV2BySpanTest()
diff --git a/AdvancedSharpAdbClient/AdbClient.Async.cs b/AdvancedSharpAdbClient/AdbClient.Async.cs
index df0911b..caf23e3 100644
--- a/AdvancedSharpAdbClient/AdbClient.Async.cs
+++ b/AdvancedSharpAdbClient/AdbClient.Async.cs
@@ -169,7 +169,7 @@ public async Task ExecuteServerCommandAsync(string target, string command, Cance
///
public virtual async Task ExecuteServerCommandAsync(string target, string command, IAdbSocket socket, CancellationToken cancellationToken = default)
{
- DefaultInterpolatedStringHandler request = new(1, 2);
+ scoped DefaultInterpolatedStringHandler request = new(1, 2);
if (!string.IsNullOrWhiteSpace(target))
{
request.AppendLiteral(target);
@@ -228,7 +228,7 @@ public virtual async Task ExecuteServerCommandAsync(string target, string comman
{
ArgumentNullException.ThrowIfNull(encoding);
- DefaultInterpolatedStringHandler request = new(1, 2);
+ scoped DefaultInterpolatedStringHandler request = new(1, 2);
if (!string.IsNullOrWhiteSpace(target))
{
request.AppendLiteral(target);
@@ -298,7 +298,7 @@ public virtual async IAsyncEnumerable ExecuteServerEnumerableAsync(strin
{
ArgumentNullException.ThrowIfNull(encoding);
- DefaultInterpolatedStringHandler request = new(1, 2);
+ scoped DefaultInterpolatedStringHandler request = new(1, 2);
if (!string.IsNullOrWhiteSpace(target))
{
request.AppendLiteral(target);
@@ -361,7 +361,7 @@ public async IAsyncEnumerable RunLogServiceAsync(DeviceData device, [E
using IAdbSocket socket = CreateAdbSocket();
await socket.SetDeviceAsync(device, cancellationToken).ConfigureAwait(false);
- DefaultInterpolatedStringHandler request = new(19, logNames.Length);
+ scoped DefaultInterpolatedStringHandler request = new(19, logNames.Length);
request.AppendLiteral("shell:logcat -B");
foreach (LogId logName in logNames)
@@ -415,7 +415,7 @@ public async Task RunLogServiceAsync(DeviceData device, Action message
using IAdbSocket socket = CreateAdbSocket();
await socket.SetDeviceAsync(device, cancellationToken).ConfigureAwait(false);
- DefaultInterpolatedStringHandler request = new(19, logNames.Length);
+ scoped DefaultInterpolatedStringHandler request = new(19, logNames.Length);
request.AppendLiteral("shell:logcat -B");
foreach (LogId logName in logNames)
@@ -584,7 +584,7 @@ public virtual async Task InstallAsync(DeviceData device, Stream apk, Action InstallCreateAsync(DeviceData device, CancellationToke
using IAdbSocket socket = CreateAdbSocket();
await socket.SetDeviceAsync(device, cancellationToken).ConfigureAwait(false);
- DefaultInterpolatedStringHandler requestBuilder = new(33, arguments?.Length ?? 0);
+ scoped DefaultInterpolatedStringHandler requestBuilder = new(33, arguments?.Length ?? 0);
requestBuilder.AppendLiteral("exec:cmd package 'install-create'");
if (arguments != null)
@@ -784,7 +784,7 @@ public async Task InstallCreateAsync(DeviceData device, string packageNa
using IAdbSocket socket = CreateAdbSocket();
await socket.SetDeviceAsync(device, cancellationToken).ConfigureAwait(false);
- DefaultInterpolatedStringHandler requestBuilder = new(37 + packageName.Length, arguments?.Length ?? 0);
+ scoped DefaultInterpolatedStringHandler requestBuilder = new(37 + packageName.Length, arguments?.Length ?? 0);
requestBuilder.AppendLiteral("exec:cmd package 'install-create'");
requestBuilder.AppendFormatted(" -p ");
requestBuilder.AppendLiteral(packageName);
@@ -972,7 +972,7 @@ public virtual async Task InstallAsync(DeviceData device, IRandomAccessStream ap
using IAdbSocket socket = CreateAdbSocket();
await socket.SetDeviceAsync(device, cancellationToken).ConfigureAwait(false);
- DefaultInterpolatedStringHandler requestBuilder = new(30, (arguments?.Length ?? 0) + 1);
+ scoped DefaultInterpolatedStringHandler requestBuilder = new(30, (arguments?.Length ?? 0) + 1);
requestBuilder.AppendLiteral("exec:cmd package 'install'");
if (arguments != null)
@@ -1251,7 +1251,7 @@ public async Task UninstallAsync(DeviceData device, string packageName, Cancella
using IAdbSocket socket = CreateAdbSocket();
await socket.SetDeviceAsync(device, cancellationToken).ConfigureAwait(false);
- DefaultInterpolatedStringHandler requestBuilder = new(29, (arguments?.Length ?? 0) + 1);
+ scoped DefaultInterpolatedStringHandler requestBuilder = new(29, (arguments?.Length ?? 0) + 1);
requestBuilder.AppendLiteral("exec:cmd package 'uninstall'");
if (arguments != null)
diff --git a/AdvancedSharpAdbClient/AdbClient.cs b/AdvancedSharpAdbClient/AdbClient.cs
index 44dbcc7..e236ade 100644
--- a/AdvancedSharpAdbClient/AdbClient.cs
+++ b/AdvancedSharpAdbClient/AdbClient.cs
@@ -185,12 +185,12 @@ public static byte[] CreateAdbForwardRequest(string address, int port)
///
/// The request to form.
/// An array containing ####req.
- public static byte[] FormAdbRequest(ReadOnlySpan req)
+ public static byte[] FormAdbRequest(scoped ReadOnlySpan req)
{
int payloadLength = Encoding.GetByteCount(req);
#if NET10_0_OR_GREATER
- DefaultInterpolatedStringHandler resultStr = $"{payloadLength:X4}{req}";
- ReadOnlySpan text = resultStr.Text;
+ scoped DefaultInterpolatedStringHandler resultStr = $"{payloadLength:X4}{req}";
+ scoped ReadOnlySpan text = resultStr.Text;
int byteCount = Encoding.GetByteCount(text);
byte[] result = new byte[byteCount];
_ = Encoding.GetBytes(text, result);
@@ -207,13 +207,13 @@ public static byte[] FormAdbRequest(ReadOnlySpan req)
/// The address.
/// The port.
/// This returns an array containing "####tcp:{port}:{addStr}".
- public static byte[] CreateAdbForwardRequest(ReadOnlySpan address, int port)
+ public static byte[] CreateAdbForwardRequest(scoped ReadOnlySpan address, int port)
{
#if NET10_0_OR_GREATER
- DefaultInterpolatedStringHandler request = address.IsEmpty ? (DefaultInterpolatedStringHandler)$"tcp:{port}" : $"tcp:{port}:{address}";
+ scoped DefaultInterpolatedStringHandler request = address.IsEmpty ? (DefaultInterpolatedStringHandler)$"tcp:{port}" : $"tcp:{port}:{address}";
return FormAdbRequest(request.Text);
#else
- string request = address == null ? $"tcp:{port}" : $"tcp:{port}:{address}";
+ string request = address.Length > 0 ? $"tcp:{port}:{address}" : $"tcp:{port}";
return FormAdbRequest(request);
#endif
}
@@ -372,7 +372,7 @@ public void ExecuteServerCommand(string target, string command)
///
public virtual void ExecuteServerCommand(string target, string command, IAdbSocket socket)
{
- DefaultInterpolatedStringHandler request = new(1, 2);
+ scoped DefaultInterpolatedStringHandler request = new(1, 2);
if (!string.IsNullOrWhiteSpace(target))
{
request.AppendLiteral(target);
@@ -422,7 +422,7 @@ public virtual void ExecuteServerCommand(string target, string command, IAdbSock
{
ArgumentNullException.ThrowIfNull(encoding);
- DefaultInterpolatedStringHandler request = new(1, 2);
+ scoped DefaultInterpolatedStringHandler request = new(1, 2);
if (!string.IsNullOrWhiteSpace(target))
{
request.AppendLiteral(target);
@@ -484,7 +484,7 @@ public virtual IEnumerable ExecuteServerEnumerable(string target, string
{
ArgumentNullException.ThrowIfNull(encoding);
- DefaultInterpolatedStringHandler request = new(1, 2);
+ scoped DefaultInterpolatedStringHandler request = new(1, 2);
if (!string.IsNullOrWhiteSpace(target))
{
request.AppendLiteral(target);
@@ -540,7 +540,7 @@ public IEnumerable RunLogService(DeviceData device, params LogId[] log
using IAdbSocket socket = CreateAdbSocket();
socket.SetDevice(device);
- DefaultInterpolatedStringHandler request = new(19, logNames.Length);
+ scoped DefaultInterpolatedStringHandler request = new(19, logNames.Length);
request.AppendLiteral("shell:logcat -B");
foreach (LogId logName in logNames)
@@ -579,7 +579,7 @@ public IEnumerable RunLogService(DeviceData device, params LogId[] log
}
///
- public void RunLogService(DeviceData device, Action messageSink, in bool isCancelled = false, params LogId[] logNames)
+ public void RunLogService(DeviceData device, Action messageSink, scoped in bool isCancelled = false, params LogId[] logNames)
{
EnsureDevice(device);
ArgumentNullException.ThrowIfNull(messageSink);
@@ -589,7 +589,7 @@ public void RunLogService(DeviceData device, Action messageSink, in bo
using IAdbSocket socket = CreateAdbSocket();
socket.SetDevice(device);
- DefaultInterpolatedStringHandler request = new(19, logNames.Length);
+ scoped DefaultInterpolatedStringHandler request = new(19, logNames.Length);
request.AppendLiteral("shell:logcat -B");
foreach (LogId logName in logNames)
@@ -762,7 +762,7 @@ public virtual void Install(DeviceData device, Stream apk, Action GetFeatureSet(DeviceData device)
/// A object to validate.
/// The name of the parameter with which corresponds.
/// The does not have a valid serial number.
- protected static void EnsureDevice(in DeviceData device, [CallerArgumentExpression(nameof(device))] string? paramName = "device")
+ protected static void EnsureDevice(scoped in DeviceData device, [CallerArgumentExpression(nameof(device))] string? paramName = "device")
{
if (device.IsEmpty)
{
diff --git a/AdvancedSharpAdbClient/AdbServer.cs b/AdvancedSharpAdbClient/AdbServer.cs
index 9a78263..e502ce8 100644
--- a/AdvancedSharpAdbClient/AdbServer.cs
+++ b/AdvancedSharpAdbClient/AdbServer.cs
@@ -149,7 +149,11 @@ public AdbServer(Func adbSocketFactory, Func
/// Gets or sets the default instance of the interface.
///
- public static IAdbServer Instance { get; set; } = new AdbServer();
+ public static IAdbServer Instance
+ {
+ get => field ??= new AdbServer();
+ set;
+ }
///
/// if is starting adb server; otherwise, .
diff --git a/AdvancedSharpAdbClient/AdbSocket.cs b/AdvancedSharpAdbClient/AdbSocket.cs
index 3262cce..91bfbea 100644
--- a/AdvancedSharpAdbClient/AdbSocket.cs
+++ b/AdvancedSharpAdbClient/AdbSocket.cs
@@ -91,7 +91,7 @@ public AdbSocket(string host, int port, ILogger? logger = null)
///
/// The reply.
/// if the specified reply is okay; otherwise, .
- public static bool IsOkay(ReadOnlySpan reply) => AdbClient.Encoding.GetString(reply).Equals("OKAY");
+ public static bool IsOkay(scoped ReadOnlySpan reply) => AdbClient.Encoding.GetString(reply).Equals("OKAY");
#endif
///
@@ -219,7 +219,7 @@ public void SendAdbRequest(string request)
#if NET10_0_OR_GREATER
///
- public void SendAdbRequest(DefaultInterpolatedStringHandler request)
+ public void SendAdbRequest(scoped DefaultInterpolatedStringHandler request)
{
byte[] data = AdbClient.FormAdbRequest(request.Text);
if (!Write(data))
@@ -358,7 +358,7 @@ public AdbResponse ReadAdbResponse()
#if COMP_NETSTANDARD2_1
///
- public virtual void Send(ReadOnlySpan data)
+ public virtual void Send(scoped ReadOnlySpan data)
{
try
{
@@ -376,7 +376,7 @@ public virtual void Send(ReadOnlySpan data)
}
///
- public virtual int Read(Span data)
+ public virtual int Read(scoped Span data)
{
int count = -1;
int totalRead = 0;
@@ -484,7 +484,7 @@ protected virtual bool Write(byte[] data)
/// The data to send.
/// Returns if all data was written; otherwise, .
/// This uses the default time out value.
- protected virtual bool Write(ReadOnlySpan data)
+ protected virtual bool Write(scoped ReadOnlySpan data)
{
try
{
@@ -547,7 +547,7 @@ protected string ReplyToString(byte[] reply)
///
/// A array that represents the ADB reply.
/// A that represents the ADB reply.
- protected string ReplyToString(ReadOnlySpan reply)
+ protected string ReplyToString(scoped ReadOnlySpan reply)
{
string result;
try
diff --git a/AdvancedSharpAdbClient/AdvancedSharpAdbClient.csproj b/AdvancedSharpAdbClient/AdvancedSharpAdbClient.csproj
index dee57de..96b8bc8 100644
--- a/AdvancedSharpAdbClient/AdvancedSharpAdbClient.csproj
+++ b/AdvancedSharpAdbClient/AdvancedSharpAdbClient.csproj
@@ -19,7 +19,7 @@
$(NoWarn);NU1603;NU1605
- $(TargetFrameworks);net6.0;netcoreapp2.1;netcoreapp3.1
+ $(TargetFrameworks);net6.0;net6.0-windows10.0.17763.0;netcoreapp2.1;netcoreapp3.1$(TargetFrameworks);net4.0-client;net4.6.1$(TargetFrameworks);netcore5.0;uap10.0;uap10.0.15138.0
@@ -34,6 +34,7 @@
System.Diagnostics.CodeAnalysis.NotNullAttribute;
System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute;
System.Diagnostics.CodeAnalysis.NotNullWhenAttribute;
+ System.Diagnostics.CodeAnalysis.StringSyntaxAttribute;
System.Diagnostics.StackTraceHiddenAttribute;
System.Index;
System.Range;
@@ -64,11 +65,11 @@
-
+
-
+
+ True
diff --git a/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.Async.cs b/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.Async.cs
index babc4cd..1f9a461 100644
--- a/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.Async.cs
+++ b/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.Async.cs
@@ -25,6 +25,7 @@ public static partial class DeviceExtensions
/// The command to execute.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ExecuteShellCommandAsync(this IAdbClient client, DeviceData device, string command, CancellationToken cancellationToken = default) =>
client.ExecuteRemoteCommandAsync(command, device, cancellationToken);
@@ -37,6 +38,7 @@ public static Task ExecuteShellCommandAsync(this IAdbClient client, DeviceData d
/// Optionally, a that processes the command output.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ExecuteShellCommandAsync(this IAdbClient client, DeviceData device, string command, IShellOutputReceiver? receiver, CancellationToken cancellationToken = default) =>
client.ExecuteRemoteCommandAsync(command, device, receiver, AdbClient.Encoding, cancellationToken);
@@ -49,6 +51,7 @@ public static Task ExecuteShellCommandAsync(this IAdbClient client, DeviceData d
/// Optionally, a that processes the command output.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ExecuteShellCommandAsync(this IAdbClient client, DeviceData device, string command, Func? predicate, CancellationToken cancellationToken = default) =>
client.ExecuteRemoteCommandAsync(command, device, predicate.AsShellOutputReceiver(), AdbClient.Encoding, cancellationToken);
@@ -59,6 +62,7 @@ public static Task ExecuteShellCommandAsync(this IAdbClient client, DeviceData d
/// The device on which to run the command.
/// A which can be used to cancel the asynchronous operation.
/// A which returns a containing current hierarchy.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task DumpScreenAsync(this IAdbClient client, DeviceData device, CancellationToken cancellationToken = default) =>
new DeviceClient(client, device).DumpScreenAsync(cancellationToken);
@@ -70,6 +74,7 @@ public static Task ExecuteShellCommandAsync(this IAdbClient client, DeviceData d
/// The to click.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ClickAsync(this IAdbClient client, DeviceData device, Point point, CancellationToken cancellationToken = default) =>
new DeviceClient(client, device).ClickAsync(point, cancellationToken);
@@ -83,6 +88,7 @@ public static Task ClickAsync(this IAdbClient client, DeviceData device, Point p
/// The time spent in swiping.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task SwipeAsync(this IAdbClient client, DeviceData device, Point first, Point second, long speed, CancellationToken cancellationToken = default) =>
new DeviceClient(client, device).SwipeAsync(first, second, speed, cancellationToken);
@@ -94,6 +100,7 @@ public static Task SwipeAsync(this IAdbClient client, DeviceData device, Point f
/// The package name of the app to check.
/// A which can be used to cancel the asynchronous operation.
/// A which returns the of the app. Foreground, stopped or running in background.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task GetAppStatusAsync(this IAdbClient client, DeviceData device, string packageName, CancellationToken cancellationToken = default) =>
new DeviceClient(client, device).GetAppStatusAsync(packageName, cancellationToken);
@@ -107,6 +114,7 @@ public static Task GetAppStatusAsync(this IAdbClient client, DeviceDa
/// A which can be used to cancel the asynchronous operation.
/// Only check once if . Or it will continue check until is .
/// A which returns the of .
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task FindElementAsync(this IAdbClient client, DeviceData device, string xpath = "hierarchy/node", CancellationToken cancellationToken = default) =>
new DeviceClient(client, device).FindElementAsync(xpath, cancellationToken);
@@ -119,6 +127,7 @@ public static Task GetAppStatusAsync(this IAdbClient client, DeviceDa
/// A which can be used to cancel the asynchronous operation.
/// Only check once if . Or it will continue check until is .
/// A which returns the of has got.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task> FindElementsAsync(this IAdbClient client, DeviceData device, string xpath = "hierarchy/node", CancellationToken cancellationToken = default) =>
new DeviceClient(client, device).FindElementsAsync(xpath, cancellationToken);
@@ -132,6 +141,7 @@ public static Task> FindElementsAsync(this IAdbClient clien
/// A which can be used to cancel the asynchronous operation.
/// Only check once if . Or it will continue check until is .
/// The of has got.
+ [MethodImpl((MethodImplOptions)0x100)]
public static IAsyncEnumerable FindAsyncElements(this IAdbClient client, DeviceData device, string xpath = "hierarchy/node", CancellationToken cancellationToken = default) =>
new DeviceClient(client, device).FindAsyncElements(xpath, cancellationToken);
#endif
@@ -145,6 +155,7 @@ public static IAsyncEnumerable FindAsyncElements(this IAdbClient client
/// The key event to send.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task SendKeyEventAsync(this IAdbClient client, DeviceData device, string key, CancellationToken cancellationToken = default) =>
new DeviceClient(client, device).SendKeyEventAsync(key, cancellationToken);
@@ -156,6 +167,7 @@ public static Task SendKeyEventAsync(this IAdbClient client, DeviceData device,
/// The text to send.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task SendTextAsync(this IAdbClient client, DeviceData device, string text, CancellationToken cancellationToken = default) =>
new DeviceClient(client, device).SendTextAsync(text, cancellationToken);
@@ -167,6 +179,7 @@ public static Task SendTextAsync(this IAdbClient client, DeviceData device, stri
/// The length of text to clear.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ClearInputAsync(this IAdbClient client, DeviceData device, int charCount, CancellationToken cancellationToken = default) =>
new DeviceClient(client, device).ClearInputAsync(charCount, cancellationToken);
@@ -177,6 +190,7 @@ public static Task ClearInputAsync(this IAdbClient client, DeviceData device, in
/// The device on which to click BACK button.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ClickBackButtonAsync(this IAdbClient client, DeviceData device, CancellationToken cancellationToken = default) =>
new DeviceClient(client, device).ClickBackButtonAsync(cancellationToken);
@@ -187,6 +201,7 @@ public static Task ClickBackButtonAsync(this IAdbClient client, DeviceData devic
/// The device on which to click HOME button.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ClickHomeButtonAsync(this IAdbClient client, DeviceData device, CancellationToken cancellationToken = default) =>
new DeviceClient(client, device).ClickHomeButtonAsync(cancellationToken);
@@ -198,6 +213,7 @@ public static Task ClickHomeButtonAsync(this IAdbClient client, DeviceData devic
/// The package name of the application to start.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task StartAppAsync(this IAdbClient client, DeviceData device, string packageName, CancellationToken cancellationToken = default) =>
client.ExecuteShellCommandAsync(device, $"monkey -p {packageName} 1", cancellationToken);
@@ -209,6 +225,7 @@ public static Task StartAppAsync(this IAdbClient client, DeviceData device, stri
/// The package name of the application to stop.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task StopAppAsync(this IAdbClient client, DeviceData device, string packageName, CancellationToken cancellationToken = default) =>
client.ExecuteShellCommandAsync(device, $"am force-stop {packageName}", cancellationToken);
@@ -296,6 +313,7 @@ public static async Task StatExAsync(this IAdbClient client, D
/// A that can be used to cancel the task.
/// A which returns a object that contains information about the file.
/// The file size will be cut off at 4 GiB due to the use of a 32-bit unsigned integer.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task StatAsync(this IAdbClient client, DeviceData device, string path, bool useV2, CancellationToken cancellationToken = default) =>
useV2 ? client.StatExAsync(device, path, cancellationToken).ContinueWith(x => x.Result as IFileStatistics) : client.StatAsync(device, path, cancellationToken).ContinueWith(x => x.Result as IFileStatistics);
@@ -338,6 +356,7 @@ public static async Task> GetDirectoryListingExAsync(this
/// A that can be used to cancel the task.
/// A which returns for each child item of the directory, a object with information of the item.
/// File size bigger than 4GB need V2, and V2 need Android 11 or above.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task> GetDirectoryListingAsync(this IAdbClient client, DeviceData device, string remotePath, bool useV2, CancellationToken cancellationToken = default) =>
#if NETFRAMEWORK && !NET40_OR_GREATER
useV2 ? client.GetDirectoryListingExAsync(device, remotePath, cancellationToken).ContinueWith(x => x.Result.OfType()) : client.GetDirectoryListingAsync(device, remotePath, cancellationToken).ContinueWith(x => x.Result.OfType());
@@ -391,6 +410,7 @@ public static async IAsyncEnumerable GetDirectoryAsyncListingE
/// A that can be used to cancel the task.
/// An which returns for each child item of the directory, a object with information of the item.
/// File size bigger than 4GB need V2, and V2 need Android 11 or above.
+ [MethodImpl((MethodImplOptions)0x100)]
public static IAsyncEnumerable GetDirectoryAsyncListing(this IAdbClient client, DeviceData device, string remotePath, bool useV2, CancellationToken cancellationToken = default) =>
useV2 ? client.GetDirectoryAsyncListingEx(device, remotePath, cancellationToken) : client.GetDirectoryAsyncListing(device, remotePath, cancellationToken);
#endif
@@ -449,11 +469,9 @@ public static async Task> GetEnvironmentVariablesAsyn
/// A which can be used to cancel the asynchronous operation.
/// The arguments to pass to adb install.
/// A which represents the asynchronous operation.
- public static Task InstallPackageAsync(this IAdbClient client, DeviceData device, string packageFilePath, Action? callback = null, CancellationToken cancellationToken = default, params string[] arguments)
- {
- PackageManager manager = new(client, device, skipInit: true);
- return manager.InstallPackageAsync(packageFilePath, callback, cancellationToken, arguments);
- }
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static Task InstallPackageAsync(this IAdbClient client, DeviceData device, string packageFilePath, Action? callback = null, CancellationToken cancellationToken = default, params string[] arguments) =>
+ new PackageManager(client, device, skipInit: true).InstallPackageAsync(packageFilePath, callback, cancellationToken, arguments);
///
/// Asynchronously installs Android multiple application on device.
@@ -467,11 +485,8 @@ public static Task InstallPackageAsync(this IAdbClient client, DeviceData device
/// A which can be used to cancel the asynchronous operation.
/// The arguments to pass to pm install-create.
/// A which represents the asynchronous operation.
- public static Task InstallMultiplePackageAsync(this IAdbClient client, DeviceData device, string basePackageFilePath, IEnumerable splitPackageFilePaths, Action? callback = null, CancellationToken cancellationToken = default, params string[] arguments)
- {
- PackageManager manager = new(client, device, skipInit: true);
- return manager.InstallMultiplePackageAsync(basePackageFilePath, splitPackageFilePaths, callback, cancellationToken, arguments);
- }
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static Task InstallMultiplePackageAsync(this IAdbClient client, DeviceData device, string basePackageFilePath, IEnumerable splitPackageFilePaths, Action? callback = null, CancellationToken cancellationToken = default, params string[] arguments) => new PackageManager(client, device, skipInit: true).InstallMultiplePackageAsync(basePackageFilePath, splitPackageFilePaths, callback, cancellationToken, arguments);
///
/// Asynchronously installs Android multiple application on device.
@@ -485,11 +500,9 @@ public static Task InstallMultiplePackageAsync(this IAdbClient client, DeviceDat
/// A which can be used to cancel the asynchronous operation.
/// The arguments to pass to pm install-create.
/// A which represents the asynchronous operation.
- public static Task InstallMultiplePackageAsync(this IAdbClient client, DeviceData device, IEnumerable splitPackageFilePaths, string packageName, Action? callback = null, CancellationToken cancellationToken = default, params string[] arguments)
- {
- PackageManager manager = new(client, device, skipInit: true);
- return manager.InstallMultiplePackageAsync(splitPackageFilePaths, packageName, callback, cancellationToken, arguments);
- }
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static Task InstallMultiplePackageAsync(this IAdbClient client, DeviceData device, IEnumerable splitPackageFilePaths, string packageName, Action? callback = null, CancellationToken cancellationToken = default, params string[] arguments) =>
+ new PackageManager(client, device, skipInit: true).InstallMultiplePackageAsync(splitPackageFilePaths, packageName, callback, cancellationToken, arguments);
#if !NETFRAMEWORK || NET40_OR_GREATER
///
@@ -548,11 +561,9 @@ public static async Task PushAsync(this IAdbClient client, DeviceData device,
/// A which can be used to cancel the asynchronous operation.
/// The arguments to pass to adb install.
/// A which represents the asynchronous operation.
- public static Task InstallPackageAsync(this IAdbClient client, DeviceData device, string packageFilePath, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments)
- {
- PackageManager manager = new(client, device, skipInit: true);
- return manager.InstallPackageAsync(packageFilePath, progress, cancellationToken, arguments);
- }
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static Task InstallPackageAsync(this IAdbClient client, DeviceData device, string packageFilePath, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
+ new PackageManager(client, device, skipInit: true).InstallPackageAsync(packageFilePath, progress, cancellationToken, arguments);
///
/// Asynchronously installs Android multiple application on device.
@@ -566,11 +577,9 @@ public static Task InstallPackageAsync(this IAdbClient client, DeviceData device
/// A which can be used to cancel the asynchronous operation.
/// The arguments to pass to pm install-create.
/// A which represents the asynchronous operation.
- public static Task InstallMultiplePackageAsync(this IAdbClient client, DeviceData device, string basePackageFilePath, IEnumerable splitPackageFilePaths, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments)
- {
- PackageManager manager = new(client, device, skipInit: true);
- return manager.InstallMultiplePackageAsync(basePackageFilePath, splitPackageFilePaths, progress, cancellationToken, arguments);
- }
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static Task InstallMultiplePackageAsync(this IAdbClient client, DeviceData device, string basePackageFilePath, IEnumerable splitPackageFilePaths, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
+ new PackageManager(client, device, skipInit: true).InstallMultiplePackageAsync(basePackageFilePath, splitPackageFilePaths, progress, cancellationToken, arguments);
///
/// Asynchronously installs Android multiple application on device.
@@ -584,11 +593,9 @@ public static Task InstallMultiplePackageAsync(this IAdbClient client, DeviceDat
/// A which can be used to cancel the asynchronous operation.
/// The arguments to pass to pm install-create.
/// A which represents the asynchronous operation.
- public static Task InstallMultiplePackageAsync(this IAdbClient client, DeviceData device, IEnumerable splitPackageFilePaths, string packageName, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments)
- {
- PackageManager manager = new(client, device, skipInit: true);
- return manager.InstallMultiplePackageAsync(splitPackageFilePaths, packageName, progress, cancellationToken, arguments);
- }
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static Task InstallMultiplePackageAsync(this IAdbClient client, DeviceData device, IEnumerable splitPackageFilePaths, string packageName, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
+ new PackageManager(client, device, skipInit: true).InstallMultiplePackageAsync(splitPackageFilePaths, packageName, progress, cancellationToken, arguments);
#if NET7_0_OR_GREATER
///
@@ -647,11 +654,9 @@ public static async Task PushAsync(this IAdbClient client, DeviceData device,
/// The name of the package to uninstall.
/// The arguments to pass to pm uninstall.
/// A which represents the asynchronous operation.
- public static Task UninstallPackageAsync(this IAdbClient client, DeviceData device, string packageName, params string[] arguments)
- {
- PackageManager manager = new(client, device, skipInit: true);
- return manager.UninstallPackageAsync(packageName, arguments);
- }
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static Task UninstallPackageAsync(this IAdbClient client, DeviceData device, string packageName, params string[] arguments) =>
+ new PackageManager(client, device, skipInit: true).UninstallPackageAsync(packageName, arguments);
///
/// Asynchronously uninstalls a package from the device.
@@ -662,11 +667,9 @@ public static Task UninstallPackageAsync(this IAdbClient client, DeviceData devi
/// A which can be used to cancel the asynchronous operation.
/// The arguments to pass to pm uninstall.
/// A which represents the asynchronous operation.
- public static Task UninstallPackageAsync(this IAdbClient client, DeviceData device, string packageName, CancellationToken cancellationToken, params string[] arguments)
- {
- PackageManager manager = new(client, device, skipInit: true);
- return manager.UninstallPackageAsync(packageName, cancellationToken, arguments);
- }
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static Task UninstallPackageAsync(this IAdbClient client, DeviceData device, string packageName, CancellationToken cancellationToken, params string[] arguments) =>
+ new PackageManager(client, device, skipInit: true).UninstallPackageAsync(packageName, cancellationToken, arguments);
///
/// Asynchronously requests the version information from the device.
@@ -676,11 +679,9 @@ public static Task UninstallPackageAsync(this IAdbClient client, DeviceData devi
/// The name of the package from which to get the application version.
/// A which can be used to cancel the asynchronous operation.
/// A which returns the of target application.
- public static Task GetPackageVersionAsync(this IAdbClient client, DeviceData device, string packageName, CancellationToken cancellationToken = default)
- {
- PackageManager manager = new(client, device, skipInit: true);
- return manager.GetVersionInfoAsync(packageName, cancellationToken);
- }
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static Task GetPackageVersionAsync(this IAdbClient client, DeviceData device, string packageName, CancellationToken cancellationToken = default) =>
+ new PackageManager(client, device, skipInit: true).GetVersionInfoAsync(packageName, cancellationToken);
///
/// Asynchronously lists all processes running on the device.
diff --git a/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.cs b/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.cs
index 6761601..1473ff9 100644
--- a/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.cs
+++ b/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.cs
@@ -24,6 +24,7 @@ public static partial class DeviceExtensions
/// The to use when executing the command.
/// The device on which to run the command.
/// The command to execute.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void ExecuteShellCommand(this IAdbClient client, DeviceData device, string command) =>
client.ExecuteRemoteCommand(command, device);
@@ -34,6 +35,7 @@ public static void ExecuteShellCommand(this IAdbClient client, DeviceData device
/// The device on which to run the command.
/// The command to execute.
/// Optionally, a that processes the command output.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void ExecuteShellCommand(this IAdbClient client, DeviceData device, string command, IShellOutputReceiver? receiver) =>
client.ExecuteRemoteCommand(command, device, receiver, AdbClient.Encoding);
@@ -44,6 +46,7 @@ public static void ExecuteShellCommand(this IAdbClient client, DeviceData device
/// The device on which to run the command.
/// The command to execute.
/// Optionally, a that processes the command output.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void ExecuteShellCommand(this IAdbClient client, DeviceData device, string command, Func? predicate) =>
client.ExecuteRemoteCommand(command, device, predicate.AsShellOutputReceiver(), AdbClient.Encoding);
@@ -53,6 +56,7 @@ public static void ExecuteShellCommand(this IAdbClient client, DeviceData device
/// An instance of a class that implements the interface.
/// The device on which to clear the input text.
/// A containing current hierarchy.
+ [MethodImpl((MethodImplOptions)0x100)]
public static XmlDocument? DumpScreen(this IAdbClient client, DeviceData device) =>
new DeviceClient(client, device).DumpScreen();
@@ -62,6 +66,7 @@ public static void ExecuteShellCommand(this IAdbClient client, DeviceData device
/// An instance of a class that implements the interface.
/// The device on which to clear the input text.
/// The to click.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void Click(this IAdbClient client, DeviceData device, Point point) =>
new DeviceClient(client, device).Click(point);
@@ -73,6 +78,7 @@ public static void Click(this IAdbClient client, DeviceData device, Point point)
/// The start .
/// The end .
/// The time spent in swiping.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void Swipe(this IAdbClient client, DeviceData device, Point first, Point second, long speed) =>
new DeviceClient(client, device).Swipe(first, second, speed);
@@ -83,6 +89,7 @@ public static void Swipe(this IAdbClient client, DeviceData device, Point first,
/// The device on which to clear the input text.
/// The package name of the app to check.
/// The of the app. Foreground, stopped or running in background.
+ [MethodImpl((MethodImplOptions)0x100)]
public static AppStatus GetAppStatus(this IAdbClient client, DeviceData device, string packageName) =>
new DeviceClient(client, device).GetAppStatus(packageName);
@@ -96,6 +103,7 @@ public static AppStatus GetAppStatus(this IAdbClient client, DeviceData device,
/// The timeout for waiting the element.
/// Only check once if or .
/// The of .
+ [MethodImpl((MethodImplOptions)0x100)]
public static Element? FindElement(this IAdbClient client, DeviceData device, string xpath = "hierarchy/node", TimeSpan timeout = default) =>
new DeviceClient(client, device).FindElement(xpath, timeout);
@@ -108,6 +116,7 @@ public static AppStatus GetAppStatus(this IAdbClient client, DeviceData device,
/// The timeout for waiting the elements.
/// Only check once if or .
/// The of has got.
+ [MethodImpl((MethodImplOptions)0x100)]
public static IEnumerable FindElements(this IAdbClient client, DeviceData device, string xpath = "hierarchy/node", TimeSpan timeout = default) =>
new DeviceClient(client, device).FindElements(xpath, timeout);
#endif
@@ -118,6 +127,7 @@ public static IEnumerable FindElements(this IAdbClient client, DeviceDa
/// An instance of a class that implements the interface.
/// The device on which to clear the input text.
/// The key event to send.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void SendKeyEvent(this IAdbClient client, DeviceData device, string key) =>
new DeviceClient(client, device).SendKeyEvent(key);
@@ -127,6 +137,7 @@ public static void SendKeyEvent(this IAdbClient client, DeviceData device, strin
/// An instance of a class that implements the interface.
/// The device on which to clear the input text.
/// The text to send.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void SendText(this IAdbClient client, DeviceData device, string text) =>
new DeviceClient(client, device).SendText(text);
@@ -136,6 +147,7 @@ public static void SendText(this IAdbClient client, DeviceData device, string te
/// An instance of a class that implements the interface.
/// The device on which to clear the input text.
/// The length of text to clear.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void ClearInput(this IAdbClient client, DeviceData device, int charCount) =>
new DeviceClient(client, device).ClearInput(charCount);
@@ -144,6 +156,7 @@ public static void ClearInput(this IAdbClient client, DeviceData device, int cha
///
/// An instance of a class that implements the interface.
/// The device on which to click BACK button.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void ClickBackButton(this IAdbClient client, DeviceData device) =>
new DeviceClient(client, device).ClickBackButton();
@@ -152,6 +165,7 @@ public static void ClickBackButton(this IAdbClient client, DeviceData device) =>
///
/// An instance of a class that implements the interface.
/// The device on which to click HOME button.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void ClickHomeButton(this IAdbClient client, DeviceData device) =>
new DeviceClient(client, device).ClickHomeButton();
@@ -161,6 +175,7 @@ public static void ClickHomeButton(this IAdbClient client, DeviceData device) =>
/// An instance of a class that implements the interface.
/// The device on which to click HOME button.
/// The package name of the application to start.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void StartApp(this IAdbClient client, DeviceData device, string packageName) =>
client.ExecuteShellCommand(device, $"monkey -p {packageName} 1");
@@ -170,6 +185,7 @@ public static void StartApp(this IAdbClient client, DeviceData device, string pa
/// An instance of a class that implements the interface.
/// The device on which to click HOME button.
/// The package name of the application to stop.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void StopApp(this IAdbClient client, DeviceData device, string packageName) =>
client.ExecuteShellCommand(device, $"am force-stop {packageName}");
@@ -188,7 +204,7 @@ public static void Pull(this IAdbClient client, DeviceData device,
string remotePath, Stream stream,
Action? callback = null,
bool useV2 = false,
- in bool isCancelled = false)
+ scoped in bool isCancelled = false)
{
using ISyncService service = Factories.SyncServiceFactory(client, device);
service.Pull(remotePath, stream, callback, useV2, in isCancelled);
@@ -211,7 +227,7 @@ public static void Push(this IAdbClient client, DeviceData device,
string remotePath, Stream stream, UnixFileStatus permission, DateTimeOffset timestamp,
Action? callback = null,
bool useV2 = false,
- in bool isCancelled = false)
+ scoped in bool isCancelled = false)
{
using ISyncService service = Factories.SyncServiceFactory(client, device);
service.Push(stream, remotePath, permission, timestamp, callback, useV2, in isCancelled);
@@ -254,6 +270,7 @@ public static FileStatisticsEx StatEx(this IAdbClient client, DeviceData device,
/// to use ; otherwise, use .
/// A object that represents the file.
/// File size bigger than 4GB need V2, and V2 need Android 8 or above.
+ [MethodImpl((MethodImplOptions)0x100)]
public static IFileStatistics Stat(this IAdbClient client, DeviceData device, string path, bool useV2) =>
useV2 ? client.StatEx(device, path) : client.Stat(device, path);
@@ -299,6 +316,7 @@ public static IEnumerable GetDirectoryListingEx(this IAdbClien
/// to use ; otherwise, use .
/// For each child item of the directory, a object with information of the item.
/// V2 need Android 11 or above.
+ [MethodImpl((MethodImplOptions)0x100)]
public static IEnumerable GetDirectoryListing(this IAdbClient client, DeviceData device, string remotePath, bool useV2) =>
#if NETFRAMEWORK && !NET40_OR_GREATER
useV2 ? client.GetDirectoryListingEx(device, remotePath).OfType() : client.GetDirectoryListing(device, remotePath).OfType();
@@ -355,11 +373,9 @@ public static Dictionary GetEnvironmentVariables(this IAdbClient
/// An optional parameter which, when specified, returns progress notifications.
/// The progress is reported as , representing the state of installation.
/// The arguments to pass to adb install.
- public static void InstallPackage(this IAdbClient client, DeviceData device, string packageFilePath, Action? callback = null, params string[] arguments)
- {
- PackageManager manager = new(client, device, skipInit: true);
- manager.InstallPackage(packageFilePath, callback, arguments);
- }
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void InstallPackage(this IAdbClient client, DeviceData device, string packageFilePath, Action? callback = null, params string[] arguments) =>
+ new PackageManager(client, device, skipInit: true).InstallPackage(packageFilePath, callback, arguments);
///
/// Installs Android multiple application on device.
@@ -371,11 +387,9 @@ public static void InstallPackage(this IAdbClient client, DeviceData device, str
/// An optional parameter which, when specified, returns progress notifications.
/// The progress is reported as , representing the state of installation.
/// The arguments to pass to pm install-create.
- public static void InstallMultiplePackage(this IAdbClient client, DeviceData device, string basePackageFilePath, IEnumerable splitPackageFilePaths, Action? callback = null, params string[] arguments)
- {
- PackageManager manager = new(client, device, skipInit: true);
- manager.InstallMultiplePackage(basePackageFilePath, splitPackageFilePaths, callback, arguments);
- }
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void InstallMultiplePackage(this IAdbClient client, DeviceData device, string basePackageFilePath, IEnumerable splitPackageFilePaths, Action? callback = null, params string[] arguments) =>
+ new PackageManager(client, device, skipInit: true).InstallMultiplePackage(basePackageFilePath, splitPackageFilePaths, callback, arguments);
///
/// Installs Android multiple application on device.
@@ -387,11 +401,9 @@ public static void InstallMultiplePackage(this IAdbClient client, DeviceData dev
/// An optional parameter which, when specified, returns progress notifications.
/// The progress is reported as , representing the state of installation.
/// The arguments to pass to pm install-create.
- public static void InstallMultiplePackage(this IAdbClient client, DeviceData device, IEnumerable splitPackageFilePaths, string packageName, Action? callback = null, params string[] arguments)
- {
- PackageManager manager = new(client, device, skipInit: true);
- manager.InstallMultiplePackage(splitPackageFilePaths, packageName, callback, arguments);
- }
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void InstallMultiplePackage(this IAdbClient client, DeviceData device, IEnumerable splitPackageFilePaths, string packageName, Action? callback = null, params string[] arguments) =>
+ new PackageManager(client, device, skipInit: true).InstallMultiplePackage(splitPackageFilePaths, packageName, callback, arguments);
#if !NETFRAMEWORK || NET40_OR_GREATER
///
@@ -409,7 +421,7 @@ public static void Pull(this IAdbClient client, DeviceData device,
string remotePath, Stream stream,
IProgress? progress = null,
bool useV2 = false,
- in bool isCancelled = false)
+ scoped in bool isCancelled = false)
{
using ISyncService service = Factories.SyncServiceFactory(client, device);
service.Pull(remotePath, stream, progress.AsAction(), useV2, in isCancelled);
@@ -432,7 +444,7 @@ public static void Push(this IAdbClient client, DeviceData device,
string remotePath, Stream stream, UnixFileStatus permission, DateTimeOffset timestamp,
IProgress? progress = null,
bool useV2 = false,
- in bool isCancelled = false)
+ scoped in bool isCancelled = false)
{
using ISyncService service = Factories.SyncServiceFactory(client, device);
service.Push(stream, remotePath, permission, timestamp, progress.AsAction(), useV2, in isCancelled);
@@ -447,11 +459,9 @@ public static void Push(this IAdbClient client, DeviceData device,
/// An optional parameter which, when specified, returns progress notifications.
/// The progress is reported as , representing the state of installation.
/// The arguments to pass to adb install.
- public static void InstallPackage(this IAdbClient client, DeviceData device, string packageFilePath, IProgress? progress = null, params string[] arguments)
- {
- PackageManager manager = new(client, device, skipInit: true);
- manager.InstallPackage(packageFilePath, progress, arguments);
- }
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void InstallPackage(this IAdbClient client, DeviceData device, string packageFilePath, IProgress? progress = null, params string[] arguments) =>
+ new PackageManager(client, device, skipInit: true).InstallPackage(packageFilePath, progress, arguments);
///
/// Installs Android multiple application on device.
@@ -463,11 +473,9 @@ public static void InstallPackage(this IAdbClient client, DeviceData device, str
/// An optional parameter which, when specified, returns progress notifications.
/// The progress is reported as , representing the state of installation.
/// The arguments to pass to pm install-create.
- public static void InstallMultiplePackage(this IAdbClient client, DeviceData device, string basePackageFilePath, IEnumerable splitPackageFilePaths, IProgress? progress = null, params string[] arguments)
- {
- PackageManager manager = new(client, device, skipInit: true);
- manager.InstallMultiplePackage(basePackageFilePath, splitPackageFilePaths, progress, arguments);
- }
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void InstallMultiplePackage(this IAdbClient client, DeviceData device, string basePackageFilePath, IEnumerable splitPackageFilePaths, IProgress? progress = null, params string[] arguments) =>
+ new PackageManager(client, device, skipInit: true).InstallMultiplePackage(basePackageFilePath, splitPackageFilePaths, progress, arguments);
///
/// Installs Android multiple application on device.
@@ -479,11 +487,9 @@ public static void InstallMultiplePackage(this IAdbClient client, DeviceData dev
/// An optional parameter which, when specified, returns progress notifications.
/// The progress is reported as , representing the state of installation.
/// The arguments to pass to pm install-create.
- public static void InstallMultiplePackage(this IAdbClient client, DeviceData device, IEnumerable splitPackageFilePaths, string packageName, IProgress? progress = null, params string[] arguments)
- {
- PackageManager manager = new(client, device, skipInit: true);
- manager.InstallMultiplePackage(splitPackageFilePaths, packageName, progress, arguments);
- }
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void InstallMultiplePackage(this IAdbClient client, DeviceData device, IEnumerable splitPackageFilePaths, string packageName, IProgress? progress = null, params string[] arguments) =>
+ new PackageManager(client, device, skipInit: true).InstallMultiplePackage(splitPackageFilePaths, packageName, progress, arguments);
#if NET7_0_OR_GREATER
///
@@ -503,7 +509,7 @@ public static void Push(this IAdbClient client, DeviceData device,
string remotePath, Stream stream, UnixFileMode permission, DateTimeOffset timestamp,
Action? callback = null,
bool useV2 = false,
- in bool isCancelled = false)
+ scoped in bool isCancelled = false)
{
using ISyncService service = Factories.SyncServiceFactory(client, device);
service.Push(stream, remotePath, (UnixFileStatus)permission, timestamp, callback, useV2, in isCancelled);
@@ -526,7 +532,7 @@ public static void Push(this IAdbClient client, DeviceData device,
string remotePath, Stream stream, UnixFileMode permission, DateTimeOffset timestamp,
IProgress? progress,
bool useV2 = false,
- in bool isCancelled = false)
+ scoped in bool isCancelled = false)
{
using ISyncService service = Factories.SyncServiceFactory(client, device);
service.Push(stream, remotePath, (UnixFileStatus)permission, timestamp, progress.AsAction(), useV2, in isCancelled);
@@ -541,11 +547,9 @@ public static void Push(this IAdbClient client, DeviceData device,
/// The device on which to uninstall the package.
/// The name of the package to uninstall.
/// The arguments to pass to pm uninstall.
- public static void UninstallPackage(this IAdbClient client, DeviceData device, string packageName, params string[] arguments)
- {
- PackageManager manager = new(client, device, skipInit: true);
- manager.UninstallPackage(packageName, arguments);
- }
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void UninstallPackage(this IAdbClient client, DeviceData device, string packageName, params string[] arguments) =>
+ new PackageManager(client, device, skipInit: true).UninstallPackage(packageName, arguments);
///
/// Requests the version information from the device.
@@ -553,11 +557,9 @@ public static void UninstallPackage(this IAdbClient client, DeviceData device, s
/// The connection to the adb server.
/// The device on which to uninstall the package.
/// The name of the package from which to get the application version.
- public static VersionInfo GetPackageVersion(this IAdbClient client, DeviceData device, string packageName)
- {
- PackageManager manager = new(client, device, skipInit: true);
- return manager.GetVersionInfo(packageName);
- }
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static VersionInfo GetPackageVersion(this IAdbClient client, DeviceData device, string packageName) =>
+ new PackageManager(client, device, skipInit: true).GetVersionInfo(packageName);
///
/// Lists all processes running on the device.
@@ -625,7 +627,7 @@ public static List ListProcesses(this IAdbClient client, DeviceD
// Doing cat on each file one by one takes too much time. Doing cat on all of them at the same time doesn't work
// either, because the command line would be too long.
// So we do it 25 processes at at time.
- DefaultInterpolatedStringHandler catBuilder = new(3, pids.Count);
+ scoped DefaultInterpolatedStringHandler catBuilder = new(3, pids.Count);
ProcessOutputReceiver processOutputReceiver = new();
catBuilder.AppendLiteral("cat");
diff --git a/AdvancedSharpAdbClient/DeviceCommands/PackageManager.Async.cs b/AdvancedSharpAdbClient/DeviceCommands/PackageManager.Async.cs
index 0a088d8..7744377 100644
--- a/AdvancedSharpAdbClient/DeviceCommands/PackageManager.Async.cs
+++ b/AdvancedSharpAdbClient/DeviceCommands/PackageManager.Async.cs
@@ -23,7 +23,7 @@ public Task RefreshPackagesAsync(CancellationToken cancellationToken = default)
{
ValidateDevice();
- DefaultInterpolatedStringHandler requestBuilder = new(19, Arguments?.Length ?? 0);
+ scoped DefaultInterpolatedStringHandler requestBuilder = new(19, Arguments?.Length ?? 0);
requestBuilder.AppendLiteral(ListFull);
if (Arguments != null)
@@ -84,7 +84,7 @@ public async Task InstallRemotePackageAsync(string remoteFilePath, Action
/// A which can be used to cancel the asynchronous operation.
/// The arguments to pass to adb install.
/// A which represents the asynchronous operation.
- public async Task InstallPackageAsync(string packageFilePath, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
- await InstallPackageAsync(packageFilePath, progress.AsAction(), cancellationToken, arguments).ConfigureAwait(false);
+ [MethodImpl((MethodImplOptions)0x100)]
+ public Task InstallPackageAsync(string packageFilePath, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
+ InstallPackageAsync(packageFilePath, progress.AsAction(), cancellationToken, arguments);
///
/// Asynchronously installs the application package that was pushed to a temporary location on the device.
@@ -368,8 +369,9 @@ public async Task InstallPackageAsync(string packageFilePath, IProgressA which can be used to cancel the asynchronous operation.
/// The arguments to pass to pm install.
/// A which represents the asynchronous operation.
- public async Task InstallRemotePackageAsync(string remoteFilePath, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
- await InstallRemotePackageAsync(remoteFilePath, progress.AsAction(), cancellationToken, arguments).ConfigureAwait(false);
+ [MethodImpl((MethodImplOptions)0x100)]
+ public Task InstallRemotePackageAsync(string remoteFilePath, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
+ InstallRemotePackageAsync(remoteFilePath, progress.AsAction(), cancellationToken, arguments);
///
/// Asynchronously installs Android multiple application on device.
@@ -381,8 +383,9 @@ public async Task InstallRemotePackageAsync(string remoteFilePath, IProgressA which can be used to cancel the asynchronous operation.
/// The arguments to pass to pm install-create.
/// A which represents the asynchronous operation.
- public async Task InstallMultiplePackageAsync(string basePackageFilePath, IEnumerable splitPackageFilePaths, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
- await InstallMultiplePackageAsync(basePackageFilePath, splitPackageFilePaths, progress.AsAction(), cancellationToken, arguments).ConfigureAwait(false);
+ [MethodImpl((MethodImplOptions)0x100)]
+ public Task InstallMultiplePackageAsync(string basePackageFilePath, IEnumerable splitPackageFilePaths, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
+ InstallMultiplePackageAsync(basePackageFilePath, splitPackageFilePaths, progress.AsAction(), cancellationToken, arguments);
///
/// Asynchronously installs Android multiple application on device.
@@ -394,8 +397,9 @@ public async Task InstallMultiplePackageAsync(string basePackageFilePath, IEnume
/// A which can be used to cancel the asynchronous operation.
/// The arguments to pass to pm install-create.
/// A which represents the asynchronous operation.
- public async Task InstallMultiplePackageAsync(IEnumerable splitPackageFilePaths, string packageName, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
- await InstallMultiplePackageAsync(splitPackageFilePaths, packageName, progress.AsAction(), cancellationToken, arguments).ConfigureAwait(false);
+ [MethodImpl((MethodImplOptions)0x100)]
+ public Task InstallMultiplePackageAsync(IEnumerable splitPackageFilePaths, string packageName, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
+ InstallMultiplePackageAsync(splitPackageFilePaths, packageName, progress.AsAction(), cancellationToken, arguments);
///
/// Asynchronously installs the multiple application package that was pushed to a temporary location on the device.
@@ -407,8 +411,9 @@ public async Task InstallMultiplePackageAsync(IEnumerable splitPackageFi
/// A which can be used to cancel the asynchronous operation.
/// The arguments to pass to pm install-create.
/// A which represents the asynchronous operation.
- public async Task InstallMultipleRemotePackageAsync(string baseRemoteFilePath, IEnumerable splitRemoteFilePaths, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
- await InstallMultipleRemotePackageAsync(baseRemoteFilePath, splitRemoteFilePaths, progress.AsAction(), cancellationToken, arguments).ConfigureAwait(false);
+ [MethodImpl((MethodImplOptions)0x100)]
+ public Task InstallMultipleRemotePackageAsync(string baseRemoteFilePath, IEnumerable splitRemoteFilePaths, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
+ InstallMultipleRemotePackageAsync(baseRemoteFilePath, splitRemoteFilePaths, progress.AsAction(), cancellationToken, arguments);
///
/// Asynchronously installs the multiple application package that was pushed to a temporary location on the device.
@@ -420,8 +425,9 @@ public async Task InstallMultipleRemotePackageAsync(string baseRemoteFilePath, I
/// A which can be used to cancel the asynchronous operation.
/// The arguments to pass to pm install-create.
/// A which represents the asynchronous operation.
- public async Task InstallMultipleRemotePackageAsync(IEnumerable splitRemoteFilePaths, string packageName, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
- await InstallMultipleRemotePackageAsync(splitRemoteFilePaths, packageName, progress.AsAction(), cancellationToken, arguments).ConfigureAwait(false);
+ [MethodImpl((MethodImplOptions)0x100)]
+ public Task InstallMultipleRemotePackageAsync(IEnumerable splitRemoteFilePaths, string packageName, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
+ InstallMultipleRemotePackageAsync(splitRemoteFilePaths, packageName, progress.AsAction(), cancellationToken, arguments);
#endif
///
@@ -444,7 +450,7 @@ public async Task UninstallPackageAsync(string packageName, CancellationToken ca
{
ValidateDevice();
- DefaultInterpolatedStringHandler requestBuilder = new(13, (arguments?.Length ?? 0) + 1);
+ scoped DefaultInterpolatedStringHandler requestBuilder = new(13, (arguments?.Length ?? 0) + 1);
requestBuilder.AppendLiteral("pm uninstall");
if (arguments != null)
@@ -494,7 +500,7 @@ protected async Task CreateInstallSessionAsync(string? packageName = nul
{
ValidateDevice();
- DefaultInterpolatedStringHandler requestBuilder = new(21, (arguments?.Length ?? 0) + 1);
+ scoped DefaultInterpolatedStringHandler requestBuilder = new(21, (arguments?.Length ?? 0) + 1);
requestBuilder.AppendLiteral("pm install-create");
if (!string.IsNullOrWhiteSpace(packageName))
diff --git a/AdvancedSharpAdbClient/DeviceCommands/PackageManager.cs b/AdvancedSharpAdbClient/DeviceCommands/PackageManager.cs
index b3668cb..56043e6 100644
--- a/AdvancedSharpAdbClient/DeviceCommands/PackageManager.cs
+++ b/AdvancedSharpAdbClient/DeviceCommands/PackageManager.cs
@@ -131,7 +131,7 @@ public void RefreshPackages()
{
ValidateDevice();
- DefaultInterpolatedStringHandler requestBuilder = new(19, Arguments?.Length ?? 0);
+ scoped DefaultInterpolatedStringHandler requestBuilder = new(19, Arguments?.Length ?? 0);
requestBuilder.AppendLiteral(ListFull);
if (Arguments != null)
@@ -188,7 +188,7 @@ public void InstallRemotePackage(string remoteFilePath, Action splitRemoteFilePath
/// An optional parameter which, when specified, returns progress notifications.
/// The progress is reported as , representing the state of installation.
/// The arguments to pass to adb install.
+ [MethodImpl((MethodImplOptions)0x100)]
public void InstallPackage(string packageFilePath, IProgress? progress = null, params string[] arguments) =>
InstallPackage(packageFilePath, progress.AsAction(), arguments);
@@ -428,6 +429,7 @@ public void InstallPackage(string packageFilePath, IProgressAn optional parameter which, when specified, returns progress notifications.
/// The progress is reported as , representing the state of installation.
/// The arguments to pass to adb install.
+ [MethodImpl((MethodImplOptions)0x100)]
public void InstallRemotePackage(string remoteFilePath, IProgress? progress = null, params string[] arguments) =>
InstallRemotePackage(remoteFilePath, progress.AsAction(), arguments);
@@ -439,6 +441,7 @@ public void InstallRemotePackage(string remoteFilePath, IProgressAn optional parameter which, when specified, returns progress notifications.
/// The progress is reported as , representing the state of installation.
/// The arguments to pass to pm install-create.
+ [MethodImpl((MethodImplOptions)0x100)]
public void InstallMultiplePackage(string basePackageFilePath, IEnumerable splitPackageFilePaths, IProgress? progress = null, params string[] arguments) =>
InstallMultiplePackage(basePackageFilePath, splitPackageFilePaths, progress.AsAction(), arguments);
@@ -450,6 +453,7 @@ public void InstallMultiplePackage(string basePackageFilePath, IEnumerableAn optional parameter which, when specified, returns progress notifications.
/// The progress is reported as , representing the state of installation.
/// The arguments to pass to pm install-create.
+ [MethodImpl((MethodImplOptions)0x100)]
public void InstallMultiplePackage(IEnumerable splitPackageFilePaths, string packageName, IProgress? progress = null, params string[] arguments) =>
InstallMultiplePackage(splitPackageFilePaths, packageName, progress.AsAction(), arguments);
@@ -461,6 +465,7 @@ public void InstallMultiplePackage(IEnumerable splitPackageFilePaths, st
/// An optional parameter which, when specified, returns progress notifications.
/// The progress is reported as , representing the state of installation.
/// The arguments to pass to pm install-create.
+ [MethodImpl((MethodImplOptions)0x100)]
public void InstallMultipleRemotePackage(string baseRemoteFilePath, IEnumerable splitRemoteFilePaths, IProgress? progress = null, params string[] arguments) =>
InstallMultipleRemotePackage(baseRemoteFilePath, splitRemoteFilePaths, progress.AsAction(), arguments);
@@ -472,6 +477,7 @@ public void InstallMultipleRemotePackage(string baseRemoteFilePath, IEnumerable<
/// An optional parameter which, when specified, returns progress notifications.
/// The progress is reported as , representing the state of installation.
/// The arguments to pass to pm install-create.
+ [MethodImpl((MethodImplOptions)0x100)]
public void InstallMultipleRemotePackage(IEnumerable splitRemoteFilePaths, string packageName, IProgress? progress = null, params string[] arguments) =>
InstallMultipleRemotePackage(splitRemoteFilePaths, packageName, progress.AsAction(), arguments);
#endif
@@ -485,7 +491,7 @@ public void UninstallPackage(string packageName, params string[] arguments)
{
ValidateDevice();
- DefaultInterpolatedStringHandler requestBuilder = new(13, (arguments?.Length ?? 0) + 1);
+ scoped DefaultInterpolatedStringHandler requestBuilder = new(13, (arguments?.Length ?? 0) + 1);
requestBuilder.AppendLiteral("pm uninstall");
if (arguments != null)
@@ -536,7 +542,7 @@ protected string CreateInstallSession(string? packageName = null, params string[
{
ValidateDevice();
- DefaultInterpolatedStringHandler requestBuilder = new(21, (arguments?.Length ?? 0) + 1);
+ scoped DefaultInterpolatedStringHandler requestBuilder = new(21, (arguments?.Length ?? 0) + 1);
requestBuilder.AppendLiteral("pm install-create");
if (!string.IsNullOrWhiteSpace(packageName))
diff --git a/AdvancedSharpAdbClient/DeviceCommands/Receivers/VersionInfoReceiver.cs b/AdvancedSharpAdbClient/DeviceCommands/Receivers/VersionInfoReceiver.cs
index fd78f2b..46b2962 100644
--- a/AdvancedSharpAdbClient/DeviceCommands/Receivers/VersionInfoReceiver.cs
+++ b/AdvancedSharpAdbClient/DeviceCommands/Receivers/VersionInfoReceiver.cs
@@ -92,7 +92,7 @@ private void CheckPackagesSection(string line)
if (inPackagesSection && line != null)
{
#if HAS_BUFFERS
- ReadOnlySpan span = line.AsSpan().Trim();
+ scoped ReadOnlySpan span = line.AsSpan().Trim();
if (span.StartsWith("versionName="))
{
return span[12..].Trim().ToString();
diff --git a/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.Async.cs b/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.Async.cs
index 1fa47ba..147e109 100644
--- a/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.Async.cs
+++ b/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.Async.cs
@@ -7,6 +7,7 @@
using System.Collections.Generic;
using System.IO;
using System.Net;
+using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
@@ -28,6 +29,7 @@ public partial class AdbClientExtensions
/// A which represents the asynchronous operation.
/// If your requested to start forwarding to local port TCP:0, the port number of the TCP port
/// which has been opened. In all other cases, 0.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task CreateForwardAsync(this IAdbClient client, DeviceData device, ForwardSpec local, ForwardSpec remote, bool allowRebind, CancellationToken cancellationToken = default) =>
client.CreateForwardAsync(device, local.ToString(), remote.ToString(), allowRebind, cancellationToken);
@@ -43,6 +45,7 @@ public static Task CreateForwardAsync(this IAdbClient client, DeviceData de
/// If your requested to start forwarding to local port TCP:0, the port number of the TCP port
/// which has been opened. In all other cases, 0.
/// Failed to submit the forward command. Or Device rejected command: + resp.Message.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task CreateForwardAsync(this IAdbClient client, DeviceData device, int localPort, int remotePort, CancellationToken cancellationToken = default) =>
client.CreateForwardAsync(device, $"tcp:{localPort}", $"tcp:{remotePort}", true, cancellationToken);
@@ -59,6 +62,7 @@ public static Task CreateForwardAsync(this IAdbClient client, DeviceData de
/// which has been opened. In all other cases, 0.
/// The client failed to submit the forward command.
/// The device rejected command. The error message will include the error message provided by the device.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task CreateForwardAsync(this IAdbClient client, DeviceData device, int localPort, string remoteSocket, CancellationToken cancellationToken = default) =>
client.CreateForwardAsync(device, $"tcp:{localPort}", $"local:{remoteSocket}", true, cancellationToken);
@@ -76,6 +80,7 @@ public static Task CreateForwardAsync(this IAdbClient client, DeviceData de
/// A which represents the asynchronous operation.
/// If your requested to start reverse to remote port TCP:0, the port number of the TCP port
/// which has been opened. In all other cases, 0.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task CreateReverseForwardAsync(this IAdbClient client, DeviceData device, ForwardSpec remote, ForwardSpec local, bool allowRebind, CancellationToken cancellationToken = default) =>
client.CreateReverseForwardAsync(device, remote.ToString(), local.ToString(), allowRebind, cancellationToken);
@@ -87,6 +92,7 @@ public static Task CreateReverseForwardAsync(this IAdbClient client, Device
/// Specification of the remote that was forwarded
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task RemoveReverseForwardAsync(this IAdbClient client, DeviceData device, ForwardSpec remote, CancellationToken cancellationToken = default) =>
client.RemoveReverseForwardAsync(device, remote.ToString(), cancellationToken);
@@ -100,6 +106,7 @@ public static Task RemoveReverseForwardAsync(this IAdbClient client, DeviceData
/// Optionally, a that processes the command output.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ExecuteServerCommandAsync(this IAdbClient client, string target, string command, IShellOutputReceiver? receiver, CancellationToken cancellationToken = default) =>
client.ExecuteServerCommandAsync(target, command, receiver, AdbClient.Encoding, cancellationToken);
@@ -114,6 +121,7 @@ public static Task ExecuteServerCommandAsync(this IAdbClient client, string targ
/// Optionally, a that processes the command output.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ExecuteServerCommandAsync(this IAdbClient client, string target, string command, IAdbSocket socket, IShellOutputReceiver? receiver, CancellationToken cancellationToken = default) =>
client.ExecuteServerCommandAsync(target, command, socket, receiver, AdbClient.Encoding, cancellationToken);
@@ -126,6 +134,7 @@ public static Task ExecuteServerCommandAsync(this IAdbClient client, string targ
/// Optionally, a that processes the command output.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ExecuteRemoteCommandAsync(this IAdbClient client, string command, DeviceData device, IShellOutputReceiver? receiver, CancellationToken cancellationToken = default) =>
client.ExecuteRemoteCommandAsync(command, device, receiver, AdbClient.Encoding, cancellationToken);
@@ -139,6 +148,7 @@ public static Task ExecuteRemoteCommandAsync(this IAdbClient client, string comm
/// Optionally, a that processes the command output.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ExecuteServerCommandAsync(this IAdbClient client, string target, string command, Func? predicate, CancellationToken cancellationToken = default) =>
client.ExecuteServerCommandAsync(target, command, predicate.AsShellOutputReceiver(), AdbClient.Encoding, cancellationToken);
@@ -153,6 +163,7 @@ public static Task ExecuteServerCommandAsync(this IAdbClient client, string targ
/// Optionally, a that processes the command output.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ExecuteServerCommandAsync(this IAdbClient client, string target, string command, IAdbSocket socket, Func? predicate, CancellationToken cancellationToken = default) =>
client.ExecuteServerCommandAsync(target, command, socket, predicate.AsShellOutputReceiver(), AdbClient.Encoding, cancellationToken);
@@ -165,6 +176,7 @@ public static Task ExecuteServerCommandAsync(this IAdbClient client, string targ
/// Optionally, a that processes the command output.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ExecuteRemoteCommandAsync(this IAdbClient client, string command, DeviceData device, Func? predicate, CancellationToken cancellationToken = default) =>
client.ExecuteRemoteCommandAsync(command, device, predicate.AsShellOutputReceiver(), AdbClient.Encoding, cancellationToken);
@@ -179,6 +191,7 @@ public static Task ExecuteRemoteCommandAsync(this IAdbClient client, string comm
/// The encoding to use when parsing the command output.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ExecuteServerCommandAsync(this IAdbClient client, string target, string command, Func? predicate, Encoding encoding, CancellationToken cancellationToken = default) =>
client.ExecuteServerCommandAsync(target, command, predicate.AsShellOutputReceiver(), encoding, cancellationToken);
@@ -194,6 +207,7 @@ public static Task ExecuteServerCommandAsync(this IAdbClient client, string targ
/// The encoding to use when parsing the command output.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ExecuteServerCommandAsync(this IAdbClient client, string target, string command, IAdbSocket socket, Func? predicate, Encoding encoding, CancellationToken cancellationToken = default) =>
client.ExecuteServerCommandAsync(target, command, socket, predicate.AsShellOutputReceiver(), encoding, cancellationToken);
@@ -207,6 +221,7 @@ public static Task ExecuteServerCommandAsync(this IAdbClient client, string targ
/// The encoding to use when parsing the command output.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ExecuteRemoteCommandAsync(this IAdbClient client, string command, DeviceData device, Func? predicate, Encoding encoding, CancellationToken cancellationToken = default) =>
client.ExecuteRemoteCommandAsync(command, device, predicate.AsShellOutputReceiver(), encoding, cancellationToken);
@@ -220,6 +235,7 @@ public static Task ExecuteRemoteCommandAsync(this IAdbClient client, string comm
/// The command to execute.
/// A which can be used to cancel the asynchronous operation.
/// A of strings, each representing a line of output from the command.
+ [MethodImpl((MethodImplOptions)0x100)]
public static IAsyncEnumerable ExecuteServerEnumerableAsync(this IAdbClient client, string target, string command, CancellationToken cancellationToken = default) =>
client.ExecuteServerEnumerableAsync(target, command, AdbClient.Encoding, cancellationToken);
@@ -233,6 +249,7 @@ public static IAsyncEnumerable ExecuteServerEnumerableAsync(this IAdbCli
/// The to send command.
/// A which can be used to cancel the asynchronous operation.
/// A of strings, each representing a line of output from the command.
+ [MethodImpl((MethodImplOptions)0x100)]
public static IAsyncEnumerable ExecuteServerEnumerableAsync(this IAdbClient client, string target, string command, IAdbSocket socket, CancellationToken cancellationToken = default) =>
client.ExecuteServerEnumerableAsync(target, command, socket, AdbClient.Encoding, cancellationToken);
@@ -244,6 +261,7 @@ public static IAsyncEnumerable ExecuteServerEnumerableAsync(this IAdbCli
/// The device on which to run the command.
/// A which can be used to cancel the asynchronous operation.
/// A of strings, each representing a line of output from the command.
+ [MethodImpl((MethodImplOptions)0x100)]
public static IAsyncEnumerable ExecuteRemoteEnumerableAsync(this IAdbClient client, string command, DeviceData device, CancellationToken cancellationToken = default) =>
client.ExecuteRemoteEnumerableAsync(command, device, AdbClient.Encoding, cancellationToken);
@@ -254,6 +272,7 @@ public static IAsyncEnumerable ExecuteRemoteEnumerableAsync(this IAdbCli
/// The device on which to run the event log service.
/// Optionally, the names of the logs to receive.
/// A which contains the log entries.
+ [MethodImpl((MethodImplOptions)0x100)]
public static IAsyncEnumerable RunLogServiceAsync(this IAdbClient client, DeviceData device, params LogId[] logNames) =>
client.RunLogServiceAsync(device, default, logNames);
#endif
@@ -266,6 +285,7 @@ public static IAsyncEnumerable RunLogServiceAsync(this IAdbClient clie
/// A callback which will receive the event log messages as they are received.
/// Optionally, the names of the logs to receive.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task RunLogServiceAsync(this IAdbClient client, DeviceData device, Action messageSink, params LogId[] logNames) =>
client.RunLogServiceAsync(device, messageSink, default, logNames);
@@ -276,6 +296,7 @@ public static Task RunLogServiceAsync(this IAdbClient client, DeviceData device,
/// The device.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task RebootAsync(this IAdbClient client, DeviceData device, CancellationToken cancellationToken = default) => client.RebootAsync(string.Empty, device, cancellationToken);
///
@@ -286,6 +307,7 @@ public static Task RunLogServiceAsync(this IAdbClient client, DeviceData device,
/// The pairing code.
/// A which can be used to cancel the asynchronous operation.
/// The results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task PairAsync(this IAdbClient client, IPAddress address, string code, CancellationToken cancellationToken = default) =>
address == null
? throw new ArgumentNullException(nameof(address))
@@ -299,6 +321,7 @@ public static Task PairAsync(this IAdbClient client, IPAddress address,
/// The pairing code.
/// A which can be used to cancel the asynchronous operation.
/// The results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task PairAsync(this IAdbClient client, IPEndPoint endpoint, string code, CancellationToken cancellationToken = default) =>
endpoint == null
? throw new ArgumentNullException(nameof(endpoint))
@@ -312,6 +335,7 @@ public static Task PairAsync(this IAdbClient client, IPEndPoint endpoint
/// The pairing code.
/// A which can be used to cancel the asynchronous operation.
/// The results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task PairAsync(this IAdbClient client, string host, string code, CancellationToken cancellationToken = default) =>
client.PairAsync(host, AdbClient.DefaultPort, code, cancellationToken);
@@ -322,6 +346,7 @@ public static Task PairAsync(this IAdbClient client, string host, string
/// The IP address of the remote device.
/// A which can be used to cancel the asynchronous operation.
/// A which returns the results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ConnectAsync(this IAdbClient client, IPAddress address, CancellationToken cancellationToken = default) =>
address == null
? throw new ArgumentNullException(nameof(address))
@@ -334,6 +359,7 @@ public static Task ConnectAsync(this IAdbClient client, IPAddress addres
/// The IP endpoint at which the adb server on the device is running.
/// A which can be used to cancel the asynchronous operation.
/// A which returns the results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ConnectAsync(this IAdbClient client, IPEndPoint endpoint, CancellationToken cancellationToken = default) =>
endpoint == null
? throw new ArgumentNullException(nameof(endpoint))
@@ -346,6 +372,7 @@ public static Task ConnectAsync(this IAdbClient client, IPEndPoint endpo
/// The host address of the remote device.
/// A which can be used to cancel the asynchronous operation.
/// The results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ConnectAsync(this IAdbClient client, string host, CancellationToken cancellationToken = default) =>
client.ConnectAsync(host, AdbClient.DefaultPort, cancellationToken);
@@ -356,6 +383,7 @@ public static Task ConnectAsync(this IAdbClient client, string host, Can
/// The IP address of the remote device.
/// A which can be used to cancel the asynchronous operation.
/// A which returns the results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task DisconnectAsync(this IAdbClient client, IPAddress address, CancellationToken cancellationToken = default) =>
address == null
? throw new ArgumentNullException(nameof(address))
@@ -368,6 +396,7 @@ public static Task DisconnectAsync(this IAdbClient client, IPAddress add
/// The IP endpoint at which the adb server on the device is running.
/// A which can be used to cancel the asynchronous operation.
/// A which returns the results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task DisconnectAsync(this IAdbClient client, IPEndPoint endpoint, CancellationToken cancellationToken = default) =>
endpoint == null
? throw new ArgumentNullException(nameof(endpoint))
@@ -380,6 +409,7 @@ public static Task DisconnectAsync(this IAdbClient client, IPEndPoint en
/// The host address of the remote device.
/// A which can be used to cancel the asynchronous operation.
/// The results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task DisconnectAsync(this IAdbClient client, string host, CancellationToken cancellationToken = default) =>
client.DisconnectAsync(host, AdbClient.DefaultPort, cancellationToken);
@@ -392,6 +422,7 @@ public static Task DisconnectAsync(this IAdbClient client, string host,
/// A callback which will receive the event log messages as they are received.
/// Optionally, the names of the logs to receive.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task RunLogServiceAsync(this IAdbClient client, DeviceData device, IProgress progress, params LogId[] logNames) =>
client.RunLogServiceAsync(device, progress.Report, default, logNames);
@@ -404,6 +435,7 @@ public static Task RunLogServiceAsync(this IAdbClient client, DeviceData device,
/// A which can be used to cancel the asynchronous operation.
/// Optionally, the names of the logs to receive.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task RunLogServiceAsync(this IAdbClient client, DeviceData device, IProgress progress, CancellationToken cancellationToken, params LogId[] logNames) =>
client.RunLogServiceAsync(device, progress.Report, cancellationToken, logNames);
@@ -418,6 +450,7 @@ public static Task RunLogServiceAsync(this IAdbClient client, DeviceData device,
/// A which can be used to cancel the asynchronous operation.
/// The arguments to pass to adb install.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task InstallAsync(this IAdbClient client, DeviceData device, Stream apk, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
client.InstallAsync(device, apk, progress.AsAction(), cancellationToken, arguments);
@@ -433,6 +466,7 @@ public static Task InstallAsync(this IAdbClient client, DeviceData device, Strea
/// A which can be used to cancel the asynchronous operation.
/// The arguments to pass to adb install-create.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task InstallMultipleAsync(this IAdbClient client, DeviceData device, Stream baseAPK, IEnumerable splitAPKs, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
client.InstallMultipleAsync(device, baseAPK, splitAPKs, progress.AsAction(), cancellationToken, arguments);
@@ -448,6 +482,7 @@ public static Task InstallMultipleAsync(this IAdbClient client, DeviceData devic
/// A which can be used to cancel the asynchronous operation.
/// The arguments to pass to adb install-create.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task InstallMultipleAsync(this IAdbClient client, DeviceData device, IEnumerable splitAPKs, string packageName, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
client.InstallMultipleAsync(device, splitAPKs, packageName, progress.AsAction(), cancellationToken, arguments);
@@ -463,6 +498,7 @@ public static Task InstallMultipleAsync(this IAdbClient client, DeviceData devic
/// The progress is reported as a value between 0 and 100, representing the percentage of the apk which has been transferred.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task InstallWriteAsync(this IAdbClient client, DeviceData device, Stream apk, string apkName, string session, IProgress? progress = null, CancellationToken cancellationToken = default) =>
client.InstallWriteAsync(device, apk, apkName, session, progress.AsAction(), cancellationToken);
@@ -474,6 +510,7 @@ public static Task InstallWriteAsync(this IAdbClient client, DeviceData device,
/// The pairing code.
/// A which can be used to cancel the asynchronous operation.
/// The results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task PairAsync(this IAdbClient client, DnsEndPoint endpoint, string code, CancellationToken cancellationToken = default) =>
endpoint == null
? throw new ArgumentNullException(nameof(endpoint))
@@ -486,6 +523,7 @@ public static Task PairAsync(this IAdbClient client, DnsEndPoint endpoin
/// The DNS endpoint at which the adb server on the device is running.
/// A which can be used to cancel the asynchronous operation.
/// A which returns the results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ConnectAsync(this IAdbClient client, DnsEndPoint endpoint, CancellationToken cancellationToken = default) =>
endpoint == null
? throw new ArgumentNullException(nameof(endpoint))
@@ -498,6 +536,7 @@ public static Task ConnectAsync(this IAdbClient client, DnsEndPoint endp
/// The DNS endpoint at which the adb server on the device is running.
/// A which can be used to cancel the asynchronous operation.
/// A which returns the results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task DisconnectAsync(this IAdbClient client, DnsEndPoint endpoint, CancellationToken cancellationToken = default) =>
endpoint == null
? throw new ArgumentNullException(nameof(endpoint))
@@ -515,6 +554,7 @@ public static Task DisconnectAsync(this IAdbClient client, DnsEndPoint e
/// A which can be used to cancel the asynchronous operation.
/// The arguments to pass to adb install.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task InstallAsync(this IAdbClient.IWinRT client, DeviceData device, IRandomAccessStream apk, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
client.InstallAsync(device, apk, progress.AsAction(), cancellationToken, arguments);
@@ -530,6 +570,7 @@ public static Task InstallAsync(this IAdbClient.IWinRT client, DeviceData device
/// A which can be used to cancel the asynchronous operation.
/// The arguments to pass to adb install-create.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task InstallMultipleAsync(this IAdbClient.IWinRT client, DeviceData device, IRandomAccessStream baseAPK, IEnumerable splitAPKs, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
client.InstallMultipleAsync(device, baseAPK, splitAPKs, progress.AsAction(), cancellationToken, arguments);
@@ -545,6 +586,7 @@ public static Task InstallMultipleAsync(this IAdbClient.IWinRT client, DeviceDat
/// A which can be used to cancel the asynchronous operation.
/// The arguments to pass to adb install-create.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task InstallMultipleAsync(this IAdbClient.IWinRT client, DeviceData device, IEnumerable splitAPKs, string packageName, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) =>
client.InstallMultipleAsync(device, splitAPKs, packageName, progress.AsAction(), cancellationToken, arguments);
@@ -560,6 +602,7 @@ public static Task InstallMultipleAsync(this IAdbClient.IWinRT client, DeviceDat
/// The progress is reported as a value between 0 and 100, representing the percentage of the apk which has been transferred.
/// A which can be used to cancel the asynchronous operation.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task InstallWriteAsync(this IAdbClient.IWinRT client, DeviceData device, IRandomAccessStream apk, string apkName, string session, IProgress? progress = null, CancellationToken cancellationToken = default) =>
client.InstallWriteAsync(device, apk, apkName, session, progress.AsAction(), cancellationToken);
#endif
@@ -573,6 +616,7 @@ public static Task InstallWriteAsync(this IAdbClient.IWinRT client, DeviceData d
/// The device on which to install the application.
/// The arguments to pass to adb install-create.
/// A which returns the session ID
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task InstallCreateAsync(this IAdbClient client, DeviceData device, params string[] arguments) =>
client.InstallCreateAsync(device, default, arguments);
@@ -585,6 +629,7 @@ public static Task InstallCreateAsync(this IAdbClient client, DeviceData
/// The package name of the baseAPK to install.
/// The arguments to pass to adb install-create.
/// A which returns the session ID
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task InstallCreateAsync(this IAdbClient client, DeviceData device, string packageName, params string[] arguments) =>
client.InstallCreateAsync(device, packageName, default, arguments);
@@ -596,6 +641,7 @@ public static Task InstallCreateAsync(this IAdbClient client, DeviceData
/// The name of the package to uninstall.
/// The arguments to pass to adb uninstall.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task UninstallAsync(this IAdbClient client, DeviceData device, string packageName, params string[] arguments) =>
client.UninstallAsync(device, packageName, default, arguments);
}
diff --git a/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.cs b/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.cs
index dfbab01..cda264e 100644
--- a/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.cs
+++ b/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.cs
@@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.IO;
using System.Net;
+using System.Runtime.CompilerServices;
using System.Text;
namespace AdvancedSharpAdbClient
@@ -27,6 +28,7 @@ public static partial class AdbClientExtensions
/// connection from .
/// If your requested to start forwarding to local port TCP:0, the port number of the TCP port
/// which has been opened. In all other cases, 0.
+ [MethodImpl((MethodImplOptions)0x100)]
public static int CreateForward(this IAdbClient client, DeviceData device, ForwardSpec local, ForwardSpec remote, bool allowRebind) =>
client.CreateForward(device, local.ToString(), remote.ToString(), allowRebind);
@@ -40,6 +42,7 @@ public static int CreateForward(this IAdbClient client, DeviceData device, Forwa
/// If your requested to start forwarding to local port TCP:0, the port number of the TCP port
/// which has been opened. In all other cases, 0.
/// Failed to submit the forward command. Or Device rejected command: + resp.Message.
+ [MethodImpl((MethodImplOptions)0x100)]
public static int CreateForward(this IAdbClient client, DeviceData device, int localPort, int remotePort) =>
client.CreateForward(device, $"tcp:{localPort}", $"tcp:{remotePort}", true);
@@ -54,6 +57,7 @@ public static int CreateForward(this IAdbClient client, DeviceData device, int l
/// which has been opened. In all other cases, 0.
/// The client failed to submit the forward command.
/// The device rejected command. The error message will include the error message provided by the device.
+ [MethodImpl((MethodImplOptions)0x100)]
public static int CreateForward(this IAdbClient client, DeviceData device, int localPort, string remoteSocket) =>
client.CreateForward(device, $"tcp:{localPort}", $"local:{remoteSocket}", true);
@@ -69,6 +73,7 @@ public static int CreateForward(this IAdbClient client, DeviceData device, int l
/// is already bound through a previous reverse command.
/// If your requested to start reverse to remote port TCP:0, the port number of the TCP port
/// which has been opened. In all other cases, 0.
+ [MethodImpl((MethodImplOptions)0x100)]
public static int CreateReverseForward(this IAdbClient client, DeviceData device, ForwardSpec remote, ForwardSpec local, bool allowRebind) =>
client.CreateReverseForward(device, remote.ToString(), local.ToString(), allowRebind);
@@ -78,6 +83,7 @@ public static int CreateReverseForward(this IAdbClient client, DeviceData device
/// An instance of a class that implements the interface.
/// The device on which to remove the reverse port forwarding
/// Specification of the remote that was forwarded
+ [MethodImpl((MethodImplOptions)0x100)]
public static void RemoveReverseForward(this IAdbClient client, DeviceData device, ForwardSpec remote) =>
client.RemoveReverseForward(device, remote.ToString());
@@ -89,6 +95,7 @@ public static void RemoveReverseForward(this IAdbClient client, DeviceData devic
/// localreserved, localabstract, jdwp, track-jdwp, sync, reverse and so on.
/// The command to execute.
/// Optionally, a that processes the command output.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void ExecuteServerCommand(this IAdbClient client, string target, string command, IShellOutputReceiver? receiver) =>
client.ExecuteServerCommand(target, command, receiver, AdbClient.Encoding);
@@ -101,6 +108,7 @@ public static void ExecuteServerCommand(this IAdbClient client, string target, s
/// The command to execute.
/// The to send command.
/// Optionally, a that processes the command output.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void ExecuteServerCommand(this IAdbClient client, string target, string command, IAdbSocket socket, IShellOutputReceiver? receiver) =>
client.ExecuteServerCommand(target, command, socket, receiver, AdbClient.Encoding);
@@ -111,6 +119,7 @@ public static void ExecuteServerCommand(this IAdbClient client, string target, s
/// The command to execute.
/// The device on which to run the command.
/// Optionally, a that processes the command output.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void ExecuteRemoteCommand(this IAdbClient client, string command, DeviceData device, IShellOutputReceiver? receiver) =>
client.ExecuteRemoteCommand(command, device, receiver, AdbClient.Encoding);
@@ -122,6 +131,7 @@ public static void ExecuteRemoteCommand(this IAdbClient client, string command,
/// localreserved, localabstract, jdwp, track-jdwp, sync, reverse and so on.
/// The command to execute.
/// Optionally, a that processes the command output.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void ExecuteServerCommand(this IAdbClient client, string target, string command, Func? predicate) =>
client.ExecuteServerCommand(target, command, predicate.AsShellOutputReceiver(), AdbClient.Encoding);
@@ -134,6 +144,7 @@ public static void ExecuteServerCommand(this IAdbClient client, string target, s
/// The command to execute.
/// The to send command.
/// Optionally, a that processes the command output.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void ExecuteServerCommand(this IAdbClient client, string target, string command, IAdbSocket socket, Func? predicate) =>
client.ExecuteServerCommand(target, command, socket, predicate.AsShellOutputReceiver(), AdbClient.Encoding);
@@ -144,6 +155,7 @@ public static void ExecuteServerCommand(this IAdbClient client, string target, s
/// The command to execute.
/// The device on which to run the command.
/// Optionally, a that processes the command output.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void ExecuteRemoteCommand(this IAdbClient client, string command, DeviceData device, Func? predicate) =>
client.ExecuteRemoteCommand(command, device, predicate.AsShellOutputReceiver(), AdbClient.Encoding);
@@ -156,6 +168,7 @@ public static void ExecuteRemoteCommand(this IAdbClient client, string command,
/// The command to execute.
/// Optionally, a that processes the command output.
/// The encoding to use when parsing the command output.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void ExecuteServerCommand(this IAdbClient client, string target, string command, Func? predicate, Encoding encoding) =>
client.ExecuteServerCommand(target, command, predicate.AsShellOutputReceiver(), encoding);
@@ -169,6 +182,7 @@ public static void ExecuteServerCommand(this IAdbClient client, string target, s
/// The to send command.
/// Optionally, a that processes the command output.
/// The encoding to use when parsing the command output.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void ExecuteServerCommand(this IAdbClient client, string target, string command, IAdbSocket socket, Func? predicate, Encoding encoding) =>
client.ExecuteServerCommand(target, command, socket, predicate.AsShellOutputReceiver(), encoding);
@@ -180,6 +194,7 @@ public static void ExecuteServerCommand(this IAdbClient client, string target, s
/// The device on which to run the command.
/// Optionally, a that processes the command output.
/// The encoding to use when parsing the command output.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void ExecuteRemoteCommand(this IAdbClient client, string command, DeviceData device, Func? predicate, Encoding encoding) =>
client.ExecuteRemoteCommand(command, device, predicate.AsShellOutputReceiver(), encoding);
@@ -191,6 +206,7 @@ public static void ExecuteRemoteCommand(this IAdbClient client, string command,
/// localreserved, localabstract, jdwp, track-jdwp, sync, reverse and so on.
/// The command to execute.
/// A of strings, each representing a line of output from the command.
+ [MethodImpl((MethodImplOptions)0x100)]
public static IEnumerable ExecuteServerEnumerable(this IAdbClient client, string target, string command) =>
client.ExecuteServerEnumerable(target, command, AdbClient.Encoding);
@@ -203,6 +219,7 @@ public static IEnumerable ExecuteServerEnumerable(this IAdbClient client
/// The command to execute.
/// The to send command.
/// A of strings, each representing a line of output from the command.
+ [MethodImpl((MethodImplOptions)0x100)]
public static IEnumerable ExecuteServerEnumerable(this IAdbClient client, string target, string command, IAdbSocket socket) =>
client.ExecuteServerEnumerable(target, command, socket, AdbClient.Encoding);
@@ -213,6 +230,7 @@ public static IEnumerable ExecuteServerEnumerable(this IAdbClient client
/// The command to execute.
/// The device on which to run the command.
/// A of strings, each representing a line of output from the command.
+ [MethodImpl((MethodImplOptions)0x100)]
public static IEnumerable ExecuteRemoteEnumerable(this IAdbClient client, string command, DeviceData device) =>
client.ExecuteRemoteEnumerable(command, device, AdbClient.Encoding);
@@ -223,6 +241,7 @@ public static IEnumerable ExecuteRemoteEnumerable(this IAdbClient client
/// The device on which to run the event log service.
/// A callback which will receive the event log messages as they are received.
/// Optionally, the names of the logs to receive.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void RunLogService(this IAdbClient client, DeviceData device, Action messageSink, params LogId[] logNames) =>
client.RunLogService(device, messageSink, false, logNames);
@@ -231,6 +250,7 @@ public static void RunLogService(this IAdbClient client, DeviceData device, Acti
///
/// An instance of a class that implements the interface.
/// The device.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void Reboot(this IAdbClient client, DeviceData device) => client.Reboot(string.Empty, device);
///
@@ -240,6 +260,7 @@ public static void RunLogService(this IAdbClient client, DeviceData device, Acti
/// The IP address of the remote device.
/// The pairing code.
/// The results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static string Pair(this IAdbClient client, IPAddress address, string code) =>
address == null
? throw new ArgumentNullException(nameof(address))
@@ -252,6 +273,7 @@ public static string Pair(this IAdbClient client, IPAddress address, string code
/// The DNS endpoint at which the adb server on the device is running.
/// The pairing code.
/// The results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static string Pair(this IAdbClient client, IPEndPoint endpoint, string code) =>
endpoint == null
? throw new ArgumentNullException(nameof(endpoint))
@@ -264,6 +286,7 @@ public static string Pair(this IAdbClient client, IPEndPoint endpoint, string co
/// The host address of the remote device.
/// The pairing code.
/// The results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static string Pair(this IAdbClient client, string host, string code) =>
client.Pair(host, AdbClient.DefaultPort, code);
@@ -273,6 +296,7 @@ public static string Pair(this IAdbClient client, string host, string code) =>
/// An instance of a class that implements the interface.
/// The IP address of the remote device.
/// The results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static string Connect(this IAdbClient client, IPAddress address) =>
address == null
? throw new ArgumentNullException(nameof(address))
@@ -284,6 +308,7 @@ public static string Connect(this IAdbClient client, IPAddress address) =>
/// An instance of a class that implements the interface.
/// The IP endpoint at which the adb server on the device is running.
/// The results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static string Connect(this IAdbClient client, IPEndPoint endpoint) =>
endpoint == null
? throw new ArgumentNullException(nameof(endpoint))
@@ -295,6 +320,7 @@ public static string Connect(this IAdbClient client, IPEndPoint endpoint) =>
/// An instance of a class that implements the interface.
/// The host address of the remote device.
/// The results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static string Connect(this IAdbClient client, string host) =>
client.Connect(host, AdbClient.DefaultPort);
@@ -304,6 +330,7 @@ public static string Connect(this IAdbClient client, string host) =>
/// An instance of a class that implements the interface.
/// The IP address of the remote device.
/// The results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static string Disconnect(this IAdbClient client, IPAddress address) =>
address == null
? throw new ArgumentNullException(nameof(address))
@@ -315,6 +342,7 @@ public static string Disconnect(this IAdbClient client, IPAddress address) =>
/// An instance of a class that implements the interface.
/// The IP endpoint at which the adb server on the device is running.
/// The results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static string Disconnect(this IAdbClient client, IPEndPoint endpoint) =>
endpoint == null
? throw new ArgumentNullException(nameof(endpoint))
@@ -326,6 +354,7 @@ public static string Disconnect(this IAdbClient client, IPEndPoint endpoint) =>
/// An instance of a class that implements the interface.
/// The host address of the remote device.
/// The results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static string Disconnect(this IAdbClient client, string host) =>
client.Disconnect(host, AdbClient.DefaultPort);
@@ -335,6 +364,7 @@ public static string Disconnect(this IAdbClient client, string host) =>
/// An instance of a class that implements the interface.
/// The device on which to process command.
/// A new instance of the class.
+ [MethodImpl((MethodImplOptions)0x100)]
public static DeviceClient CreateDeviceClient(this IAdbClient client, DeviceData device) => new(client, device);
///
@@ -344,6 +374,7 @@ public static string Disconnect(this IAdbClient client, string host) =>
/// The device on which to look for packages.
/// The arguments to pass to pm list packages.
/// A new instance of the class.
+ [MethodImpl((MethodImplOptions)0x100)]
public static PackageManager CreatePackageManager(this IAdbClient client, DeviceData device, params string[] arguments) => new(client, device, arguments);
#if !NETFRAMEWORK || NET40_OR_GREATER
@@ -354,6 +385,7 @@ public static string Disconnect(this IAdbClient client, string host) =>
/// The device on which to run the event log service.
/// A callback which will receive the event log messages as they are received.
/// Optionally, the names of the logs to receive.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void RunLogService(this IAdbClient client, DeviceData device, IProgress progress, params LogId[] logNames) =>
client.RunLogService(device, progress, false, logNames);
@@ -365,7 +397,8 @@ public static void RunLogService(this IAdbClient client, DeviceData device, IPro
/// A callback which will receive the event log messages as they are received.
/// A that can be used to cancel the task.
/// Optionally, the names of the logs to receive.
- public static void RunLogService(this IAdbClient client, DeviceData device, IProgress progress, in bool isCancelled, params LogId[] logNames) =>
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void RunLogService(this IAdbClient client, DeviceData device, IProgress progress, scoped in bool isCancelled, params LogId[] logNames) =>
client.RunLogService(device, progress.Report, isCancelled, logNames);
///
@@ -377,6 +410,7 @@ public static void RunLogService(this IAdbClient client, DeviceData device, IPro
/// An optional parameter which, when specified, returns progress notifications.
/// The progress is reported as , representing the state of installation.
/// The arguments to pass to adb install.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void Install(this IAdbClient client, DeviceData device, Stream apk, IProgress? progress = null, params string[] arguments) =>
client.Install(device, apk, progress.AsAction(), arguments);
@@ -390,6 +424,7 @@ public static void Install(this IAdbClient client, DeviceData device, Stream apk
/// An optional parameter which, when specified, returns progress notifications.
/// The progress is reported as , representing the state of installation.
/// The arguments to pass to adb install-create.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void InstallMultiple(this IAdbClient client, DeviceData device, Stream baseAPK, IEnumerable splitAPKs, IProgress? progress = null, params string[] arguments) =>
client.InstallMultiple(device, baseAPK, splitAPKs, progress.AsAction(), arguments);
@@ -403,6 +438,7 @@ public static void InstallMultiple(this IAdbClient client, DeviceData device, St
/// An optional parameter which, when specified, returns progress notifications.
/// The progress is reported as , representing the state of installation.
/// The arguments to pass to adb install-create.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void InstallMultiple(this IAdbClient client, DeviceData device, IEnumerable splitAPKs, string packageName, IProgress? progress = null, params string[] arguments) =>
client.InstallMultiple(device, splitAPKs, packageName, progress.AsAction(), arguments);
@@ -416,6 +452,7 @@ public static void InstallMultiple(this IAdbClient client, DeviceData device, IE
/// The session ID of the install session.
/// An optional parameter which, when specified, returns progress notifications.
/// The progress is reported as a value between 0 and 100, representing the percentage of the apk which has been transferred.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void InstallWrite(this IAdbClient client, DeviceData device, Stream apk, string apkName, string session, IProgress? progress) =>
client.InstallWrite(device, apk, apkName, session, progress.AsAction());
@@ -426,6 +463,7 @@ public static void InstallWrite(this IAdbClient client, DeviceData device, Strea
/// The DNS endpoint at which the adb server on the device is running.
/// The pairing code.
/// The results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static string Pair(this IAdbClient client, DnsEndPoint endpoint, string code) =>
endpoint == null
? throw new ArgumentNullException(nameof(endpoint))
@@ -437,6 +475,7 @@ public static string Pair(this IAdbClient client, DnsEndPoint endpoint, string c
/// An instance of a class that implements the interface.
/// The DNS endpoint at which the adb server on the device is running.
/// The results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static string Connect(this IAdbClient client, DnsEndPoint endpoint) =>
endpoint == null
? throw new ArgumentNullException(nameof(endpoint))
@@ -448,6 +487,7 @@ public static string Connect(this IAdbClient client, DnsEndPoint endpoint) =>
/// An instance of a class that implements the interface.
/// The DNS endpoint at which the adb server on the device is running.
/// The results from adb.
+ [MethodImpl((MethodImplOptions)0x100)]
public static string Disconnect(this IAdbClient client, DnsEndPoint endpoint) =>
endpoint == null
? throw new ArgumentNullException(nameof(endpoint))
diff --git a/AdvancedSharpAdbClient/Extensions/EnumerableBuilder.cs b/AdvancedSharpAdbClient/Extensions/EnumerableBuilder.cs
index d6e934d..45eebcc 100644
--- a/AdvancedSharpAdbClient/Extensions/EnumerableBuilder.cs
+++ b/AdvancedSharpAdbClient/Extensions/EnumerableBuilder.cs
@@ -23,7 +23,8 @@ public static class EnumerableBuilder
///
/// The data that feeds the struct.
/// A new instance of struct.
- public static AdbCommandLineStatus AdbCommandLineStatusCreator(params ReadOnlySpan values) =>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static AdbCommandLineStatus AdbCommandLineStatusCreator(params scoped ReadOnlySpan values) =>
AdbCommandLineStatus.GetVersionFromOutput(values);
///
@@ -31,42 +32,47 @@ public static AdbCommandLineStatus AdbCommandLineStatusCreator(params ReadOnlySp
///
/// The data that feeds the struct.
/// A new instance of struct.
- public static unsafe ColorData ColorDataCreator(ReadOnlySpan values) => Unsafe.As(ref MemoryMarshal.GetReference(values));
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ColorData ColorDataCreator(scoped ReadOnlySpan values) => Unsafe.As(ref MemoryMarshal.GetReference(values));
///
/// Build a struct.
///
/// The data that feeds the struct.
/// A new instance of struct.
- public static FramebufferHeader FramebufferHeaderCreator(ReadOnlySpan values) => new(values);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static FramebufferHeader FramebufferHeaderCreator(scoped ReadOnlySpan values) => new(values);
///
/// Build a struct.
///
/// The data that feeds the struct.
/// A new instance of struct.
- public static unsafe FileStatisticsData FileStatisticsDataCreator(ReadOnlySpan values) => Unsafe.As(ref MemoryMarshal.GetReference(values));
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static FileStatisticsData FileStatisticsDataCreator(scoped ReadOnlySpan values) => Unsafe.As(ref MemoryMarshal.GetReference(values));
///
/// Build a struct.
///
/// The data that feeds the struct.
/// A new instance of struct.
- public static unsafe FileStatisticsDataEx FileStatisticsDataV2Creator(ReadOnlySpan values) => Unsafe.As(ref MemoryMarshal.GetReference(values));
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static FileStatisticsDataEx FileStatisticsDataV2Creator(scoped ReadOnlySpan values) => Unsafe.As(ref MemoryMarshal.GetReference(values));
///
/// Build a enum.
///
/// The data that feeds the struct.
/// A new instance of struct.
- public static unsafe UnixFileStatus UnixFileStatusCreator(ReadOnlySpan values) => (UnixFileStatus)BitConverter.ToUInt32(values);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static UnixFileStatus UnixFileStatusCreator(scoped ReadOnlySpan values) => (UnixFileStatus)BitConverter.ToUInt32(values);
///
/// Build a class.
///
/// The data that feeds the struct.
/// A new instance of struct.
- public static LogEntry? LogEntryCreator(ReadOnlySpan values)
+ public static LogEntry? LogEntryCreator(scoped ReadOnlySpan values)
{
if (values.IsEmpty) { return null; }
int index = 0;
@@ -140,7 +146,7 @@ public static AdbCommandLineStatus AdbCommandLineStatusCreator(params ReadOnlySp
}
}
- ReadOnlySpan data = ReadBytesSafe(values, payloadLength);
+ scoped ReadOnlySpan data = ReadBytesSafe(values, payloadLength);
if (data.IsEmpty)
{
@@ -269,25 +275,25 @@ static void ReadLogEntry(BinaryReader reader, params ICollection
/// The function to call for each line of output
/// The created from the specified function.
+ [MethodImpl((MethodImplOptions)0x100)]
[return: NotNullIfNotNull(nameof(predicate))]
public static IShellOutputReceiver? AsShellOutputReceiver(this Func? predicate) =>
- predicate == null ? null! : new FunctionOutputReceiver(predicate);
+ predicate == null ? null : new FunctionOutputReceiver(predicate);
#if HAS_TASK
#if !NET7_0_OR_GREATER
@@ -107,12 +108,14 @@ public static Task ReadToEndAsync(this TextReader reader, CancellationTo
/// Closes the connection and releases all associated resources.
///
/// The to release.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void Close(this Socket socket) => socket.Dispose();
///
/// Closes the and releases any system resources associated with the .
///
/// The to release.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void Close(this TextReader reader) => reader.Dispose();
#else
#if HAS_TASK && !NET5_0_OR_GREATER
@@ -124,6 +127,7 @@ public static Task ReadToEndAsync(this TextReader reader, CancellationTo
/// An optional token to cancel the asynchronous operation.
/// A task that will complete when the process has exited, cancellation has been requested,
/// or an error occurs.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task WaitForExitAsync(this Process process, CancellationToken cancellationToken = default) =>
Task.Run(process.WaitForExit, cancellationToken);
#endif
@@ -156,9 +160,9 @@ public static void Dispose(this WaitHandle waitHandle)
/// The type of progress update value.
/// The to convert.
/// The created from the specified .
+ [MethodImpl((MethodImplOptions)0x100)]
[return: NotNullIfNotNull(nameof(progress))]
- public static Action? AsAction(this IProgress? progress) =>
- progress == null ? null : progress.Report;
+ public static Action? AsAction(this IProgress? progress) => progress == null ? null : progress.Report;
#endif
#if HAS_WINRT
@@ -183,6 +187,7 @@ public static string GetFullPath(string path) =>
///
/// The socket to use.
/// The request to send.
+ [MethodImpl((MethodImplOptions)0x100)]
public static void SendAdbRequest(this IAdbSocket socket, scoped in DefaultInterpolatedStringHandler request) => socket.SendAdbRequest(request.ToString());
}
}
diff --git a/AdvancedSharpAdbClient/Extensions/LoggerExtensions.cs b/AdvancedSharpAdbClient/Extensions/LoggerExtensions.cs
index 0a39c61..807c200 100644
--- a/AdvancedSharpAdbClient/Extensions/LoggerExtensions.cs
+++ b/AdvancedSharpAdbClient/Extensions/LoggerExtensions.cs
@@ -3,6 +3,8 @@
//
using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
namespace AdvancedSharpAdbClient.Logs
{
@@ -21,7 +23,8 @@ public static class LoggerExtensions
/// Format string of the log message in message template format. Example: "User {User} logged in from {Address}"
/// An object array that contains zero or more objects to format.
/// logger.LogDebug(exception, "Error while processing request from {Address}", address)
- public static void LogDebug(this ILogger logger, Exception? exception, string? message, params object?[] args) =>
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void LogDebug(this ILogger logger, Exception? exception, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[] args) =>
logger.Log(LogLevel.Debug, exception, message, args);
///
@@ -31,7 +34,8 @@ public static void LogDebug(this ILogger logger, Exception? exception, string? m
/// Format string of the log message in message template format. Example: "User {User} logged in from {Address}"
/// An object array that contains zero or more objects to format.
/// logger.LogDebug("Processing request from {Address}", address)
- public static void LogDebug(this ILogger logger, string? message, params object?[] args) =>
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void LogDebug(this ILogger logger, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[] args) =>
logger.Log(LogLevel.Debug, message, args);
//------------------------------------------TRACE------------------------------------------//
@@ -44,7 +48,8 @@ public static void LogDebug(this ILogger logger, string? message, params object?
/// Format string of the log message in message template format. Example: "User {User} logged in from {Address}"
/// An object array that contains zero or more objects to format.
/// logger.LogTrace(exception, "Error while processing request from {Address}", address)
- public static void LogTrace(this ILogger logger, Exception? exception, string? message, params object?[] args) =>
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void LogTrace(this ILogger logger, Exception? exception, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[] args) =>
logger.Log(LogLevel.Trace, exception, message, args);
///
@@ -54,7 +59,8 @@ public static void LogTrace(this ILogger logger, Exception? exception, string? m
/// Format string of the log message in message template format. Example: "User {User} logged in from {Address}"
/// An object array that contains zero or more objects to format.
/// logger.LogTrace("Processing request from {Address}", address)
- public static void LogTrace(this ILogger logger, string? message, params object?[] args) =>
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void LogTrace(this ILogger logger, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[] args) =>
logger.Log(LogLevel.Trace, message, args);
//------------------------------------------INFORMATION------------------------------------------//
@@ -67,7 +73,8 @@ public static void LogTrace(this ILogger logger, string? message, params object?
/// Format string of the log message in message template format. Example: "User {User} logged in from {Address}"
/// An object array that contains zero or more objects to format.
/// logger.LogInformation(exception, "Error while processing request from {Address}", address)
- public static void LogInformation(this ILogger logger, Exception? exception, string? message, params object?[] args) =>
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void LogInformation(this ILogger logger, Exception? exception, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[] args) =>
logger.Log(LogLevel.Information, exception, message, args);
///
@@ -77,7 +84,8 @@ public static void LogInformation(this ILogger logger, Exception? exception, str
/// Format string of the log message in message template format. Example: "User {User} logged in from {Address}"
/// An object array that contains zero or more objects to format.
/// logger.LogInformation("Processing request from {Address}", address)
- public static void LogInformation(this ILogger logger, string? message, params object?[] args) =>
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void LogInformation(this ILogger logger, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[] args) =>
logger.Log(LogLevel.Information, message, args);
//------------------------------------------WARNING------------------------------------------//
@@ -90,7 +98,8 @@ public static void LogInformation(this ILogger logger, string? message, params o
/// Format string of the log message in message template format. Example: "User {User} logged in from {Address}"
/// An object array that contains zero or more objects to format.
/// logger.LogWarning(exception, "Error while processing request from {Address}", address)
- public static void LogWarning(this ILogger logger, Exception? exception, string? message, params object?[] args) =>
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void LogWarning(this ILogger logger, Exception? exception, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[] args) =>
logger.Log(LogLevel.Warning, exception, message, args);
///
@@ -100,7 +109,8 @@ public static void LogWarning(this ILogger logger, Exception? exception, string?
/// Format string of the log message in message template format. Example: "User {User} logged in from {Address}"
/// An object array that contains zero or more objects to format.
/// logger.LogWarning("Processing request from {Address}", address)
- public static void LogWarning(this ILogger logger, string? message, params object?[] args) =>
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void LogWarning(this ILogger logger, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[] args) =>
logger.Log(LogLevel.Warning, message, args);
//------------------------------------------ERROR------------------------------------------//
@@ -113,7 +123,8 @@ public static void LogWarning(this ILogger logger, string? message, params objec
/// Format string of the log message in message template format. Example: "User {User} logged in from {Address}"
/// An object array that contains zero or more objects to format.
/// logger.LogError(exception, "Error while processing request from {Address}", address)
- public static void LogError(this ILogger logger, Exception? exception, string? message, params object?[] args) =>
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void LogError(this ILogger logger, Exception? exception, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[] args) =>
logger.Log(LogLevel.Error, exception, message, args);
///
@@ -123,7 +134,8 @@ public static void LogError(this ILogger logger, Exception? exception, string? m
/// Format string of the log message in message template format. Example: "User {User} logged in from {Address}"
/// An object array that contains zero or more objects to format.
/// logger.LogError("Processing request from {Address}", address)
- public static void LogError(this ILogger logger, string? message, params object?[] args) =>
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void LogError(this ILogger logger, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[] args) =>
logger.Log(LogLevel.Error, message, args);
//------------------------------------------CRITICAL------------------------------------------//
@@ -136,7 +148,8 @@ public static void LogError(this ILogger logger, string? message, params object?
/// Format string of the log message in message template format. Example: "User {User} logged in from {Address}"
/// An object array that contains zero or more objects to format.
/// logger.LogCritical(exception, "Error while processing request from {Address}", address)
- public static void LogCritical(this ILogger logger, Exception? exception, string? message, params object?[] args) =>
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void LogCritical(this ILogger logger, Exception? exception, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[] args) =>
logger.Log(LogLevel.Critical, exception, message, args);
///
@@ -146,7 +159,8 @@ public static void LogCritical(this ILogger logger, Exception? exception, string
/// Format string of the log message in message template format. Example: "User {User} logged in from {Address}"
/// An object array that contains zero or more objects to format.
/// logger.LogCritical("Processing request from {Address}", address)
- public static void LogCritical(this ILogger logger, string? message, params object?[] args) =>
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void LogCritical(this ILogger logger, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[] args) =>
logger.Log(LogLevel.Critical, message, args);
///
@@ -156,7 +170,8 @@ public static void LogCritical(this ILogger logger, string? message, params obje
/// Entry will be written on this level.
/// Format string of the log message.
/// An object array that contains zero or more objects to format.
- public static void Log(this ILogger logger, LogLevel logLevel, string? message, params object?[] args) =>
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void Log(this ILogger logger, LogLevel logLevel, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[] args) =>
logger.Log(logLevel, null, message, args);
}
}
\ No newline at end of file
diff --git a/AdvancedSharpAdbClient/Extensions/SyncCommandConverter.cs b/AdvancedSharpAdbClient/Extensions/SyncCommandConverter.cs
index 95a8480..4271f81 100644
--- a/AdvancedSharpAdbClient/Extensions/SyncCommandConverter.cs
+++ b/AdvancedSharpAdbClient/Extensions/SyncCommandConverter.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
+using System.Runtime.CompilerServices;
namespace AdvancedSharpAdbClient.Models
{
@@ -22,12 +23,14 @@ public static class SyncCommandConverter
/// Gets the byte array that represents the .
///
/// A byte array that represents the .
+ [MethodImpl((MethodImplOptions)0x100)]
public byte[] GetBytes() => BitConverter.GetBytes((int)command);
///
/// Returns an enumerator that iterates through the .
///
/// An enumerator that can be used to iterate through the .
+ [MethodImpl((MethodImplOptions)0x100)]
public IEnumerator GetEnumerator() => ((IEnumerable)command.GetBytes()).GetEnumerator();
///
@@ -38,7 +41,6 @@ public static class SyncCommandConverter
public static SyncCommand GetCommand(byte[] value)
{
ArgumentNullException.ThrowIfNull(value);
-
return value.Length != 4 ? throw new ArgumentOutOfRangeException(nameof(value)) : (SyncCommand)BitConverter.ToInt32(value);
}
@@ -48,10 +50,8 @@ public static SyncCommand GetCommand(byte[] value)
///
/// A byte array that represents a .
/// The corresponding .
- public static SyncCommand GetCommand(ReadOnlySpan value)
- {
- return value.Length != 4 ? throw new ArgumentOutOfRangeException(nameof(value)) : (SyncCommand)BitConverter.ToInt32(value);
- }
+ public static SyncCommand GetCommand(scoped ReadOnlySpan value) =>
+ value.Length != 4 ? throw new ArgumentOutOfRangeException(nameof(value)) : (SyncCommand)BitConverter.ToInt32(value);
#endif
}
}
diff --git a/AdvancedSharpAdbClient/Extensions/SyncServiceExtensions.Async.cs b/AdvancedSharpAdbClient/Extensions/SyncServiceExtensions.Async.cs
index e46c136..5b21052 100644
--- a/AdvancedSharpAdbClient/Extensions/SyncServiceExtensions.Async.cs
+++ b/AdvancedSharpAdbClient/Extensions/SyncServiceExtensions.Async.cs
@@ -7,6 +7,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Runtime.CompilerServices;
using System.Threading;
namespace AdvancedSharpAdbClient
@@ -22,6 +23,7 @@ public static partial class SyncServiceExtensions
/// A that can be used to cancel the task.
/// A which returns a object that contains information about the file.
/// File size bigger than 4GB need V2, and V2 need Android 8 or above.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task StatAsync(this ISyncService service, string remotePath, bool useV2 = false, CancellationToken cancellationToken = default) =>
useV2 ? service.StatExAsync(remotePath, cancellationToken).ContinueWith(x => x.Result as IFileStatistics) : service.StatAsync(remotePath, cancellationToken).ContinueWith(x => x.Result as IFileStatistics);
@@ -34,6 +36,7 @@ public static Task StatAsync(this ISyncService service, string
/// A that can be used to cancel the task.
/// A which returns for each child item of the directory, a object with information of the item.
/// File size bigger than 4GB need V2, and V2 need Android 11 or above.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task> GetDirectoryListingAsync(this ISyncService service, string remotePath, bool useV2 = false, CancellationToken cancellationToken = default) =>
#if NETFRAMEWORK && !NET40_OR_GREATER
useV2 ? service.GetDirectoryListingExAsync(remotePath, cancellationToken).ContinueWith(x => x.Result.OfType()) : service.GetDirectoryListingAsync(remotePath, cancellationToken).ContinueWith(x => x.Result.OfType());
@@ -51,6 +54,7 @@ public static Task> GetDirectoryListingAsync(this I
/// A that can be used to cancel the task.
/// An which returns for each child item of the directory, a object with information of the item.
/// File size bigger than 4GB need V2, and V2 need Android 11 or above.
+ [MethodImpl((MethodImplOptions)0x100)]
public static IAsyncEnumerable GetDirectoryAsyncListing(this ISyncService service, string remotePath, bool useV2 = false, CancellationToken cancellationToken = default) =>
useV2 ? service.GetDirectoryAsyncListingEx(remotePath, cancellationToken) : service.GetDirectoryAsyncListing(remotePath, cancellationToken);
#endif
@@ -68,6 +72,7 @@ public static IAsyncEnumerable GetDirectoryAsyncListing(this IS
/// to use ; otherwise, use .
/// A that can be used to cancel the task.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task PushAsync(this ISyncService service, Stream stream, string remotePath, UnixFileStatus permissions, DateTimeOffset timestamp, IProgress? progress = null, bool useV2 = false, CancellationToken cancellationToken = default) =>
service.PushAsync(stream, remotePath, permissions, timestamp, progress.AsAction(), useV2, cancellationToken);
@@ -82,6 +87,7 @@ public static Task PushAsync(this ISyncService service, Stream stream, string re
/// A that can be used to cancel the task.
/// A which represents the asynchronous operation.
/// File size bigger than 4GB need V2, and V2 need Android 11 or above.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task PullAsync(this ISyncService service, string remotePath, Stream stream, IProgress? progress = null, bool useV2 = false, CancellationToken cancellationToken = default) =>
service.PullAsync(remotePath, stream, progress.AsAction(), useV2, cancellationToken);
@@ -98,6 +104,7 @@ public static Task PullAsync(this ISyncService service, string remotePath, Strea
/// to use ; otherwise, use .
/// A that can be used to cancel the task.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task PushAsync(this ISyncService.IWinRT service, IInputStream stream, string remotePath, UnixFileStatus permissions, DateTimeOffset timestamp, IProgress? progress = null, bool useV2 = false, CancellationToken cancellationToken = default) =>
service.PushAsync(stream, remotePath, permissions, timestamp, progress.AsAction(), useV2, cancellationToken);
@@ -112,6 +119,7 @@ public static Task PushAsync(this ISyncService.IWinRT service, IInputStream stre
/// A that can be used to cancel the task.
/// A which represents the asynchronous operation.
/// File size bigger than 4GB need V2, and V2 need Android 11 or above.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task PullAsync(this ISyncService.IWinRT service, string remotePath, IOutputStream stream, IProgress? progress = null, bool useV2 = false, CancellationToken cancellationToken = default) =>
service.PullAsync(remotePath, stream, progress.AsAction(), useV2, cancellationToken);
#endif
@@ -129,6 +137,7 @@ public static Task PullAsync(this ISyncService.IWinRT service, string remotePath
/// to use ; otherwise, use .
/// A that can be used to cancel the task.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task PushAsync(this ISyncService service, Stream stream, string remotePath, UnixFileMode permissions, DateTimeOffset timestamp, Action? callback = null, bool useV2 = false, CancellationToken cancellationToken = default) =>
service.PushAsync(stream, remotePath, (UnixFileStatus)permissions, timestamp, callback, useV2, cancellationToken);
@@ -144,6 +153,7 @@ public static Task PushAsync(this ISyncService service, Stream stream, string re
/// to use ; otherwise, use .
/// A that can be used to cancel the task.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task PushAsync(this ISyncService service, Stream stream, string remotePath, UnixFileMode permissions, DateTimeOffset timestamp, IProgress? progress, bool useV2 = false, CancellationToken cancellationToken = default) =>
service.PushAsync(stream, remotePath, (UnixFileStatus)permissions, timestamp, progress.AsAction(), useV2, cancellationToken);
@@ -160,6 +170,7 @@ public static Task PushAsync(this ISyncService service, Stream stream, string re
/// to use ; otherwise, use .
/// A that can be used to cancel the task.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task PushAsync(this ISyncService.IWinRT service, IInputStream stream, string remotePath, UnixFileMode permissions, DateTimeOffset timestamp, Action? callback = null, bool useV2 = false, CancellationToken cancellationToken = default) =>
service.PushAsync(stream, remotePath, (UnixFileStatus)permissions, timestamp, callback, useV2, cancellationToken);
@@ -175,6 +186,7 @@ public static Task PushAsync(this ISyncService.IWinRT service, IInputStream stre
/// to use ; otherwise, use .
/// A that can be used to cancel the task.
/// A which represents the asynchronous operation.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task PushAsync(this ISyncService.IWinRT service, IInputStream stream, string remotePath, UnixFileMode permissions, DateTimeOffset timestamp, IProgress? progress, bool useV2 = false, CancellationToken cancellationToken = default) =>
service.PushAsync(stream, remotePath, (UnixFileStatus)permissions, timestamp, progress.AsAction(), useV2, cancellationToken);
#endif
diff --git a/AdvancedSharpAdbClient/Extensions/SyncServiceExtensions.cs b/AdvancedSharpAdbClient/Extensions/SyncServiceExtensions.cs
index 48e1f9d..7b64bd5 100644
--- a/AdvancedSharpAdbClient/Extensions/SyncServiceExtensions.cs
+++ b/AdvancedSharpAdbClient/Extensions/SyncServiceExtensions.cs
@@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Runtime.CompilerServices;
namespace AdvancedSharpAdbClient
{
@@ -22,6 +23,7 @@ public static partial class SyncServiceExtensions
/// to use ; otherwise, use .
/// A object that contains information about the file.
/// File size bigger than 4GB need V2, and V2 need Android 8 or above.
+ [MethodImpl((MethodImplOptions)0x100)]
public static IFileStatistics Stat(this ISyncService service, string remotePath, bool useV2 = false) =>
useV2 ? service.StatEx(remotePath) : service.Stat(remotePath);
@@ -33,6 +35,7 @@ public static IFileStatistics Stat(this ISyncService service, string remotePath,
/// to use ; otherwise, use .
/// For each child item of the directory, a object with information of the item.
/// V2 need Android 11 or above.
+ [MethodImpl((MethodImplOptions)0x100)]
public static IEnumerable GetDirectoryListing(this ISyncService service, string remotePath, bool useV2 = false) =>
#if NETFRAMEWORK && !NET40_OR_GREATER
useV2 ? service.GetDirectoryListingEx(remotePath).OfType() : service.GetDirectoryListing(remotePath).OfType();
@@ -53,7 +56,8 @@ public static IEnumerable GetDirectoryListing(this ISyncService
/// to use ; otherwise, use .
/// A that can be used to cancel the task.
/// V2 need Android 11 or above.
- public static void Push(this ISyncService service, Stream stream, string remotePath, UnixFileStatus permissions, DateTimeOffset timestamp, IProgress? progress = null, bool useV2 = false, in bool isCancelled = false) =>
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void Push(this ISyncService service, Stream stream, string remotePath, UnixFileStatus permissions, DateTimeOffset timestamp, IProgress? progress = null, bool useV2 = false, scoped in bool isCancelled = false) =>
service.Push(stream, remotePath, permissions, timestamp, progress.AsAction(), useV2, isCancelled);
///
@@ -66,7 +70,8 @@ public static void Push(this ISyncService service, Stream stream, string remoteP
/// to use and ; otherwise, use and .
/// A that can be used to cancel the task.
/// File size bigger than 4GB need V2, and V2 need Android 11 or above.
- public static void Pull(this ISyncService service, string remotePath, Stream stream, IProgress? progress = null, bool useV2 = false, in bool isCancelled = false) =>
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void Pull(this ISyncService service, string remotePath, Stream stream, IProgress? progress = null, bool useV2 = false, scoped in bool isCancelled = false) =>
service.Pull(remotePath, stream, progress.AsAction(), useV2, isCancelled);
#if NET7_0_OR_GREATER
@@ -82,7 +87,8 @@ public static void Pull(this ISyncService service, string remotePath, Stream str
/// to use ; otherwise, use .
/// A that can be used to cancel the task.
/// V2 need Android 11 or above.
- public static void Push(this ISyncService service, Stream stream, string remotePath, UnixFileMode permissions, DateTimeOffset timestamp, Action? callback = null, bool useV2 = false, in bool isCancelled = false) =>
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void Push(this ISyncService service, Stream stream, string remotePath, UnixFileMode permissions, DateTimeOffset timestamp, Action? callback = null, bool useV2 = false, scoped in bool isCancelled = false) =>
service.Push(stream, remotePath, (UnixFileStatus)permissions, timestamp, callback, useV2, isCancelled);
///
@@ -97,7 +103,8 @@ public static void Push(this ISyncService service, Stream stream, string remoteP
/// to use ; otherwise, use .
/// A that can be used to cancel the task.
/// V2 need Android 11 or above.
- public static void Push(this ISyncService service, Stream stream, string remotePath, UnixFileMode permissions, DateTimeOffset timestamp, IProgress? progress, bool useV2 = false, in bool isCancelled = false) =>
+ [MethodImpl((MethodImplOptions)0x100)]
+ public static void Push(this ISyncService service, Stream stream, string remotePath, UnixFileMode permissions, DateTimeOffset timestamp, IProgress? progress, bool useV2 = false, scoped in bool isCancelled = false) =>
service.Push(stream, remotePath, (UnixFileStatus)permissions, timestamp, progress.AsAction(), useV2, isCancelled);
#endif
#endif
diff --git a/AdvancedSharpAdbClient/Extensions/UnixFileStatusExtensions.cs b/AdvancedSharpAdbClient/Extensions/UnixFileStatusExtensions.cs
index 6a50d97..59b5e4e 100644
--- a/AdvancedSharpAdbClient/Extensions/UnixFileStatusExtensions.cs
+++ b/AdvancedSharpAdbClient/Extensions/UnixFileStatusExtensions.cs
@@ -8,6 +8,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Runtime.CompilerServices;
namespace AdvancedSharpAdbClient.Models
{
@@ -26,24 +27,28 @@ public static class UnixFileStatusExtensions
/// Gets the type of the given file status.
///
/// The type of the file status.
+ [MethodImpl((MethodImplOptions)0x100)]
public UnixFileStatus GetFileType() => mode & UnixFileStatus.TypeMask;
///
/// Gets the permissions of the given file status.
///
/// The permissions of the given file status.
+ [MethodImpl((MethodImplOptions)0x100)]
public UnixFileStatus GetPermissions() => mode & UnixFileStatus.AllPermissions;
///
/// Gets the access permissions of the given file status.
///
/// The access permissions of the given file status.
+ [MethodImpl((MethodImplOptions)0x100)]
public UnixFileStatus GetAccessPermissions() => mode & UnixFileStatus.AccessPermissions;
///
/// Checks if the given file status corresponds to a directory, as if determined by .
///
/// if the type indicated refers to a directory, otherwise .
+ [MethodImpl((MethodImplOptions)0x100)]
public bool IsDirectory() => mode.GetFileType() == UnixFileStatus.Directory;
///
@@ -51,6 +56,7 @@ public static class UnixFileStatusExtensions
/// Examples of character special files are character devices such as /dev/null, /dev/tty, /dev/audio, or /dev/nvram on Linux.
///
/// if the type indicated refers to a character device, otherwise .
+ [MethodImpl((MethodImplOptions)0x100)]
public bool IsCharacterFile() => mode.GetFileType() == UnixFileStatus.Character;
///
@@ -58,42 +64,49 @@ public static class UnixFileStatusExtensions
/// Examples of block special files are block devices such as /dev/sda or /dev/loop0 on Linux.
///
/// if the type indicated refers to a block device, otherwise .
+ [MethodImpl((MethodImplOptions)0x100)]
public bool IsBlockFile() => mode.GetFileType() == UnixFileStatus.Block;
///
/// Checks if the given file status corresponds to a regular file, as if determined by .
///
/// if the type indicated by refers to a regular file, otherwise .
+ [MethodImpl((MethodImplOptions)0x100)]
public bool IsRegularFile() => mode.GetFileType() == UnixFileStatus.Regular;
///
/// Checks if the given file status corresponds to a FIFO or pipe file as if determined by .
///
/// if the type indicated refers to a FIFO pipe, otherwise .
+ [MethodImpl((MethodImplOptions)0x100)]
public bool IsFIFO() => mode.GetFileType() == UnixFileStatus.FIFO;
///
/// Checks if the given file status corresponds to a symbolic link, as if determined by .
///
/// if the type indicated refers to a symbolic link, otherwise .
+ [MethodImpl((MethodImplOptions)0x100)]
public bool IsSymbolicLink() => mode.GetFileType() == UnixFileStatus.SymbolicLink;
///
/// Checks if the given file status or path corresponds to a named IPC socket, as if determined by .
///
/// if the type indicated refers to a named socket, otherwise .
+ [MethodImpl((MethodImplOptions)0x100)]
public bool IsSocket() => mode.GetFileType() == UnixFileStatus.Socket;
///
/// Checks if the given file status corresponds to a file of type other type. That is, the file exists, but is neither regular file, nor directory nor a symlink.
///
/// if the type indicated refers to a file that is not regular file, directory, or a symlink, otherwise .
+ [MethodImpl((MethodImplOptions)0x100)]
public bool IsOther() => mode.GetFileType() is not (UnixFileStatus.Regular or UnixFileStatus.Directory or UnixFileStatus.SymbolicLink);
///
/// Checks if the given file type is known, equivalent to mode.GetFileType() != .
///
/// if the given file type is a known file type, otherwise .
+ [MethodImpl((MethodImplOptions)0x100)]
public bool IsTypeKnown() => mode.GetFileType() != UnixFileStatus.None;
///
@@ -208,7 +221,7 @@ public static UnixFileStatus FromPermissionCode(string code)
public string ToPermissionCode()
{
#if HAS_BUFFERS
- Span code = stackalloc char[10];
+ scoped Span code = stackalloc char[10];
#else
char[] code = new char[10];
#endif
diff --git a/AdvancedSharpAdbClient/Logs/Interfaces/ILogger.cs b/AdvancedSharpAdbClient/Logs/Interfaces/ILogger.cs
index 4b93efd..af069a1 100644
--- a/AdvancedSharpAdbClient/Logs/Interfaces/ILogger.cs
+++ b/AdvancedSharpAdbClient/Logs/Interfaces/ILogger.cs
@@ -3,6 +3,7 @@
//
using System;
+using System.Diagnostics.CodeAnalysis;
namespace AdvancedSharpAdbClient.Logs
{
@@ -19,7 +20,7 @@ public interface ILogger
/// The exception to log.
/// Format string of the log message.
/// An object array that contains zero or more objects to format.
- void Log(LogLevel logLevel, Exception? exception, string? message, params object?[] args);
+ void Log(LogLevel logLevel, Exception? exception, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[] args);
}
///
diff --git a/AdvancedSharpAdbClient/Logs/NullLogger.cs b/AdvancedSharpAdbClient/Logs/NullLogger.cs
index 104581f..93a2ba9 100644
--- a/AdvancedSharpAdbClient/Logs/NullLogger.cs
+++ b/AdvancedSharpAdbClient/Logs/NullLogger.cs
@@ -3,6 +3,7 @@
//
using System;
+using System.Diagnostics.CodeAnalysis;
namespace AdvancedSharpAdbClient.Logs
{
@@ -17,7 +18,7 @@ public class NullLogger : ILogger
public static NullLogger Instance { get; } = new();
///
- public void Log(LogLevel logLevel, Exception? exception, string? message, params object?[] args) { }
+ public void Log(LogLevel logLevel, Exception? exception, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[] args) { }
}
///
diff --git a/AdvancedSharpAdbClient/Models/AdbCommandLineStatus.cs b/AdvancedSharpAdbClient/Models/AdbCommandLineStatus.cs
index 3e38859..1a90ccc 100644
--- a/AdvancedSharpAdbClient/Models/AdbCommandLineStatus.cs
+++ b/AdvancedSharpAdbClient/Models/AdbCommandLineStatus.cs
@@ -95,12 +95,12 @@ public static AdbCommandLineStatus GetVersionFromOutput(params IEnumerable
/// The output of the adb.exe version command.
/// A object that represents the version and path of the adb command line client.
- public static AdbCommandLineStatus GetVersionFromOutput(params ReadOnlySpan output)
+ public static AdbCommandLineStatus GetVersionFromOutput(params scoped ReadOnlySpan output)
{
int index = 0;
Version? adbVersion = null;
string? fileVersion = null, filePath = null;
- ReadOnlySpan.Enumerator enumerator = output.GetEnumerator();
+ scoped ReadOnlySpan.Enumerator enumerator = output.GetEnumerator();
while (index < 3 && enumerator.MoveNext())
{
string line = enumerator.Current;
diff --git a/AdvancedSharpAdbClient/Models/ColorData.cs b/AdvancedSharpAdbClient/Models/ColorData.cs
index 22eef9b..e504e6a 100644
--- a/AdvancedSharpAdbClient/Models/ColorData.cs
+++ b/AdvancedSharpAdbClient/Models/ColorData.cs
@@ -106,7 +106,7 @@ public readonly IEnumerator GetEnumerator()
/// equal to the size of the structure in bytes.
public byte[] ToArray()
{
- ref readonly ColorData data = ref this;
+ scoped ref readonly ColorData data = ref this;
unsafe
{
byte[] array = new byte[Size];
diff --git a/AdvancedSharpAdbClient/Models/DeviceData.EventArgs.cs b/AdvancedSharpAdbClient/Models/DeviceData.EventArgs.cs
index 5dee9de..a410385 100644
--- a/AdvancedSharpAdbClient/Models/DeviceData.EventArgs.cs
+++ b/AdvancedSharpAdbClient/Models/DeviceData.EventArgs.cs
@@ -26,7 +26,7 @@ public abstract class DeviceDataEventArgs(DeviceData device) : EventArgs
///
public override string ToString()
{
- DefaultInterpolatedStringHandler builder = new(18, 2);
+ scoped DefaultInterpolatedStringHandler builder = new(18, 2);
builder.AppendLiteral("Device changed");
if (!Device.IsEmpty)
{
@@ -76,7 +76,7 @@ public sealed class DeviceDataConnectEventArgs(DeviceData device, bool isConnect
///
public override string ToString()
{
- DefaultInterpolatedStringHandler builder = new(23, 2);
+ scoped DefaultInterpolatedStringHandler builder = new(23, 2);
builder.AppendLiteral("Device ");
builder.AppendLiteral(IsConnect ? "connected" : "disconnected");
if (Device.IsEmpty)
@@ -120,7 +120,7 @@ public sealed class DeviceDataChangeEventArgs(DeviceData device, DeviceState new
///
public override string ToString()
{
- DefaultInterpolatedStringHandler builder = new(29, 4);
+ scoped DefaultInterpolatedStringHandler builder = new(29, 4);
builder.AppendLiteral("Device state changed:");
if (!Device.IsEmpty)
{
diff --git a/AdvancedSharpAdbClient/Models/DeviceData.cs b/AdvancedSharpAdbClient/Models/DeviceData.cs
index 9fc3dfa..eb7cbe0 100644
--- a/AdvancedSharpAdbClient/Models/DeviceData.cs
+++ b/AdvancedSharpAdbClient/Models/DeviceData.cs
@@ -213,7 +213,7 @@ public override string ToString()
return $"An empty {GetType()} without {nameof(TransportId)} and {nameof(Serial)}";
}
- DefaultInterpolatedStringHandler builder = new(55, 9);
+ scoped DefaultInterpolatedStringHandler builder = new(55, 9);
builder.AppendLiteral(Serial);
builder.AppendFormatted('\t');
@@ -337,7 +337,7 @@ public static DeviceState GetStateFromString(string state)
/// The value of the for this instance.
private string GetDebuggerDisplay()
{
- DefaultInterpolatedStringHandler builder = new(113, 9);
+ scoped DefaultInterpolatedStringHandler builder = new(113, 9);
builder.AppendFormatted(GetType());
builder.AppendLiteral($" {{ ");
diff --git a/AdvancedSharpAdbClient/Models/FileStatistics.Base.cs b/AdvancedSharpAdbClient/Models/FileStatistics.Base.cs
index 49d17ca..01992f8 100644
--- a/AdvancedSharpAdbClient/Models/FileStatistics.Base.cs
+++ b/AdvancedSharpAdbClient/Models/FileStatistics.Base.cs
@@ -14,7 +14,7 @@ namespace AdvancedSharpAdbClient.Models
/// The type of the data for file.
/// The type of the derived class.
/// The for the data of file.
- public abstract class FileStatisticsBase(in T data) : IEquatable, IEquatable>
+ public abstract class FileStatisticsBase(scoped in T data) : IEquatable, IEquatable>
#if NET7_0_OR_GREATER
, IEqualityOperators, IEqualityOperators, bool>
#endif
diff --git a/AdvancedSharpAdbClient/Models/FileStatistics.V2.cs b/AdvancedSharpAdbClient/Models/FileStatistics.V2.cs
index 7f603f6..883c673 100644
--- a/AdvancedSharpAdbClient/Models/FileStatistics.V2.cs
+++ b/AdvancedSharpAdbClient/Models/FileStatistics.V2.cs
@@ -13,7 +13,7 @@ namespace AdvancedSharpAdbClient.Models
///
///
[DebuggerDisplay($"{{{nameof(GetType)}().{nameof(Type.ToString)}(),nq}} \\{{ {nameof(Path)} = {{{nameof(Path)}}}, {nameof(FileMode)} = {{{nameof(FileMode)}}}, {nameof(Size)} = {{{nameof(Size)}}}, {nameof(ModifiedTime)} = {{{nameof(ModifiedTime)}}} }}")]
- public class FileStatisticsEx(in FileStatisticsDataEx data) : FileStatisticsBase(data), IFileStatistics
+ public class FileStatisticsEx(scoped in FileStatisticsDataEx data) : FileStatisticsBase(data), IFileStatistics
#if NET7_0_OR_GREATER
, IEqualityOperators
#endif
diff --git a/AdvancedSharpAdbClient/Models/FileStatistics.cs b/AdvancedSharpAdbClient/Models/FileStatistics.cs
index d213a62..1e2f480 100644
--- a/AdvancedSharpAdbClient/Models/FileStatistics.cs
+++ b/AdvancedSharpAdbClient/Models/FileStatistics.cs
@@ -13,7 +13,7 @@ namespace AdvancedSharpAdbClient.Models
///
/// The data of the file.
[DebuggerDisplay($"{{{nameof(GetType)}().{nameof(Type.ToString)}(),nq}} \\{{ {nameof(Path)} = {{{nameof(Path)}}}, {nameof(FileMode)} = {{{nameof(FileMode)}}}, {nameof(Size)} = {{{nameof(Size)}}}, {nameof(Time)} = {{{nameof(Time)}}} }}")]
- public sealed class FileStatistics(in FileStatisticsData data) : FileStatisticsBase(data), IFileStatistics
+ public sealed class FileStatistics(scoped in FileStatisticsData data) : FileStatisticsBase(data), IFileStatistics
#if NET7_0_OR_GREATER
, IEqualityOperators
#endif
diff --git a/AdvancedSharpAdbClient/Models/FileStatisticsData.V2.cs b/AdvancedSharpAdbClient/Models/FileStatisticsData.V2.cs
index f74f57d..8a57903 100644
--- a/AdvancedSharpAdbClient/Models/FileStatisticsData.V2.cs
+++ b/AdvancedSharpAdbClient/Models/FileStatisticsData.V2.cs
@@ -125,7 +125,7 @@ public unsafe byte[] ToArray()
/// Returns a read-only span of bytes representing the contents of this instance.
///
/// A that provides a read-only view of the bytes in this instance.
- public unsafe ReadOnlySpan AsSpan() => MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Length);
+ public ReadOnlySpan AsSpan() => MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref Unsafe.AsRef(in this)), Length);
///
/// Returns an enumerator that iterates through the .
diff --git a/AdvancedSharpAdbClient/Models/FramebufferHeader.Drawing.cs b/AdvancedSharpAdbClient/Models/FramebufferHeader.Drawing.cs
new file mode 100644
index 0000000..41cb022
--- /dev/null
+++ b/AdvancedSharpAdbClient/Models/FramebufferHeader.Drawing.cs
@@ -0,0 +1,164 @@
+#if HAS_IMAGING
+//
+// Copyright (c) The Android Open Source Project, Ryan Conrad, Quamotion, yungd1plomat, wherewhere. All rights reserved.
+//
+
+using System;
+using System.Drawing;
+using System.Runtime.InteropServices;
+
+namespace AdvancedSharpAdbClient.Models
+{
+ ///
+ /// Provides extension methods for that allow to convert the raw data contained in a framebuffer to a .
+ ///
+ public static class FramebufferHeaderDrawing
+ {
+ ///
+ /// Converts a array containing the raw frame buffer data to a .
+ ///
+ /// The header of the frame buffer, which contains information about how the image data is stored in the .
+ /// The buffer containing the image data.
+ /// A that represents the image contained in the frame buffer, or
+ /// if the framebuffer does not contain any data. This can happen when DRM is enabled on the device.
+#if NET
+ [SupportedOSPlatform("windows6.1")]
+#endif
+ public static Bitmap? ToImage(this scoped in FramebufferHeader header, byte[] buffer)
+ {
+ ArgumentNullException.ThrowIfNull(buffer);
+
+ // This happens, for example, when DRM is enabled. In that scenario, no screenshot is taken on the device and an empty
+ // framebuffer is returned; we'll just return null.
+ if (header.Width == 0 || header.Height == 0 || header.Bpp == 0)
+ {
+ return null;
+ }
+
+ // The pixel format of the framebuffer may not be one that .NET recognizes, so we need to fix that
+ PixelFormat pixelFormat = header.StandardizePixelFormat(ref buffer);
+
+ Bitmap bitmap = new((int)header.Width, (int)header.Height, pixelFormat);
+ BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, pixelFormat);
+ Marshal.Copy(buffer, 0, bitmapData.Scan0, (int)header.Size);
+ bitmap.UnlockBits(bitmapData);
+
+ return bitmap;
+ }
+
+ ///
+ /// Returns the that describes pixel format of an image that is stored according to the information
+ /// present in this . Because the enumeration does not allow for all
+ /// formats supported by Android, this method also takes a and reorganizes the bytes in the buffer to
+ /// match the return value of this function.
+ ///
+ /// The header of the frame buffer, which contains information about how the image data is stored in the .
+ /// A byte array in which the images are stored according to this .
+ /// A that describes how the image data is represented in this .
+#if NET
+ [SupportedOSPlatform("windows6.1")]
+#endif
+ private static PixelFormat StandardizePixelFormat(this scoped in FramebufferHeader header, ref byte[] buffer)
+ {
+ // Initial parameter validation.
+ ArgumentNullException.ThrowIfNull(buffer);
+
+ if (buffer.Length < header.Width * header.Height * (header.Bpp / 8))
+ {
+ throw new ArgumentOutOfRangeException(nameof(buffer), $"The buffer length {buffer.Length} is less than expected buffer " +
+ $"length ({header.Width * header.Height * (header.Bpp / 8)}) for a picture of width {header.Width}, height {header.Height} and pixel depth {header.Bpp}");
+ }
+
+ if (header.Width == 0 || header.Height == 0 || header.Bpp == 0)
+ {
+ throw new InvalidOperationException("Cannot cannulate the pixel format of an empty framebuffer");
+ }
+
+ // By far, the most common format is a 32-bit pixel format, which is either
+ // RGB or RGBA, where each color has 1 byte.
+ if (header.Bpp == 8 * 4)
+ {
+ // Require at least RGB to be present; and require them to be exactly one byte (8 bits) long.
+ if (header.Red.Length != 8 || header.Blue.Length != 8 || header.Green.Length != 8)
+ {
+ throw new ArgumentOutOfRangeException($"The pixel format with with RGB lengths of {header.Red.Length}:{header.Blue.Length}:{header.Green.Length} is not supported");
+ }
+
+ // Alpha can be present or absent, but must be 8 bytes long
+ if (header.Alpha.Length is not (0 or 8))
+ {
+ throw new ArgumentOutOfRangeException($"The alpha length {header.Alpha.Length} is not supported");
+ }
+
+ // Gets the index at which the red, bue, green and alpha values are stored.
+ int redIndex = (int)header.Red.Offset / 8;
+ int blueIndex = (int)header.Blue.Offset / 8;
+ int greenIndex = (int)header.Green.Offset / 8;
+ int alphaIndex = (int)header.Alpha.Offset / 8;
+
+ byte[] array = new byte[(int)header.Size * 4];
+ // Loop over the array and re-order as required
+ for (int i = 0; i < (int)header.Size; i += 4)
+ {
+ byte red = buffer[i + redIndex];
+ byte blue = buffer[i + blueIndex];
+ byte green = buffer[i + greenIndex];
+ byte alpha = buffer[i + alphaIndex];
+
+ // Convert to ARGB. Note, we're on a little endian system,
+ // so it's really BGRA. Confusing!
+ if (header.Alpha.Length == 8)
+ {
+ array[i + 3] = alpha;
+ array[i + 2] = red;
+ array[i + 1] = green;
+ array[i + 0] = blue;
+ }
+ else
+ {
+ array[i + 3] = 0;
+ array[i + 2] = red;
+ array[i + 1] = green;
+ array[i + 0] = blue;
+ }
+ }
+ buffer = array;
+
+ // Returns RGB or RGBA, function of the presence of an alpha channel.
+ return header.Alpha.Length == 0 ? PixelFormat.Format32bppRgb : PixelFormat.Format32bppArgb;
+ }
+ else if (header.Bpp == 8 * 3)
+ {
+ // For 24-bit image depths, we only support RGB.
+ if (header.Red.Offset == 0
+ && header.Red.Length == 8
+ && header.Green.Offset == 8
+ && header.Green.Length == 8
+ && header.Blue.Offset == 16
+ && header.Blue.Length == 8
+ && header.Alpha.Offset == 24
+ && header.Alpha.Length == 0)
+ {
+ return PixelFormat.Format24bppRgb;
+ }
+ }
+ else if (header.Bpp == 5 + 6 + 5
+ && header.Red.Offset == 11
+ && header.Red.Length == 5
+ && header.Green.Offset == 5
+ && header.Green.Length == 6
+ && header.Blue.Offset == 0
+ && header.Blue.Length == 5
+ && header.Alpha.Offset == 0
+ && header.Alpha.Length == 0)
+ {
+ // For 16-bit image depths, we only support Rgb565.
+ return PixelFormat.Format16bppRgb565;
+ }
+
+ // If not caught by any of the statements before, the format is not supported.
+ throw new NotSupportedException($"Pixel depths of {header.Bpp} are not supported");
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/AdvancedSharpAdbClient/Models/FramebufferHeader.WinRT.cs b/AdvancedSharpAdbClient/Models/FramebufferHeader.WinRT.cs
new file mode 100644
index 0000000..67ecd38
--- /dev/null
+++ b/AdvancedSharpAdbClient/Models/FramebufferHeader.WinRT.cs
@@ -0,0 +1,185 @@
+#if HAS_WUXC
+//
+// Copyright (c) The Android Open Source Project, Ryan Conrad, Quamotion, yungd1plomat, wherewhere. All rights reserved.
+//
+
+using System;
+using System.Threading;
+
+namespace AdvancedSharpAdbClient.Models
+{
+ ///
+ /// Provides extension methods for that allow to convert the raw data contained in a framebuffer to a .
+ ///
+ public static class FramebufferHeaderWinRT
+ {
+ ///
+ /// Gets is supported.
+ ///
+#if NET
+ [SupportedOSPlatformGuard("Windows10.0.18362.0")]
+#endif
+ public static bool IsHasThreadAccessSupported { get; } = ApiInformation.IsMethodPresent("Windows.System.DispatcherQueue", "HasThreadAccess");
+
+ ///
+ /// Converts a array containing the raw frame buffer data to a .
+ ///
+ /// The header of the frame buffer, which contains information about how the image data is stored in the .
+ /// The buffer containing the image data.
+ /// The target to invoke the code on.
+ /// A which can be used to cancel the asynchronous task.
+ /// A that represents the image contained in the frame buffer, or
+ /// if the framebuffer does not contain any data. This can happen when DRM is enabled on the device.
+ public static Task ToBitmapAsync(this scoped in FramebufferHeader header, byte[] buffer, CoreDispatcher dispatcher, CancellationToken cancellationToken = default)
+ {
+ if (dispatcher.HasThreadAccess)
+ {
+ return header.ToBitmapAsync(buffer, cancellationToken);
+ }
+ else
+ {
+ FramebufferHeader self = header;
+ TaskCompletionSource taskCompletionSource = new();
+ _ = dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
+ {
+ try
+ {
+ WriteableBitmap? result = await self.ToBitmapAsync(buffer, cancellationToken).ConfigureAwait(false);
+ _ = taskCompletionSource.TrySetResult(result);
+ }
+ catch (Exception e)
+ {
+ _ = taskCompletionSource.TrySetException(e);
+ }
+ });
+ return taskCompletionSource.Task;
+ }
+ }
+
+ ///
+ /// Converts a array containing the raw frame buffer data to a .
+ ///
+ /// The header of the frame buffer, which contains information about how the image data is stored in the .
+ /// The buffer containing the image data.
+ /// The target to invoke the code on.
+ /// A which can be used to cancel the asynchronous task.
+ /// A that represents the image contained in the frame buffer, or
+ /// if the framebuffer does not contain any data. This can happen when DRM is enabled on the device.
+#if NET
+ [SupportedOSPlatform("Windows10.0.16299.0")]
+#endif
+ [ContractVersion(typeof(UniversalApiContract), 0x50000u)]
+ public static Task ToBitmapAsync(this scoped in FramebufferHeader header, byte[] buffer, DispatcherQueue dispatcher, CancellationToken cancellationToken = default)
+ {
+ if (IsHasThreadAccessSupported && dispatcher.HasThreadAccess)
+ {
+ return header.ToBitmapAsync(buffer, cancellationToken);
+ }
+ else
+ {
+ FramebufferHeader self = header;
+ TaskCompletionSource taskCompletionSource = new();
+ if (!dispatcher.TryEnqueue(async () =>
+ {
+ try
+ {
+ WriteableBitmap? result = await self.ToBitmapAsync(buffer, cancellationToken).ConfigureAwait(false);
+ _ = taskCompletionSource.TrySetResult(result);
+ }
+ catch (Exception e)
+ {
+ _ = taskCompletionSource.TrySetException(e);
+ }
+ }))
+ {
+ _ = taskCompletionSource.TrySetException(new InvalidOperationException("Failed to enqueue the operation"));
+ }
+ return taskCompletionSource.Task;
+ }
+ }
+
+ ///
+ /// Converts a array containing the raw frame buffer data to a .
+ ///
+ /// The header of the frame buffer, which contains information about how the image data is stored in the .
+ /// The buffer containing the image data.
+ /// A which can be used to cancel the asynchronous task.
+ /// A that represents the image contained in the frame buffer, or
+ /// if the framebuffer does not contain any data. This can happen when DRM is enabled on the device.
+ public static async Task ToBitmapAsync(this FramebufferHeader header, byte[] buffer, CancellationToken cancellationToken = default)
+ {
+ ArgumentNullException.ThrowIfNull(buffer);
+
+ // This happens, for example, when DRM is enabled. In that scenario, no screenshot is taken on the device and an empty
+ // framebuffer is returned; we'll just return null.
+ if (header.Width == 0 || header.Height == 0 || header.Bpp == 0)
+ {
+ return null;
+ }
+
+ // The pixel format of the framebuffer may not be one that WinRT recognizes, so we need to fix that
+ BitmapPixelFormat bitmapPixelFormat = header.StandardizePixelFormat(buffer, out BitmapAlphaMode alphaMode);
+
+ using InMemoryRandomAccessStream random = new();
+ BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, random).AsTask(cancellationToken);
+ encoder.SetPixelData(bitmapPixelFormat, alphaMode, header.Width, header.Height, 96, 96, buffer);
+ await encoder.FlushAsync().AsTask(cancellationToken);
+ WriteableBitmap WriteableImage = new((int)header.Width, (int)header.Height);
+ await WriteableImage.SetSourceAsync(random).AsTask(cancellationToken).ConfigureAwait(false);
+
+ return WriteableImage;
+ }
+
+ ///
+ /// Returns the that describes pixel format of an image that is stored according to the information
+ /// present in this . Because the enumeration does not allow for all
+ /// formats supported by Android, this method also takes a and reorganizes the bytes in the buffer to
+ /// match the return value of this function.
+ ///
+ /// The header of the frame buffer, which contains information about how the image data is stored in the .
+ /// A byte array in which the images are stored according to this .
+ /// A which describes how the alpha channel is stored.
+ /// A that describes how the image data is represented in this .
+ private static BitmapPixelFormat StandardizePixelFormat(this scoped in FramebufferHeader header, byte[] buffer, out BitmapAlphaMode alphaMode)
+ {
+ // Initial parameter validation.
+ ArgumentNullException.ThrowIfNull(buffer);
+
+ if (buffer.Length < header.Width * header.Height * (header.Bpp / 8))
+ {
+ throw new ArgumentOutOfRangeException(nameof(buffer), $"The buffer length {buffer.Length} is less than expected buffer " +
+ $"length ({header.Width * header.Height * (header.Bpp / 8)}) for a picture of width {header.Width}, height {header.Height} and pixel depth {header.Bpp}");
+ }
+
+ if (header.Width == 0 || header.Height == 0 || header.Bpp == 0)
+ {
+ throw new InvalidOperationException("Cannot cannulate the pixel format of an empty framebuffer");
+ }
+
+ // By far, the most common format is a 32-bit pixel format, which is either
+ // RGB or RGBA, where each color has 1 byte.
+ if (header.Bpp == 8 * 4)
+ {
+ // Require at least RGB to be present; and require them to be exactly one byte (8 bits) long.
+ if (header.Red.Length != 8 || header.Blue.Length != 8 || header.Green.Length != 8)
+ {
+ throw new ArgumentOutOfRangeException($"The pixel format with with RGB lengths of {header.Red.Length}:{header.Blue.Length}:{header.Green.Length} is not supported");
+ }
+
+ // Alpha can be present or absent, but must be 8 bytes long
+ alphaMode = header.Alpha.Length switch
+ {
+ 0 => BitmapAlphaMode.Ignore,
+ 8 => BitmapAlphaMode.Straight,
+ _ => throw new ArgumentOutOfRangeException($"The alpha length {header.Alpha.Length} is not supported"),
+ };
+
+ return BitmapPixelFormat.Rgba8;
+ }
+
+ // If not caught by any of the statements before, the format is not supported.
+ throw new NotSupportedException($"Pixel depths of {header.Bpp} are not supported");
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/AdvancedSharpAdbClient/Models/FramebufferHeader.cs b/AdvancedSharpAdbClient/Models/FramebufferHeader.cs
index abf663e..b2afdf3 100644
--- a/AdvancedSharpAdbClient/Models/FramebufferHeader.cs
+++ b/AdvancedSharpAdbClient/Models/FramebufferHeader.cs
@@ -6,14 +6,9 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
-using System.Drawing;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-#if HAS_WUXC
-using System.Threading;
-#endif
-
namespace AdvancedSharpAdbClient.Models
{
///
@@ -44,7 +39,7 @@ namespace AdvancedSharpAdbClient.Models
/// The data that feeds the struct.
public FramebufferHeader(byte[] data)
{
- byte[] _data;
+ byte[] source;
switch (data)
{
// Technically, 0 is not a supported version either; we assume version 0 indicates
@@ -56,16 +51,15 @@ public FramebufferHeader(byte[] data)
case [2, ..]:
goto default;
case [< 2, ..]:
- _data = new byte[MaxLength];
- Array.Copy(data, 0, _data, 0, 2 * sizeof(uint));
- Array.Copy(data, 2 * sizeof(uint), _data, (2 * sizeof(uint)) + 4, MinLength - (2 * sizeof(uint)));
+ source = new byte[MaxLength];
+ Array.Copy(data, 0, source, 0, 2 * sizeof(uint));
+ Array.Copy(data, 2 * sizeof(uint), source, (2 * sizeof(uint)) + 4, MinLength - (2 * sizeof(uint)));
break;
default:
- _data = data;
+ source = data;
break;
}
-
- this = Unsafe.As(ref _data[0]);
+ this = Unsafe.As(ref source[0]);
}
#if HAS_BUFFERS
@@ -74,9 +68,9 @@ public FramebufferHeader(byte[] data)
///
/// The data that feeds the struct.
[OverloadResolutionPriority(1)]
- public FramebufferHeader(ReadOnlySpan data)
+ public FramebufferHeader(scoped in ReadOnlySpan data)
{
- ReadOnlySpan _data = data switch
+ scoped ReadOnlySpan source = data switch
{
{ Length: < MinLength or > MaxLength } => throw new ArgumentOutOfRangeException(nameof(data), $"The length of {nameof(data)} must be {MinLength} or {MaxLength}."),
// Technically, 0 is not a supported version either; we assume version 0 indicates
@@ -85,8 +79,7 @@ public FramebufferHeader(ReadOnlySpan data)
[2, ..] => data,
[< 2, ..] => [.. data[..(2 * sizeof(uint))], 0, 0, 0, 0, .. data[(2 * sizeof(uint))..]]
};
-
- this = Unsafe.As(ref MemoryMarshal.GetReference(_data));
+ this = Unsafe.As(ref MemoryMarshal.GetReference(source));
}
#endif
@@ -204,325 +197,13 @@ public byte this[int index]
/// The data that feeds the struct.
/// A new object.
[OverloadResolutionPriority(1)]
- public static FramebufferHeader Read(ReadOnlySpan data) => new(data);
-#endif
-
-#if HAS_IMAGING
- ///
- /// Converts a array containing the raw frame buffer data to a .
- ///
- /// The buffer containing the image data.
- /// A that represents the image contained in the frame buffer, or
- /// if the framebuffer does not contain any data. This can happen when DRM is enabled on the device.
-#if NET
- [SupportedOSPlatform("windows6.1")]
-#endif
- public Bitmap? ToImage(byte[] buffer)
- {
- ArgumentNullException.ThrowIfNull(buffer);
-
- // This happens, for example, when DRM is enabled. In that scenario, no screenshot is taken on the device and an empty
- // framebuffer is returned; we'll just return null.
- if (Width == 0 || Height == 0 || Bpp == 0)
- {
- return null;
- }
-
- // The pixel format of the framebuffer may not be one that .NET recognizes, so we need to fix that
- PixelFormat pixelFormat = StandardizePixelFormat(ref buffer);
-
- Bitmap bitmap = new((int)Width, (int)Height, pixelFormat);
- BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, pixelFormat);
- Marshal.Copy(buffer, 0, bitmapData.Scan0, (int)Size);
- bitmap.UnlockBits(bitmapData);
-
- return bitmap;
- }
-
- ///
- /// Returns the that describes pixel format of an image that is stored according to the information
- /// present in this . Because the enumeration does not allow for all
- /// formats supported by Android, this method also takes a and reorganizes the bytes in the buffer to
- /// match the return value of this function.
- ///
- /// A byte array in which the images are stored according to this .
- /// A that describes how the image data is represented in this .
-#if NET
- [SupportedOSPlatform("windows6.1")]
-#endif
- private PixelFormat StandardizePixelFormat(ref byte[] buffer)
- {
- // Initial parameter validation.
- ArgumentNullException.ThrowIfNull(buffer);
-
- if (buffer.Length < Width * Height * (Bpp / 8))
- {
- throw new ArgumentOutOfRangeException(nameof(buffer), $"The buffer length {buffer.Length} is less than expected buffer " +
- $"length ({Width * Height * (Bpp / 8)}) for a picture of width {Width}, height {Height} and pixel depth {Bpp}");
- }
-
- if (Width == 0 || Height == 0 || Bpp == 0)
- {
- throw new InvalidOperationException("Cannot cannulate the pixel format of an empty framebuffer");
- }
-
- // By far, the most common format is a 32-bit pixel format, which is either
- // RGB or RGBA, where each color has 1 byte.
- if (Bpp == 8 * 4)
- {
- // Require at least RGB to be present; and require them to be exactly one byte (8 bits) long.
- if (Red.Length != 8 || Blue.Length != 8 || Green.Length != 8)
- {
- throw new ArgumentOutOfRangeException($"The pixel format with with RGB lengths of {Red.Length}:{Blue.Length}:{Green.Length} is not supported");
- }
-
- // Alpha can be present or absent, but must be 8 bytes long
- if (Alpha.Length is not (0 or 8))
- {
- throw new ArgumentOutOfRangeException($"The alpha length {Alpha.Length} is not supported");
- }
-
- // Gets the index at which the red, bue, green and alpha values are stored.
- int redIndex = (int)Red.Offset / 8;
- int blueIndex = (int)Blue.Offset / 8;
- int greenIndex = (int)Green.Offset / 8;
- int alphaIndex = (int)Alpha.Offset / 8;
-
- byte[] array = new byte[(int)Size * 4];
- // Loop over the array and re-order as required
- for (int i = 0; i < (int)Size; i += 4)
- {
- byte red = buffer[i + redIndex];
- byte blue = buffer[i + blueIndex];
- byte green = buffer[i + greenIndex];
- byte alpha = buffer[i + alphaIndex];
-
- // Convert to ARGB. Note, we're on a little endian system,
- // so it's really BGRA. Confusing!
- if (Alpha.Length == 8)
- {
- array[i + 3] = alpha;
- array[i + 2] = red;
- array[i + 1] = green;
- array[i + 0] = blue;
- }
- else
- {
- array[i + 3] = 0;
- array[i + 2] = red;
- array[i + 1] = green;
- array[i + 0] = blue;
- }
- }
- buffer = array;
-
- // Returns RGB or RGBA, function of the presence of an alpha channel.
- return Alpha.Length == 0 ? PixelFormat.Format32bppRgb : PixelFormat.Format32bppArgb;
- }
- else if (Bpp == 8 * 3)
- {
- // For 24-bit image depths, we only support RGB.
- if (Red.Offset == 0
- && Red.Length == 8
- && Green.Offset == 8
- && Green.Length == 8
- && Blue.Offset == 16
- && Blue.Length == 8
- && Alpha.Offset == 24
- && Alpha.Length == 0)
- {
- return PixelFormat.Format24bppRgb;
- }
- }
- else if (Bpp == 5 + 6 + 5
- && Red.Offset == 11
- && Red.Length == 5
- && Green.Offset == 5
- && Green.Length == 6
- && Blue.Offset == 0
- && Blue.Length == 5
- && Alpha.Offset == 0
- && Alpha.Length == 0)
- {
- // For 16-bit image depths, we only support Rgb565.
- return PixelFormat.Format16bppRgb565;
- }
-
- // If not caught by any of the statements before, the format is not supported.
- throw new NotSupportedException($"Pixel depths of {Bpp} are not supported");
- }
-#endif
-
-#if HAS_WUXC
- ///
- /// Gets is supported.
- ///
-#if NET
- [SupportedOSPlatformGuard("Windows10.0.18362.0")]
-#endif
- public static bool IsHasThreadAccessSupported { get; } = ApiInformation.IsMethodPresent("Windows.System.DispatcherQueue", "HasThreadAccess");
-
- ///
- /// Converts a array containing the raw frame buffer data to a .
- ///
- /// The buffer containing the image data.
- /// The target to invoke the code on.
- /// A which can be used to cancel the asynchronous task.
- /// A that represents the image contained in the frame buffer, or
- /// if the framebuffer does not contain any data. This can happen when DRM is enabled on the device.
- public Task ToBitmapAsync(byte[] buffer, CoreDispatcher dispatcher, CancellationToken cancellationToken = default)
- {
- if (dispatcher.HasThreadAccess)
- {
- return ToBitmapAsync(buffer, cancellationToken);
- }
- else
- {
- FramebufferHeader self = this;
- TaskCompletionSource taskCompletionSource = new();
- _ = dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
- {
- try
- {
- WriteableBitmap? result = await self.ToBitmapAsync(buffer, cancellationToken).ConfigureAwait(false);
- _ = taskCompletionSource.TrySetResult(result);
- }
- catch (Exception e)
- {
- _ = taskCompletionSource.TrySetException(e);
- }
- });
- return taskCompletionSource.Task;
- }
- }
-
- ///
- /// Converts a array containing the raw frame buffer data to a .
- ///
- /// The buffer containing the image data.
- /// The target to invoke the code on.
- /// A which can be used to cancel the asynchronous task.
- /// A that represents the image contained in the frame buffer, or
- /// if the framebuffer does not contain any data. This can happen when DRM is enabled on the device.
-#if NET
- [SupportedOSPlatform("Windows10.0.16299.0")]
-#endif
- [ContractVersion(typeof(UniversalApiContract), 0x50000u)]
- public Task ToBitmapAsync(byte[] buffer, DispatcherQueue dispatcher, CancellationToken cancellationToken = default)
- {
- if (IsHasThreadAccessSupported && dispatcher.HasThreadAccess)
- {
- return ToBitmapAsync(buffer, cancellationToken);
- }
- else
- {
- FramebufferHeader self = this;
- TaskCompletionSource taskCompletionSource = new();
- if (!dispatcher.TryEnqueue(async () =>
- {
- try
- {
- WriteableBitmap? result = await self.ToBitmapAsync(buffer, cancellationToken).ConfigureAwait(false);
- _ = taskCompletionSource.TrySetResult(result);
- }
- catch (Exception e)
- {
- _ = taskCompletionSource.TrySetException(e);
- }
- }))
- {
- _ = taskCompletionSource.TrySetException(new InvalidOperationException("Failed to enqueue the operation"));
- }
- return taskCompletionSource.Task;
- }
- }
-
- ///
- /// Converts a array containing the raw frame buffer data to a .
- ///
- /// The buffer containing the image data.
- /// A which can be used to cancel the asynchronous task.
- /// A that represents the image contained in the frame buffer, or
- /// if the framebuffer does not contain any data. This can happen when DRM is enabled on the device.
- public async Task ToBitmapAsync(byte[] buffer, CancellationToken cancellationToken = default)
- {
- ArgumentNullException.ThrowIfNull(buffer);
-
- // This happens, for example, when DRM is enabled. In that scenario, no screenshot is taken on the device and an empty
- // framebuffer is returned; we'll just return null.
- if (Width == 0 || Height == 0 || Bpp == 0)
- {
- return null;
- }
-
- // The pixel format of the framebuffer may not be one that WinRT recognizes, so we need to fix that
- BitmapPixelFormat bitmapPixelFormat = StandardizePixelFormat(buffer, out BitmapAlphaMode alphaMode);
-
- using InMemoryRandomAccessStream random = new();
- BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, random).AsTask(cancellationToken);
- encoder.SetPixelData(bitmapPixelFormat, alphaMode, Width, Height, 96, 96, buffer);
- await encoder.FlushAsync().AsTask(cancellationToken);
- WriteableBitmap WriteableImage = new((int)Width, (int)Height);
- await WriteableImage.SetSourceAsync(random).AsTask(cancellationToken).ConfigureAwait(false);
-
- return WriteableImage;
- }
-
- ///
- /// Returns the that describes pixel format of an image that is stored according to the information
- /// present in this . Because the enumeration does not allow for all
- /// formats supported by Android, this method also takes a and reorganizes the bytes in the buffer to
- /// match the return value of this function.
- ///
- /// A byte array in which the images are stored according to this .
- /// A which describes how the alpha channel is stored.
- /// A that describes how the image data is represented in this .
- private BitmapPixelFormat StandardizePixelFormat(byte[] buffer, out BitmapAlphaMode alphaMode)
- {
- // Initial parameter validation.
- ArgumentNullException.ThrowIfNull(buffer);
-
- if (buffer.Length < Width * Height * (Bpp / 8))
- {
- throw new ArgumentOutOfRangeException(nameof(buffer), $"The buffer length {buffer.Length} is less than expected buffer " +
- $"length ({Width * Height * (Bpp / 8)}) for a picture of width {Width}, height {Height} and pixel depth {Bpp}");
- }
-
- if (Width == 0 || Height == 0 || Bpp == 0)
- {
- throw new InvalidOperationException("Cannot cannulate the pixel format of an empty framebuffer");
- }
-
- // By far, the most common format is a 32-bit pixel format, which is either
- // RGB or RGBA, where each color has 1 byte.
- if (Bpp == 8 * 4)
- {
- // Require at least RGB to be present; and require them to be exactly one byte (8 bits) long.
- if (Red.Length != 8 || Blue.Length != 8 || Green.Length != 8)
- {
- throw new ArgumentOutOfRangeException($"The pixel format with with RGB lengths of {Red.Length}:{Blue.Length}:{Green.Length} is not supported");
- }
-
- // Alpha can be present or absent, but must be 8 bytes long
- alphaMode = Alpha.Length switch
- {
- 0 => BitmapAlphaMode.Ignore,
- 8 => BitmapAlphaMode.Straight,
- _ => throw new ArgumentOutOfRangeException($"The alpha length {Alpha.Length} is not supported"),
- };
-
- return BitmapPixelFormat.Rgba8;
- }
-
- // If not caught by any of the statements before, the format is not supported.
- throw new NotSupportedException($"Pixel depths of {Bpp} are not supported");
- }
+ public static FramebufferHeader Read(scoped ReadOnlySpan data) => new(data);
#endif
///
public override string ToString()
{
- DefaultInterpolatedStringHandler handler = new(121, 10);
+ scoped DefaultInterpolatedStringHandler handler = new(121, 10);
handler.AppendFormatted(GetType());
handler.AppendLiteral($" {{ {nameof(Version)} = ");
handler.AppendFormatted(Version);
diff --git a/AdvancedSharpAdbClient/Models/InstallProgress.EventArgs.cs b/AdvancedSharpAdbClient/Models/InstallProgress.EventArgs.cs
index 088cbed..b3f5b8e 100644
--- a/AdvancedSharpAdbClient/Models/InstallProgress.EventArgs.cs
+++ b/AdvancedSharpAdbClient/Models/InstallProgress.EventArgs.cs
@@ -88,7 +88,7 @@ public override string ToString()
split.Add(c);
}
- DefaultInterpolatedStringHandler builder = new(4, 4);
+ scoped DefaultInterpolatedStringHandler builder = new(4, 4);
#if NET
builder.AppendFormatted(CollectionsMarshal.AsSpan(split));
#elif HAS_BUFFERS
diff --git a/AdvancedSharpAdbClient/Models/ShellStream.cs b/AdvancedSharpAdbClient/Models/ShellStream.cs
index 09c6c93..b13bc35 100644
--- a/AdvancedSharpAdbClient/Models/ShellStream.cs
+++ b/AdvancedSharpAdbClient/Models/ShellStream.cs
@@ -70,7 +70,7 @@ public override long Position
#if HAS_BUFFERS
///
- public override int Read(Span buffer)
+ public override int Read(scoped Span buffer)
{
if (buffer.Length == 0)
{
diff --git a/AdvancedSharpAdbClient/Polyfills/Attributes/ExcludeFromCodeCoverageAttribute.cs b/AdvancedSharpAdbClient/Polyfills/Attributes/ExcludeFromCodeCoverageAttribute.cs
new file mode 100644
index 0000000..c268226
--- /dev/null
+++ b/AdvancedSharpAdbClient/Polyfills/Attributes/ExcludeFromCodeCoverageAttribute.cs
@@ -0,0 +1,19 @@
+#if !NET40_OR_GREATER && !NETCOREAPP && !COMP_NETSTANDARD2_0
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace System.Diagnostics.CodeAnalysis
+{
+ ///
+ /// Specifies that the attributed code should be excluded from code coverage information.
+ ///
+ [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)]
+ public sealed class ExcludeFromCodeCoverageAttribute : Attribute
+ {
+ ///
+ /// Gets or sets the justification for excluding the member from code coverage.
+ ///
+ public string? Justification { get; set; }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/AdvancedSharpAdbClient/Polyfills/Extensions/BitConverterExtensions.cs b/AdvancedSharpAdbClient/Polyfills/Extensions/BitConverterExtensions.cs
index 60eafe3..0d846a1 100644
--- a/AdvancedSharpAdbClient/Polyfills/Extensions/BitConverterExtensions.cs
+++ b/AdvancedSharpAdbClient/Polyfills/Extensions/BitConverterExtensions.cs
@@ -4,6 +4,7 @@
//
using System;
+using System.Runtime.CompilerServices;
namespace AdvancedSharpAdbClient.Polyfills
{
@@ -22,6 +23,7 @@ internal static class BitConverterExtensions
///
/// An array of bytes that includes the four bytes to convert.
/// A 32-bit signed integer representing the converted bytes.
+ [MethodImpl((MethodImplOptions)0x100)]
public static int ToInt32(byte[] value) => BitConverter.ToInt32(value, 0);
///
@@ -29,6 +31,7 @@ internal static class BitConverterExtensions
///
/// The array of bytes that includes the two bytes to convert.
/// An 16-bit unsigned integer representing the converted bytes.
+ [MethodImpl((MethodImplOptions)0x100)]
public static ushort ToUInt16(byte[] value) => BitConverter.ToUInt16(value, 0);
///
@@ -36,6 +39,7 @@ internal static class BitConverterExtensions
///
/// An array of bytes.
/// A 32-bit unsigned integer representing the converted bytes.
+ [MethodImpl((MethodImplOptions)0x100)]
public static uint ToUInt32(byte[] value) => BitConverter.ToUInt32(value, 0);
}
}
diff --git a/AdvancedSharpAdbClient/Polyfills/Extensions/ExceptionExtensions.cs b/AdvancedSharpAdbClient/Polyfills/Extensions/ExceptionExtensions.cs
index 7f8391f..736798e 100644
--- a/AdvancedSharpAdbClient/Polyfills/Extensions/ExceptionExtensions.cs
+++ b/AdvancedSharpAdbClient/Polyfills/Extensions/ExceptionExtensions.cs
@@ -4,6 +4,7 @@
//
using System;
+using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
diff --git a/AdvancedSharpAdbClient/Polyfills/Extensions/OperatingSystemExtensions.cs b/AdvancedSharpAdbClient/Polyfills/Extensions/OperatingSystemExtensions.cs
index a82a07a..7107a12 100644
--- a/AdvancedSharpAdbClient/Polyfills/Extensions/OperatingSystemExtensions.cs
+++ b/AdvancedSharpAdbClient/Polyfills/Extensions/OperatingSystemExtensions.cs
@@ -5,6 +5,7 @@
using System;
using System.ComponentModel;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace AdvancedSharpAdbClient.Polyfills
@@ -23,6 +24,7 @@ internal static class OperatingSystemExtensions
///
/// Indicates whether the current application is running on Windows.
///
+ [MethodImpl((MethodImplOptions)0x100)]
public static bool IsWindows() =>
#if NETCORE && !UAP10_0_15138_0
true;
@@ -40,6 +42,7 @@ or PlatformID.WinCE
///
/// Indicates whether the current application is running on Linux.
///
+ [MethodImpl((MethodImplOptions)0x100)]
public static bool IsLinux() =>
#if NETCORE && !UAP10_0_15138_0
false;
@@ -52,6 +55,7 @@ public static bool IsLinux() =>
///
/// Indicates whether the current application is running on macOS.
///
+ [MethodImpl((MethodImplOptions)0x100)]
public static bool IsMacOS() =>
#if NETCORE && !UAP10_0_15138_0
false;
@@ -63,6 +67,7 @@ public static bool IsMacOS() =>
///
/// Indicates whether the current application is running on FreeBSD.
///
+ [MethodImpl((MethodImplOptions)0x100)]
public static bool IsFreeBSD() =>
#if NETCOREAPP3_0_OR_GREATER
RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD);
diff --git a/AdvancedSharpAdbClient/Polyfills/Extensions/SocketExtensions.cs b/AdvancedSharpAdbClient/Polyfills/Extensions/SocketExtensions.cs
index 18c53b4..6369c61 100644
--- a/AdvancedSharpAdbClient/Polyfills/Extensions/SocketExtensions.cs
+++ b/AdvancedSharpAdbClient/Polyfills/Extensions/SocketExtensions.cs
@@ -7,6 +7,7 @@
using System.ComponentModel;
using System.Net;
using System.Net.Sockets;
+using System.Runtime.CompilerServices;
using System.Threading;
namespace AdvancedSharpAdbClient.Polyfills
@@ -25,6 +26,7 @@ internal static class SocketExtensions
/// The endpoint to connect to.
/// A cancellation token that can be used to cancel the asynchronous operation.
/// An asynchronous task that completes when the connection is established.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ConnectAsync(this Socket socket, EndPoint remoteEP, CancellationToken cancellationToken) =>
Task.Run(() => socket.Connect(remoteEP), cancellationToken);
#endif
@@ -39,6 +41,7 @@ public static Task ConnectAsync(this Socket socket, EndPoint remoteEP, Cancellat
/// A which can be used to cancel the asynchronous task.
/// Cancelling the task will also close the socket.
/// A which returns the number of bytes received.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ReceiveAsync(this Socket socket, byte[] buffer, SocketFlags socketFlags, CancellationToken cancellationToken = default) =>
socket.ReceiveAsync(buffer, 0, buffer.Length, socketFlags, cancellationToken);
#endif
@@ -53,6 +56,7 @@ public static Task ReceiveAsync(this Socket socket, byte[] buffer, SocketFl
/// A which can be used to cancel the asynchronous task.
/// Cancelling the task will also close the socket.
/// A which returns the number of bytes received.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task ReceiveAsync(this Socket socket, byte[] buffer, int size, SocketFlags socketFlags, CancellationToken cancellationToken = default) =>
socket.ReceiveAsync(buffer, 0, size, socketFlags, cancellationToken);
@@ -118,6 +122,7 @@ public static Task ReceiveAsync(this Socket socket, byte[] buffer, int offs
/// A which can be used to cancel the asynchronous task.
/// Cancelling the task will also close the socket.
/// A which returns the number of bytes sent.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task SendAsync(this Socket socket, byte[] buffer, SocketFlags socketFlags, CancellationToken cancellationToken = default) =>
socket.SendAsync(buffer, 0, buffer.Length, socketFlags, cancellationToken);
#endif
@@ -132,6 +137,7 @@ public static Task SendAsync(this Socket socket, byte[] buffer, SocketFlags
/// A which can be used to cancel the asynchronous task.
/// Cancelling the task will also close the socket.
/// A which returns the number of bytes sent.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task SendAsync(this Socket socket, byte[] buffer, int size, SocketFlags socketFlags, CancellationToken cancellationToken = default) =>
socket.SendAsync(buffer, 0, size, socketFlags, cancellationToken);
diff --git a/AdvancedSharpAdbClient/Polyfills/Extensions/StringExtensions.cs b/AdvancedSharpAdbClient/Polyfills/Extensions/StringExtensions.cs
index 6258670..eff6709 100644
--- a/AdvancedSharpAdbClient/Polyfills/Extensions/StringExtensions.cs
+++ b/AdvancedSharpAdbClient/Polyfills/Extensions/StringExtensions.cs
@@ -7,6 +7,7 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
using System.Text;
namespace AdvancedSharpAdbClient.Polyfills
@@ -56,6 +57,7 @@ public static bool IsNullOrWhiteSpace([NotNullWhen(false)] string? value)
/// One of the enumeration values that specifies the rules to use in the comparison.
/// if the parameter occurs within this string,
/// or if is the empty string (""); otherwise, .
+ [MethodImpl((MethodImplOptions)0x100)]
public bool Contains(string value, StringComparison comparisonType) => text.IndexOf(value, comparisonType) >= 0;
///
@@ -64,6 +66,7 @@ public static bool IsNullOrWhiteSpace([NotNullWhen(false)] string? value)
/// A character that delimits the substrings in this string.
/// A bitwise combination of the enumeration values that specifies whether to trim substrings and include empty substrings.
/// An array whose elements contain the substrings from this instance that are delimited by .
+ [MethodImpl((MethodImplOptions)0x100)]
public string[] Split(char separator, StringSplitOptions options = StringSplitOptions.None) => text.Split([separator], options);
///
@@ -76,6 +79,7 @@ public static bool IsNullOrWhiteSpace([NotNullWhen(false)] string? value)
/// The maximum number of elements expected in the array.
/// A bitwise combination of the enumeration values that specifies whether to trim substrings and include empty substrings.
/// An array that contains at most count substrings from this instance that are delimited by .
+ [MethodImpl((MethodImplOptions)0x100)]
public string[] Split(char separator, int count, StringSplitOptions options = StringSplitOptions.None) => text.Split([separator], count, options);
///
@@ -83,6 +87,7 @@ public static bool IsNullOrWhiteSpace([NotNullWhen(false)] string? value)
///
/// The character to compare.
/// if matches the beginning of this string; otherwise, .
+ [MethodImpl((MethodImplOptions)0x100)]
public bool StartsWith(char value) => text.StartsWith(new string([value]));
///
@@ -90,6 +95,7 @@ public static bool IsNullOrWhiteSpace([NotNullWhen(false)] string? value)
///
/// The character to compare to the character at the end of this instance.
/// if matches the end of this instance; otherwise, .
+ [MethodImpl((MethodImplOptions)0x100)]
public bool EndsWith(char value) => text.EndsWith(new string([value]));
///
diff --git a/AdvancedSharpAdbClient/Polyfills/Extensions/TaskCompletionSourceExtensions.cs b/AdvancedSharpAdbClient/Polyfills/Extensions/TaskCompletionSourceExtensions.cs
index 4e9a26e..a9eec07 100644
--- a/AdvancedSharpAdbClient/Polyfills/Extensions/TaskCompletionSourceExtensions.cs
+++ b/AdvancedSharpAdbClient/Polyfills/Extensions/TaskCompletionSourceExtensions.cs
@@ -1,5 +1,6 @@
#if !NET && HAS_TASK
global using TaskCompletionSource = System.Threading.Tasks.TaskCompletionSource
/// The to set the result for.
/// if the operation was successful; otherwise, .
+ [MethodImpl((MethodImplOptions)0x100)]
public static bool TrySetResult(this TaskCompletionSource source) => source.TrySetResult(null);
}
}
diff --git a/AdvancedSharpAdbClient/Polyfills/Extensions/TaskExExtensions.cs b/AdvancedSharpAdbClient/Polyfills/Extensions/TaskExExtensions.cs
index 5187655..1248d4f 100644
--- a/AdvancedSharpAdbClient/Polyfills/Extensions/TaskExExtensions.cs
+++ b/AdvancedSharpAdbClient/Polyfills/Extensions/TaskExExtensions.cs
@@ -6,6 +6,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
+using System.Runtime.CompilerServices;
using System.Threading;
#if NET40
@@ -54,6 +55,7 @@ internal static class TaskExExtensions
/// A Task that represents the work queued to execute in the ThreadPool.
/// The parameter was null.
/// The associated with was disposed.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task Run(Action action, CancellationToken cancellationToken) => TaskEx.Run(action, cancellationToken);
///
@@ -62,6 +64,7 @@ internal static class TaskExExtensions
/// The work to execute asynchronously
/// A that represents the work queued to execute in the ThreadPool.
/// The parameter was null.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task Run(Func function) => TaskEx.Run(function);
///
@@ -72,6 +75,7 @@ internal static class TaskExExtensions
/// A that represents the work queued to execute in the ThreadPool.
/// The parameter was null.
/// The associated with was disposed.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task Run(Func function, CancellationToken cancellationToken) => TaskEx.Run(function, cancellationToken);
///
@@ -81,6 +85,7 @@ internal static class TaskExExtensions
/// A cancellation token to observe while waiting for the task to complete.
/// A task that represents the time delay.
/// The argument is less than -1.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task Delay(int dueTime, CancellationToken cancellationToken = default) => TaskEx.Delay(dueTime, cancellationToken);
///
@@ -89,6 +94,7 @@ internal static class TaskExExtensions
/// The type of the result returned by the task.
/// The result to store into the completed task.
/// The successfully completed task.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task FromResult(TResult result) => TaskEx.FromResult(result);
#endif
}
@@ -99,6 +105,7 @@ internal static class TaskExExtensions
///
/// The tasks to wait on for completion.
/// A task that represents the completion of all of the supplied tasks.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task WhenAll(this IEnumerable tasks) =>
#if NETFRAMEWORK && !NET45_OR_GREATER
TaskEx
@@ -113,6 +120,7 @@ public static Task WhenAll(this IEnumerable tasks) =>
/// The type of the completed task.
/// The tasks to wait on for completion.
/// A task that represents the completion of all of the supplied tasks.
+ [MethodImpl((MethodImplOptions)0x100)]
public static Task WhenAll(this IEnumerable> tasks) =>
#if NETFRAMEWORK && !NET45_OR_GREATER
TaskEx
diff --git a/AdvancedSharpAdbClient/Polyfills/StringHandler.cs b/AdvancedSharpAdbClient/Polyfills/StringHandler.cs
index 2c4d078..d4183e5 100644
--- a/AdvancedSharpAdbClient/Polyfills/StringHandler.cs
+++ b/AdvancedSharpAdbClient/Polyfills/StringHandler.cs
@@ -278,7 +278,7 @@ public void AppendFormatted(string? value, int alignment = 0, string? format = n
/// Writes the specified character span to the handler.
///
/// The span to write.
- public void AppendFormatted(ReadOnlySpan value) => _ = _stringBuilder.Append(value);
+ public void AppendFormatted(scoped ReadOnlySpan value) => _ = _stringBuilder.Append(value);
///
/// Writes the specified string of chars to the handler.
@@ -286,7 +286,7 @@ public void AppendFormatted(string? value, int alignment = 0, string? format = n
/// The span to write.
/// Minimum number of characters that should be written for this value. If the value is negative, it indicates left-aligned and the required minimum is the absolute value.
/// The format string.
- public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? __ = null)
+ public void AppendFormatted(scoped ReadOnlySpan value, int alignment = 0, string? __ = null)
{
bool leftAlign = false;
if (alignment < 0)
@@ -428,5 +428,5 @@ private void AppendOrInsertAlignmentIfNeeded(int startingPos, int alignment)
}
}
#else
- [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.DefaultInterpolatedStringHandler))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.DefaultInterpolatedStringHandler))]
#endif
\ No newline at end of file
diff --git a/AdvancedSharpAdbClient/SyncService.Async.cs b/AdvancedSharpAdbClient/SyncService.Async.cs
index 853b15a..d59d823 100644
--- a/AdvancedSharpAdbClient/SyncService.Async.cs
+++ b/AdvancedSharpAdbClient/SyncService.Async.cs
@@ -684,7 +684,7 @@ protected async Task ReadStatisticsAsync(CancellationToken cance
#else
byte[] statResult = new byte[FileStatisticsData.Length];
_ = await Socket.ReadAsync(statResult, cancellationToken).ConfigureAwait(false);
- ref FileStatisticsData data = ref Unsafe.As(ref statResult[0]);
+ scoped ref FileStatisticsData data = ref Unsafe.As(ref statResult[0]);
return new FileStatistics(data);
#endif
}
@@ -704,7 +704,7 @@ protected async Task ReadStatisticsV2Async(CancellationToken c
#else
byte[] statResult = new byte[FileStatisticsDataEx.Length];
_ = await Socket.ReadAsync(statResult, cancellationToken).ConfigureAwait(false);
- ref FileStatisticsDataEx data = ref Unsafe.As(ref statResult[0]);
+ scoped ref FileStatisticsDataEx data = ref Unsafe.As(ref statResult[0]);
return new FileStatisticsEx(data);
#endif
}
diff --git a/AdvancedSharpAdbClient/SyncService.cs b/AdvancedSharpAdbClient/SyncService.cs
index 283fa4c..af96759 100644
--- a/AdvancedSharpAdbClient/SyncService.cs
+++ b/AdvancedSharpAdbClient/SyncService.cs
@@ -146,7 +146,7 @@ public void Reopen()
}
///
- public virtual void Push(Stream stream, string remotePath, UnixFileStatus permission, DateTimeOffset timestamp, Action? callback = null, bool useV2 = false, in bool isCancelled = false)
+ public virtual void Push(Stream stream, string remotePath, UnixFileStatus permission, DateTimeOffset timestamp, Action? callback = null, bool useV2 = false, scoped in bool isCancelled = false)
{
if (IsProcessing) { throw new InvalidOperationException($"The {nameof(SyncService)} is currently processing a request. Please {nameof(Clone)} a new {nameof(ISyncService)} or wait until the process is finished."); }
@@ -253,7 +253,7 @@ public virtual void Push(Stream stream, string remotePath, UnixFileStatus permis
}
///
- public virtual void Pull(string remoteFilePath, Stream stream, Action? callback = null, bool useV2 = false, in bool isCancelled = false)
+ public virtual void Pull(string remoteFilePath, Stream stream, Action? callback = null, bool useV2 = false, scoped in bool isCancelled = false)
{
if (IsProcessing) { throw new InvalidOperationException($"The {nameof(SyncService)} is currently processing a request. Please {nameof(Clone)} a new {nameof(ISyncService)} or wait until the process is finished."); }
@@ -515,14 +515,14 @@ Socket is ICloneable cloneable
protected FileStatistics ReadStatistics()
{
#if COMP_NETSTANDARD2_1
- Span statResult = stackalloc byte[FileStatisticsData.Length];
+ scoped Span statResult = stackalloc byte[FileStatisticsData.Length];
_ = Socket.Read(statResult);
FileStatisticsData data = EnumerableBuilder.FileStatisticsDataCreator(statResult);
return new FileStatistics(data);
#else
byte[] statResult = new byte[FileStatisticsData.Length];
_ = Socket.Read(statResult);
- ref FileStatisticsData data = ref Unsafe.As(ref statResult[0]);
+ scoped ref FileStatisticsData data = ref Unsafe.As(ref statResult[0]);
return new FileStatistics(data);
#endif
}
@@ -534,14 +534,14 @@ protected FileStatistics ReadStatistics()
protected FileStatisticsEx ReadStatisticsV2()
{
#if COMP_NETSTANDARD2_1
- Span statResult = stackalloc byte[FileStatisticsDataEx.Length];
+ scoped Span statResult = stackalloc byte[FileStatisticsDataEx.Length];
_ = Socket.Read(statResult);
FileStatisticsDataEx data = EnumerableBuilder.FileStatisticsDataV2Creator(statResult);
return new FileStatisticsEx(data);
#else
byte[] statResult = new byte[FileStatisticsDataEx.Length];
_ = Socket.Read(statResult);
- ref FileStatisticsDataEx data = ref Unsafe.As(ref statResult[0]);
+ scoped ref FileStatisticsDataEx data = ref Unsafe.As(ref statResult[0]);
return new FileStatisticsEx(data);
#endif
}
diff --git a/AdvancedSharpAdbClient/TcpSocket.cs b/AdvancedSharpAdbClient/TcpSocket.cs
index c27b652..33762a1 100644
--- a/AdvancedSharpAdbClient/TcpSocket.cs
+++ b/AdvancedSharpAdbClient/TcpSocket.cs
@@ -120,11 +120,11 @@ public int Receive(byte[] buffer, int offset, int size, SocketFlags socketFlags)
#if HAS_BUFFERS
///
- public int Send(ReadOnlySpan buffer, SocketFlags socketFlags) =>
+ public int Send(scoped ReadOnlySpan buffer, SocketFlags socketFlags) =>
Socket.Send(buffer, socketFlags);
///
- public int Receive(Span buffer, SocketFlags socketFlags) =>
+ public int Receive(scoped Span buffer, SocketFlags socketFlags) =>
Socket.Receive(buffer, socketFlags);
#endif
@@ -134,7 +134,7 @@ public int Receive(Span buffer, SocketFlags socketFlags) =>
///
public override string ToString()
{
- DefaultInterpolatedStringHandler handler = new(33, 1);
+ scoped DefaultInterpolatedStringHandler handler = new(33, 1);
handler.AppendLiteral("The ");
handler.AppendFormatted(GetType());
diff --git a/Directory.Build.props b/Directory.Build.props
index 8a3b2cc..3666d85 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -23,7 +23,7 @@
https://github.com/SharpAdb/AdvancedSharpAdbClientsnupkg.NET client for adb, Android Debug Bridge (AdvancedSharpAdbClient)
- 3.6.16
+ 3.7.17
diff --git a/Directory.Build.targets b/Directory.Build.targets
index ed5ce60..c2156f2 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -1,7 +1,7 @@
-
+ runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/README.md b/README.md
index 44ef31d..ba3fbea 100644
--- a/README.md
+++ b/README.md
@@ -56,8 +56,6 @@ if (!AdbServer.Instance.GetStatus().IsRunning)
### Connecting to device
Before using all the methods, you must initialize the new AdbClient class and then connect to the device
-If you want to automate 2 or more devices at the same time, you must remember: 1 device - 1 AdbClient class
-
You can look at the examples to understand more
```cs
diff --git a/global.json b/global.json
deleted file mode 100644
index f3cb0dc..0000000
--- a/global.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "msbuild-sdks": {
- "MSBuild.Sdk.Extras": "3.0.44"
- }
-}
\ No newline at end of file