Skip to content

Commit a60f0c5

Browse files
author
Vit Nemecky
committed
Merge branch 'default' into local/feature/win-adv-devices
2 parents d9c1bc7 + b67a33d commit a60f0c5

67 files changed

Lines changed: 1771 additions & 934 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

BrickController2.sln

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{02EA681E
1515
EndProject
1616
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BrickController2.Tests", "BrickController2\BrickController2.Tests\BrickController2.Tests.csproj", "{7981CBBF-BB2F-4AF4-BEF3-3CF0C92DBB23}"
1717
EndProject
18+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{5AFB0DE9-536E-4C5D-831A-421ADC3EF3D9}"
19+
EndProject
20+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BrickController2.Tools", "BrickController2\BrickController2.Tools\BrickController2.Tools.csproj", "{C127AB50-E104-2345-5239-13258E2B7474}"
21+
EndProject
1822
Global
1923
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2024
Debug|Any CPU = Debug|Any CPU
@@ -103,12 +107,25 @@ Global
103107
{7981CBBF-BB2F-4AF4-BEF3-3CF0C92DBB23}.Release|ARM64.Build.0 = Release|Any CPU
104108
{7981CBBF-BB2F-4AF4-BEF3-3CF0C92DBB23}.Release|x64.ActiveCfg = Release|Any CPU
105109
{7981CBBF-BB2F-4AF4-BEF3-3CF0C92DBB23}.Release|x64.Build.0 = Release|Any CPU
110+
{C127AB50-E104-2345-5239-13258E2B7474}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
111+
{C127AB50-E104-2345-5239-13258E2B7474}.Debug|Any CPU.Build.0 = Debug|Any CPU
112+
{C127AB50-E104-2345-5239-13258E2B7474}.Debug|ARM64.ActiveCfg = Debug|Any CPU
113+
{C127AB50-E104-2345-5239-13258E2B7474}.Debug|ARM64.Build.0 = Debug|Any CPU
114+
{C127AB50-E104-2345-5239-13258E2B7474}.Debug|x64.ActiveCfg = Debug|Any CPU
115+
{C127AB50-E104-2345-5239-13258E2B7474}.Debug|x64.Build.0 = Debug|Any CPU
116+
{C127AB50-E104-2345-5239-13258E2B7474}.Release|Any CPU.ActiveCfg = Release|Any CPU
117+
{C127AB50-E104-2345-5239-13258E2B7474}.Release|Any CPU.Build.0 = Release|Any CPU
118+
{C127AB50-E104-2345-5239-13258E2B7474}.Release|ARM64.ActiveCfg = Release|Any CPU
119+
{C127AB50-E104-2345-5239-13258E2B7474}.Release|ARM64.Build.0 = Release|Any CPU
120+
{C127AB50-E104-2345-5239-13258E2B7474}.Release|x64.ActiveCfg = Release|Any CPU
121+
{C127AB50-E104-2345-5239-13258E2B7474}.Release|x64.Build.0 = Release|Any CPU
106122
EndGlobalSection
107123
GlobalSection(SolutionProperties) = preSolution
108124
HideSolutionNode = FALSE
109125
EndGlobalSection
110126
GlobalSection(NestedProjects) = preSolution
111127
{7981CBBF-BB2F-4AF4-BEF3-3CF0C92DBB23} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
128+
{C127AB50-E104-2345-5239-13258E2B7474} = {5AFB0DE9-536E-4C5D-831A-421ADC3EF3D9}
112129
EndGlobalSection
113130
GlobalSection(ExtensibilityGlobals) = postSolution
114131
SolutionGuid = {024A01F8-4022-4F9E-A006-AC2CABB04620}

BrickController2/BrickController2.Android/PlatformServices/DI/PlatformServicesModule.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using Autofac;
2-
using BrickController2.DeviceManagement;
3-
using BrickController2.Droid.PlatformServices.DeviceManagement;
2+
using BrickController2.DeviceManagement.CaDA;
3+
using BrickController2.DeviceManagement.MouldKing;
44
using BrickController2.Droid.PlatformServices.BluetoothLE;
5+
using BrickController2.Droid.PlatformServices.DeviceManagement.CaDA;
6+
using BrickController2.Droid.PlatformServices.DeviceManagement.MouldKing;
57
using BrickController2.Droid.PlatformServices.GameController;
68
using BrickController2.Droid.PlatformServices.Infrared;
79
using BrickController2.Droid.PlatformServices.Localization;
@@ -32,6 +34,7 @@ protected override void Load(ContainerBuilder builder)
3234
builder.RegisterType<BluetoothPermission>().As<IBluetoothPermission>().InstancePerDependency();
3335
builder.RegisterType<CameraPermission>().As<ICameraPermission>().InstancePerDependency();
3436
builder.RegisterType<MKPlatformService>().As<IMKPlatformService>().SingleInstance();
37+
builder.RegisterType<CaDAPlatformService>().As<ICaDAPlatformService>().SingleInstance();
3538
}
3639
}
3740
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using BrickController2.DeviceManagement.CaDA;
2+
using BrickController2.Protocols;
3+
4+
namespace BrickController2.Droid.PlatformServices.DeviceManagement.CaDA;
5+
6+
public class CaDAPlatformService : ICaDAPlatformService
7+
{
8+
private const int HeaderOffset = 15;
9+
private const int PayloadLength = 24;
10+
11+
public bool TryGetRfPayload(byte[] rawData, out byte[] rfPayload)
12+
{
13+
rfPayload = new byte[PayloadLength];
14+
15+
int payloadLength = CryptTools.GetRfPayload(CaDAProtocol.SeedArray, CaDAProtocol.HeaderArray, rawData, HeaderOffset, CaDAProtocol.CTXValue1, CaDAProtocol.CTXValue2, rfPayload);
16+
17+
return true;
18+
}
19+
}

BrickController2/BrickController2.Android/PlatformServices/DeviceManagement/MouldKing/MKPlatformService.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
using BrickController2.DeviceManagement;
1+
using BrickController2.DeviceManagement.MouldKing;
22
using BrickController2.Protocols;
33

4-
namespace BrickController2.Droid.PlatformServices.DeviceManagement;
4+
namespace BrickController2.Droid.PlatformServices.DeviceManagement.MouldKing;
55

6-
public class MKPlatformService : IMKPlatformService
6+
public class MKPlatformService : IMKPlatformService
77
{
88
private const int HeaderOffset = 15;
99
private const int PayloadLength = 24;
1010

1111
public bool TryGetRfPayload(byte[] rawData, out byte[] rfPayload)
1212
{
1313
rfPayload = new byte[PayloadLength];
14-
int payloadLength = MKProtocol.GetRfPayload(MKProtocol.SeedArray, rawData, HeaderOffset, MKProtocol.CTXValue1, MKProtocol.CTXValue2, rfPayload);
14+
int payloadLength = CryptTools.GetRfPayload(MKProtocol.SeedArray, MKProtocol.HeaderArray, rawData, HeaderOffset, MKProtocol.CTXValue1, MKProtocol.CTXValue2, rfPayload);
1515

1616
// fill rest of array
1717
for (int index = payloadLength; index < PayloadLength; index++)

BrickController2/BrickController2.Android/PlatformServices/GameController/GamepadController.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public GamepadController(GameControllerService service, InputDevice gamePad)
2424
: base(service, gamePad)
2525
{
2626
// initialize properties
27-
Name = gamePad.Name!;
27+
Name = GetDisplayName(gamePad);
2828
VendorId = gamePad.VendorId;
2929
ProductId = gamePad.ProductId;
3030
ControllerNumber = gamePad.ControllerNumber;
@@ -96,5 +96,26 @@ internal bool OnAxisEvent(MotionEvent e)
9696

9797
return true;
9898
}
99+
100+
private static string GetDisplayName(InputDevice device)
101+
{
102+
// Try Name first
103+
if (!string.IsNullOrWhiteSpace(device.Name))
104+
return device.Name;
105+
106+
var deviceType = device.Sources switch
107+
{
108+
var s when s.HasFlag(InputSourceType.Gamepad) => "Gamepad",
109+
var s when s.HasFlag(InputSourceType.Joystick) => "Joystick",
110+
var s when s.HasFlag(InputSourceType.Dpad) => "DPad",
111+
_ => "Device"
112+
};
113+
114+
// apply some fallbacks using VendorId / ProductId if possible
115+
if (device.VendorId != 0 || device.ProductId != 0)
116+
return $"{deviceType} ({device.VendorId:X4}:{device.ProductId:X4})";
117+
118+
return $"{deviceType}";
119+
}
99120
}
100121
}

BrickController2/BrickController2.Android/PlatformServices/GameController/InputEventExtensions.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ internal static bool IsGameControllerButtonEvent(this KeyEvent? keyEvent) => key
88
keyEvent.Source.IsButtonEventSource() &&
99
keyEvent.RepeatCount == 0;
1010

11-
internal static bool IsButtonEventSource(this InputSourceType sourceType) => sourceType.HasFlag(InputSourceType.Gamepad);
11+
internal static bool IsButtonEventSource(this InputSourceType sourceType) => sourceType.HasFlag(InputSourceType.Gamepad) ||
12+
sourceType.HasFlag(InputSourceType.Dpad);
1213

1314
internal static bool IsGameControllerAxisEvent(this MotionEvent? motionEvent) => motionEvent != null &&
1415
motionEvent.Source.IsAxisEventSource() &&
1516
motionEvent.Action == MotionEventActions.Move;
1617

17-
internal static bool IsAxisEventSource(this InputSourceType sourceType) => sourceType.HasFlag(InputSourceType.Joystick);
18+
internal static bool IsAxisEventSource(this InputSourceType sourceType) => sourceType.HasFlag(InputSourceType.Joystick) ||
19+
sourceType.HasFlag(InputSourceType.Dpad);
1820
}

BrickController2/BrickController2.Tests/BrickController2.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
</ItemGroup>
1515

1616
<ItemGroup>
17+
<ProjectReference Include="..\BrickController2.Tools\BrickController2.Tools.csproj" />
1718
<ProjectReference Include="..\BrickController2\BrickController2.csproj" />
1819
</ItemGroup>
1920

BrickController2/BrickController2.Tests/DeviceManagement/CaDA/CaDADeviceManagerTests.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,21 @@ public class CaDADeviceManagerTests
1313
{
1414
private readonly CaDADeviceManager _manager;
1515
private readonly Mock<IPreferencesService> _preferencesService = new(MockBehavior.Strict);
16+
private readonly Mock<ICaDAPlatformService> _cadaPlatformService = new(MockBehavior.Strict);
1617

1718
public CaDADeviceManagerTests()
1819
{
1920
_preferencesService.Setup(x => x.ContainsKey("AppID", "CaDA")).Returns(true);
2021
_preferencesService.Setup(x => x.Get("AppID", "", "CaDA")).Returns("YWJj");
2122

22-
_manager = new CaDADeviceManager(_preferencesService.Object);
23+
_cadaPlatformService.Setup(x => x.TryGetRfPayload(It.IsAny<byte[]>(), out It.Ref<byte[]>.IsAny))
24+
.Callback((byte[] input, out byte[] rfPayload) =>
25+
{
26+
rfPayload = new byte[] { 0x61, 0x62, 0x63 }; // Example AppID bytes
27+
})
28+
.Returns(true);
29+
30+
_manager = new CaDADeviceManager(_preferencesService.Object, _cadaPlatformService.Object);
2331
}
2432

2533
[Fact]
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using Autofac;
2+
using BrickController2.DeviceManagement;
3+
using BrickController2.DeviceManagement.DI;
4+
using BrickController2.DeviceManagement.MouldKing;
5+
using BrickController2.Settings;
6+
using FluentAssertions;
7+
using Xunit;
8+
9+
using MouldKingVendor = BrickController2.DeviceManagement.MouldKing.MouldKing;
10+
11+
namespace BrickController2.Tests.DeviceManagement.DI;
12+
13+
public class DeviceBuilderTests
14+
{
15+
[Fact]
16+
public void WithDeviceFactory_MouldKingVendor_ReturnedDeviceFactoryHasCorreectProperties()
17+
{
18+
// Arrange
19+
var builder = new ContainerBuilder();
20+
var deviceBuilder = new DeviceBuilder<MouldKingVendor, MK4>(new VendorBuilder<MouldKingVendor>(builder, new MouldKingVendor()));
21+
22+
string address = "00:11:22:33:44:55";
23+
string name = "TestDevice";
24+
byte[] deviceData = [1, 2, 3];
25+
var settings = new[]
26+
{
27+
new NamedSetting() { Name = "Setting1", Value = 42 }
28+
};
29+
30+
// Act
31+
deviceBuilder.WithDeviceFactory(address, name, deviceData, settings);
32+
var container = builder.Build();
33+
var factoryData = container.Resolve<IDeviceFactoryData>();
34+
35+
// Assert
36+
factoryData.Should().NotBeNull();
37+
factoryData.Name.Should().Be(name);
38+
factoryData.Address.Should().Be(address);
39+
factoryData.DeviceData.Should().BeEquivalentTo(deviceData);
40+
factoryData.Settings.Should().BeEquivalentTo(settings);
41+
factoryData.VendorName.Should().Be("Mould King");
42+
factoryData.DeviceTypeName.Should().Be("MK 4.0");
43+
}
44+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using Autofac;
2+
using BrickController2.DeviceManagement;
3+
using BrickController2.DeviceManagement.DI;
4+
using BrickController2.DeviceManagement.MouldKing;
5+
using BrickController2.PlatformServices.BluetoothLE;
6+
using BrickController2.Settings;
7+
using FluentAssertions;
8+
using Moq;
9+
using Xunit;
10+
11+
using MouldKingVendor = BrickController2.DeviceManagement.MouldKing.MouldKing;
12+
13+
namespace BrickController2.Tests.DeviceManagement.DI;
14+
15+
public class VendorBuilderTests
16+
{
17+
[Fact]
18+
public void RegisterDevice_MK6_ReturnedDevice()
19+
{
20+
// Arrange
21+
var builder = new ContainerBuilder();
22+
builder.RegisterInstance(Mock.Of<IDeviceRepository>());
23+
builder.RegisterInstance(Mock.Of<IBluetoothLEService>());
24+
builder.RegisterInstance(Mock.Of<IMKPlatformService>());
25+
26+
var vendorBuilder = new VendorBuilder<MouldKingVendor>(builder, new MouldKingVendor());
27+
28+
// Act
29+
var deviceBuilder = vendorBuilder.RegisterDevice<MK6>();
30+
var container = builder.Build();
31+
32+
// Assert
33+
deviceBuilder.Should().BeOfType<DeviceBuilder<MouldKingVendor, MK6>>();
34+
35+
string address = "Device2";
36+
string name = "TestDevice";
37+
byte[] deviceData = [1, 2, 3];
38+
var device = container.ResolveKeyed<Device>(DeviceType.MK6,
39+
new NamedParameter(nameof(name), name),
40+
new NamedParameter(nameof(address), address),
41+
new NamedParameter(nameof(deviceData), deviceData));
42+
43+
device.Should().NotBeNull();
44+
device.Should().BeOfType<MK6>();
45+
}
46+
}

0 commit comments

Comments
 (0)