Os: add GetControlSocket()
Add the GetControlSocket() method to Os, and
add unit tests for the same.
A "control socket" is a service-specific socket
created by the init daemon, to enable other
processes to talk to a given service.
Bug: 32446680
Test: ./runtests.sh (on angler)
Change-Id: I25ea54f8ab85fafd492ec2953e4e369d64ecd02d
diff --git a/Android.mk b/Android.mk
index ed5ec0a..eabfb24 100644
--- a/Android.mk
+++ b/Android.mk
@@ -39,6 +39,7 @@
raw_os.cpp
LOCAL_SHARED_LIBRARIES := \
libbase \
+ libcutils \
liblog
include $(BUILD_STATIC_LIBRARY)
@@ -66,5 +67,6 @@
libwifilogd
LOCAL_SHARED_LIBRARIES := \
libbase \
+ libcutils \
liblog
include $(BUILD_NATIVE_TEST)
diff --git a/os.cpp b/os.cpp
index ae8caca..ab178c1 100644
--- a/os.cpp
+++ b/os.cpp
@@ -33,10 +33,22 @@
constexpr auto kMaxNanoSeconds = 1000 * 1000 * 1000 - 1;
}
+constexpr int Os::kInvalidFd;
+
Os::Os() : raw_os_(new RawOs()) {}
Os::Os(std::unique_ptr<RawOs> raw_os) : raw_os_(std::move(raw_os)) {}
Os::~Os() {}
+std::tuple<int, Os::Errno> Os::GetControlSocket(
+ const std::string& socket_name) {
+ int sock_fd = raw_os_->GetControlSocket(socket_name.c_str());
+ if (sock_fd < 0) {
+ return {kInvalidFd, errno};
+ } else {
+ return {sock_fd, 0};
+ }
+}
+
Os::Timestamp Os::GetTimestamp(clockid_t clock_id) const {
struct timespec now_timespec;
int failed = raw_os_->ClockGettime(clock_id, &now_timespec);
diff --git a/os.h b/os.h
index ca1e886..31fecbe 100644
--- a/os.h
+++ b/os.h
@@ -21,6 +21,7 @@
#include <cstdint>
#include <memory>
+#include <string>
#include <tuple>
#include <utility>
@@ -58,6 +59,12 @@
virtual ~Os();
+ // Returns the Android control socket with name |socket_name|. If no such
+ // socket exists, or the init daemon has not provided this process with
+ // access to said socket, returns {kInvalidFd, errno}.
+ virtual std::tuple<int, Errno> GetControlSocket(
+ const std::string& socket_name);
+
// Returns the current time, as reported by the clock with |clock_id|.
virtual Timestamp GetTimestamp(clockid_t clock_id) const;
diff --git a/raw_os.cpp b/raw_os.cpp
index 26aa1b8..8d08901 100644
--- a/raw_os.cpp
+++ b/raw_os.cpp
@@ -17,6 +17,8 @@
#include <time.h>
#include <unistd.h>
+#include "cutils/sockets.h"
+
#include "wifilogd/raw_os.h"
namespace android {
@@ -33,6 +35,10 @@
return clock_gettime(clock_id, ts);
}
+int RawOs::GetControlSocket(const char* socket_name) {
+ return android_get_control_socket(socket_name);
+}
+
ssize_t RawOs::Recv(int sockfd, void* buf, size_t buflen, int flags) {
return recv(sockfd, buf, buflen, flags);
}
diff --git a/raw_os.h b/raw_os.h
index 6d74b6d..3ba9a0f 100644
--- a/raw_os.h
+++ b/raw_os.h
@@ -38,6 +38,9 @@
virtual int ClockGettime(clockid_t clock_id,
NONNULL struct timespec* tspec) const;
+ // See android_get_control_socket().
+ virtual int GetControlSocket(const char* socket_name);
+
// See recv().
virtual ssize_t Recv(int sockfd, void* buf, size_t buflen, int flags);
diff --git a/tests/mock_os.h b/tests/mock_os.h
index 5a378f3..3e02730 100644
--- a/tests/mock_os.h
+++ b/tests/mock_os.h
@@ -17,6 +17,7 @@
#ifndef TESTS_MOCK_OS_H_
#define TESTS_MOCK_OS_H_
+#include <string>
#include <tuple>
#include "android-base/macros.h"
@@ -33,6 +34,8 @@
~MockOs() override;
MOCK_CONST_METHOD1(GetTimestamp, Timestamp(clockid_t clock_id));
+ MOCK_METHOD1(GetControlSocket,
+ std::tuple<int, Errno>(const std::string& socket_name));
MOCK_METHOD3(ReceiveDatagram,
std::tuple<size_t, Errno>(int fd, void* buf, size_t buflen));
MOCK_METHOD3(Write, std::tuple<size_t, Os::Errno>(int fd, const void* buf,
diff --git a/tests/mock_raw_os.h b/tests/mock_raw_os.h
index 13149d9..3931cb0 100644
--- a/tests/mock_raw_os.h
+++ b/tests/mock_raw_os.h
@@ -32,6 +32,7 @@
MOCK_CONST_METHOD2(ClockGettime,
int(clockid_t clock_id, struct timespec* tspec));
+ MOCK_METHOD1(GetControlSocket, int(const char* socket_name));
MOCK_METHOD4(Recv, ssize_t(int sockfd, void* buf, size_t buflen, int flags));
MOCK_METHOD3(Write, ssize_t(int fd, const void* buf, size_t buflen));
diff --git a/tests/os_unittest.cpp b/tests/os_unittest.cpp
index 00dea33..e90755a 100644
--- a/tests/os_unittest.cpp
+++ b/tests/os_unittest.cpp
@@ -34,6 +34,7 @@
using ::testing::SetArgumentPointee;
using ::testing::SetErrnoAndReturn;
using ::testing::StrictMock;
+using ::testing::StrEq;
using local_utils::GetMaxVal;
@@ -53,6 +54,26 @@
} // namespace
+TEST_F(OsTest, GetControlSocketReturnsFdAndZeroOnSuccess) {
+ constexpr char kSocketName[] = "fake-daemon";
+ constexpr int kFakeValidFd = 100;
+ EXPECT_CALL(*raw_os_, GetControlSocket(StrEq(kSocketName)))
+ .WillOnce(Return(kFakeValidFd));
+
+ constexpr std::tuple<int, Os::Errno> kExpectedResult{kFakeValidFd, 0};
+ EXPECT_EQ(kExpectedResult, os_->GetControlSocket(kSocketName));
+}
+
+TEST_F(OsTest, GetControlSocketReturnsInvalidFdAndErrorOnFailure) {
+ constexpr char kSocketName[] = "fake-daemon";
+ constexpr Os::Errno kError = EINVAL;
+ EXPECT_CALL(*raw_os_, GetControlSocket(StrEq(kSocketName)))
+ .WillOnce(SetErrnoAndReturn(kError, -1));
+
+ constexpr std::tuple<int, Os::Errno> kExpectedResult{Os::kInvalidFd, kError};
+ EXPECT_EQ(kExpectedResult, os_->GetControlSocket(kSocketName));
+}
+
TEST_F(OsTest, GetTimestampSucceeds) {
constexpr auto kFakeSecs = 1U;
constexpr auto kFakeNsecs = 2U;