Skip to content

Commit 8d23a47

Browse files
committed
Add send v2 and recv v2
Update adb source link
1 parent 64e398a commit 8d23a47

33 files changed

Lines changed: 1320 additions & 243 deletions

AdvancedSharpAdbClient.Tests/DeviceCommands/DeviceExtensionsTests.Async.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public async Task ClickHomeButtonAsyncTest()
9898
public async Task StatAsyncTest()
9999
{
100100
const string remotePath = "/test";
101-
FileStatistics stats = new();
101+
FileStatistics stats = new(default);
102102

103103
IAdbClient client = Substitute.For<IAdbClient>();
104104
ISyncService mock = Substitute.For<ISyncService>();
@@ -127,7 +127,7 @@ public async Task StatAsyncTest()
127127
public async Task GetDirectoryListingAsyncTest()
128128
{
129129
const string remotePath = "/test";
130-
List<FileStatistics> stats = [new()];
130+
List<FileStatistics> stats = [new(default)];
131131

132132
IAdbClient client = Substitute.For<IAdbClient>();
133133
ISyncService mock = Substitute.For<ISyncService>();
@@ -156,7 +156,7 @@ public async Task GetDirectoryListingAsyncTest()
156156
public async Task GetDirectoryAsyncListingTest()
157157
{
158158
const string remotePath = "/test";
159-
List<FileStatistics> stats = [new()];
159+
List<FileStatistics> stats = [new(default)];
160160

161161
IAdbClient client = Substitute.For<IAdbClient>();
162162
ISyncService mock = Substitute.For<ISyncService>();

AdvancedSharpAdbClient.Tests/DeviceCommands/DeviceExtensionsTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public void ClickHomeButtonTest()
9898
public void StatTest()
9999
{
100100
const string remotePath = "/test";
101-
FileStatistics stats = new();
101+
FileStatistics stats = new(default);
102102

103103
IAdbClient client = Substitute.For<IAdbClient>();
104104
ISyncService mock = Substitute.For<ISyncService>();
@@ -126,7 +126,7 @@ public void StatTest()
126126
public void GetDirectoryListingTest()
127127
{
128128
const string remotePath = "/test";
129-
IEnumerable<FileStatistics> stats = [new()];
129+
IEnumerable<FileStatistics> stats = [new(default)];
130130

131131
IAdbClient client = Substitute.For<IAdbClient>();
132132
ISyncService mock = Substitute.For<ISyncService>();

AdvancedSharpAdbClient.Tests/Dummys/DummyAdbSocket.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ internal partial class DummyAdbSocket : IDummyAdbSocket, ICloneable<DummyAdbSock
6464

6565
public void SendSyncRequest(SyncCommand command, string path, UnixFileStatus permission) => SyncRequests.Add((command, $"{path},{(int)permission}"));
6666

67+
public void SendSyncRequest(SyncCommand command, UnixFileStatus permission, SyncFlags flag) => SyncRequests.Add((command, $"{(int)permission}{(int)flag}"));
68+
6769
public void SendAdbRequest(string request) => Requests.Add(request);
6870

6971
public void SendAdbRequest(DefaultInterpolatedStringHandler request) => Requests.Add(request.ToString());
@@ -202,6 +204,12 @@ public async ValueTask SendAsync(ReadOnlyMemory<byte> data, CancellationToken ca
202204
Send(data.Span);
203205
}
204206

207+
public async Task SendSyncRequestAsync(SyncCommand command, UnixFileStatus permission, SyncFlags flags, CancellationToken cancellationToken = default)
208+
{
209+
await Task.Yield();
210+
SendSyncRequest(command, permission, flags);
211+
}
212+
205213
public async Task SendSyncRequestAsync(SyncCommand command, string path, UnixFileStatus permission, CancellationToken cancellationToken = default)
206214
{
207215
await Task.Yield();

AdvancedSharpAdbClient.Tests/Dummys/DummySyncService.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public async Task PullAsync(string remotePath, Stream stream, Action<SyncProgres
4242
}
4343
}
4444

45-
public void Push(Stream stream, string remotePath, UnixFileStatus permission, DateTimeOffset timestamp, Action<SyncProgressChangedEventArgs> callback = null, in bool isCancelled = false)
45+
public void Push(Stream stream, string remotePath, UnixFileStatus permission, DateTimeOffset timestamp, Action<SyncProgressChangedEventArgs> callback = null, bool useV2 = false, in bool isCancelled = false)
4646
{
4747
for (uint i = 0; i <= 100; i++)
4848
{
@@ -54,7 +54,7 @@ public void Push(Stream stream, string remotePath, UnixFileStatus permission, Da
5454
}
5555
}
5656

57-
public async Task PushAsync(Stream stream, string remotePath, UnixFileStatus permission, DateTimeOffset timestamp, Action<SyncProgressChangedEventArgs> callback = null, CancellationToken cancellationToken = default)
57+
public async Task PushAsync(Stream stream, string remotePath, UnixFileStatus permission, DateTimeOffset timestamp, Action<SyncProgressChangedEventArgs> callback = null, bool useV2 = false, CancellationToken cancellationToken = default)
5858
{
5959
for (uint i = 0; i <= 100; i++)
6060
{
@@ -79,23 +79,23 @@ public async Task ReopenAsync(CancellationToken cancellationToken = default)
7979

8080
IAsyncEnumerable<FileStatistics> ISyncService.GetDirectoryAsyncListing(string remotePath, CancellationToken cancellationToken) => throw new NotImplementedException();
8181

82-
IAsyncEnumerable<FileStatisticsV2> ISyncService.GetDirectoryAsyncListingV2(string remotePath, CancellationToken cancellationToken) => throw new NotImplementedException();
82+
IAsyncEnumerable<FileStatisticsEx> ISyncService.GetDirectoryAsyncListingEx(string remotePath, CancellationToken cancellationToken) => throw new NotImplementedException();
8383

8484
IEnumerable<FileStatistics> ISyncService.GetDirectoryListing(string remotePath) => throw new NotImplementedException();
8585

8686
Task<List<FileStatistics>> ISyncService.GetDirectoryListingAsync(string remotePath, CancellationToken cancellationToken) => throw new NotImplementedException();
8787

88-
IEnumerable<FileStatisticsV2> ISyncService.GetDirectoryListingV2(string remotePath) => throw new NotImplementedException();
88+
IEnumerable<FileStatisticsEx> ISyncService.GetDirectoryListingEx(string remotePath) => throw new NotImplementedException();
8989

90-
Task<List<FileStatisticsV2>> ISyncService.GetDirectoryListingV2Async(string remotePath, CancellationToken cancellationToken) => throw new NotImplementedException();
90+
Task<List<FileStatisticsEx>> ISyncService.GetDirectoryListingExAsync(string remotePath, CancellationToken cancellationToken) => throw new NotImplementedException();
9191

9292
FileStatistics ISyncService.Stat(string remotePath) => throw new NotImplementedException();
9393

9494
Task<FileStatistics> ISyncService.StatAsync(string remotePath, CancellationToken cancellationToken) => throw new NotImplementedException();
9595

96-
FileStatisticsV2 ISyncService.StatV2(string remotePath) => throw new NotImplementedException();
96+
FileStatisticsEx ISyncService.StatEx(string remotePath) => throw new NotImplementedException();
9797

98-
Task<FileStatisticsV2> ISyncService.StatV2Async(string remotePath, CancellationToken cancellationToken) => throw new NotImplementedException();
98+
Task<FileStatisticsEx> ISyncService.StatExAsync(string remotePath, CancellationToken cancellationToken) => throw new NotImplementedException();
9999

100100
#endregion
101101
}

AdvancedSharpAdbClient.Tests/SyncServiceTests.Async.cs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,57 @@ public async Task StatAsyncTest()
4141
Assert.Equal($"-rw-r-----\t597\t{value.Time}\t/fstab.donatello", value.ToString());
4242
}
4343

44+
/// <summary>
45+
/// Tests the <see cref="SyncService.StatExAsync(string, CancellationToken)"/> method.
46+
/// </summary>
47+
[Fact]
48+
public async Task StatExAsyncTest()
49+
{
50+
FileStatisticsEx value = await RunTestAsync(
51+
OkResponses(2),
52+
NoResponseMessages,
53+
["host:transport:169.254.109.177:5555", "sync:"],
54+
[(SyncCommand.STA2, "/fstab.donatello")],
55+
[SyncCommand.STA2],
56+
[[
57+
0, 0, 0, 0,
58+
167, 0, 0, 0, 0, 0, 0, 0,
59+
38, 240, 15, 0, 0, 0, 0, 0,
60+
160, 129, 0, 0,
61+
1, 0, 0, 0,
62+
146, 39, 0, 0,
63+
255, 3, 0, 0,
64+
85, 2, 0, 0, 0, 0, 0, 0,
65+
0, 0, 0, 0, 0, 0, 0, 0,
66+
0, 0, 0, 0, 0, 0, 0, 0,
67+
0, 0, 0, 0, 0, 0, 0, 0
68+
]],
69+
null,
70+
async () =>
71+
{
72+
using SyncService service = new(Socket, Device);
73+
FileStatisticsEx value = await service.StatExAsync("/fstab.donatello");
74+
Assert.False(service.IsProcessing);
75+
Assert.False(service.IsOutdate);
76+
return value;
77+
});
78+
79+
Assert.Equal("/fstab.donatello", value.Path);
80+
Assert.Equal(UnixErrorCode.Default, value.Error);
81+
Assert.Equal(167u, value.Device);
82+
Assert.Equal(1044518u, value.IndexNode);
83+
Assert.Equal(UnixFileStatus.Regular, value.FileMode.GetFileType());
84+
Assert.Equal((UnixFileStatus)416, value.FileMode.GetPermissions());
85+
Assert.Equal(1u, value.LinkCount);
86+
Assert.Equal(597u, value.Size);
87+
Assert.Equal(10130u, value.UserId);
88+
Assert.Equal(1023u, value.GroupId);
89+
Assert.Equal(DateTimeExtensions.Epoch.ToLocalTime(), value.AccessTime);
90+
Assert.Equal(DateTimeExtensions.Epoch.ToLocalTime(), value.ModifiedTime);
91+
Assert.Equal(DateTimeExtensions.Epoch.ToLocalTime(), value.ChangedTime);
92+
Assert.Equal($"-rw-r-----\t597\t{value.ModifiedTime}\t/fstab.donatello", value.ToString());
93+
}
94+
4495
/// <summary>
4596
/// Tests the <see cref="SyncService.GetDirectoryListingAsync(string, CancellationToken)"/> method.
4697
/// </summary>
@@ -201,7 +252,7 @@ await RunTestAsync(
201252
}
202253

203254
/// <summary>
204-
/// Tests the <see cref="SyncService.PushAsync(Stream, string, UnixFileStatus, DateTimeOffset, Action{SyncProgressChangedEventArgs}?, CancellationToken)"/> method.
255+
/// Tests the <see cref="SyncService.PushAsync(Stream, string, UnixFileStatus, DateTimeOffset, Action{SyncProgressChangedEventArgs}?, bool, CancellationToken)"/> method.
205256
/// </summary>
206257
[Fact]
207258
public async Task PushAsyncTest()

AdvancedSharpAdbClient.Tests/SyncServiceTests.cs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,57 @@ public void StatTest()
4949
Assert.Equal($"-rw-r-----\t597\t{value.Time}\t/fstab.donatello", value.ToString());
5050
}
5151

52+
/// <summary>
53+
/// Tests the <see cref="SyncService.StatEx(string)"/> method.
54+
/// </summary>
55+
[Fact]
56+
public void StatExTest()
57+
{
58+
FileStatisticsEx value = RunTest(
59+
OkResponses(2),
60+
NoResponseMessages,
61+
["host:transport:169.254.109.177:5555", "sync:"],
62+
[(SyncCommand.STA2, "/fstab.donatello")],
63+
[SyncCommand.STA2],
64+
[[
65+
0, 0, 0, 0,
66+
167, 0, 0, 0, 0, 0, 0, 0,
67+
38, 240, 15, 0, 0, 0, 0, 0,
68+
160, 129, 0, 0,
69+
1, 0, 0, 0,
70+
146, 39, 0, 0,
71+
255, 3, 0, 0,
72+
85, 2, 0, 0, 0, 0, 0, 0,
73+
0, 0, 0, 0, 0, 0, 0, 0,
74+
0, 0, 0, 0, 0, 0, 0, 0,
75+
0, 0, 0, 0, 0, 0, 0, 0
76+
]],
77+
null,
78+
() =>
79+
{
80+
using SyncService service = new(Socket, Device);
81+
FileStatisticsEx value = service.StatEx("/fstab.donatello");
82+
Assert.False(service.IsProcessing);
83+
Assert.False(service.IsOutdate);
84+
return value;
85+
});
86+
87+
Assert.Equal("/fstab.donatello", value.Path);
88+
Assert.Equal(UnixErrorCode.Default, value.Error);
89+
Assert.Equal(167u, value.Device);
90+
Assert.Equal(1044518u, value.IndexNode);
91+
Assert.Equal(UnixFileStatus.Regular, value.FileMode.GetFileType());
92+
Assert.Equal((UnixFileStatus)416, value.FileMode.GetPermissions());
93+
Assert.Equal(1u, value.LinkCount);
94+
Assert.Equal(597u, value.Size);
95+
Assert.Equal(10130u, value.UserId);
96+
Assert.Equal(1023u, value.GroupId);
97+
Assert.Equal(DateTimeExtensions.Epoch.ToLocalTime(), value.AccessTime);
98+
Assert.Equal(DateTimeExtensions.Epoch.ToLocalTime(), value.ModifiedTime);
99+
Assert.Equal(DateTimeExtensions.Epoch.ToLocalTime(), value.ChangedTime);
100+
Assert.Equal($"-rw-r-----\t597\t{value.ModifiedTime}\t/fstab.donatello", value.ToString());
101+
}
102+
52103
/// <summary>
53104
/// Tests the <see cref="SyncService.GetDirectoryListing(string)"/> method.
54105
/// </summary>
@@ -148,7 +199,7 @@ public void PullTest()
148199
}
149200

150201
/// <summary>
151-
/// Tests the <see cref="SyncService.Push(Stream, string, UnixFileStatus, DateTimeOffset, Action{SyncProgressChangedEventArgs}?, in bool)"/> method.
202+
/// Tests the <see cref="SyncService.Push(Stream, string, UnixFileStatus, DateTimeOffset, Action{SyncProgressChangedEventArgs}?, bool, in bool)"/> method.
152203
/// </summary>
153204
[Fact]
154205
public void PushTest()

AdvancedSharpAdbClient/AdbClient.Async.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ protected async Task RootAsync(string request, DeviceData device, CancellationTo
554554
Encoding.GetString(buffer, 0, read);
555555
#endif
556556

557-
// see https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/master/daemon/restart_service.cpp
557+
// see https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/main/daemon/restart_service.cpp
558558
// for possible return strings
559559
if (!responseMessage.Contains("restarting", StringComparison.OrdinalIgnoreCase))
560560
{

AdvancedSharpAdbClient/AdbClient.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,7 @@ protected void Root(string request, DeviceData device)
728728
Encoding.GetString(buffer, 0, read);
729729
#endif
730730

731-
// see https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/master/daemon/restart_service.cpp
731+
// see https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/main/daemon/restart_service.cpp
732732
// for possible return strings
733733
if (!responseMessage.Contains("restarting", StringComparison.OrdinalIgnoreCase))
734734
{

AdvancedSharpAdbClient/AdbSocket.Async.cs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,25 @@ public virtual async Task SendAsync(byte[] data, int offset, int length, Cancell
7878
}
7979
}
8080

81+
/// <inheritdoc/>
82+
public async Task SendSyncRequestAsync(SyncCommand command, UnixFileStatus permissions, SyncFlags flags, CancellationToken cancellationToken = default)
83+
{
84+
byte[] commandBytes = command.GetBytes();
85+
byte[] modeBytes = BitConverter.GetBytes((uint)permissions.GetPermissions());
86+
byte[] flagsBytes = BitConverter.GetBytes((int)flags);
87+
88+
if (!BitConverter.IsLittleEndian)
89+
{
90+
// Convert from big endian to little endian
91+
Array.Reverse(modeBytes);
92+
Array.Reverse(flagsBytes);
93+
}
94+
95+
_ = await WriteAsync(commandBytes, cancellationToken).ConfigureAwait(false);
96+
_ = await WriteAsync(modeBytes, cancellationToken).ConfigureAwait(false);
97+
_ = await WriteAsync(flagsBytes, cancellationToken).ConfigureAwait(false);
98+
}
99+
81100
/// <inheritdoc/>
82101
public Task SendSyncRequestAsync(SyncCommand command, string path, UnixFileStatus permissions, CancellationToken cancellationToken = default) =>
83102
SendSyncRequestAsync(command, $"{path},{(int)permissions.GetPermissions()}", cancellationToken);
@@ -92,15 +111,15 @@ public async Task SendSyncRequestAsync(SyncCommand command, string path, Cancell
92111
}
93112

94113
/// <inheritdoc/>
95-
public async Task SendSyncRequestAsync(SyncCommand command, int length, CancellationToken cancellationToken = default)
114+
public async Task SendSyncRequestAsync(SyncCommand command, int value, CancellationToken cancellationToken = default)
96115
{
97116
// The message structure is:
98117
// First four bytes: command
99118
// Next four bytes: length of the path
100119
// Final bytes: path
101120
byte[] commandBytes = command.GetBytes();
102121

103-
byte[] lengthBytes = BitConverter.GetBytes(length);
122+
byte[] lengthBytes = BitConverter.GetBytes(value);
104123

105124
if (!BitConverter.IsLittleEndian)
106125
{

AdvancedSharpAdbClient/AdbSocket.cs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace AdvancedSharpAdbClient
2121
/// Bridge exposes, use the <see cref="AdbClient"/>.</para>
2222
/// <para>For more information about the protocol that is implemented here, see chapter
2323
/// II Protocol Details, section 1. Client &lt;-&gt;Server protocol at
24-
/// <see href="https://android.googlesource.com/platform/system/core/+/master/adb/OVERVIEW.TXT"/>.</para>
24+
/// <see href="https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/main/docs/dev/overview.md"/>.</para>
2525
/// </summary>
2626
/// <param name="socket">The <see cref="ITcpSocket"/> at which the Android Debug Bridge is listening for clients.</param>
2727
/// <param name="logger">The logger to use when logging.</param>
@@ -154,6 +154,25 @@ public virtual void Send(byte[] data, int offset, int length)
154154
}
155155
}
156156

157+
/// <inheritdoc/>
158+
public void SendSyncRequest(SyncCommand command, UnixFileStatus permissions, SyncFlags flags)
159+
{
160+
byte[] commandBytes = command.GetBytes();
161+
byte[] modeBytes = BitConverter.GetBytes((uint)permissions.GetPermissions());
162+
byte[] flagsBytes = BitConverter.GetBytes((int)flags);
163+
164+
if (!BitConverter.IsLittleEndian)
165+
{
166+
// Convert from big endian to little endian
167+
Array.Reverse(modeBytes);
168+
Array.Reverse(flagsBytes);
169+
}
170+
171+
_ = Write(commandBytes);
172+
_ = Write(modeBytes);
173+
_ = Write(flagsBytes);
174+
}
175+
157176
/// <inheritdoc/>
158177
public void SendSyncRequest(SyncCommand command, string path, UnixFileStatus permissions) =>
159178
SendSyncRequest(command, $"{path},{(int)permissions.GetPermissions()}");
@@ -168,15 +187,15 @@ public void SendSyncRequest(SyncCommand command, string path)
168187
}
169188

170189
/// <inheritdoc/>
171-
public void SendSyncRequest(SyncCommand command, int length)
190+
public void SendSyncRequest(SyncCommand command, int value)
172191
{
173192
// The message structure is:
174193
// First four bytes: command
175194
// Next four bytes: length of the path
176195
// Final bytes: path
177196
byte[] commandBytes = command.GetBytes();
178197

179-
byte[] lengthBytes = BitConverter.GetBytes(length);
198+
byte[] lengthBytes = BitConverter.GetBytes(value);
180199

181200
if (!BitConverter.IsLittleEndian)
182201
{

0 commit comments

Comments
 (0)