implement Milestone 15: sensor interface with fingerprinting prevention
This commit is contained in:
@@ -28,6 +28,7 @@ add_library(mosis-sandbox STATIC
|
||||
../src/main/cpp/sandbox/microphone_interface.cpp
|
||||
../src/main/cpp/sandbox/audio_output.cpp
|
||||
../src/main/cpp/sandbox/location_interface.cpp
|
||||
../src/main/cpp/sandbox/sensor_interface.cpp
|
||||
)
|
||||
target_include_directories(mosis-sandbox PUBLIC
|
||||
../src/main/cpp/sandbox
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "microphone_interface.h"
|
||||
#include "audio_output.h"
|
||||
#include "location_interface.h"
|
||||
#include "sensor_interface.h"
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
@@ -2519,6 +2520,173 @@ bool Test_LocationLuaIntegration(std::string& error_msg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Milestone 15: Sensors
|
||||
//=============================================================================
|
||||
|
||||
bool Test_SensorRequiresPermission(std::string& error_msg) {
|
||||
mosis::SensorInterface sensors("test.app");
|
||||
// No permissions granted
|
||||
|
||||
std::string err;
|
||||
auto sub = sensors.Subscribe("accelerometer", {}, err);
|
||||
|
||||
EXPECT_TRUE(sub == nullptr);
|
||||
EXPECT_TRUE(err.find("permission") != std::string::npos);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Test_SensorAutoGrantsEnvironmental(std::string& error_msg) {
|
||||
mosis::SensorInterface sensors("test.app");
|
||||
// No motion permission
|
||||
|
||||
std::string err;
|
||||
|
||||
// Proximity should work without permission
|
||||
auto proxSub = sensors.Subscribe("proximity", {}, err);
|
||||
EXPECT_TRUE(proxSub != nullptr);
|
||||
EXPECT_TRUE(proxSub->IsActive());
|
||||
|
||||
// Light should work without permission
|
||||
auto lightSub = sensors.Subscribe("light", {}, err);
|
||||
EXPECT_TRUE(lightSub != nullptr);
|
||||
EXPECT_TRUE(lightSub->IsActive());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Test_SensorReducesPrecision(std::string& error_msg) {
|
||||
mosis::SensorInterface sensors("test.app");
|
||||
sensors.SetMotionPermission(true);
|
||||
|
||||
std::string err;
|
||||
auto sub = sensors.Subscribe("accelerometer", {}, err);
|
||||
EXPECT_TRUE(sub != nullptr);
|
||||
|
||||
mosis::SensorData received;
|
||||
bool got_data = false;
|
||||
|
||||
sub->SetOnData([&](const mosis::SensorData& data) {
|
||||
got_data = true;
|
||||
received = data;
|
||||
});
|
||||
|
||||
// Simulate high-precision data
|
||||
mosis::SensorData precise;
|
||||
precise.x = 9.80665123456;
|
||||
precise.y = 0.12345678901;
|
||||
precise.z = -0.98765432109;
|
||||
precise.timestamp = 1234567890;
|
||||
|
||||
// Apply precision reduction manually (as SimulateData bypasses it)
|
||||
mosis::SensorData reduced = sensors.ApplyPrecision(precise);
|
||||
sub->SimulateData(reduced);
|
||||
|
||||
EXPECT_TRUE(got_data);
|
||||
// Values should be rounded to 2 decimal places
|
||||
EXPECT_TRUE(std::abs(received.x - 9.81) < 0.001);
|
||||
EXPECT_TRUE(std::abs(received.y - 0.12) < 0.001);
|
||||
EXPECT_TRUE(std::abs(received.z - (-0.99)) < 0.001);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Test_SensorLimitsFrequency(std::string& error_msg) {
|
||||
mosis::SensorInterface sensors("test.app");
|
||||
sensors.SetMotionPermission(true);
|
||||
|
||||
mosis::SensorOptions options;
|
||||
options.frequency = 120; // Request 120 Hz
|
||||
|
||||
std::string err;
|
||||
auto sub = sensors.Subscribe("gyroscope", options, err);
|
||||
|
||||
EXPECT_TRUE(sub != nullptr);
|
||||
// Should be capped at 60 Hz
|
||||
EXPECT_TRUE(sub->GetFrequency() <= 60);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Test_SensorSubscriptionLimit(std::string& error_msg) {
|
||||
mosis::SensorInterface sensors("test.app");
|
||||
sensors.SetMotionPermission(true);
|
||||
|
||||
std::vector<std::shared_ptr<mosis::SensorSubscription>> subs;
|
||||
std::string err;
|
||||
|
||||
// Create MAX_SUBSCRIPTIONS (10)
|
||||
for (int i = 0; i < 10; i++) {
|
||||
auto sub = sensors.Subscribe("accelerometer", {}, err);
|
||||
EXPECT_TRUE(sub != nullptr);
|
||||
subs.push_back(sub);
|
||||
}
|
||||
|
||||
// 11th should fail
|
||||
auto extra = sensors.Subscribe("accelerometer", {}, err);
|
||||
EXPECT_TRUE(extra == nullptr);
|
||||
EXPECT_TRUE(err.find("limit") != std::string::npos ||
|
||||
err.find("maximum") != std::string::npos);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Test_SensorCleansUpOnShutdown(std::string& error_msg) {
|
||||
mosis::SensorInterface sensors("test.app");
|
||||
sensors.SetMotionPermission(true);
|
||||
|
||||
std::string err;
|
||||
auto sub1 = sensors.Subscribe("accelerometer", {}, err);
|
||||
auto sub2 = sensors.Subscribe("gyroscope", {}, err);
|
||||
|
||||
EXPECT_TRUE(sensors.GetActiveSubscriptionCount() == 2);
|
||||
|
||||
sensors.Shutdown();
|
||||
|
||||
EXPECT_TRUE(sensors.GetActiveSubscriptionCount() == 0);
|
||||
EXPECT_TRUE(!sub1->IsActive());
|
||||
EXPECT_TRUE(!sub2->IsActive());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Test_SensorLuaIntegration(std::string& error_msg) {
|
||||
SandboxContext ctx = TestContext();
|
||||
LuaSandbox sandbox(ctx);
|
||||
|
||||
mosis::SensorInterface sensors("test.app");
|
||||
mosis::RegisterSensorAPI(sandbox.GetState(), &sensors);
|
||||
|
||||
std::string script = R"lua(
|
||||
-- Test that sensors global exists
|
||||
if not sensors then
|
||||
error("sensors global not found")
|
||||
end
|
||||
if not sensors.subscribe then
|
||||
error("sensors.subscribe not found")
|
||||
end
|
||||
if not sensors.unsubscribeAll then
|
||||
error("sensors.unsubscribeAll not found")
|
||||
end
|
||||
if not sensors.getSubscriptionCount then
|
||||
error("sensors.getSubscriptionCount not found")
|
||||
end
|
||||
|
||||
-- Subscription count should be 0 initially
|
||||
if sensors.getSubscriptionCount() ~= 0 then
|
||||
error("should have no active subscriptions initially")
|
||||
end
|
||||
)lua";
|
||||
|
||||
bool ok = sandbox.LoadString(script, "sensor_test");
|
||||
if (!ok) {
|
||||
error_msg = "Lua test failed: " + sandbox.GetLastError();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// MAIN
|
||||
//=============================================================================
|
||||
@@ -2693,6 +2861,15 @@ int main(int argc, char* argv[]) {
|
||||
harness.AddTest("LocationCleansUpOnShutdown", Test_LocationCleansUpOnShutdown);
|
||||
harness.AddTest("LocationLuaIntegration", Test_LocationLuaIntegration);
|
||||
|
||||
// Milestone 15: Sensors
|
||||
harness.AddTest("SensorRequiresPermission", Test_SensorRequiresPermission);
|
||||
harness.AddTest("SensorAutoGrantsEnvironmental", Test_SensorAutoGrantsEnvironmental);
|
||||
harness.AddTest("SensorReducesPrecision", Test_SensorReducesPrecision);
|
||||
harness.AddTest("SensorLimitsFrequency", Test_SensorLimitsFrequency);
|
||||
harness.AddTest("SensorSubscriptionLimit", Test_SensorSubscriptionLimit);
|
||||
harness.AddTest("SensorCleansUpOnShutdown", Test_SensorCleansUpOnShutdown);
|
||||
harness.AddTest("SensorLuaIntegration", Test_SensorLuaIntegration);
|
||||
|
||||
// Run tests
|
||||
auto results = harness.Run(filter);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user