Merge "libui: log an error on allocation failure" into oc-dev
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index ae4c797..ff838ce 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -313,8 +313,7 @@
+ 1 // filter
+ 1 // volume
+ 1 // libs
- + 1 // seinfo
- + 1; // null
+ + 1; // seinfo
if (argc == kV2ArgCount) {
return ReadArgumentsV2(argc, argv, false);
} else {
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index 1f56a47..45bb1d0 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -65,11 +65,7 @@
static bool check_mac_perms(pid_t spid, uid_t uid, const char *tctx, const char *perm, const char *name)
{
char *sctx = NULL;
-#ifdef VENDORSERVICEMANAGER
- const char *class = "vndservice_manager";
-#else
const char *class = "service_manager";
-#endif
bool allowed;
struct audit_data ad;
diff --git a/libs/vr/libdisplay/include/private/dvr/late_latch.h b/libs/vr/libdisplay/include/private/dvr/late_latch.h
index d0eff51..b7c5e4f 100644
--- a/libs/vr/libdisplay/include/private/dvr/late_latch.h
+++ b/libs/vr/libdisplay/include/private/dvr/late_latch.h
@@ -178,6 +178,9 @@
LateLatchOutput* eds_late_latch_output_;
DvrPose* pose_client_;
+
+ pdx::LocalHandle surface_metadata_fd_;
+ pdx::LocalHandle pose_buffer_fd_;
};
} // namespace dvr
diff --git a/libs/vr/libdisplay/late_latch.cpp b/libs/vr/libdisplay/late_latch.cpp
index b1a1589..e67f009 100644
--- a/libs/vr/libdisplay/late_latch.cpp
+++ b/libs/vr/libdisplay/late_latch.cpp
@@ -252,7 +252,8 @@
LocalHandle&& surface_metadata_fd)
: is_app_late_latch_(is_app_late_latch),
app_late_latch_output_(NULL),
- eds_late_latch_output_(NULL) {
+ eds_late_latch_output_(NULL),
+ surface_metadata_fd_(std::move(surface_metadata_fd)) {
CHECK_GL();
glGenBuffers(1, &input_buffer_id_);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, input_buffer_id_);
@@ -264,12 +265,11 @@
GL_DYNAMIC_COPY);
CHECK_GL();
- LocalHandle pose_buffer_fd;
pose_client_ = dvrPoseCreate();
if (!pose_client_) {
ALOGE("LateLatch Error: failed to create pose client");
} else {
- int ret = privateDvrPoseGetRingBufferFd(pose_client_, &pose_buffer_fd);
+ int ret = privateDvrPoseGetRingBufferFd(pose_client_, &pose_buffer_fd_);
if (ret < 0) {
ALOGE("LateLatch Error: failed to get pose ring buffer");
}
@@ -280,20 +280,20 @@
if (!glBindSharedBufferQCOM) {
ALOGE("Error: Missing gralloc buffer extension, no pose data");
} else {
- if (pose_buffer_fd) {
+ if (pose_buffer_fd_) {
glBindBuffer(GL_SHADER_STORAGE_BUFFER, pose_buffer_object_);
glBindSharedBufferQCOM(GL_SHADER_STORAGE_BUFFER,
kPoseAsyncBufferTotalCount * sizeof(DvrPoseAsync),
- pose_buffer_fd.Release());
+ pose_buffer_fd_.Get());
}
CHECK_GL();
}
glBindBuffer(GL_SHADER_STORAGE_BUFFER, metadata_buffer_id_);
- if (surface_metadata_fd && glBindSharedBufferQCOM) {
+ if (surface_metadata_fd_ && glBindSharedBufferQCOM) {
glBindSharedBufferQCOM(GL_SHADER_STORAGE_BUFFER,
sizeof(DisplaySurfaceMetadata),
- surface_metadata_fd.Release());
+ surface_metadata_fd_.Get());
} else {
// Fall back on internal metadata buffer when none provided, for example
// when distortion is done in the application process.
diff --git a/libs/vr/libeds/Android.bp b/libs/vr/libeds/Android.bp
index 85e43cc..a149853 100644
--- a/libs/vr/libeds/Android.bp
+++ b/libs/vr/libeds/Android.bp
@@ -19,7 +19,6 @@
"display_metrics.cpp",
"distortion_renderer.cpp",
"device_metrics.cpp",
- "lookup_radial_distortion.cpp",
"polynomial_radial_distortion.cpp",
]
diff --git a/libs/vr/libeds/device_metrics.cpp b/libs/vr/libeds/device_metrics.cpp
index 50c3e54..68ee186 100644
--- a/libs/vr/libeds/device_metrics.cpp
+++ b/libs/vr/libeds/device_metrics.cpp
@@ -3,14 +3,12 @@
#include <cutils/properties.h>
#include <private/dvr/head_mount_metrics.h>
#include <private/dvr/identity_distortion.h>
-#include <private/dvr/lookup_radial_distortion.h>
#include <private/dvr/polynomial_radial_distortion.h>
#include <private/dvr/types.h>
#include "include/private/dvr/display_metrics.h"
namespace {
-static constexpr char kRGBPolynomialOffset[] = "persist.dvr.rgb_poly_offset";
static constexpr char kRPolynomial[] = "persist.dvr.r_poly";
static constexpr char kGPolynomial[] = "persist.dvr.g_poly";
static constexpr char kBPolynomial[] = "persist.dvr.b_poly";
@@ -68,7 +66,9 @@
float GetDisplayGap() { return GetProperty(kDisplayGap, 0.0f); }
-float GetVEyeToDisplay() { return GetProperty(kVEyeToDisplay, 0.035f); }
+float GetTrayToLensDistance() { return 0.035f; }
+
+float GetVEyeToDisplay() { return GetProperty(kVEyeToDisplay, 0.042f); }
android::dvr::vec2 GetDisplaySize() {
static const std::vector<float> default_size = {0.0742177f, 0.131943f};
@@ -110,33 +110,23 @@
HeadMountMetrics CreateHeadMountMetrics(const FieldOfView& l_fov,
const FieldOfView& r_fov) {
static const std::vector<float> default_r = {
- -4.08519004f, 34.70282075f, -67.37781249f, 56.97304235f,
- -23.35768685f, 4.7199597f, 0.63198082f};
+ 0.00103f, 2.63917f, -7.14427f, 8.98036f, -4.10586f, 0.83705f, 0.00130f};
static const std::vector<float> default_g = {
- 4.43078318f, 3.47806617f, -20.58017398f, 20.85880414f,
- -8.4046504f, 1.61284685f, 0.8881761f};
+ 0.08944f, 2.26005f, -6.30924f, 7.94561f, -3.22788f, 0.45577f, 0.07300f};
static const std::vector<float> default_b = {
- 12.04141265f, -21.98112491f, 14.06758389f, -3.15245629f,
- 0.36549102f, 0.05252705f, 0.99844279f};
- static const std::vector<float> default_offsets = {
- 0.20971645238f, 0.15189450000f, 1.00096958278f};
-
- std::vector<float> poly_offsets =
- GetProperty(kRGBPolynomialOffset, default_offsets);
+ 0.16364f, 1.94083f, -5.55033f, 6.89578f, -2.19053f, -0.04050f, 0.17380f};
std::vector<float> poly_r = GetProperty(kRPolynomial, default_r);
std::vector<float> poly_g = GetProperty(kGPolynomial, default_g);
std::vector<float> poly_b = GetProperty(kBPolynomial, default_b);
- if (poly_offsets.size() != 3)
- poly_offsets = default_offsets;
std::shared_ptr<ColorChannelDistortion> distortion_r(
- new PolynomialRadialDistortion(poly_offsets[0], poly_r));
+ new PolynomialRadialDistortion(poly_r));
std::shared_ptr<ColorChannelDistortion> distortion_g(
- new PolynomialRadialDistortion(poly_offsets[1], poly_g));
+ new PolynomialRadialDistortion(poly_g));
std::shared_ptr<ColorChannelDistortion> distortion_b(
- new PolynomialRadialDistortion(poly_offsets[2], poly_b));
+ new PolynomialRadialDistortion(poly_b));
- return HeadMountMetrics(GetInterLensDistance(), GetVEyeToDisplay(),
+ return HeadMountMetrics(GetInterLensDistance(), GetTrayToLensDistance(),
GetVEyeToDisplay(), kDefaultVerticalAlignment, l_fov,
r_fov, distortion_r, distortion_g, distortion_b,
HeadMountMetrics::EyeOrientation::kCCW0Degrees,
diff --git a/libs/vr/libeds/include/private/dvr/lookup_radial_distortion.h b/libs/vr/libeds/include/private/dvr/lookup_radial_distortion.h
deleted file mode 100644
index 56fc5db..0000000
--- a/libs/vr/libeds/include/private/dvr/lookup_radial_distortion.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef ANDROID_DVR_LOOKUP_RADIAL_DISTORTION_H_
-#define ANDROID_DVR_LOOKUP_RADIAL_DISTORTION_H_
-
-#include <vector>
-
-#include <private/dvr/color_channel_distortion.h>
-
-namespace android {
-namespace dvr {
-
-// LookupRadialDistortion implements a radial distortion based using using a
-// vector of tan(angle) -> multipliers. This can use measured data directly.
-class LookupRadialDistortion : public ColorChannelDistortion {
- public:
- // lookup.x = tan(angle), lookup.y = distance from center multiplier.
- explicit LookupRadialDistortion(const vec2* lookup, size_t count);
-
- vec2 Distort(vec2 p) const override;
- vec2 DistortInverse(vec2 p) const override;
-
- private:
- float DistortionFactor(float r) const;
- float DistortRadius(float r) const;
-
- std::vector<vec2> lookup_;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_LOOKUP_RADIAL_DISTORTION_H_
diff --git a/libs/vr/libeds/include/private/dvr/polynomial_radial_distortion.h b/libs/vr/libeds/include/private/dvr/polynomial_radial_distortion.h
index c1f1ce9..8f080aa 100644
--- a/libs/vr/libeds/include/private/dvr/polynomial_radial_distortion.h
+++ b/libs/vr/libeds/include/private/dvr/polynomial_radial_distortion.h
@@ -28,8 +28,7 @@
// in the distortion equation: coefficients[0] is K1, coefficients[1] is K2,
// etc. Thus the polynomial used for distortion has degree
// (2 * coefficients.size()).
- explicit PolynomialRadialDistortion(float polynomial_offset,
- const std::vector<float>& coefficients);
+ explicit PolynomialRadialDistortion(const std::vector<float>& coefficients);
// Given a radius (measuring distance from the optical axis of the lens),
// returns the distortion factor for that radius.
@@ -52,10 +51,6 @@
const std::vector<float>& GetCoefficients() const;
private:
- // This is makes the polynomial work nicer with a specific lens that doesn't
- // fit nicely to a lower order polynomial. It's basically piecewise
- // line->poly.
- float polynomial_offset_;
std::vector<float> coefficients_;
};
diff --git a/libs/vr/libeds/lookup_radial_distortion.cpp b/libs/vr/libeds/lookup_radial_distortion.cpp
deleted file mode 100644
index 2cee863..0000000
--- a/libs/vr/libeds/lookup_radial_distortion.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#include "include/private/dvr/lookup_radial_distortion.h"
-
-namespace android {
-namespace dvr {
-
-LookupRadialDistortion::LookupRadialDistortion(const vec2* lookup, size_t count)
- : lookup_(lookup, lookup + count) {}
-
-float LookupRadialDistortion::DistortionFactor(float r) const {
- for (size_t i = 1; i < lookup_.size(); ++i) {
- if (lookup_[i].x() > r) {
- float t =
- (r - lookup_[i - 1].x()) / (lookup_[i].x() - lookup_[i - 1].x());
- return lookup_[i - 1].y() + t * (lookup_[i].y() - lookup_[i - 1].y());
- }
- }
- return lookup_.back().y();
-}
-
-float LookupRadialDistortion::DistortRadius(float r) const {
- return r * DistortionFactor(r);
-}
-
-vec2 LookupRadialDistortion::Distort(vec2 p) const {
- return p * DistortionFactor(p.norm());
-}
-
-vec2 LookupRadialDistortion::DistortInverse(vec2 p) const {
- // Secant method.
- const float radius = p.norm();
- float r0 = radius / 0.9f;
- float r1 = radius * 0.9f;
- float r2;
- float dr0 = radius - DistortRadius(r0);
- float dr1;
- while (fabsf(r1 - r0) > 0.0001f /** 0.1mm */) {
- dr1 = radius - DistortRadius(r1);
- r2 = r1 - dr1 * ((r1 - r0) / (dr1 - dr0));
- r0 = r1;
- r1 = r2;
- dr0 = dr1;
- }
- return (r1 / radius) * p;
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libeds/polynomial_radial_distortion.cpp b/libs/vr/libeds/polynomial_radial_distortion.cpp
index a0c6ea3..fa01bb4 100644
--- a/libs/vr/libeds/polynomial_radial_distortion.cpp
+++ b/libs/vr/libeds/polynomial_radial_distortion.cpp
@@ -4,13 +4,10 @@
namespace dvr {
PolynomialRadialDistortion::PolynomialRadialDistortion(
- float polynomial_offset, const std::vector<float>& coefficients)
- : polynomial_offset_(polynomial_offset), coefficients_(coefficients) {}
+ const std::vector<float>& coefficients)
+ : coefficients_(coefficients) {}
float PolynomialRadialDistortion::DistortionFactor(float r_squared) const {
- if (r_squared < polynomial_offset_)
- return 1.0f;
-
float r_factor = 1.0f;
float distortion_factor = 1.0f;
diff --git a/libs/vr/libpdx_uds/Android.bp b/libs/vr/libpdx_uds/Android.bp
index f2bcc0c..cfc2022 100644
--- a/libs/vr/libpdx_uds/Android.bp
+++ b/libs/vr/libpdx_uds/Android.bp
@@ -35,6 +35,7 @@
"-Werror",
],
srcs: [
+ "client_channel_tests.cpp",
"ipc_helper_tests.cpp",
"remote_method_tests.cpp",
"service_framework_tests.cpp",
diff --git a/libs/vr/libpdx_uds/client_channel.cpp b/libs/vr/libpdx_uds/client_channel.cpp
index 924335f..9d91617 100644
--- a/libs/vr/libpdx_uds/client_channel.cpp
+++ b/libs/vr/libpdx_uds/client_channel.cpp
@@ -156,6 +156,7 @@
Status<void> ClientChannel::SendImpulse(int opcode, const void* buffer,
size_t length) {
+ std::unique_lock<std::mutex> lock(socket_mutex_);
Status<void> status;
android::pdx::uds::RequestHeader<BorrowedHandle> request;
if (length > request.impulse_payload.size() ||
@@ -174,6 +175,7 @@
size_t send_count,
const iovec* receive_vector,
size_t receive_count) {
+ std::unique_lock<std::mutex> lock(socket_mutex_);
Status<int> result;
if ((send_vector == nullptr && send_count != 0) ||
(receive_vector == nullptr && receive_count != 0)) {
diff --git a/libs/vr/libpdx_uds/client_channel_factory.cpp b/libs/vr/libpdx_uds/client_channel_factory.cpp
index 9202cd5..850c6d3 100644
--- a/libs/vr/libpdx_uds/client_channel_factory.cpp
+++ b/libs/vr/libpdx_uds/client_channel_factory.cpp
@@ -39,32 +39,42 @@
ClientChannelFactory::ClientChannelFactory(const std::string& endpoint_path)
: endpoint_path_{GetEndpointPath(endpoint_path)} {}
+ClientChannelFactory::ClientChannelFactory(LocalHandle socket)
+ : socket_{std::move(socket)} {}
+
std::unique_ptr<pdx::ClientChannelFactory> ClientChannelFactory::Create(
const std::string& endpoint_path) {
return std::unique_ptr<pdx::ClientChannelFactory>{
new ClientChannelFactory{endpoint_path}};
}
+std::unique_ptr<pdx::ClientChannelFactory> ClientChannelFactory::Create(
+ LocalHandle socket) {
+ return std::unique_ptr<pdx::ClientChannelFactory>{
+ new ClientChannelFactory{std::move(socket)}};
+}
+
Status<std::unique_ptr<pdx::ClientChannel>> ClientChannelFactory::Connect(
int64_t timeout_ms) const {
Status<void> status;
- LocalHandle socket_fd{socket(AF_UNIX, SOCK_STREAM, 0)};
- if (!socket_fd) {
+ bool connected = socket_.IsValid();
+ if (!connected) {
+ socket_.Reset(socket(AF_UNIX, SOCK_STREAM, 0));
+ LOG_ALWAYS_FATAL_IF(
+ endpoint_path_.empty(),
+ "ClientChannelFactory::Connect: unspecified socket path");
+ }
+
+ if (!socket_) {
ALOGE("ClientChannelFactory::Connect: socket error: %s", strerror(errno));
return ErrorStatus(errno);
}
- sockaddr_un remote;
- remote.sun_family = AF_UNIX;
- strncpy(remote.sun_path, endpoint_path_.c_str(), sizeof(remote.sun_path));
- remote.sun_path[sizeof(remote.sun_path) - 1] = '\0';
-
bool use_timeout = (timeout_ms >= 0);
auto now = steady_clock::now();
auto time_end = now + std::chrono::milliseconds{timeout_ms};
- bool connected = false;
int max_eaccess = 5; // Max number of times to retry when EACCES returned.
while (!connected) {
int64_t timeout = -1;
@@ -74,6 +84,10 @@
if (timeout < 0)
return ErrorStatus(ETIMEDOUT);
}
+ sockaddr_un remote;
+ remote.sun_family = AF_UNIX;
+ strncpy(remote.sun_path, endpoint_path_.c_str(), sizeof(remote.sun_path));
+ remote.sun_path[sizeof(remote.sun_path) - 1] = '\0';
ALOGD("ClientChannelFactory: Waiting for endpoint at %s", remote.sun_path);
status = WaitForEndpoint(endpoint_path_, timeout);
if (!status)
@@ -81,7 +95,7 @@
ALOGD("ClientChannelFactory: Connecting to %s", remote.sun_path);
int ret = RETRY_EINTR(connect(
- socket_fd.Get(), reinterpret_cast<sockaddr*>(&remote), sizeof(remote)));
+ socket_.Get(), reinterpret_cast<sockaddr*>(&remote), sizeof(remote)));
if (ret == -1) {
ALOGD("ClientChannelFactory: Connect error %d: %s", errno,
strerror(errno));
@@ -107,20 +121,20 @@
}
} else {
connected = true;
+ ALOGD("ClientChannelFactory: Connected successfully to %s...",
+ remote.sun_path);
}
if (use_timeout)
now = steady_clock::now();
} // while (!connected)
- ALOGD("ClientChannelFactory: Connected successfully to %s...",
- remote.sun_path);
RequestHeader<BorrowedHandle> request;
InitRequest(&request, opcodes::CHANNEL_OPEN, 0, 0, false);
- status = SendData(socket_fd.Borrow(), request);
+ status = SendData(socket_.Borrow(), request);
if (!status)
return ErrorStatus(status.error());
ResponseHeader<LocalHandle> response;
- status = ReceiveData(socket_fd.Borrow(), &response);
+ status = ReceiveData(socket_.Borrow(), &response);
if (!status)
return ErrorStatus(status.error());
int ref = response.ret_code;
@@ -129,7 +143,7 @@
LocalHandle event_fd = std::move(response.file_descriptors[ref]);
return ClientChannel::Create(ChannelManager::Get().CreateHandle(
- std::move(socket_fd), std::move(event_fd)));
+ std::move(socket_), std::move(event_fd)));
}
} // namespace uds
diff --git a/libs/vr/libpdx_uds/client_channel_tests.cpp b/libs/vr/libpdx_uds/client_channel_tests.cpp
new file mode 100644
index 0000000..7c3c68a
--- /dev/null
+++ b/libs/vr/libpdx_uds/client_channel_tests.cpp
@@ -0,0 +1,162 @@
+#include <uds/client_channel.h>
+
+#include <sys/socket.h>
+
+#include <algorithm>
+#include <limits>
+#include <random>
+#include <thread>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <pdx/client.h>
+#include <pdx/rpc/remote_method.h>
+#include <pdx/service.h>
+
+#include <uds/client_channel_factory.h>
+#include <uds/service_endpoint.h>
+
+using testing::Return;
+using testing::_;
+
+using android::pdx::ClientBase;
+using android::pdx::LocalChannelHandle;
+using android::pdx::LocalHandle;
+using android::pdx::Message;
+using android::pdx::ServiceBase;
+using android::pdx::ServiceDispatcher;
+using android::pdx::Status;
+using android::pdx::rpc::DispatchRemoteMethod;
+using android::pdx::uds::ClientChannel;
+using android::pdx::uds::ClientChannelFactory;
+using android::pdx::uds::Endpoint;
+
+namespace {
+
+struct TestProtocol {
+ using DataType = int8_t;
+ enum {
+ kOpSum = 0,
+ };
+ PDX_REMOTE_METHOD(Sum, kOpSum, int64_t(const std::vector<DataType>&));
+};
+
+class TestService : public ServiceBase<TestService> {
+ public:
+ TestService(std::unique_ptr<Endpoint> endpoint)
+ : ServiceBase{"TestService", std::move(endpoint)} {}
+
+ Status<void> HandleMessage(Message& message) override {
+ switch (message.GetOp()) {
+ case TestProtocol::kOpSum:
+ DispatchRemoteMethod<TestProtocol::Sum>(*this, &TestService::OnSum,
+ message);
+ return {};
+
+ default:
+ return Service::HandleMessage(message);
+ }
+ }
+
+ int64_t OnSum(Message& /*message*/,
+ const std::vector<TestProtocol::DataType>& data) {
+ return std::accumulate(data.begin(), data.end(), int64_t{0});
+ }
+};
+
+class TestClient : public ClientBase<TestClient> {
+ public:
+ using ClientBase::ClientBase;
+
+ int64_t Sum(const std::vector<TestProtocol::DataType>& data) {
+ auto status = InvokeRemoteMethod<TestProtocol::Sum>(data);
+ return status ? status.get() : -1;
+ }
+};
+
+class TestServiceRunner {
+ public:
+ TestServiceRunner(LocalHandle channel_socket) {
+ auto endpoint = Endpoint::CreateFromSocketFd(LocalHandle{});
+ endpoint->RegisterNewChannelForTests(std::move(channel_socket));
+ service_ = TestService::Create(std::move(endpoint));
+ dispatcher_ = android::pdx::uds::ServiceDispatcher::Create();
+ dispatcher_->AddService(service_);
+ dispatch_thread_ = std::thread(
+ std::bind(&ServiceDispatcher::EnterDispatchLoop, dispatcher_.get()));
+ }
+
+ ~TestServiceRunner() {
+ dispatcher_->SetCanceled(true);
+ dispatch_thread_.join();
+ dispatcher_->RemoveService(service_);
+ }
+
+ private:
+ std::shared_ptr<TestService> service_;
+ std::unique_ptr<ServiceDispatcher> dispatcher_;
+ std::thread dispatch_thread_;
+};
+
+class ClientChannelTest : public testing::Test {
+ public:
+ void SetUp() override {
+ int channel_sockets[2] = {};
+ ASSERT_EQ(
+ 0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, channel_sockets));
+ LocalHandle service_channel{channel_sockets[0]};
+ LocalHandle client_channel{channel_sockets[1]};
+
+ service_runner_.reset(new TestServiceRunner{std::move(service_channel)});
+ auto factory = ClientChannelFactory::Create(std::move(client_channel));
+ auto status = factory->Connect(android::pdx::Client::kInfiniteTimeout);
+ ASSERT_TRUE(status);
+ client_ = TestClient::Create(status.take());
+ }
+
+ void TearDown() override {
+ service_runner_.reset();
+ client_.reset();
+ }
+
+ protected:
+ std::unique_ptr<TestServiceRunner> service_runner_;
+ std::shared_ptr<TestClient> client_;
+};
+
+TEST_F(ClientChannelTest, MultithreadedClient) {
+ constexpr int kNumTestThreads = 8;
+ constexpr size_t kDataSize = 1000; // Try to keep RPC buffer size below 4K.
+
+ std::random_device rd;
+ std::mt19937 gen{rd()};
+ std::uniform_int_distribution<TestProtocol::DataType> dist{
+ std::numeric_limits<TestProtocol::DataType>::min(),
+ std::numeric_limits<TestProtocol::DataType>::max()};
+
+ auto worker = [](std::shared_ptr<TestClient> client,
+ std::vector<TestProtocol::DataType> data) {
+ constexpr int kMaxIterations = 500;
+ int64_t expected = std::accumulate(data.begin(), data.end(), int64_t{0});
+ for (int i = 0; i < kMaxIterations; i++) {
+ ASSERT_EQ(expected, client->Sum(data));
+ }
+ };
+
+ // Start client threads.
+ std::vector<TestProtocol::DataType> data;
+ data.resize(kDataSize);
+ std::vector<std::thread> threads;
+ for (int i = 0; i < kNumTestThreads; i++) {
+ std::generate(data.begin(), data.end(),
+ [&dist, &gen]() { return dist(gen); });
+ threads.emplace_back(worker, client_, data);
+ }
+
+ // Wait for threads to finish.
+ for (auto& thread : threads)
+ thread.join();
+}
+
+} // namespace
diff --git a/libs/vr/libpdx_uds/ipc_helper.cpp b/libs/vr/libpdx_uds/ipc_helper.cpp
index b675894..d75ce86 100644
--- a/libs/vr/libpdx_uds/ipc_helper.cpp
+++ b/libs/vr/libpdx_uds/ipc_helper.cpp
@@ -275,6 +275,7 @@
return ret;
if (preamble.magic != kMagicPreamble) {
+ ALOGE("ReceivePayload::Receive: Message header is invalid");
ret.SetError(EIO);
return ret;
}
@@ -319,8 +320,10 @@
cmsg = CMSG_NXTHDR(&msg, cmsg);
}
- if (cred && !cred_available)
+ if (cred && !cred_available) {
+ ALOGE("ReceivePayload::Receive: Failed to obtain message credentials");
ret.SetError(EIO);
+ }
return ret;
}
diff --git a/libs/vr/libpdx_uds/private/uds/client_channel.h b/libs/vr/libpdx_uds/private/uds/client_channel.h
index 45f6473..8f607f5 100644
--- a/libs/vr/libpdx_uds/private/uds/client_channel.h
+++ b/libs/vr/libpdx_uds/private/uds/client_channel.h
@@ -3,6 +3,8 @@
#include <pdx/client_channel.h>
+#include <mutex>
+
#include <uds/channel_event_set.h>
#include <uds/channel_manager.h>
#include <uds/service_endpoint.h>
@@ -73,6 +75,7 @@
LocalChannelHandle channel_handle_;
ChannelManager::ChannelData* channel_data_;
+ std::mutex socket_mutex_;
};
} // namespace uds
diff --git a/libs/vr/libpdx_uds/private/uds/client_channel_factory.h b/libs/vr/libpdx_uds/private/uds/client_channel_factory.h
index 6f80d31..c43c5c7 100644
--- a/libs/vr/libpdx_uds/private/uds/client_channel_factory.h
+++ b/libs/vr/libpdx_uds/private/uds/client_channel_factory.h
@@ -13,6 +13,7 @@
public:
static std::unique_ptr<pdx::ClientChannelFactory> Create(
const std::string& endpoint_path);
+ static std::unique_ptr<pdx::ClientChannelFactory> Create(LocalHandle socket);
Status<std::unique_ptr<pdx::ClientChannel>> Connect(
int64_t timeout_ms) const override;
@@ -22,7 +23,9 @@
private:
explicit ClientChannelFactory(const std::string& endpoint_path);
+ explicit ClientChannelFactory(LocalHandle socket);
+ mutable LocalHandle socket_;
std::string endpoint_path_;
};
diff --git a/libs/vr/libpdx_uds/private/uds/service_endpoint.h b/libs/vr/libpdx_uds/private/uds/service_endpoint.h
index f747abc..eb87827 100644
--- a/libs/vr/libpdx_uds/private/uds/service_endpoint.h
+++ b/libs/vr/libpdx_uds/private/uds/service_endpoint.h
@@ -97,6 +97,14 @@
static std::unique_ptr<Endpoint> CreateAndBindSocket(
const std::string& endpoint_path, bool blocking = kDefaultBlocking);
+ // Helper method to create an endpoint from an existing socket FD.
+ // Mostly helpful for tests.
+ static std::unique_ptr<Endpoint> CreateFromSocketFd(LocalHandle socket_fd);
+
+ // Test helper method to register a new channel identified by |channel_fd|
+ // socket file descriptor.
+ Status<void> RegisterNewChannelForTests(LocalHandle channel_fd);
+
int epoll_fd() const { return epoll_fd_.Get(); }
private:
@@ -109,6 +117,9 @@
// This class must be instantiated using Create() static methods above.
Endpoint(const std::string& endpoint_path, bool blocking,
bool use_init_socket_fd = true);
+ Endpoint(LocalHandle socket_fd);
+
+ void Init(LocalHandle socket_fd);
Endpoint(const Endpoint&) = delete;
void operator=(const Endpoint&) = delete;
diff --git a/libs/vr/libpdx_uds/service_endpoint.cpp b/libs/vr/libpdx_uds/service_endpoint.cpp
index 65fd59f..6c92259 100644
--- a/libs/vr/libpdx_uds/service_endpoint.cpp
+++ b/libs/vr/libpdx_uds/service_endpoint.cpp
@@ -161,9 +161,16 @@
bind(fd.Get(), reinterpret_cast<sockaddr*>(&local), sizeof(local));
CHECK_EQ(ret, 0) << "Endpoint::Endpoint: bind error: " << strerror(errno);
}
- CHECK_EQ(listen(fd.Get(), kMaxBackLogForSocketListen), 0)
- << "Endpoint::Endpoint: listen error: " << strerror(errno);
+ Init(std::move(fd));
+}
+Endpoint::Endpoint(LocalHandle socket_fd) { Init(std::move(socket_fd)); }
+
+void Endpoint::Init(LocalHandle socket_fd) {
+ if (socket_fd) {
+ CHECK_EQ(listen(socket_fd.Get(), kMaxBackLogForSocketListen), 0)
+ << "Endpoint::Endpoint: listen error: " << strerror(errno);
+ }
cancel_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
CHECK(cancel_event_fd_.IsValid())
<< "Endpoint::Endpoint: Failed to create event fd: " << strerror(errno);
@@ -172,24 +179,27 @@
CHECK(epoll_fd_.IsValid())
<< "Endpoint::Endpoint: Failed to create epoll fd: " << strerror(errno);
- epoll_event socket_event;
- socket_event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT;
- socket_event.data.fd = fd.Get();
+ if (socket_fd) {
+ epoll_event socket_event;
+ socket_event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT;
+ socket_event.data.fd = socket_fd.Get();
+ int ret = epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, socket_fd.Get(),
+ &socket_event);
+ CHECK_EQ(ret, 0)
+ << "Endpoint::Endpoint: Failed to add socket fd to epoll fd: "
+ << strerror(errno);
+ }
epoll_event cancel_event;
cancel_event.events = EPOLLIN;
cancel_event.data.fd = cancel_event_fd_.Get();
- int ret = epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, fd.Get(), &socket_event);
- CHECK_EQ(ret, 0)
- << "Endpoint::Endpoint: Failed to add socket fd to epoll fd: "
- << strerror(errno);
- ret = epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, cancel_event_fd_.Get(),
- &cancel_event);
+ int ret = epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, cancel_event_fd_.Get(),
+ &cancel_event);
CHECK_EQ(ret, 0)
<< "Endpoint::Endpoint: Failed to add cancel event fd to epoll fd: "
<< strerror(errno);
- socket_fd_ = std::move(fd);
+ socket_fd_ = std::move(socket_fd);
}
void* Endpoint::AllocateMessageState() { return new MessageState; }
@@ -199,6 +209,9 @@
}
Status<void> Endpoint::AcceptConnection(Message* message) {
+ if (!socket_fd_)
+ return ErrorStatus(EBADF);
+
sockaddr_un remote;
socklen_t addrlen = sizeof(remote);
LocalHandle channel_fd{accept4(socket_fd_.Get(),
@@ -515,7 +528,7 @@
return ErrorStatus{ESHUTDOWN};
}
- if (event.data.fd == socket_fd_.Get()) {
+ if (socket_fd_ && event.data.fd == socket_fd_.Get()) {
auto status = AcceptConnection(message);
if (!status)
return status;
@@ -680,6 +693,23 @@
new Endpoint(endpoint_path, blocking, false));
}
+std::unique_ptr<Endpoint> Endpoint::CreateFromSocketFd(LocalHandle socket_fd) {
+ return std::unique_ptr<Endpoint>(new Endpoint(std::move(socket_fd)));
+}
+
+Status<void> Endpoint::RegisterNewChannelForTests(LocalHandle channel_fd) {
+ int optval = 1;
+ if (setsockopt(channel_fd.Get(), SOL_SOCKET, SO_PASSCRED, &optval,
+ sizeof(optval)) == -1) {
+ ALOGE(
+ "Endpoint::RegisterNewChannelForTests: Failed to enable the receiving"
+ "of the credentials for channel %d: %s",
+ channel_fd.Get(), strerror(errno));
+ return ErrorStatus(errno);
+ }
+ return OnNewChannel(std::move(channel_fd));
+}
+
} // namespace uds
} // namespace pdx
} // namespace android
diff --git a/libs/vr/libvrflinger/compositor.cpp b/libs/vr/libvrflinger/compositor.cpp
index 07e4a8b..239ef75 100644
--- a/libs/vr/libvrflinger/compositor.cpp
+++ b/libs/vr/libvrflinger/compositor.cpp
@@ -246,16 +246,17 @@
class Compositor::RenderPoseBufferObject {
public:
- RenderPoseBufferObject(LocalHandle&& render_pose_buffer_fd) {
+ RenderPoseBufferObject(LocalHandle&& render_pose_buffer_fd) :
+ fd_(std::move(render_pose_buffer_fd)) {
// Create new pose tracking buffer for this surface.
glGenBuffers(1, &render_pose_buffer_object_);
glBindBuffer(GL_UNIFORM_BUFFER, render_pose_buffer_object_);
- if (render_pose_buffer_fd) {
+ if (fd_) {
LOG_ALWAYS_FATAL_IF(!glBindSharedBufferQCOM);
if (glBindSharedBufferQCOM)
glBindSharedBufferQCOM(GL_UNIFORM_BUFFER,
sizeof(DisplaySurfaceMetadata),
- render_pose_buffer_fd.Get());
+ fd_.Get());
else
ALOGE("Error: Missing gralloc buffer extension");
CHECK_GL();
@@ -271,6 +272,7 @@
// Render pose buffer object. This contains an array of poses that corresponds
// with the surface buffers.
GLuint render_pose_buffer_object_;
+ LocalHandle fd_;
RenderPoseBufferObject(const RenderPoseBufferObject&) = delete;
void operator=(const RenderPoseBufferObject&) = delete;
@@ -429,6 +431,7 @@
}
void Compositor::Shutdown() {
+ glFinish();
render_target_[0].Destroy();
render_target_[1].Destroy();
layers_.clear();
diff --git a/libs/vr/libvrflinger/display_service.cpp b/libs/vr/libvrflinger/display_service.cpp
index 971345b..d3d50d0 100644
--- a/libs/vr/libvrflinger/display_service.cpp
+++ b/libs/vr/libvrflinger/display_service.cpp
@@ -209,16 +209,16 @@
// We should always have a red distortion.
LOG_FATAL_IF(view_params.distortion_coefficients_r.empty());
red_distortion = std::make_shared<PolynomialRadialDistortion>(
- 0.0f, view_params.distortion_coefficients_r);
+ view_params.distortion_coefficients_r);
if (!view_params.distortion_coefficients_g.empty()) {
green_distortion = std::make_shared<PolynomialRadialDistortion>(
- 0.0f, view_params.distortion_coefficients_g);
+ view_params.distortion_coefficients_g);
}
if (!view_params.distortion_coefficients_b.empty()) {
blue_distortion = std::make_shared<PolynomialRadialDistortion>(
- 0.0f, view_params.distortion_coefficients_b);
+ view_params.distortion_coefficients_b);
}
HeadMountMetrics::EyeOrientation left_orientation =
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 080c02b..986c268 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -31,6 +31,7 @@
using namespace android::hardware::sensors::V1_0;
using namespace android::hardware::sensors::V1_0::implementation;
+
namespace android {
// ---------------------------------------------------------------------------
@@ -138,20 +139,19 @@
result.append("sampling_period(ms) = {");
for (size_t j = 0; j < info.batchParams.size(); j++) {
- const BatchParams& params = info.batchParams.valueAt(j);
- result.appendFormat("%.1f%s", params.batchDelay / 1e6f,
+ const BatchParams& params = info.batchParams[j];
+ result.appendFormat("%.1f%s", params.mTSample / 1e6f,
j < info.batchParams.size() - 1 ? ", " : "");
}
- result.appendFormat("}, selected = %.1f ms; ", info.bestBatchParams.batchDelay / 1e6f);
+ result.appendFormat("}, selected = %.2f ms; ", info.bestBatchParams.mTSample / 1e6f);
result.append("batching_period(ms) = {");
for (size_t j = 0; j < info.batchParams.size(); j++) {
- BatchParams params = info.batchParams.valueAt(j);
-
- result.appendFormat("%.1f%s", params.batchTimeout / 1e6f,
+ const BatchParams& params = info.batchParams[j];
+ result.appendFormat("%.1f%s", params.mTBatch / 1e6f,
j < info.batchParams.size() - 1 ? ", " : "");
}
- result.appendFormat("}, selected = %.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f);
+ result.appendFormat("}, selected = %.2f ms\n", info.bestBatchParams.mTBatch / 1e6f);
}
return result.string();
@@ -270,13 +270,10 @@
// batch_rate and timeout. One of the apps has unregistered for sensor
// events, and the best effort batch parameters might have changed.
ALOGD_IF(DEBUG_CONNECTIONS,
- "\t>>> actuating h/w batch %d %d %" PRId64 " %" PRId64, handle,
- info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
- info.bestBatchParams.batchTimeout);
+ "\t>>> actuating h/w batch 0x%08x %" PRId64 " %" PRId64, handle,
+ info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch);
checkReturn(mSensors->batch(
- handle,
- info.bestBatchParams.batchDelay,
- info.bestBatchParams.batchTimeout));
+ handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch));
}
} else {
// sensor wasn't enabled for this ident
@@ -314,6 +311,9 @@
if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
}
+ if (maxBatchReportLatencyNs < 0) {
+ maxBatchReportLatencyNs = 0;
+ }
ALOGD_IF(DEBUG_CONNECTIONS,
"SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64,
@@ -323,7 +323,7 @@
Info& info(mActivationCount.editValueFor(handle));
if (info.batchParams.indexOfKey(ident) < 0) {
- BatchParams params(flags, samplingPeriodNs, maxBatchReportLatencyNs);
+ BatchParams params(samplingPeriodNs, maxBatchReportLatencyNs);
info.batchParams.add(ident, params);
} else {
// A batch has already been called with this ident. Update the batch parameters.
@@ -337,25 +337,21 @@
ALOGD_IF(DEBUG_CONNECTIONS,
"\t>>> curr_period=%" PRId64 " min_period=%" PRId64
" curr_timeout=%" PRId64 " min_timeout=%" PRId64,
- prevBestBatchParams.batchDelay, info.bestBatchParams.batchDelay,
- prevBestBatchParams.batchTimeout, info.bestBatchParams.batchTimeout);
+ prevBestBatchParams.mTSample, info.bestBatchParams.mTSample,
+ prevBestBatchParams.mTBatch, info.bestBatchParams.mTBatch);
status_t err(NO_ERROR);
// If the min period or min timeout has changed since the last batch call, call batch.
if (prevBestBatchParams != info.bestBatchParams) {
- ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %" PRId64 " %" PRId64, handle,
- info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
- info.bestBatchParams.batchTimeout);
+ ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH 0x%08x %" PRId64 " %" PRId64, handle,
+ info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch);
err = StatusFromResult(
checkReturn(mSensors->batch(
- handle,
- info.bestBatchParams.batchDelay,
- info.bestBatchParams.batchTimeout)));
+ handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch)));
if (err != NO_ERROR) {
- ALOGE("sensor batch failed %p %d %d %" PRId64 " %" PRId64 " err=%s",
- mSensors.get(), handle,
- info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
- info.bestBatchParams.batchTimeout, strerror(-err));
+ ALOGE("sensor batch failed %p 0x%08x %" PRId64 " %" PRId64 " err=%s",
+ mSensors.get(), handle, info.bestBatchParams.mTSample,
+ info.bestBatchParams.mTBatch, strerror(-err));
info.removeBatchParamsForIdent(ident);
}
}
@@ -363,28 +359,7 @@
}
status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) {
- if (mSensors == nullptr) return NO_INIT;
- if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
- samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
- }
- Mutex::Autolock _l(mLock);
- if (isClientDisabledLocked(ident)) return INVALID_OPERATION;
- Info& info( mActivationCount.editValueFor(handle) );
- // If the underlying sensor is NOT in continuous mode, setDelay() should return an error.
- // Calling setDelay() in batch mode is an invalid operation.
- if (info.bestBatchParams.batchTimeout != 0) {
- return INVALID_OPERATION;
- }
- ssize_t index = info.batchParams.indexOfKey(ident);
- if (index < 0) {
- return BAD_INDEX;
- }
- BatchParams& params = info.batchParams.editValueAt(index);
- params.batchDelay = samplingPeriodNs;
- info.selectBatchParams();
-
- return StatusFromResult(
- checkReturn(mSensors->batch(handle, info.bestBatchParams.batchDelay, 0)));
+ return batch(ident, handle, 0, samplingPeriodNs, 0);
}
int SensorDevice::getHalDeviceVersion() const {
@@ -423,8 +398,8 @@
status_t err = StatusFromResult(
checkReturn(mSensors->batch(
sensor_handle,
- info.bestBatchParams.batchDelay,
- info.bestBatchParams.batchTimeout)));
+ info.bestBatchParams.mTSample,
+ info.bestBatchParams.mTBatch)));
ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err));
if (err == NO_ERROR) {
@@ -581,35 +556,35 @@
return num;
}
-status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags,
+status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int,
int64_t samplingPeriodNs,
int64_t maxBatchReportLatencyNs) {
ssize_t index = batchParams.indexOfKey(ident);
if (index < 0) {
- ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64 " timeout=%" PRId64 ") failed (%s)",
+ ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64
+ " timeout=%" PRId64 ") failed (%s)",
ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
return BAD_INDEX;
}
BatchParams& params = batchParams.editValueAt(index);
- params.flags = flags;
- params.batchDelay = samplingPeriodNs;
- params.batchTimeout = maxBatchReportLatencyNs;
+ params.mTSample = samplingPeriodNs;
+ params.mTBatch = maxBatchReportLatencyNs;
return NO_ERROR;
}
void SensorDevice::Info::selectBatchParams() {
- BatchParams bestParams(0, -1, -1);
+ BatchParams bestParams; // default to max Tsample and max Tbatch
SensorDevice& device(SensorDevice::getInstance());
for (size_t i = 0; i < batchParams.size(); ++i) {
- if (device.isClientDisabledLocked(batchParams.keyAt(i))) continue;
- BatchParams params = batchParams.valueAt(i);
- if (bestParams.batchDelay == -1 || params.batchDelay < bestParams.batchDelay) {
- bestParams.batchDelay = params.batchDelay;
+ if (device.isClientDisabledLocked(batchParams.keyAt(i))) {
+ continue;
}
- if (bestParams.batchTimeout == -1 || params.batchTimeout < bestParams.batchTimeout) {
- bestParams.batchTimeout = params.batchTimeout;
- }
+ bestParams.merge(batchParams[i]);
+ }
+ // if mTBatch <= mTSample, it is in streaming mode. set mTbatch to 0 to demand this explicitly.
+ if (bestParams.mTBatch <= bestParams.mTSample) {
+ bestParams.mTBatch = 0;
}
bestBatchParams = bestParams;
}
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index 2520a81..fd6cee6 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -27,7 +27,8 @@
#include <utils/String8.h>
#include <string>
-#include <map>
+#include <unordered_map>
+#include <algorithm> //std::max std::min
#include "android/hardware/sensors/1.0/ISensors.h"
@@ -106,7 +107,7 @@
sp<android::hardware::sensors::V1_0::ISensors> mSensors;
Vector<sensor_t> mSensorList;
- std::map<int32_t, sensor_t*> mConnectedDynamicSensors;
+ std::unordered_map<int32_t, sensor_t*> mConnectedDynamicSensors;
static const nsecs_t MINIMUM_EVENTS_PERIOD = 1000000; // 1000 Hz
mutable Mutex mLock; // protect mActivationCount[].batchParams
@@ -115,15 +116,18 @@
// Struct to store all the parameters(samplingPeriod, maxBatchReportLatency and flags) from
// batch call. For continous mode clients, maxBatchReportLatency is set to zero.
struct BatchParams {
- // TODO: Get rid of flags parameter everywhere.
- int flags;
- nsecs_t batchDelay, batchTimeout;
- BatchParams() : flags(0), batchDelay(0), batchTimeout(0) {}
- BatchParams(int flag, nsecs_t delay, nsecs_t timeout): flags(flag), batchDelay(delay),
- batchTimeout(timeout) { }
+ nsecs_t mTSample, mTBatch;
+ BatchParams() : mTSample(INT64_MAX), mTBatch(INT64_MAX) {}
+ BatchParams(nsecs_t tSample, nsecs_t tBatch): mTSample(tSample), mTBatch(tBatch) {}
bool operator != (const BatchParams& other) {
- return other.batchDelay != batchDelay || other.batchTimeout != batchTimeout ||
- other.flags != flags;
+ return !(mTSample == other.mTSample && mTBatch == other.mTBatch);
+ }
+ // Merge another parameter with this one. The updated mTSample will be the min of the two.
+ // The update mTBatch will be the min of original mTBatch and the apparent batch period
+ // of the other. the apparent batch is the maximum of mTBatch and mTSample,
+ void merge(const BatchParams &other) {
+ mTSample = std::min(mTSample, other.mTSample);
+ mTBatch = std::min(mTBatch, std::max(other.mTBatch, other.mTSample));
}
};
@@ -139,7 +143,6 @@
// requested by the client.
KeyedVector<void*, BatchParams> batchParams;
- Info() : bestBatchParams(0, -1, -1) {}
// Sets batch parameters for this ident. Returns error if this ident is not already present
// in the KeyedVector above.
status_t setBatchParamsForIdent(void* ident, int flags, int64_t samplingPeriodNs,
diff --git a/services/sensorservice/hidl/EventQueue.cpp b/services/sensorservice/hidl/EventQueue.cpp
index c0365e5..ff20066 100644
--- a/services/sensorservice/hidl/EventQueue.cpp
+++ b/services/sensorservice/hidl/EventQueue.cpp
@@ -27,7 +27,8 @@
class EventQueueLooperCallback : public ::android::LooperCallback {
public:
- EventQueueLooperCallback(sp<EventQueue> queue, sp<IEventQueueCallback> callback)
+ EventQueueLooperCallback(sp<::android::SensorEventQueue> queue,
+ sp<IEventQueueCallback> callback)
: mQueue(queue), mCallback(callback) {
}
@@ -35,7 +36,11 @@
ASensorEvent event;
ssize_t actual;
- const sp<::android::SensorEventQueue>& internalQueue = mQueue->mInternalQueue;
+
+ auto internalQueue = mQueue.promote();
+ if (internalQueue == nullptr) {
+ return 1;
+ }
while ((actual = internalQueue->read(&event, 1 /* count */)) > 0) {
internalQueue->sendAck(&event, actual);
@@ -47,7 +52,7 @@
}
private:
- sp<EventQueue> mQueue;
+ wp<::android::SensorEventQueue> mQueue;
sp<IEventQueueCallback> mCallback;
};
@@ -58,18 +63,18 @@
: mLooper(looper),
mInternalQueue(internalQueue) {
- mLooper->addFd(mInternalQueue->getFd(), ALOOPER_POLL_CALLBACK, ALOOPER_EVENT_INPUT,
- new EventQueueLooperCallback(this, callback), NULL /* data */);
+ mLooper->addFd(internalQueue->getFd(), ALOOPER_POLL_CALLBACK, ALOOPER_EVENT_INPUT,
+ new EventQueueLooperCallback(internalQueue, callback), NULL /* data */);
}
-EventQueue::~EventQueue() {
+void EventQueue::onLastStrongRef(const void *id) {
+ IEventQueue::onLastStrongRef(id);
mLooper->removeFd(mInternalQueue->getFd());
}
// Methods from ::android::frameworks::sensorservice::V1_0::IEventQueue follow.
Return<Result> EventQueue::enableSensor(int32_t sensorHandle, int32_t samplingPeriodUs,
int64_t maxBatchReportLatencyUs) {
- // TODO implement
return convertResult(mInternalQueue->enableSensor(sensorHandle, samplingPeriodUs,
maxBatchReportLatencyUs, 0 /* reserved flags */));
}
diff --git a/services/sensorservice/hidl/EventQueue.h b/services/sensorservice/hidl/EventQueue.h
index 87c614b..6be03b7 100644
--- a/services/sensorservice/hidl/EventQueue.h
+++ b/services/sensorservice/hidl/EventQueue.h
@@ -42,7 +42,7 @@
sp<IEventQueueCallback> callback,
sp<::android::Looper> looper,
sp<::android::SensorEventQueue> internalQueue);
- ~EventQueue();
+ void onLastStrongRef(const void *) override;
// Methods from ::android::frameworks::sensorservice::V1_0::IEventQueue follow.
Return<Result> enableSensor(int32_t sensorHandle, int32_t samplingPeriodUs, int64_t maxBatchReportLatencyUs) override;