Merge "vr_hwc: Address ion buffer leakage" into oc-dev
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 20b960d..e9a135c 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -1729,7 +1729,8 @@
const std::unique_ptr<std::string>& packageName, const std::string& instructionSet,
int32_t dexoptNeeded, const std::unique_ptr<std::string>& outputPath, int32_t dexFlags,
const std::string& compilerFilter, const std::unique_ptr<std::string>& uuid,
- const std::unique_ptr<std::string>& sharedLibraries) {
+ const std::unique_ptr<std::string>& sharedLibraries,
+ const std::unique_ptr<std::string>& seInfo) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
if (packageName && *packageName != "*") {
@@ -1744,9 +1745,9 @@
const char* compiler_filter = compilerFilter.c_str();
const char* volume_uuid = uuid ? uuid->c_str() : nullptr;
const char* shared_libraries = sharedLibraries ? sharedLibraries->c_str() : nullptr;
-
+ const char* se_info = seInfo ? seInfo->c_str() : nullptr;
int res = android::installd::dexopt(apk_path, uid, pkgname, instruction_set, dexoptNeeded,
- oat_dir, dexFlags, compiler_filter, volume_uuid, shared_libraries);
+ oat_dir, dexFlags, compiler_filter, volume_uuid, shared_libraries, se_info);
return res ? error(res, "Failed to dexopt") : ok();
}
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index f5b7142..fe8aa14 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -82,7 +82,8 @@
const std::unique_ptr<std::string>& packageName, const std::string& instructionSet,
int32_t dexoptNeeded, const std::unique_ptr<std::string>& outputPath, int32_t dexFlags,
const std::string& compilerFilter, const std::unique_ptr<std::string>& uuid,
- const std::unique_ptr<std::string>& sharedLibraries);
+ const std::unique_ptr<std::string>& sharedLibraries,
+ const std::unique_ptr<std::string>& seInfo);
binder::Status rmdex(const std::string& codePath, const std::string& instructionSet);
diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl
index 03ff96e..e738b81 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -50,7 +50,8 @@
@utf8InCpp String instructionSet, int dexoptNeeded,
@nullable @utf8InCpp String outputPath, int dexFlags,
@utf8InCpp String compilerFilter, @nullable @utf8InCpp String uuid,
- @nullable @utf8InCpp String sharedLibraries);
+ @nullable @utf8InCpp String sharedLibraries,
+ @nullable @utf8InCpp String seInfo);
void rmdex(@utf8InCpp String codePath, @utf8InCpp String instructionSet);
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index f7e8d13..63afdcd 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -36,6 +36,7 @@
#include <cutils/sched_policy.h>
#include <log/log.h> // TODO: Move everything to base/logging.
#include <private/android_filesystem_config.h>
+#include <selinux/android.h>
#include <system/thread_defs.h>
#include "dexopt.h"
@@ -1302,17 +1303,9 @@
}
std::string dex_dir = dex_path.substr(0, dirIndex);
- // Assign the gid to the cache gid so that the oat file storage
- // is counted towards the app cache.
- int32_t cache_gid = multiuser_get_cache_gid(
- multiuser_get_user_id(uid), multiuser_get_app_id(uid));
- // If UID doesn't have a specific cache GID, use UID value
- if (cache_gid == -1) {
- cache_gid = uid;
- }
-
// Create oat file output directory.
- if (prepare_app_cache_dir(dex_dir, "oat", 02711, uid, cache_gid) != 0) {
+ mode_t oat_dir_mode = S_IRWXU | S_IRWXG | S_IXOTH;
+ if (prepare_app_cache_dir(dex_dir, "oat", oat_dir_mode, uid, uid) != 0) {
LOG(ERROR) << "Could not prepare oat dir for secondary dex: " << dex_path;
return false;
}
@@ -1322,7 +1315,7 @@
oat_dir_out->assign(oat_dir);
// Create oat/isa output directory.
- if (prepare_app_cache_dir(*oat_dir_out, instruction_set, 02711, uid, cache_gid) != 0) {
+ if (prepare_app_cache_dir(*oat_dir_out, instruction_set, oat_dir_mode, uid, uid) != 0) {
LOG(ERROR) << "Could not prepare oat/isa dir for secondary dex: " << dex_path;
return false;
}
@@ -1366,12 +1359,15 @@
// Processes the dex_path as a secondary dex files and return true if the path dex file should
// be compiled. Returns false for errors (logged) or true if the secondary dex path was process
// successfully.
-// When returning true, dexopt_needed_out is assigned a valid OatFileAsssitant::DexOptNeeded
-// code and oat_dir_out is assigned the oat dir path where the oat file should be stored.
+// When returning true, the output parameters will be:
+// - is_public_out: whether or not the oat file should not be made public
+// - dexopt_needed_out: valid OatFileAsssitant::DexOptNeeded
+// - oat_dir_out: the oat dir path where the oat file should be stored
+// - dex_path_out: the real path of the dex file
static bool process_secondary_dex_dexopt(const char* original_dex_path, const char* pkgname,
int dexopt_flags, const char* volume_uuid, int uid, const char* instruction_set,
- const char* compiler_filter, int* dexopt_needed_out, std::string* oat_dir_out,
- std::string* dex_path_out) {
+ const char* compiler_filter, bool* is_public_out, int* dexopt_needed_out,
+ std::string* oat_dir_out, std::string* dex_path_out) {
int storage_flag;
if ((dexopt_flags & DEXOPT_STORAGE_CE) != 0) {
@@ -1407,7 +1403,8 @@
}
// Check if the path exist. If not, there's nothing to do.
- if (access(dex_path.c_str(), F_OK) != 0) {
+ struct stat dex_path_stat;
+ if (stat(dex_path.c_str(), &dex_path_stat) != 0) {
if (errno == ENOENT) {
// Secondary dex files might be deleted any time by the app.
// Nothing to do if that's the case
@@ -1418,6 +1415,11 @@
}
}
+ // Check if we should make the oat file public.
+ // Note that if the dex file is not public the compiled code cannot be made public.
+ *is_public_out = ((dexopt_flags & DEXOPT_PUBLIC) != 0) &&
+ ((dex_path_stat.st_mode & S_IROTH) != 0);
+
// Prepare the oat directories.
if (!prepare_secondary_dex_oat_dir(dex_path, uid, instruction_set, oat_dir_out)) {
return false;
@@ -1458,14 +1460,14 @@
int dexopt(const char* dex_path, uid_t uid, const char* pkgname, const char* instruction_set,
int dexopt_needed, const char* oat_dir, int dexopt_flags, const char* compiler_filter,
- const char* volume_uuid, const char* shared_libraries) {
+ const char* volume_uuid, const char* shared_libraries, const char* se_info) {
CHECK(pkgname != nullptr);
CHECK(pkgname[0] != 0);
if ((dexopt_flags & ~DEXOPT_MASK) != 0) {
LOG_FATAL("dexopt flags contains unknown fields\n");
}
- bool is_public = ((dexopt_flags & DEXOPT_PUBLIC) != 0);
+ bool is_public = (dexopt_flags & DEXOPT_PUBLIC) != 0;
bool vm_safe_mode = (dexopt_flags & DEXOPT_SAFEMODE) != 0;
bool debuggable = (dexopt_flags & DEXOPT_DEBUGGABLE) != 0;
bool boot_complete = (dexopt_flags & DEXOPT_BOOTCOMPLETE) != 0;
@@ -1477,7 +1479,8 @@
std::string dex_real_path;
if (is_secondary_dex) {
if (process_secondary_dex_dexopt(dex_path, pkgname, dexopt_flags, volume_uuid, uid,
- instruction_set, compiler_filter, &dexopt_needed, &oat_dir_str, &dex_real_path)) {
+ instruction_set, compiler_filter, &is_public, &dexopt_needed, &oat_dir_str,
+ &dex_real_path)) {
oat_dir = oat_dir_str.c_str();
dex_path = dex_real_path.c_str();
if (dexopt_needed == NO_DEXOPT_NEEDED) {
@@ -1516,6 +1519,19 @@
return -1;
}
+ // Ensure that the oat dir and the compiler artifacts of secondary dex files have the correct
+ // selinux context (we generate them on the fly during the dexopt invocation and they don't
+ // fully inherit their parent context).
+ // Note that for primary apk the oat files are created before, in a separate installd
+ // call which also does the restorecon. TODO(calin): unify the paths.
+ if (is_secondary_dex) {
+ if (selinux_android_restorecon_pkgdir(oat_dir, se_info, uid,
+ SELINUX_ANDROID_RESTORECON_RECURSE)) {
+ LOG(ERROR) << "Failed to restorecon " << oat_dir;
+ return -1;
+ }
+ }
+
// Create a swap file if necessary.
unique_fd swap_fd = maybe_open_dexopt_swap_file(out_oat_path);
@@ -1857,8 +1873,9 @@
atoi(params[6]), // dexopt_flags
params[7], // compiler_filter
parse_null(params[8]), // volume_uuid
- parse_null(params[9])); // shared_libraries
- static_assert(DEXOPT_PARAM_COUNT == 10U, "Unexpected dexopt param count");
+ parse_null(params[9]), // shared_libraries
+ parse_null(params[10])); // se_info
+ static_assert(DEXOPT_PARAM_COUNT == 11U, "Unexpected dexopt param count");
}
} // namespace installd
diff --git a/cmds/installd/dexopt.h b/cmds/installd/dexopt.h
index dbf3fae..88144b7 100644
--- a/cmds/installd/dexopt.h
+++ b/cmds/installd/dexopt.h
@@ -60,10 +60,10 @@
int dexopt(const char *apk_path, uid_t uid, const char *pkgName, const char *instruction_set,
int dexopt_needed, const char* oat_dir, int dexopt_flags, const char* compiler_filter,
- const char* volume_uuid, const char* shared_libraries);
+ const char* volume_uuid, const char* shared_libraries, const char* se_info);
-static constexpr size_t DEXOPT_PARAM_COUNT = 10U;
-static_assert(DEXOPT_PARAM_COUNT == 10U, "Unexpected dexopt param size");
+static constexpr size_t DEXOPT_PARAM_COUNT = 11U;
+static_assert(DEXOPT_PARAM_COUNT == 11U, "Unexpected dexopt param size");
// Helper for the above, converting arguments.
int dexopt(const char* const params[DEXOPT_PARAM_COUNT]);
diff --git a/cmds/service/service.cpp b/cmds/service/service.cpp
index 428b87c..09921e4 100644
--- a/cmds/service/service.cpp
+++ b/cmds/service/service.cpp
@@ -68,18 +68,12 @@
int main(int argc, char* const argv[])
{
- sp<IServiceManager> sm = defaultServiceManager();
- fflush(stdout);
- if (sm == NULL) {
- aerr << "service: Unable to get default service manager!" << endl;
- return 20;
- }
-
bool wantsUsage = false;
+ bool wantsVendorServices = false;
int result = 0;
while (1) {
- int ic = getopt(argc, argv, "h?");
+ int ic = getopt(argc, argv, "vh?");
if (ic < 0)
break;
@@ -88,6 +82,9 @@
case '?':
wantsUsage = true;
break;
+ case 'v':
+ wantsVendorServices = true;
+ break;
default:
aerr << "service: Unknown option -" << ic << endl;
wantsUsage = true;
@@ -95,6 +92,16 @@
break;
}
}
+
+ if (wantsVendorServices) {
+ ProcessState::initWithDriver("/dev/vndbinder");
+ }
+ sp<IServiceManager> sm = defaultServiceManager();
+ fflush(stdout);
+ if (sm == NULL) {
+ aerr << "service: Unable to get default service manager!" << endl;
+ return 20;
+ }
if (optind >= argc) {
wantsUsage = true;
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index 45bb1d0..1f56a47 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -65,7 +65,11 @@
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/binder/tests/schd-dbg.cpp b/libs/binder/tests/schd-dbg.cpp
index 2732071..fe9e05a 100644
--- a/libs/binder/tests/schd-dbg.cpp
+++ b/libs/binder/tests/schd-dbg.cpp
@@ -15,6 +15,7 @@
#include <pthread.h>
#include <sys/wait.h>
#include <unistd.h>
+#include <fstream>
using namespace std;
using namespace android;
@@ -41,6 +42,8 @@
#define DUMP_PRICISION 3
+string trace_path = "/sys/kernel/debug/tracing";
+
// the default value
int no_process = 2;
int iterations = 100;
@@ -48,6 +51,23 @@
int no_inherent = 0;
int no_sync = 0;
int verbose = 0;
+int trace;
+
+bool traceIsOn() {
+ fstream file;
+ file.open(trace_path + "/tracing_on", ios::in);
+ char on;
+ file >> on;
+ file.close();
+ return on == '1';
+}
+
+void traceStop() {
+ ofstream file;
+ file.open(trace_path + "/tracing_on", ios::out | ios::trunc);
+ file << '0' << endl;
+ file.close();
+}
// the deadline latency that we are interested in
uint64_t deadline_us = 2500;
@@ -197,13 +217,29 @@
uint64_t m_transactions = 0;
uint64_t m_total_time = 0;
uint64_t m_miss = 0;
-
+ bool tracing;
+ Results(bool _tracing) : tracing(_tracing) {
+ }
+ inline bool miss_deadline(uint64_t nano) {
+ return nano > deadline_us * 1000;
+ }
void add_time(uint64_t nano) {
m_best = min(nano, m_best);
m_worst = max(nano, m_worst);
m_transactions += 1;
m_total_time += nano;
- if (nano > deadline_us * 1000) m_miss++;
+ if (miss_deadline(nano)) m_miss++;
+ if (miss_deadline(nano) && tracing) {
+ // There might be multiple process pair running the test concurrently
+ // each may execute following statements and only the first one actually
+ // stop the trace and any traceStop() afterthen has no effect.
+ traceStop();
+ cout << endl;
+ cout << "deadline triggered: halt & stop trace" << endl;
+ cout << "log:" + trace_path + "/trace" << endl;
+ cout << endl;
+ exit(1);
+ }
}
void dump() {
double best = (double)m_best / 1.0E6;
@@ -212,8 +248,9 @@
// FIXME: libjson?
cout << std::setprecision(DUMP_PRICISION) << "{ \"avg\":" << setw(5) << left
<< average << ", \"wst\":" << setw(5) << left << worst
- << ", \"bst\":" << setw(5) << left << best << ", \"miss\":" << m_miss
- << "}";
+ << ", \"bst\":" << setw(5) << left << best << ", \"miss\":" << setw(5)
+ << left << m_miss << ", \"meetR\":" << setw(3) << left
+ << (1.0 - (double)m_miss / m_transactions) << "}";
}
};
@@ -272,7 +309,7 @@
void worker_fx(int num, int no_process, int iterations, int payload_size,
Pipe p) {
int dummy;
- Results results_other, results_fifo;
+ Results results_other(false), results_fifo(trace);
// Create BinderWorkerService and for go.
ProcessState::self()->startThreadPool();
@@ -389,8 +426,28 @@
}
if (string(argv[i]) == "-v") {
verbose = 1;
- i++;
}
+ // The -trace argument is used like that:
+ //
+ // First start trace with atrace command as usual
+ // >atrace --async_start sched freq
+ //
+ // then use schd-dbg with -trace arguments
+ //./schd-dbg -trace -deadline_us 2500
+ //
+ // This makes schd-dbg to stop trace once it detects a transaction
+ // duration over the deadline. By writing '0' to
+ // /sys/kernel/debug/tracing and halt the process. The tracelog is
+ // then available on /sys/kernel/debug/trace
+ if (string(argv[i]) == "-trace") {
+ trace = 1;
+ }
+ }
+ if (trace && !traceIsOn()) {
+ cout << "trace is not running" << endl;
+ cout << "check " << trace_path + "/tracing_on" << endl;
+ cout << "use atrace --async_start first" << endl;
+ exit(-1);
}
vector<Pipe> pipes;
thread_dump("main");
diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h
index aacc385..dfeed50 100644
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h
+++ b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h
@@ -94,9 +94,12 @@
}
IonBuffer* buffer() { return &slices_[0]; }
+ const IonBuffer* buffer() const { return &slices_[0]; }
+
// If index is greater than or equal to slice_count(), the result is
// undefined.
IonBuffer* slice(size_t index) { return &slices_[index]; }
+ const IonBuffer* slice(size_t index) const { return &slices_[index]; }
int slice_count() const { return static_cast<int>(slices_.size()); }
int id() const { return id_; }
@@ -171,9 +174,8 @@
int Post(const LocalHandle& ready_fence) {
return Post(ready_fence, nullptr, 0);
}
- template <
- typename Meta,
- typename = typename std::enable_if<!std::is_void<Meta>::value>::type>
+ template <typename Meta, typename = typename std::enable_if<
+ !std::is_void<Meta>::value>::type>
int Post(const LocalHandle& ready_fence, const Meta& meta) {
return Post(ready_fence, &meta, sizeof(meta));
}
diff --git a/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h b/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
index ed11551..7ed024f 100644
--- a/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
+++ b/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
@@ -119,6 +119,14 @@
using LocalFence = FenceHandle<pdx::LocalHandle>;
using BorrowedFence = FenceHandle<pdx::BorrowedHandle>;
+struct QueueInfo {
+ size_t meta_size_bytes;
+ int id;
+
+ private:
+ PDX_SERIALIZABLE_MEMBERS(QueueInfo, meta_size_bytes, id);
+};
+
// BufferHub Service RPC interface. Defines the endpoints, op codes, and method
// type signatures supported by bufferhubd.
struct BufferHubRPC {
@@ -151,6 +159,7 @@
kOpConsumerSetIgnore,
kOpCreateProducerQueue,
kOpCreateConsumerQueue,
+ kOpGetQueueInfo,
kOpProducerQueueAllocateBuffers,
kOpProducerQueueDetachBuffer,
kOpConsumerQueueImportBuffers,
@@ -192,18 +201,19 @@
// Buffer Queue Methods.
PDX_REMOTE_METHOD(CreateProducerQueue, kOpCreateProducerQueue,
- int(size_t meta_size_bytes, int usage_set_mask,
- int usage_clear_mask, int usage_deny_set_mask,
- int usage_deny_clear_mask));
+ QueueInfo(size_t meta_size_bytes, int usage_set_mask,
+ int usage_clear_mask, int usage_deny_set_mask,
+ int usage_deny_clear_mask));
PDX_REMOTE_METHOD(CreateConsumerQueue, kOpCreateConsumerQueue,
- std::pair<LocalChannelHandle, size_t>(Void));
+ LocalChannelHandle(Void));
+ PDX_REMOTE_METHOD(GetQueueInfo, kOpGetQueueInfo, QueueInfo(Void));
PDX_REMOTE_METHOD(ProducerQueueAllocateBuffers,
kOpProducerQueueAllocateBuffers,
std::vector<std::pair<LocalChannelHandle, size_t>>(
int width, int height, int format, int usage,
size_t slice_count, size_t buffer_count));
PDX_REMOTE_METHOD(ProducerQueueDetachBuffer, kOpProducerQueueDetachBuffer,
- int(size_t slot));
+ void(size_t slot));
PDX_REMOTE_METHOD(ConsumerQueueImportBuffers, kOpConsumerQueueImportBuffers,
std::vector<std::pair<LocalChannelHandle, size_t>>(Void));
};
diff --git a/libs/vr/libbufferhub/include/private/dvr/ion_buffer.h b/libs/vr/libbufferhub/include/private/dvr/ion_buffer.h
index e449cbd..ffc42d6 100644
--- a/libs/vr/libbufferhub/include/private/dvr/ion_buffer.h
+++ b/libs/vr/libbufferhub/include/private/dvr/ion_buffer.h
@@ -60,21 +60,20 @@
int LockYUV(int usage, int x, int y, int width, int height,
struct android_ycbcr* yuv);
int Unlock();
- buffer_handle_t handle() const { if (buffer_.get()) return buffer_->handle;
- else return nullptr; }
- int width() const { if (buffer_.get()) return buffer_->getWidth();
- else return 0; }
- int height() const { if (buffer_.get()) return buffer_->getHeight();
- else return 0; }
- int layer_count() const { if (buffer_.get()) return buffer_->getLayerCount();
- else return 0; }
- int stride() const { if (buffer_.get()) return buffer_->getStride();
- else return 0; }
+
+ const sp<GraphicBuffer>& buffer() const { return buffer_; }
+ buffer_handle_t handle() const {
+ return buffer_.get() ? buffer_->handle : nullptr;
+ }
+ int width() const { return buffer_.get() ? buffer_->getWidth() : 0; }
+ int height() const { return buffer_.get() ? buffer_->getHeight() : 0; }
+ int layer_count() const {
+ return buffer_.get() ? buffer_->getLayerCount() : 0;
+ }
+ int stride() const { return buffer_.get() ? buffer_->getStride() : 0; }
int layer_stride() const { return 0; }
- int format() const { if (buffer_.get()) return buffer_->getPixelFormat();
- else return 0; }
- int usage() const { if (buffer_.get()) return buffer_->getUsage();
- else return 0; }
+ int format() const { return buffer_.get() ? buffer_->getPixelFormat() : 0; }
+ int usage() const { return buffer_.get() ? buffer_->getUsage() : 0; }
private:
sp<GraphicBuffer> buffer_;
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
index 031401a..e491abc 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
@@ -11,34 +11,36 @@
#include <pdx/file_handle.h>
#include <private/dvr/bufferhub_rpc.h>
+using android::pdx::ErrorStatus;
+using android::pdx::LocalChannelHandle;
+using android::pdx::Status;
+
namespace android {
namespace dvr {
-BufferHubQueue::BufferHubQueue(LocalChannelHandle channel_handle,
- size_t meta_size)
+BufferHubQueue::BufferHubQueue(LocalChannelHandle channel_handle)
: Client{pdx::default_transport::ClientChannel::Create(
std::move(channel_handle))},
- meta_size_(meta_size),
- meta_buffer_tmp_(meta_size ? new uint8_t[meta_size] : nullptr),
+ meta_size_(0),
buffers_(BufferHubQueue::kMaxQueueCapacity),
epollhup_pending_(BufferHubQueue::kMaxQueueCapacity, false),
available_buffers_(BufferHubQueue::kMaxQueueCapacity),
fences_(BufferHubQueue::kMaxQueueCapacity),
- capacity_(0) {
+ capacity_(0),
+ id_(-1) {
Initialize();
}
-BufferHubQueue::BufferHubQueue(const std::string& endpoint_path,
- size_t meta_size)
+BufferHubQueue::BufferHubQueue(const std::string& endpoint_path)
: Client{pdx::default_transport::ClientChannelFactory::Create(
endpoint_path)},
- meta_size_(meta_size),
- meta_buffer_tmp_(meta_size ? new uint8_t[meta_size] : nullptr),
+ meta_size_(0),
buffers_(BufferHubQueue::kMaxQueueCapacity),
epollhup_pending_(BufferHubQueue::kMaxQueueCapacity, false),
available_buffers_(BufferHubQueue::kMaxQueueCapacity),
fences_(BufferHubQueue::kMaxQueueCapacity),
- capacity_(0) {
+ capacity_(0),
+ id_(-1) {
Initialize();
}
@@ -55,26 +57,47 @@
BufferHubQueue::kEpollQueueEventIndex)}};
ret = epoll_fd_.Control(EPOLL_CTL_ADD, event_fd(), &event);
if (ret < 0) {
- ALOGE("Failed to register ConsumerQueue into epoll event: %s",
+ ALOGE("BufferHubQueue::Initialize: Failed to add event fd to epoll set: %s",
strerror(-ret));
}
}
-std::unique_ptr<ConsumerQueue> BufferHubQueue::CreateConsumerQueue() {
- Status<std::pair<LocalChannelHandle, size_t>> status =
- InvokeRemoteMethod<BufferHubRPC::CreateConsumerQueue>();
-
+Status<void> BufferHubQueue::ImportQueue() {
+ auto status = InvokeRemoteMethod<BufferHubRPC::GetQueueInfo>();
if (!status) {
- ALOGE("Cannot create ConsumerQueue: %s", status.GetErrorMessage().c_str());
+ ALOGE("BufferHubQueue::ImportQueue: Failed to import queue: %s",
+ status.GetErrorMessage().c_str());
+ return ErrorStatus(status.error());
+ } else {
+ SetupQueue(status.get().meta_size_bytes, status.get().id);
+ return {};
+ }
+}
+
+void BufferHubQueue::SetupQueue(size_t meta_size_bytes, int id) {
+ meta_size_ = meta_size_bytes;
+ id_ = id;
+ meta_buffer_tmp_.reset(meta_size_ > 0 ? new uint8_t[meta_size_] : nullptr);
+}
+
+std::unique_ptr<ConsumerQueue> BufferHubQueue::CreateConsumerQueue() {
+ if (auto status = CreateConsumerQueueHandle())
+ return std::unique_ptr<ConsumerQueue>(new ConsumerQueue(status.take()));
+ else
return nullptr;
+}
+
+Status<LocalChannelHandle> BufferHubQueue::CreateConsumerQueueHandle() {
+ auto status = InvokeRemoteMethod<BufferHubRPC::CreateConsumerQueue>();
+ if (!status) {
+ ALOGE(
+ "BufferHubQueue::CreateConsumerQueue: Failed to create consumer queue: "
+ "%s",
+ status.GetErrorMessage().c_str());
+ return ErrorStatus(status.error());
}
- auto return_value = status.take();
-
- ALOGD_IF(TRACE, "BufferHubQueue::CreateConsumerQueue: meta_size_bytes=%zu",
- return_value.second);
- return ConsumerQueue::Create(std::move(return_value.first),
- return_value.second);
+ return status;
}
bool BufferHubQueue::WaitForBuffers(int timeout) {
@@ -89,7 +112,8 @@
}
if (ret < 0 && ret != -EINTR) {
- ALOGE("Failed to wait for buffers: %s", strerror(-ret));
+ ALOGE("BufferHubQueue::WaitForBuffers: Failed to wait for buffers: %s",
+ strerror(-ret));
return false;
}
@@ -108,7 +132,8 @@
} else if (is_queue_event_index(index)) {
HandleQueueEvent(events[i]);
} else {
- ALOGW("Unknown event index: %" PRId64, index);
+ ALOGW("BufferHubQueue::WaitForBuffers: Unknown event index: %" PRId64,
+ index);
}
}
}
@@ -134,7 +159,8 @@
if (events & EPOLLIN) {
int ret = OnBufferReady(buffer, &fences_[slot]);
if (ret < 0) {
- ALOGE("Failed to set buffer ready: %s", strerror(-ret));
+ ALOGE("BufferHubQueue::HandleBufferEvent: Failed to set buffer ready: %s",
+ strerror(-ret));
return;
}
Enqueue(buffer, slot);
@@ -144,8 +170,8 @@
// epoll FD is cleaned up when the replacement consumer client is imported,
// we shouldn't detach again if |epollhub_pending_[slot]| is set.
ALOGW(
- "Receives EPOLLHUP at slot: %zu, buffer event fd: %d, EPOLLHUP "
- "pending: %d",
+ "BufferHubQueue::HandleBufferEvent: Received EPOLLHUP at slot: %zu, "
+ "buffer event fd: %d, EPOLLHUP pending: %d",
slot, buffer->event_fd(), int{epollhup_pending_[slot]});
if (epollhup_pending_[slot]) {
epollhup_pending_[slot] = false;
@@ -153,7 +179,10 @@
DetachBuffer(slot);
}
} else {
- ALOGW("Unknown event, slot=%zu, epoll events=%d", slot, events);
+ ALOGW(
+ "BufferHubQueue::HandleBufferEvent: Unknown event, slot=%zu, epoll "
+ "events=%d",
+ slot, events);
}
}
@@ -169,12 +198,13 @@
if (events & EPOLLIN) {
// Note that after buffer imports, if |count()| still returns 0, epoll
// wait will be tried again to acquire the newly imported buffer.
- int ret = OnBufferAllocated();
- if (ret < 0) {
- ALOGE("Failed to import buffer: %s", strerror(-ret));
+ auto buffer_status = OnBufferAllocated();
+ if (!buffer_status) {
+ ALOGE("BufferHubQueue::HandleQueueEvent: Failed to import buffer: %s",
+ buffer_status.GetErrorMessage().c_str());
}
} else {
- ALOGW("Unknown epoll events=%d", events);
+ ALOGW("BufferHubQueue::HandleQueueEvent: Unknown epoll events=%d", events);
}
}
@@ -233,7 +263,7 @@
void BufferHubQueue::Enqueue(std::shared_ptr<BufferHubBuffer> buf,
size_t slot) {
if (count() == capacity_) {
- ALOGE("Buffer queue is full!");
+ ALOGE("BufferHubQueue::Enqueue: Buffer queue is full!");
return;
}
@@ -274,7 +304,7 @@
available_buffers_.PopFront();
if (!buf) {
- ALOGE("Dequeue: Buffer to be dequeued is nullptr");
+ ALOGE("BufferHubQueue::Dequeue: Buffer to be dequeued is nullptr");
return nullptr;
}
@@ -289,15 +319,22 @@
ProducerQueue::ProducerQueue(size_t meta_size)
: ProducerQueue(meta_size, 0, 0, 0, 0) {}
-ProducerQueue::ProducerQueue(LocalChannelHandle handle, size_t meta_size)
- : BASE(std::move(handle), meta_size) {}
+ProducerQueue::ProducerQueue(LocalChannelHandle handle)
+ : BASE(std::move(handle)) {
+ auto status = ImportQueue();
+ if (!status) {
+ ALOGE("ProducerQueue::ProducerQueue: Failed to import queue: %s",
+ status.GetErrorMessage().c_str());
+ Close(-status.error());
+ }
+}
ProducerQueue::ProducerQueue(size_t meta_size, int usage_set_mask,
int usage_clear_mask, int usage_deny_set_mask,
int usage_deny_clear_mask)
- : BASE(BufferHubRPC::kClientPath, meta_size) {
+ : BASE(BufferHubRPC::kClientPath) {
auto status = InvokeRemoteMethod<BufferHubRPC::CreateProducerQueue>(
- meta_size_, usage_set_mask, usage_clear_mask, usage_deny_set_mask,
+ meta_size, usage_set_mask, usage_clear_mask, usage_deny_set_mask,
usage_deny_clear_mask);
if (!status) {
ALOGE("ProducerQueue::ProducerQueue: Failed to create producer queue: %s",
@@ -305,12 +342,14 @@
Close(-status.error());
return;
}
+
+ SetupQueue(status.get().meta_size_bytes, status.get().id);
}
int ProducerQueue::AllocateBuffer(int width, int height, int format, int usage,
size_t slice_count, size_t* out_slot) {
if (out_slot == nullptr) {
- ALOGE("Parameter out_slot cannot be null.");
+ ALOGE("ProducerQueue::AllocateBuffer: Parameter out_slot cannot be null.");
return -EINVAL;
}
@@ -362,7 +401,7 @@
}
int ProducerQueue::DetachBuffer(size_t slot) {
- Status<int> status =
+ auto status =
InvokeRemoteMethod<BufferHubRPC::ProducerQueueDetachBuffer>(slot);
if (!status) {
ALOGE(
@@ -378,7 +417,9 @@
std::shared_ptr<BufferProducer> ProducerQueue::Dequeue(
int timeout, size_t* slot, LocalHandle* release_fence) {
if (slot == nullptr || release_fence == nullptr) {
- ALOGE("invalid parameter, slot=%p, release_fence=%p", slot, release_fence);
+ ALOGE(
+ "ProducerQueue::Dequeue: invalid parameter, slot=%p, release_fence=%p",
+ slot, release_fence);
return nullptr;
}
@@ -392,21 +433,27 @@
return buffer->Gain(release_fence);
}
-ConsumerQueue::ConsumerQueue(LocalChannelHandle handle, size_t meta_size)
- : BASE(std::move(handle), meta_size) {
- // TODO(b/34387835) Import consumer queue in case the ProducerQueue we are
+ConsumerQueue::ConsumerQueue(LocalChannelHandle handle)
+ : BufferHubQueue(std::move(handle)) {
+ auto status = ImportQueue();
+ if (!status) {
+ ALOGE("ConsumerQueue::ConsumerQueue: Failed to import queue: %s",
+ status.GetErrorMessage().c_str());
+ Close(-status.error());
+ }
+
+ // TODO(b/34387835) Import buffers in case the ProducerQueue we are
// based on was not empty.
}
-int ConsumerQueue::ImportBuffers() {
- Status<std::vector<std::pair<LocalChannelHandle, size_t>>> status =
- InvokeRemoteMethod<BufferHubRPC::ConsumerQueueImportBuffers>();
+Status<size_t> ConsumerQueue::ImportBuffers() {
+ auto status = InvokeRemoteMethod<BufferHubRPC::ConsumerQueueImportBuffers>();
if (!status) {
ALOGE(
"ConsumerQueue::ImportBuffers failed to import consumer buffer through "
"BufferBub, error: %s",
status.GetErrorMessage().c_str());
- return -status.error();
+ return ErrorStatus(status.error());
}
int last_error = 0;
@@ -431,7 +478,10 @@
}
}
- return imported_buffers > 0 ? imported_buffers : last_error;
+ if (imported_buffers > 0)
+ return {imported_buffers};
+ else
+ return ErrorStatus(-last_error);
}
int ConsumerQueue::AddBuffer(const std::shared_ptr<BufferConsumer>& buf,
@@ -445,15 +495,17 @@
LocalHandle* acquire_fence) {
if (meta_size != meta_size_) {
ALOGE(
- "metadata size (%zu) for the dequeuing buffer does not match metadata "
- "size (%zu) for the queue.",
+ "ConsumerQueue::Dequeue: Metadata size (%zu) for the dequeuing buffer "
+ "does not match metadata size (%zu) for the queue.",
meta_size, meta_size_);
return nullptr;
}
if (slot == nullptr || meta == nullptr || acquire_fence == nullptr) {
- ALOGE("invalid parameter, slot=%p, meta=%p, acquire_fence=%p", slot, meta,
- acquire_fence);
+ ALOGE(
+ "ConsumerQueue::Dequeue: Invalid parameter, slot=%p, meta=%p, "
+ "acquire_fence=%p",
+ slot, meta, acquire_fence);
return nullptr;
}
@@ -467,15 +519,19 @@
return buffer->Acquire(acquire_fence, meta_buffer_tmp_.get(), meta_size_);
}
-int ConsumerQueue::OnBufferAllocated() {
- const int ret = ImportBuffers();
- if (ret == 0) {
- ALOGW("No new buffer can be imported on buffer allocated event.");
- } else if (ret < 0) {
- ALOGE("Failed to import buffers on buffer allocated event.");
+Status<void> ConsumerQueue::OnBufferAllocated() {
+ auto status = ImportBuffers();
+ if (!status) {
+ ALOGE("ConsumerQueue::OnBufferAllocated: Failed to import buffers: %s",
+ status.GetErrorMessage().c_str());
+ return ErrorStatus(status.error());
+ } else if (status.get() == 0) {
+ ALOGW("ConsumerQueue::OnBufferAllocated: No new buffers allocated!");
+ return ErrorStatus(ENOBUFS);
+ } else {
+ ALOGD_IF(TRACE, "Imported %zu consumer buffers.", status.get());
+ return {};
}
- ALOGD_IF(TRACE, "Imported %d consumer buffers.", ret);
- return ret;
}
} // namespace dvr
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
index 37cd8c7..2b70c5b 100644
--- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
+++ b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
@@ -4,6 +4,7 @@
#include <gui/BufferQueueDefs.h>
#include <pdx/client.h>
+#include <pdx/status.h>
#include <private/dvr/buffer_hub_client.h>
#include <private/dvr/epoll_file_descriptor.h>
#include <private/dvr/ring_buffer.h>
@@ -41,6 +42,9 @@
// Return the default buffer format of this buffer queue.
int32_t default_format() const { return default_format_; }
+ // Create a new consumer in handle form for immediate transport over RPC.
+ Status<LocalChannelHandle> CreateConsumerQueueHandle();
+
// Return the number of buffers avaiable for dequeue.
size_t count() const { return available_buffers_.GetSize(); }
@@ -51,7 +55,7 @@
size_t metadata_size() const { return meta_size_; }
// Return whether the buffer queue is alrady full.
- bool is_full() const { return available_buffers_.IsFull(); }
+ bool is_full() const { return available_buffers_.IsFull(); }
explicit operator bool() const { return epoll_fd_.IsValid(); }
@@ -83,9 +87,18 @@
// timeout.
static constexpr int kNoTimeOut = -1;
+ int id() const { return id_; }
+
protected:
- BufferHubQueue(LocalChannelHandle channel, size_t meta_size);
- BufferHubQueue(const std::string& endpoint_path, size_t meta_size);
+ BufferHubQueue(LocalChannelHandle channel);
+ BufferHubQueue(const std::string& endpoint_path);
+
+ // Imports the queue parameters by querying BufferHub for the parameters for
+ // this channel.
+ Status<void> ImportQueue();
+
+ // Sets up the queue with the given parameters.
+ void SetupQueue(size_t meta_size_bytes_, int id);
// Called by ProducerQueue::AddBuffer and ConsumerQueue::AddBuffer only. to
// register a buffer for epoll and internal bookkeeping.
@@ -112,7 +125,7 @@
LocalHandle* fence) = 0;
// Called when a buffer is allocated remotely.
- virtual int OnBufferAllocated() = 0;
+ virtual Status<void> OnBufferAllocated() { return {}; }
// Data members to handle arbitrary metadata passed through BufferHub. It is
// fair to enforce that all buffers in the same queue share the same metadata
@@ -235,6 +248,9 @@
// Epoll fd used to wait for BufferHub events.
EpollFileDescriptor epoll_fd_;
+ // Global id for the queue that is consistent across processes.
+ int id_;
+
BufferHubQueue(const BufferHubQueue&) = delete;
void operator=(BufferHubQueue&) = delete;
};
@@ -267,9 +283,8 @@
}
// Import a |ProducerQueue| from a channel handle.
- template <typename Meta>
static std::unique_ptr<ProducerQueue> Import(LocalChannelHandle handle) {
- return BASE::Create(std::move(handle), sizeof(Meta));
+ return BASE::Create(std::move(handle));
}
// Get a buffer producer. Note that the method doesn't check whether the
@@ -311,18 +326,15 @@
// static template methods inherited from ClientBase, which take the same
// arguments as the constructors.
explicit ProducerQueue(size_t meta_size);
- ProducerQueue(LocalChannelHandle handle, size_t meta_size);
+ ProducerQueue(LocalChannelHandle handle);
ProducerQueue(size_t meta_size, int usage_set_mask, int usage_clear_mask,
int usage_deny_set_mask, int usage_deny_clear_mask);
int OnBufferReady(std::shared_ptr<BufferHubBuffer> buf,
LocalHandle* release_fence) override;
-
- // Producer buffer is always allocated from the client (i.e. local) side.
- int OnBufferAllocated() override { return 0; }
};
-class ConsumerQueue : public pdx::ClientBase<ConsumerQueue, BufferHubQueue> {
+class ConsumerQueue : public BufferHubQueue {
public:
// Get a buffer consumer. Note that the method doesn't check whether the
// buffer slot has a valid buffer that has been imported already. When no
@@ -333,10 +345,14 @@
BufferHubQueue::GetBuffer(slot));
}
+ // Import a |ConsumerQueue| from a channel handle.
+ static std::unique_ptr<ConsumerQueue> Import(LocalChannelHandle handle) {
+ return std::unique_ptr<ConsumerQueue>(new ConsumerQueue(std::move(handle)));
+ }
+
// Import newly created buffers from the service side.
- // Returns number of buffers successfully imported; or negative error code
- // when buffer import fails.
- int ImportBuffers();
+ // Returns number of buffers successfully imported or an error.
+ Status<size_t> ImportBuffers();
// Dequeue a consumer buffer to read. The returned buffer in |Acquired|'ed
// mode, and caller should call Releasse() once it's done writing to release
@@ -353,10 +369,11 @@
std::shared_ptr<BufferConsumer> Dequeue(int timeout, size_t* slot, void* meta,
size_t meta_size,
LocalHandle* acquire_fence);
- private:
- friend BASE;
- ConsumerQueue(LocalChannelHandle handle, size_t meta_size);
+ private:
+ friend BufferHubQueue;
+
+ ConsumerQueue(LocalChannelHandle handle);
// Add a consumer buffer to populate the queue. Once added, a consumer buffer
// is NOT available to use until the producer side |Post| it. |WaitForBuffers|
@@ -367,7 +384,7 @@
int OnBufferReady(std::shared_ptr<BufferHubBuffer> buf,
LocalHandle* acquire_fence) override;
- int OnBufferAllocated() override;
+ Status<void> OnBufferAllocated() override;
};
} // namespace dvr
diff --git a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
index 811543d..171577d 100644
--- a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
+++ b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
@@ -22,16 +22,20 @@
class BufferHubQueueTest : public ::testing::Test {
public:
template <typename Meta>
- void CreateQueues(int usage_set_mask = 0, int usage_clear_mask = 0,
+ bool CreateQueues(int usage_set_mask = 0, int usage_clear_mask = 0,
int usage_deny_set_mask = 0,
int usage_deny_clear_mask = 0) {
producer_queue_ =
ProducerQueue::Create<Meta>(usage_set_mask, usage_clear_mask,
usage_deny_set_mask, usage_deny_clear_mask);
- ASSERT_NE(nullptr, producer_queue_);
+ if (!producer_queue_)
+ return false;
consumer_queue_ = producer_queue_->CreateConsumerQueue();
- ASSERT_NE(nullptr, consumer_queue_);
+ if (!consumer_queue_)
+ return false;
+
+ return true;
}
void AllocateBuffer() {
@@ -51,7 +55,7 @@
TEST_F(BufferHubQueueTest, TestDequeue) {
const size_t nb_dequeue_times = 16;
- CreateQueues<size_t>();
+ ASSERT_TRUE(CreateQueues<size_t>());
// Allocate only one buffer.
AllocateBuffer();
@@ -77,7 +81,7 @@
size_t slot;
uint64_t seq;
- CreateQueues<uint64_t>();
+ ASSERT_TRUE(CreateQueues<uint64_t>());
for (size_t i = 0; i < nb_buffer; i++) {
AllocateBuffer();
@@ -127,7 +131,7 @@
};
TEST_F(BufferHubQueueTest, TestMetadata) {
- CreateQueues<TestMetadata>();
+ ASSERT_TRUE(CreateQueues<TestMetadata>());
AllocateBuffer();
std::vector<TestMetadata> ms = {
@@ -149,7 +153,7 @@
}
TEST_F(BufferHubQueueTest, TestMetadataMismatch) {
- CreateQueues<int64_t>();
+ ASSERT_TRUE(CreateQueues<int64_t>());
AllocateBuffer();
int64_t mi = 3;
@@ -166,7 +170,7 @@
}
TEST_F(BufferHubQueueTest, TestEnqueue) {
- CreateQueues<int64_t>();
+ ASSERT_TRUE(CreateQueues<int64_t>());
AllocateBuffer();
size_t slot;
@@ -181,7 +185,7 @@
}
TEST_F(BufferHubQueueTest, TestAllocateBuffer) {
- CreateQueues<int64_t>();
+ ASSERT_TRUE(CreateQueues<int64_t>());
size_t s1;
AllocateBuffer();
@@ -227,7 +231,7 @@
TEST_F(BufferHubQueueTest, TestUsageSetMask) {
const int set_mask = GRALLOC_USAGE_SW_WRITE_OFTEN;
- CreateQueues<int64_t>(set_mask, 0, 0, 0);
+ ASSERT_TRUE(CreateQueues<int64_t>(set_mask, 0, 0, 0));
// When allocation, leave out |set_mask| from usage bits on purpose.
size_t slot;
@@ -243,7 +247,7 @@
TEST_F(BufferHubQueueTest, TestUsageClearMask) {
const int clear_mask = GRALLOC_USAGE_SW_WRITE_OFTEN;
- CreateQueues<int64_t>(0, clear_mask, 0, 0);
+ ASSERT_TRUE(CreateQueues<int64_t>(0, clear_mask, 0, 0));
// When allocation, add |clear_mask| into usage bits on purpose.
size_t slot;
@@ -259,7 +263,7 @@
TEST_F(BufferHubQueueTest, TestUsageDenySetMask) {
const int deny_set_mask = GRALLOC_USAGE_SW_WRITE_OFTEN;
- CreateQueues<int64_t>(0, 0, deny_set_mask, 0);
+ ASSERT_TRUE(CreateQueues<int64_t>(0, 0, deny_set_mask, 0));
// Now that |deny_set_mask| is illegal, allocation without those bits should
// be able to succeed.
@@ -278,7 +282,7 @@
TEST_F(BufferHubQueueTest, TestUsageDenyClearMask) {
const int deny_clear_mask = GRALLOC_USAGE_SW_WRITE_OFTEN;
- CreateQueues<int64_t>(0, 0, 0, deny_clear_mask);
+ ASSERT_TRUE(CreateQueues<int64_t>(0, 0, 0, deny_clear_mask));
// Now that clearing |deny_clear_mask| is illegal (i.e. setting these bits are
// mandatory), allocation with those bits should be able to succeed.
diff --git a/libs/vr/libdisplay/display_client.cpp b/libs/vr/libdisplay/display_client.cpp
index 9952e59..6d39cdb 100644
--- a/libs/vr/libdisplay/display_client.cpp
+++ b/libs/vr/libdisplay/display_client.cpp
@@ -160,8 +160,7 @@
return nullptr;
}
- producer_queue_ =
- ProducerQueue::Import<DisplaySurfaceMetadata>(status.take());
+ producer_queue_ = ProducerQueue::Import(status.take());
}
return producer_queue_;
}
diff --git a/libs/vr/libdisplay/video_mesh_surface_client.cpp b/libs/vr/libdisplay/video_mesh_surface_client.cpp
index 04cc194..a2307e5 100644
--- a/libs/vr/libdisplay/video_mesh_surface_client.cpp
+++ b/libs/vr/libdisplay/video_mesh_surface_client.cpp
@@ -30,8 +30,7 @@
return nullptr;
}
- producer_queue_ =
- ProducerQueue::Import<VideoMeshSurfaceBufferMetadata>(status.take());
+ producer_queue_ = ProducerQueue::Import(status.take());
}
return producer_queue_;
}
diff --git a/libs/vr/libpdx/private/pdx/rpc/serialization.h b/libs/vr/libpdx/private/pdx/rpc/serialization.h
index 9a012ed..f12aef1 100644
--- a/libs/vr/libpdx/private/pdx/rpc/serialization.h
+++ b/libs/vr/libpdx/private/pdx/rpc/serialization.h
@@ -247,7 +247,7 @@
inline std::size_t GetSerializedSize(const EmptyVariant&);
template <typename... Types>
inline std::size_t GetSerializedSize(const Variant<Types...>&);
-template <typename T, typename Enabled>
+template <typename T, typename Enabled = EnableIfHasSerializableMembers<T>>
inline constexpr std::size_t GetSerializedSize(const T&);
template <typename T>
inline constexpr std::size_t GetSerializedSize(const PointerWrapper<T>&);
@@ -293,7 +293,7 @@
}
// Overload for structs/classes with SerializableMembers defined.
-template <typename T, typename Enabled = EnableIfHasSerializableMembers<T>>
+template <typename T, typename Enabled>
inline constexpr std::size_t GetSerializedSize(const T& value) {
return SerializableTraits<T>::GetSerializedSize(value);
}
@@ -836,7 +836,7 @@
inline void SerializeObject(const EmptyVariant&, MessageWriter*, void*&);
template <typename... Types>
inline void SerializeObject(const Variant<Types...>&, MessageWriter*, void*&);
-template <typename T, typename Enabled>
+template <typename T, typename Enabled = EnableIfHasSerializableMembers<T>>
inline void SerializeObject(const T&, MessageWriter*, void*&);
template <typename T>
inline void SerializeObject(const PointerWrapper<T>&, MessageWriter*, void*&);
@@ -887,7 +887,7 @@
}
// Overload for serializable structure/class types.
-template <typename T, typename Enabled = EnableIfHasSerializableMembers<T>>
+template <typename T, typename Enabled>
inline void SerializeObject(const T& value, MessageWriter* writer,
void*& buffer) {
SerializableTraits<T>::SerializeObject(value, writer, buffer);
@@ -1379,7 +1379,7 @@
}
// Forward declarations for nested definitions.
-template <typename T, typename Enabled>
+template <typename T, typename Enabled = EnableIfHasSerializableMembers<T>>
inline ErrorType DeserializeObject(T*, MessageReader*, const void*&,
const void*&);
template <typename T>
@@ -1438,7 +1438,7 @@
const void*&);
// Deserializes a Serializable type.
-template <typename T, typename Enable = EnableIfHasSerializableMembers<T>>
+template <typename T, typename Enable>
inline ErrorType DeserializeObject(T* value, MessageReader* reader,
const void*& start, const void*& end) {
return SerializableTraits<T>::DeserializeObject(value, reader, start, end);
diff --git a/libs/vr/libpdx/private/pdx/rpc/variant.h b/libs/vr/libpdx/private/pdx/rpc/variant.h
index 09789e5..cb44a51 100644
--- a/libs/vr/libpdx/private/pdx/rpc/variant.h
+++ b/libs/vr/libpdx/private/pdx/rpc/variant.h
@@ -39,15 +39,11 @@
template <typename... Types>
struct HasType : std::false_type {};
template <typename T, typename U>
-struct HasType<T, U> : std::is_same<T, U> {};
+struct HasType<T, U> : std::is_same<std::decay_t<T>, std::decay_t<U>> {};
template <typename T, typename First, typename... Rest>
struct HasType<T, First, Rest...>
- : std::integral_constant<
- bool, std::is_same<T, First>::value || HasType<T, Rest...>::value> {};
-
-template <typename T, typename... Types>
-using HasTypeIgnoreRef =
- HasType<typename std::remove_reference<T>::type, Types...>;
+ : std::integral_constant<bool, HasType<T, First>::value ||
+ HasType<T, Rest...>::value> {};
// Defines set operations on a set of Types...
template <typename... Types>
@@ -59,8 +55,8 @@
struct IsSubset<T> : HasType<T, Types...> {};
template <typename First, typename... Rest>
struct IsSubset<First, Rest...>
- : std::integral_constant<
- bool, IsSubset<First>::value && IsSubset<Rest...>::value> {};
+ : std::integral_constant<bool, IsSubset<First>::value &&
+ IsSubset<Rest...>::value> {};
};
// Determines the number of elements of Types... that are constructible from
@@ -80,18 +76,18 @@
// Enable if T is an element of Types...
template <typename R, typename T, typename... Types>
using EnableIfElement =
- typename std::enable_if<HasTypeIgnoreRef<T, Types...>::value, R>::type;
+ typename std::enable_if<HasType<T, Types...>::value, R>::type;
// Enable if T is not an element of Types...
template <typename R, typename T, typename... Types>
using EnableIfNotElement =
- typename std::enable_if<!HasTypeIgnoreRef<T, Types...>::value, R>::type;
+ typename std::enable_if<!HasType<T, Types...>::value, R>::type;
// Enable if T is convertible to an element of Types... T is considered
// convertible IIF a single element of Types... is assignable from T and T is
// not a direct element of Types...
template <typename R, typename T, typename... Types>
using EnableIfConvertible =
- typename std::enable_if<!HasTypeIgnoreRef<T, Types...>::value &&
+ typename std::enable_if<!HasType<T, Types...>::value &&
ConstructibleCount<T, Types...>::value == 1,
R>::type;
@@ -102,7 +98,7 @@
// in conversion.
template <typename R, typename T, typename... Types>
using EnableIfAssignable =
- typename std::enable_if<HasTypeIgnoreRef<T, Types...>::value ||
+ typename std::enable_if<HasType<T, Types...>::value ||
ConstructibleCount<T, Types...>::value == 1,
R>::type;
@@ -362,15 +358,13 @@
template <typename T>
using TypeTag = detail::TypeTag<T>;
template <typename T>
- using TypeTagIgnoreRef = TypeTag<typename std::remove_reference<T>::type>;
+ using DecayedTypeTag = TypeTag<std::decay_t<T>>;
template <std::size_t I>
using TypeForIndex = detail::TypeForIndex<I, Types...>;
template <std::size_t I>
using TypeTagForIndex = detail::TypeTagForIndex<I, Types...>;
template <typename T>
using HasType = detail::HasType<T, Types...>;
- template <typename T>
- using HasTypeIgnoreRef = detail::HasTypeIgnoreRef<T, Types...>;
template <typename R, typename T>
using EnableIfElement = detail::EnableIfElement<R, T, Types...>;
template <typename R, typename T>
@@ -381,13 +375,12 @@
struct Direct {};
struct Convert {};
template <typename T>
- using SelectConstructor =
- detail::Select<HasTypeIgnoreRef<T>::value, Direct, Convert>;
+ using SelectConstructor = detail::Select<HasType<T>::value, Direct, Convert>;
// Constructs by type tag when T is an direct element of Types...
template <typename T>
explicit Variant(T&& value, Direct)
- : value_(0, &index_, TypeTagIgnoreRef<T>{}, std::forward<T>(value)) {}
+ : value_(0, &index_, DecayedTypeTag<T>{}, std::forward<T>(value)) {}
// Conversion constructor when T is not a direct element of Types...
template <typename T>
explicit Variant(T&& value, Convert)
@@ -421,7 +414,7 @@
// convertible to multiple elements of Types.
template <typename T>
EnableIfElement<Variant&, T> operator=(T&& value) {
- Assign(TypeTagIgnoreRef<T>{}, std::forward<T>(value));
+ Assign(DecayedTypeTag<T>{}, std::forward<T>(value));
return *this;
}
@@ -487,7 +480,7 @@
template <typename T>
constexpr std::int32_t index_of() const {
static_assert(HasType<T>::value, "T is not an element type of Variant.");
- return value_.template index(TypeTag<T>{});
+ return value_.template index(DecayedTypeTag<T>{});
}
// Returns the index of the active type. If the Variant is empty -1 is
@@ -509,14 +502,14 @@
template <typename T>
T* get() {
if (is<T>())
- return &value_.template get(TypeTag<T>{});
+ return &value_.template get(DecayedTypeTag<T>{});
else
return nullptr;
}
template <typename T>
const T* get() const {
if (is<T>())
- return &value_.template get(TypeTag<T>{});
+ return &value_.template get(DecayedTypeTag<T>{});
else
return nullptr;
}
@@ -537,7 +530,7 @@
private:
std::int32_t index_ = kEmptyIndex;
- detail::Union<Types...> value_;
+ detail::Union<std::decay_t<Types>...> value_;
// Constructs an element from the given arguments and sets the Variant to the
// resulting type.
diff --git a/libs/vr/libpdx/thread_local_buffer_tests.cpp b/libs/vr/libpdx/thread_local_buffer_tests.cpp
index 1747d79..6cdaf10 100644
--- a/libs/vr/libpdx/thread_local_buffer_tests.cpp
+++ b/libs/vr/libpdx/thread_local_buffer_tests.cpp
@@ -89,13 +89,13 @@
EXPECT_NE(id1, id2);
}
-// TODO(b/36456321): Fix this and enable it again.
// Tests that thread-local buffers are allocated at the first buffer request.
-TEST(ThreadLocalBufferTest, DISABLED_InitialValue) {
+TEST(ThreadLocalBufferTest, InitialValue) {
struct TypeTagX;
using SendSlotX = ThreadLocalSlot<TypeTagX, kSendBufferIndex>;
auto value1 = ThreadLocalBufferTest::GetSlotValue<SendSlotX>();
+ MessageBuffer<SendSlotX>::GetBuffer();
auto value2 = ThreadLocalBufferTest::GetSlotValue<SendSlotX>();
EXPECT_EQ(0U, value1);
diff --git a/libs/vr/libpdx/variant_tests.cpp b/libs/vr/libpdx/variant_tests.cpp
index c30c055..325f33f 100644
--- a/libs/vr/libpdx/variant_tests.cpp
+++ b/libs/vr/libpdx/variant_tests.cpp
@@ -368,6 +368,13 @@
}
{
+ TestType<int> i(1);
+ Variant<int, bool, float> v(i.get());
+ ASSERT_TRUE(v.is<int>());
+ EXPECT_EQ(1, std::get<int>(v));
+ }
+
+ {
TestType<bool> b(true);
Variant<int, bool, float> v(b.take());
ASSERT_TRUE(v.is<bool>());
@@ -375,6 +382,13 @@
}
{
+ TestType<bool> b(true);
+ Variant<int, bool, float> v(b.get());
+ ASSERT_TRUE(v.is<bool>());
+ EXPECT_EQ(true, std::get<bool>(v));
+ }
+
+ {
Variant<const char*> c("test");
Variant<std::string> s(c);
ASSERT_TRUE(s.is<std::string>());
@@ -1060,8 +1074,8 @@
EXPECT_FALSE((detail::HasType<char, int, float, bool>::value));
EXPECT_FALSE(detail::HasType<>::value);
- EXPECT_TRUE((detail::HasTypeIgnoreRef<int&, int, float, bool>::value));
- EXPECT_FALSE((detail::HasTypeIgnoreRef<char&, int, float, bool>::value));
+ EXPECT_TRUE((detail::HasType<int&, int, float, bool>::value));
+ EXPECT_FALSE((detail::HasType<char&, int, float, bool>::value));
}
TEST(Variant, Set) {
diff --git a/libs/vr/libpdx_uds/client_channel.cpp b/libs/vr/libpdx_uds/client_channel.cpp
index 4cbdb94..924335f 100644
--- a/libs/vr/libpdx_uds/client_channel.cpp
+++ b/libs/vr/libpdx_uds/client_channel.cpp
@@ -67,7 +67,7 @@
ResponseHeader<LocalHandle> response;
};
-Status<void> ReadAndDiscardData(int socket_fd, size_t size) {
+Status<void> ReadAndDiscardData(const BorrowedHandle& socket_fd, size_t size) {
while (size > 0) {
// If there is more data to read in the message than the buffers provided
// by the caller, read and discard the extra data from the socket.
@@ -83,9 +83,10 @@
return ErrorStatus(EIO);
}
-Status<void> SendRequest(int socket_fd, TransactionState* transaction_state,
- int opcode, const iovec* send_vector,
- size_t send_count, size_t max_recv_len) {
+Status<void> SendRequest(const BorrowedHandle& socket_fd,
+ TransactionState* transaction_state, int opcode,
+ const iovec* send_vector, size_t send_count,
+ size_t max_recv_len) {
size_t send_len = CountVectorSize(send_vector, send_count);
InitRequest(&transaction_state->request, opcode, send_len, max_recv_len,
false);
@@ -95,7 +96,8 @@
return status;
}
-Status<void> ReceiveResponse(int socket_fd, TransactionState* transaction_state,
+Status<void> ReceiveResponse(const BorrowedHandle& socket_fd,
+ TransactionState* transaction_state,
const iovec* receive_vector, size_t receive_count,
size_t max_recv_len) {
auto status = ReceiveData(socket_fd, &transaction_state->response);
@@ -164,7 +166,7 @@
InitRequest(&request, opcode, length, 0, true);
memcpy(request.impulse_payload.data(), buffer, length);
- return SendData(channel_handle_.value(), request);
+ return SendData(BorrowedHandle{channel_handle_.value()}, request);
}
Status<int> ClientChannel::SendAndReceive(void* transaction_state, int opcode,
@@ -182,11 +184,11 @@
auto* state = static_cast<TransactionState*>(transaction_state);
size_t max_recv_len = CountVectorSize(receive_vector, receive_count);
- auto status = SendRequest(channel_handle_.value(), state, opcode, send_vector,
- send_count, max_recv_len);
+ auto status = SendRequest(BorrowedHandle{channel_handle_.value()}, state,
+ opcode, send_vector, send_count, max_recv_len);
if (status) {
- status = ReceiveResponse(channel_handle_.value(), state, receive_vector,
- receive_count, max_recv_len);
+ status = ReceiveResponse(BorrowedHandle{channel_handle_.value()}, state,
+ receive_vector, receive_count, max_recv_len);
}
if (!result.PropagateError(status)) {
const int return_code = state->response.ret_code;
diff --git a/libs/vr/libpdx_uds/client_channel_factory.cpp b/libs/vr/libpdx_uds/client_channel_factory.cpp
index f059453..323236d 100644
--- a/libs/vr/libpdx_uds/client_channel_factory.cpp
+++ b/libs/vr/libpdx_uds/client_channel_factory.cpp
@@ -111,11 +111,11 @@
remote.sun_path);
RequestHeader<BorrowedHandle> request;
InitRequest(&request, opcodes::CHANNEL_OPEN, 0, 0, false);
- status = SendData(socket_fd.Get(), request);
+ status = SendData(socket_fd.Borrow(), request);
if (!status)
return ErrorStatus(status.error());
ResponseHeader<LocalHandle> response;
- status = ReceiveData(socket_fd.Get(), &response);
+ status = ReceiveData(socket_fd.Borrow(), &response);
if (!status)
return ErrorStatus(status.error());
int ref = response.ret_code;
diff --git a/libs/vr/libpdx_uds/ipc_helper.cpp b/libs/vr/libpdx_uds/ipc_helper.cpp
index fe5c986..d604f62 100644
--- a/libs/vr/libpdx_uds/ipc_helper.cpp
+++ b/libs/vr/libpdx_uds/ipc_helper.cpp
@@ -26,18 +26,19 @@
uint32_t fd_count{0};
};
-Status<void> SendPayload::Send(int socket_fd) {
+Status<void> SendPayload::Send(const BorrowedHandle& socket_fd) {
return Send(socket_fd, nullptr);
}
-Status<void> SendPayload::Send(int socket_fd, const ucred* cred) {
+Status<void> SendPayload::Send(const BorrowedHandle& socket_fd,
+ const ucred* cred) {
MessagePreamble preamble;
preamble.magic = kMagicPreamble;
preamble.data_size = buffer_.size();
preamble.fd_count = file_handles_.size();
- ssize_t ret =
- RETRY_EINTR(send(socket_fd, &preamble, sizeof(preamble), MSG_NOSIGNAL));
+ ssize_t ret = RETRY_EINTR(
+ send(socket_fd.Get(), &preamble, sizeof(preamble), MSG_NOSIGNAL));
if (ret < 0)
return ErrorStatus(errno);
if (ret != sizeof(preamble))
@@ -71,7 +72,7 @@
}
}
- ret = RETRY_EINTR(sendmsg(socket_fd, &msg, MSG_NOSIGNAL));
+ ret = RETRY_EINTR(sendmsg(socket_fd.Get(), &msg, MSG_NOSIGNAL));
if (ret < 0)
return ErrorStatus(errno);
if (static_cast<size_t>(ret) != buffer_.size())
@@ -125,14 +126,15 @@
return ErrorStatus{EOPNOTSUPP};
}
-Status<void> ReceivePayload::Receive(int socket_fd) {
+Status<void> ReceivePayload::Receive(const BorrowedHandle& socket_fd) {
return Receive(socket_fd, nullptr);
}
-Status<void> ReceivePayload::Receive(int socket_fd, ucred* cred) {
+Status<void> ReceivePayload::Receive(const BorrowedHandle& socket_fd,
+ ucred* cred) {
MessagePreamble preamble;
- ssize_t ret =
- RETRY_EINTR(recv(socket_fd, &preamble, sizeof(preamble), MSG_WAITALL));
+ ssize_t ret = RETRY_EINTR(
+ recv(socket_fd.Get(), &preamble, sizeof(preamble), MSG_WAITALL));
if (ret < 0)
return ErrorStatus(errno);
else if (ret == 0)
@@ -157,7 +159,7 @@
msg.msg_control = alloca(msg.msg_controllen);
}
- ret = RETRY_EINTR(recvmsg(socket_fd, &msg, MSG_WAITALL));
+ ret = RETRY_EINTR(recvmsg(socket_fd.Get(), &msg, MSG_WAITALL));
if (ret < 0)
return ErrorStatus(errno);
else if (ret == 0)
@@ -219,8 +221,10 @@
return false;
}
-Status<void> SendData(int socket_fd, const void* data, size_t size) {
- ssize_t size_written = RETRY_EINTR(send(socket_fd, data, size, MSG_NOSIGNAL));
+Status<void> SendData(const BorrowedHandle& socket_fd, const void* data,
+ size_t size) {
+ ssize_t size_written =
+ RETRY_EINTR(send(socket_fd.Get(), data, size, MSG_NOSIGNAL));
if (size_written < 0)
return ErrorStatus(errno);
if (static_cast<size_t>(size_written) != size)
@@ -228,11 +232,13 @@
return {};
}
-Status<void> SendDataVector(int socket_fd, const iovec* data, size_t count) {
+Status<void> SendDataVector(const BorrowedHandle& socket_fd, const iovec* data,
+ size_t count) {
msghdr msg = {};
msg.msg_iov = const_cast<iovec*>(data);
msg.msg_iovlen = count;
- ssize_t size_written = RETRY_EINTR(sendmsg(socket_fd, &msg, MSG_NOSIGNAL));
+ ssize_t size_written =
+ RETRY_EINTR(sendmsg(socket_fd.Get(), &msg, MSG_NOSIGNAL));
if (size_written < 0)
return ErrorStatus(errno);
if (static_cast<size_t>(size_written) != CountVectorSize(data, count))
@@ -240,8 +246,10 @@
return {};
}
-Status<void> ReceiveData(int socket_fd, void* data, size_t size) {
- ssize_t size_read = RETRY_EINTR(recv(socket_fd, data, size, MSG_WAITALL));
+Status<void> ReceiveData(const BorrowedHandle& socket_fd, void* data,
+ size_t size) {
+ ssize_t size_read =
+ RETRY_EINTR(recv(socket_fd.Get(), data, size, MSG_WAITALL));
if (size_read < 0)
return ErrorStatus(errno);
else if (size_read == 0)
@@ -251,11 +259,12 @@
return {};
}
-Status<void> ReceiveDataVector(int socket_fd, const iovec* data, size_t count) {
+Status<void> ReceiveDataVector(const BorrowedHandle& socket_fd,
+ const iovec* data, size_t count) {
msghdr msg = {};
msg.msg_iov = const_cast<iovec*>(data);
msg.msg_iovlen = count;
- ssize_t size_read = RETRY_EINTR(recvmsg(socket_fd, &msg, MSG_WAITALL));
+ ssize_t size_read = RETRY_EINTR(recvmsg(socket_fd.Get(), &msg, MSG_WAITALL));
if (size_read < 0)
return ErrorStatus(errno);
else if (size_read == 0)
diff --git a/libs/vr/libpdx_uds/private/uds/ipc_helper.h b/libs/vr/libpdx_uds/private/uds/ipc_helper.h
index 80530bf..82950a2 100644
--- a/libs/vr/libpdx_uds/private/uds/ipc_helper.h
+++ b/libs/vr/libpdx_uds/private/uds/ipc_helper.h
@@ -25,8 +25,8 @@
class SendPayload : public MessageWriter, public OutputResourceMapper {
public:
- Status<void> Send(int socket_fd);
- Status<void> Send(int socket_fd, const ucred* cred);
+ Status<void> Send(const BorrowedHandle& socket_fd);
+ Status<void> Send(const BorrowedHandle& socket_fd, const ucred* cred);
// MessageWriter
void* GetNextWriteBufferSection(size_t size) override;
@@ -50,8 +50,8 @@
class ReceivePayload : public MessageReader, public InputResourceMapper {
public:
- Status<void> Receive(int socket_fd);
- Status<void> Receive(int socket_fd, ucred* cred);
+ Status<void> Receive(const BorrowedHandle& socket_fd);
+ Status<void> Receive(const BorrowedHandle& socket_fd, ucred* cred);
// MessageReader
BufferSection GetNextReadBufferSection() override;
@@ -111,25 +111,27 @@
};
template <typename T>
-inline Status<void> SendData(int socket_fd, const T& data) {
+inline Status<void> SendData(const BorrowedHandle& socket_fd, const T& data) {
SendPayload payload;
rpc::Serialize(data, &payload);
return payload.Send(socket_fd);
}
template <typename FileHandleType>
-inline Status<void> SendData(int socket_fd,
+inline Status<void> SendData(const BorrowedHandle& socket_fd,
const RequestHeader<FileHandleType>& request) {
SendPayload payload;
rpc::Serialize(request, &payload);
return payload.Send(socket_fd, &request.cred);
}
-Status<void> SendData(int socket_fd, const void* data, size_t size);
-Status<void> SendDataVector(int socket_fd, const iovec* data, size_t count);
+Status<void> SendData(const BorrowedHandle& socket_fd, const void* data,
+ size_t size);
+Status<void> SendDataVector(const BorrowedHandle& socket_fd, const iovec* data,
+ size_t count);
template <typename T>
-inline Status<void> ReceiveData(int socket_fd, T* data) {
+inline Status<void> ReceiveData(const BorrowedHandle& socket_fd, T* data) {
ReceivePayload payload;
Status<void> status = payload.Receive(socket_fd);
if (status && rpc::Deserialize(data, &payload) != rpc::ErrorCode::NO_ERROR)
@@ -138,7 +140,7 @@
}
template <typename FileHandleType>
-inline Status<void> ReceiveData(int socket_fd,
+inline Status<void> ReceiveData(const BorrowedHandle& socket_fd,
RequestHeader<FileHandleType>* request) {
ReceivePayload payload;
Status<void> status = payload.Receive(socket_fd, &request->cred);
@@ -147,8 +149,10 @@
return status;
}
-Status<void> ReceiveData(int socket_fd, void* data, size_t size);
-Status<void> ReceiveDataVector(int socket_fd, const iovec* data, size_t count);
+Status<void> ReceiveData(const BorrowedHandle& socket_fd, void* data,
+ size_t size);
+Status<void> ReceiveDataVector(const BorrowedHandle& socket_fd,
+ const iovec* data, size_t count);
size_t CountVectorSize(const iovec* data, size_t count);
void InitRequest(android::pdx::uds::RequestHeader<BorrowedHandle>* request,
diff --git a/libs/vr/libpdx_uds/private/uds/service_endpoint.h b/libs/vr/libpdx_uds/private/uds/service_endpoint.h
index 2b24f62..f747abc 100644
--- a/libs/vr/libpdx_uds/private/uds/service_endpoint.h
+++ b/libs/vr/libpdx_uds/private/uds/service_endpoint.h
@@ -117,18 +117,20 @@
return next_message_id_.fetch_add(1, std::memory_order_relaxed);
}
- void BuildCloseMessage(int channel_id, Message* message);
+ void BuildCloseMessage(int32_t channel_id, Message* message);
Status<void> AcceptConnection(Message* message);
- Status<void> ReceiveMessageForChannel(int channel_id, Message* message);
+ Status<void> ReceiveMessageForChannel(const BorrowedHandle& channel_fd,
+ Message* message);
Status<void> OnNewChannel(LocalHandle channel_fd);
- Status<ChannelData*> OnNewChannelLocked(LocalHandle channel_fd,
- Channel* channel_state);
- Status<void> CloseChannelLocked(int channel_id);
- Status<void> ReenableEpollEvent(int fd);
- Channel* GetChannelState(int channel_id);
- int GetChannelSocketFd(int channel_id);
- int GetChannelEventFd(int channel_id);
+ Status<std::pair<int32_t, ChannelData*>> OnNewChannelLocked(
+ LocalHandle channel_fd, Channel* channel_state);
+ Status<void> CloseChannelLocked(int32_t channel_id);
+ Status<void> ReenableEpollEvent(const BorrowedHandle& channel_fd);
+ Channel* GetChannelState(int32_t channel_id);
+ BorrowedHandle GetChannelSocketFd(int32_t channel_id);
+ BorrowedHandle GetChannelEventFd(int32_t channel_id);
+ int32_t GetChannelId(const BorrowedHandle& channel_fd);
std::string endpoint_path_;
bool is_blocking_;
@@ -137,7 +139,9 @@
LocalHandle epoll_fd_;
mutable std::mutex channel_mutex_;
- std::map<int, ChannelData> channels_;
+ std::map<int32_t, ChannelData> channels_;
+ std::map<int, int32_t> channel_fd_to_id_;
+ int32_t last_channel_id_{0};
Service* service_{nullptr};
std::atomic<uint32_t> next_message_id_;
diff --git a/libs/vr/libpdx_uds/service_endpoint.cpp b/libs/vr/libpdx_uds/service_endpoint.cpp
index 6f32867..65fd59f 100644
--- a/libs/vr/libpdx_uds/service_endpoint.cpp
+++ b/libs/vr/libpdx_uds/service_endpoint.cpp
@@ -220,9 +220,11 @@
return ErrorStatus(errno);
}
- auto status = ReceiveMessageForChannel(channel_fd.Get(), message);
+ // Borrow the channel handle before we pass (move) it into OnNewChannel().
+ BorrowedHandle borrowed_channel_handle = channel_fd.Borrow();
+ auto status = OnNewChannel(std::move(channel_fd));
if (status)
- status = OnNewChannel(std::move(channel_fd));
+ status = ReceiveMessageForChannel(borrowed_channel_handle, message);
return status;
}
@@ -247,7 +249,7 @@
return status;
}
-Status<Endpoint::ChannelData*> Endpoint::OnNewChannelLocked(
+Status<std::pair<int32_t, Endpoint::ChannelData*>> Endpoint::OnNewChannelLocked(
LocalHandle channel_fd, Channel* channel_state) {
epoll_event event;
event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT;
@@ -259,19 +261,28 @@
return ErrorStatus(errno);
}
ChannelData channel_data;
- const int channel_id = channel_fd.Get();
channel_data.event_set.AddDataFd(channel_fd);
channel_data.data_fd = std::move(channel_fd);
channel_data.channel_state = channel_state;
- auto pair = channels_.emplace(channel_id, std::move(channel_data));
- return &pair.first->second;
+ for (;;) {
+ // Try new channel IDs until we find one which is not already in the map.
+ if (last_channel_id_++ == std::numeric_limits<int32_t>::max())
+ last_channel_id_ = 1;
+ auto iter = channels_.lower_bound(last_channel_id_);
+ if (iter == channels_.end() || iter->first != last_channel_id_) {
+ channel_fd_to_id_.emplace(channel_data.data_fd.Get(), last_channel_id_);
+ iter = channels_.emplace_hint(iter, last_channel_id_,
+ std::move(channel_data));
+ return std::make_pair(last_channel_id_, &iter->second);
+ }
+ }
}
-Status<void> Endpoint::ReenableEpollEvent(int fd) {
+Status<void> Endpoint::ReenableEpollEvent(const BorrowedHandle& fd) {
epoll_event event;
event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT;
- event.data.fd = fd;
- if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_MOD, fd, &event) < 0) {
+ event.data.fd = fd.Get();
+ if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_MOD, fd.Get(), &event) < 0) {
ALOGE(
"Endpoint::ReenableEpollEvent: Failed to re-enable channel to "
"endpoint: %s\n",
@@ -286,16 +297,17 @@
return CloseChannelLocked(channel_id);
}
-Status<void> Endpoint::CloseChannelLocked(int channel_id) {
+Status<void> Endpoint::CloseChannelLocked(int32_t channel_id) {
ALOGD_IF(TRACE, "Endpoint::CloseChannelLocked: channel_id=%d", channel_id);
- auto channel_data = channels_.find(channel_id);
- if (channel_data == channels_.end())
+ auto iter = channels_.find(channel_id);
+ if (iter == channels_.end())
return ErrorStatus{EINVAL};
+ int channel_fd = iter->second.data_fd.Get();
Status<void> status;
epoll_event dummy; // See BUGS in man 2 epoll_ctl.
- if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_DEL, channel_id, &dummy) < 0) {
+ if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_DEL, channel_fd, &dummy) < 0) {
status.SetError(errno);
ALOGE(
"Endpoint::CloseChannelLocked: Failed to remove channel from endpoint: "
@@ -305,7 +317,8 @@
status.SetValue();
}
- channels_.erase(channel_data);
+ channel_fd_to_id_.erase(channel_fd);
+ channels_.erase(iter);
return status;
}
@@ -348,10 +361,10 @@
}
std::lock_guard<std::mutex> autolock(channel_mutex_);
- *channel_id = local_socket.Get();
auto channel_data = OnNewChannelLocked(std::move(local_socket), channel);
if (!channel_data)
return channel_data.error_status();
+ *channel_id = channel_data.get().first;
// Flags are ignored for now.
// TODO(xiaohuit): Implement those.
@@ -359,7 +372,7 @@
auto* state = static_cast<MessageState*>(message->GetState());
Status<ChannelReference> ref = state->PushChannelHandle(
remote_socket.Borrow(),
- channel_data.get()->event_set.event_fd().Borrow());
+ channel_data.get().second->event_set.event_fd().Borrow());
if (!ref)
return ref.error_status();
state->sockets_to_close.push_back(std::move(remote_socket));
@@ -373,32 +386,42 @@
return ErrorStatus(EFAULT);
}
-Channel* Endpoint::GetChannelState(int channel_id) {
+Channel* Endpoint::GetChannelState(int32_t channel_id) {
std::lock_guard<std::mutex> autolock(channel_mutex_);
auto channel_data = channels_.find(channel_id);
return (channel_data != channels_.end()) ? channel_data->second.channel_state
: nullptr;
}
-int Endpoint::GetChannelSocketFd(int channel_id) {
+BorrowedHandle Endpoint::GetChannelSocketFd(int32_t channel_id) {
std::lock_guard<std::mutex> autolock(channel_mutex_);
+ BorrowedHandle handle;
auto channel_data = channels_.find(channel_id);
- return (channel_data != channels_.end()) ? channel_data->second.data_fd.Get()
- : -1;
+ if (channel_data != channels_.end())
+ handle = channel_data->second.data_fd.Borrow();
+ return handle;
}
-int Endpoint::GetChannelEventFd(int channel_id) {
+BorrowedHandle Endpoint::GetChannelEventFd(int32_t channel_id) {
std::lock_guard<std::mutex> autolock(channel_mutex_);
+ BorrowedHandle handle;
auto channel_data = channels_.find(channel_id);
- return (channel_data != channels_.end())
- ? channel_data->second.event_set.event_fd().Get()
- : -1;
+ if (channel_data != channels_.end())
+ handle = channel_data->second.event_set.event_fd().Borrow();
+ return handle;
}
-Status<void> Endpoint::ReceiveMessageForChannel(int channel_id,
- Message* message) {
+int32_t Endpoint::GetChannelId(const BorrowedHandle& channel_fd) {
+ std::lock_guard<std::mutex> autolock(channel_mutex_);
+ auto iter = channel_fd_to_id_.find(channel_fd.Get());
+ return (iter != channel_fd_to_id_.end()) ? iter->second : -1;
+}
+
+Status<void> Endpoint::ReceiveMessageForChannel(
+ const BorrowedHandle& channel_fd, Message* message) {
RequestHeader<LocalHandle> request;
- auto status = ReceiveData(channel_id, &request);
+ int32_t channel_id = GetChannelId(channel_fd);
+ auto status = ReceiveData(channel_fd.Borrow(), &request);
if (!status) {
if (status.error() == ESHUTDOWN) {
BuildCloseMessage(channel_id, message);
@@ -434,12 +457,12 @@
state->request = std::move(request);
if (request.send_len > 0 && !request.is_impulse) {
state->request_data.resize(request.send_len);
- status = ReceiveData(channel_id, state->request_data.data(),
+ status = ReceiveData(channel_fd, state->request_data.data(),
state->request_data.size());
}
if (status && request.is_impulse)
- status = ReenableEpollEvent(channel_id);
+ status = ReenableEpollEvent(channel_fd);
if (!status) {
if (status.error() == ESHUTDOWN) {
@@ -454,7 +477,7 @@
return status;
}
-void Endpoint::BuildCloseMessage(int channel_id, Message* message) {
+void Endpoint::BuildCloseMessage(int32_t channel_id, Message* message) {
ALOGD_IF(TRACE, "Endpoint::BuildCloseMessage: channel_id=%d", channel_id);
MessageInfo info;
info.pid = -1;
@@ -496,22 +519,22 @@
auto status = AcceptConnection(message);
if (!status)
return status;
- return ReenableEpollEvent(socket_fd_.Get());
+ return ReenableEpollEvent(socket_fd_.Borrow());
}
- int channel_id = event.data.fd;
+ BorrowedHandle channel_fd{event.data.fd};
if (event.events & (EPOLLRDHUP | EPOLLHUP)) {
- BuildCloseMessage(channel_id, message);
+ BuildCloseMessage(GetChannelId(channel_fd), message);
return {};
}
- return ReceiveMessageForChannel(channel_id, message);
+ return ReceiveMessageForChannel(channel_fd, message);
}
Status<void> Endpoint::MessageReply(Message* message, int return_code) {
- const int channel_id = message->GetChannelId();
- const int channel_socket = GetChannelSocketFd(channel_id);
- if (channel_socket < 0)
+ const int32_t channel_id = message->GetChannelId();
+ auto channel_socket = GetChannelSocketFd(channel_id);
+ if (!channel_socket)
return ErrorStatus{EBADF};
auto* state = static_cast<MessageState*>(message->GetState());
@@ -524,8 +547,7 @@
return CloseChannel(channel_id);
} else {
// Reply with the event fd.
- auto push_status = state->PushFileHandle(
- BorrowedHandle{GetChannelEventFd(channel_socket)});
+ auto push_status = state->PushFileHandle(GetChannelEventFd(channel_id));
state->response_data.clear(); // Just in case...
if (!push_status)
return push_status.error_status();
diff --git a/libs/vr/libvrsensor/include/private/dvr/latency_model.h b/libs/vr/libvrsensor/include/private/dvr/latency_model.h
index 1bb3c4f..40b4638 100644
--- a/libs/vr/libvrsensor/include/private/dvr/latency_model.h
+++ b/libs/vr/libvrsensor/include/private/dvr/latency_model.h
@@ -6,23 +6,21 @@
namespace android {
namespace dvr {
-// This class holds a rolling average of the sensor latency.
+// This class models the latency from sensors. It will look at the first
+// window_size measurements and return their average after that.
class LatencyModel {
public:
- LatencyModel(size_t window_size, double weight_mass_in_window);
+ LatencyModel(size_t window_size);
~LatencyModel() = default;
void AddLatency(int64_t latency_ns);
- int64_t CurrentLatencyEstimate() const {
- return static_cast<int64_t>(rolling_average_);
- }
+ int64_t CurrentLatencyEstimate() const { return latency_; }
private:
- // The rolling average of the latencies.
- double rolling_average_ = 0;
-
- // The alpha parameter for an exponential moving average.
- double alpha_;
+ size_t window_size_;
+ int64_t latency_sum_ = 0;
+ size_t num_summed_ = 0;
+ int64_t latency_ = 0;
};
} // namespace dvr
diff --git a/libs/vr/libvrsensor/latency_model.cpp b/libs/vr/libvrsensor/latency_model.cpp
index 8233889..d3a4521 100644
--- a/libs/vr/libvrsensor/latency_model.cpp
+++ b/libs/vr/libvrsensor/latency_model.cpp
@@ -5,28 +5,19 @@
namespace android {
namespace dvr {
-LatencyModel::LatencyModel(size_t window_size, double weight_mass_in_window) {
- // Compute an alpha so the weight of the last window_size measurements is
- // weight_mass_in_window of the total weights.
-
- // The weight in a series of k measurements:
- // alpha + (1 + (1 - alpha) + (1 - alpha)^2 + ... (1 - alpha)^k-1)
- // = alpha x (1 - (1 - alpha) ^ k) / alpha
- // = 1 - (1 - alpha) ^ k
- // weight_mass_in_window = 1 - (1 - alpha) ^ k / lim_k->inf (1 - alpha) ^ k
- // weight_mass_in_window = 1 - (1 - alpha) ^ k / 1
- // 1 - weight_mass_in_window = (1 - alpha) ^ k
- // log(1 - weight_mass_in_window) = k * log(1 - alpha)
- // 10 ^ (log(1 - weight_mass_in_window) / k) = 1 - alpha
- // alpha = 1 - 10 ^ (log(1 - weight_mass_in_window) / k)
- // alpha = 1 - 10 ^ (log(1 - weight_mass_in_window) / window_size)
-
- alpha_ = 1 - std::pow(10.0, std::log10(1 - weight_mass_in_window) /
- static_cast<double>(window_size));
-}
+LatencyModel::LatencyModel(size_t window_size) : window_size_(window_size) {}
void LatencyModel::AddLatency(int64_t latency_ns) {
- rolling_average_ = latency_ns * alpha_ + rolling_average_ * (1 - alpha_);
+ // Not enough samples yet?
+ if (num_summed_ < window_size_) {
+ // Accumulate.
+ latency_sum_ += latency_ns;
+
+ // Have enough samples for latency estimate?
+ if (++num_summed_ == window_size_) {
+ latency_ = latency_sum_ / window_size_;
+ }
+ }
}
} // namespace dvr
diff --git a/services/vr/bufferhubd/buffer_hub.cpp b/services/vr/bufferhubd/buffer_hub.cpp
index de4950e..2ce60e5 100644
--- a/services/vr/bufferhubd/buffer_hub.cpp
+++ b/services/vr/bufferhubd/buffer_hub.cpp
@@ -16,7 +16,9 @@
#include "producer_queue_channel.h"
using android::pdx::Channel;
+using android::pdx::ErrorStatus;
using android::pdx::Message;
+using android::pdx::Status;
using android::pdx::rpc::DispatchRemoteMethod;
using android::pdx::default_transport::Endpoint;
@@ -28,9 +30,7 @@
BufferHubService::~BufferHubService() {}
-bool BufferHubService::IsInitialized() const {
- return BASE::IsInitialized();
-}
+bool BufferHubService::IsInitialized() const { return BASE::IsInitialized(); }
std::string BufferHubService::DumpState(size_t /*max_length*/) {
std::ostringstream stream;
@@ -374,7 +374,7 @@
}
}
-int BufferHubService::OnCreateProducerQueue(
+Status<QueueInfo> BufferHubService::OnCreateProducerQueue(
pdx::Message& message, size_t meta_size_bytes, int usage_set_mask,
int usage_clear_mask, int usage_deny_set_mask, int usage_deny_clear_mask) {
// Use the producer channel id as the global queue id.
@@ -386,7 +386,7 @@
if (const auto channel = message.GetChannel<BufferHubChannel>()) {
ALOGE("BufferHubService::OnCreateProducerQueue: already created: queue=%d",
queue_id);
- return -EALREADY;
+ return ErrorStatus(EALREADY);
}
int error;
@@ -394,10 +394,10 @@
this, queue_id, meta_size_bytes, usage_set_mask, usage_clear_mask,
usage_deny_set_mask, usage_deny_clear_mask, &error)) {
message.SetChannel(producer_channel);
- return 0;
+ return {{meta_size_bytes, queue_id}};
} else {
ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer!!");
- return error;
+ return ErrorStatus(-error);
}
}
diff --git a/services/vr/bufferhubd/buffer_hub.h b/services/vr/bufferhubd/buffer_hub.h
index 8a7dca8..150e399 100644
--- a/services/vr/bufferhubd/buffer_hub.h
+++ b/services/vr/bufferhubd/buffer_hub.h
@@ -7,6 +7,7 @@
#include <hardware/gralloc.h>
#include <pdx/service.h>
+#include <private/dvr/bufferhub_rpc.h>
namespace android {
namespace dvr {
@@ -73,9 +74,9 @@
slice_count(slice_count),
name(name) {}
- BufferInfo(int id, size_t consumer_count, size_t capacity, int usage_set_mask,
- int usage_clear_mask, int usage_deny_set_mask,
- int usage_deny_clear_mask)
+ BufferInfo(int id, size_t consumer_count, size_t capacity,
+ int usage_set_mask, int usage_clear_mask,
+ int usage_deny_set_mask, int usage_deny_clear_mask)
: id(id),
type(kProducerQueueType),
consumer_count(consumer_count),
@@ -168,9 +169,9 @@
int format, int usage, size_t meta_size_bytes,
size_t slice_count);
int OnGetPersistentBuffer(pdx::Message& message, const std::string& name);
- int OnCreateProducerQueue(pdx::Message& message, size_t meta_size_bytes,
- int usage_set_mask, int usage_clear_mask,
- int usage_deny_set_mask, int usage_deny_clear_mask);
+ pdx::Status<QueueInfo> OnCreateProducerQueue(
+ pdx::Message& message, size_t meta_size_bytes, int usage_set_mask,
+ int usage_clear_mask, int usage_deny_set_mask, int usage_deny_clear_mask);
BufferHubService(const BufferHubService&) = delete;
void operator=(const BufferHubService&) = delete;
diff --git a/services/vr/bufferhubd/consumer_queue_channel.cpp b/services/vr/bufferhubd/consumer_queue_channel.cpp
index ae87acd..cc16f1f 100644
--- a/services/vr/bufferhubd/consumer_queue_channel.cpp
+++ b/services/vr/bufferhubd/consumer_queue_channel.cpp
@@ -40,6 +40,11 @@
*producer, &ProducerQueueChannel::OnCreateConsumerQueue, message);
return true;
+ case BufferHubRPC::GetQueueInfo::Opcode:
+ DispatchRemoteMethod<BufferHubRPC::GetQueueInfo>(
+ *producer, &ProducerQueueChannel::OnGetQueueInfo, message);
+ return true;
+
case BufferHubRPC::ConsumerQueueImportBuffers::Opcode:
DispatchRemoteMethod<BufferHubRPC::ConsumerQueueImportBuffers>(
*this, &ConsumerQueueChannel::OnConsumerQueueImportBuffers, message);
diff --git a/services/vr/bufferhubd/producer_queue_channel.cpp b/services/vr/bufferhubd/producer_queue_channel.cpp
index 7952642..7741058 100644
--- a/services/vr/bufferhubd/producer_queue_channel.cpp
+++ b/services/vr/bufferhubd/producer_queue_channel.cpp
@@ -3,6 +3,9 @@
#include "consumer_queue_channel.h"
#include "producer_channel.h"
+using android::pdx::ErrorStatus;
+using android::pdx::Message;
+using android::pdx::Status;
using android::pdx::RemoteChannelHandle;
using android::pdx::rpc::DispatchRemoteMethod;
@@ -58,6 +61,11 @@
*this, &ProducerQueueChannel::OnCreateConsumerQueue, message);
return true;
+ case BufferHubRPC::GetQueueInfo::Opcode:
+ DispatchRemoteMethod<BufferHubRPC::GetQueueInfo>(
+ *this, &ProducerQueueChannel::OnGetQueueInfo, message);
+ return true;
+
case BufferHubRPC::ProducerQueueAllocateBuffers::Opcode:
DispatchRemoteMethod<BufferHubRPC::ProducerQueueAllocateBuffers>(
*this, &ProducerQueueChannel::OnProducerQueueAllocateBuffers,
@@ -84,8 +92,8 @@
usage_deny_clear_mask_);
}
-std::pair<RemoteChannelHandle, size_t>
-ProducerQueueChannel::OnCreateConsumerQueue(Message& message) {
+Status<RemoteChannelHandle> ProducerQueueChannel::OnCreateConsumerQueue(
+ Message& message) {
ATRACE_NAME("ProducerQueueChannel::OnCreateConsumerQueue");
ALOGD_IF(TRACE, "ProducerQueueChannel::OnCreateConsumerQueue: channel_id=%d",
channel_id());
@@ -97,7 +105,7 @@
"ProducerQueueChannel::OnCreateConsumerQueue: failed to push consumer "
"channel: %s",
status.GetErrorMessage().c_str());
- REPLY_ERROR_RETURN(message, status.error(), {});
+ return ErrorStatus(ENOMEM);
}
const auto channel_status = service()->SetChannel(
@@ -108,13 +116,17 @@
"ProducerQueueChannel::OnCreateConsumerQueue: failed to set new "
"consumer channel: %s",
channel_status.GetErrorMessage().c_str());
- REPLY_ERROR_RETURN(message, channel_status.error(), {});
+ return ErrorStatus(ENOMEM);
}
- return std::make_pair(status.take(), meta_size_bytes_);
+ return {status.take()};
}
-std::vector<std::pair<RemoteChannelHandle, size_t>>
+Status<QueueInfo> ProducerQueueChannel::OnGetQueueInfo(Message&) {
+ return {{meta_size_bytes_, buffer_id()}};
+}
+
+Status<std::vector<std::pair<RemoteChannelHandle, size_t>>>
ProducerQueueChannel::OnProducerQueueAllocateBuffers(Message& message,
int width, int height,
int format, int usage,
@@ -135,7 +147,7 @@
"not permitted. Violating usage_deny_set_mask, the following bits "
"shall not be set: %d.",
usage, usage_deny_set_mask_);
- REPLY_ERROR_RETURN(message, EINVAL, buffer_handles);
+ return ErrorStatus(EINVAL);
}
if (~usage & usage_deny_clear_mask_) {
@@ -144,7 +156,7 @@
"not permitted. Violating usage_deny_clear_mask, the following bits "
"must be set: %d.",
usage, usage_deny_clear_mask_);
- REPLY_ERROR_RETURN(message, EINVAL, buffer_handles);
+ return ErrorStatus(EINVAL);
}
// Force set mask and clear mask. Note that |usage_set_mask_| takes precedence
@@ -152,24 +164,24 @@
int effective_usage = (usage & ~usage_clear_mask_) | usage_set_mask_;
for (size_t i = 0; i < buffer_count; i++) {
- auto buffer_handle_slot = AllocateBuffer(message, width, height, format,
- effective_usage, slice_count);
- if (!buffer_handle_slot.first) {
+ auto status = AllocateBuffer(message, width, height, format,
+ effective_usage, slice_count);
+ if (!status) {
ALOGE(
- "ProducerQueueChannel::OnProducerQueueAllocateBuffers: failed to "
+ "ProducerQueueChannel::OnProducerQueueAllocateBuffers: Failed to "
"allocate new buffer.");
- REPLY_ERROR_RETURN(message, ENOMEM, buffer_handles);
+ return ErrorStatus(status.error());
}
- buffer_handles.emplace_back(std::move(buffer_handle_slot.first),
- buffer_handle_slot.second);
+ buffer_handles.push_back(status.take());
}
- return buffer_handles;
+ return {std::move(buffer_handles)};
}
-std::pair<RemoteChannelHandle, size_t> ProducerQueueChannel::AllocateBuffer(
- Message& message, int width, int height, int format, int usage,
- size_t slice_count) {
+Status<std::pair<RemoteChannelHandle, size_t>>
+ProducerQueueChannel::AllocateBuffer(Message& message, int width, int height,
+ int format, int usage,
+ size_t slice_count) {
ATRACE_NAME("ProducerQueueChannel::AllocateBuffer");
ALOGD_IF(TRACE,
"ProducerQueueChannel::AllocateBuffer: producer_channel_id=%d",
@@ -177,7 +189,7 @@
if (capacity_ >= BufferHubRPC::kMaxQueueCapacity) {
ALOGE("ProducerQueueChannel::AllocateBuffer: reaches kMaxQueueCapacity.");
- return {};
+ return ErrorStatus(E2BIG);
}
// Here we are creating a new BufferHubBuffer, initialize the producer
@@ -189,7 +201,7 @@
if (!status) {
ALOGE("ProducerQueueChannel::AllocateBuffer: failed to push channel: %s",
status.GetErrorMessage().c_str());
- return {};
+ return ErrorStatus(status.error());
}
ALOGD_IF(TRACE,
@@ -199,14 +211,14 @@
auto buffer_handle = status.take();
int error;
- const auto producer_channel = ProducerChannel::Create(
- service(), buffer_id, width, height, format, usage,
- meta_size_bytes_, slice_count, &error);
+ const auto producer_channel =
+ ProducerChannel::Create(service(), buffer_id, width, height, format,
+ usage, meta_size_bytes_, slice_count, &error);
if (!producer_channel) {
ALOGE(
"ProducerQueueChannel::AllocateBuffer: Failed to create "
"BufferHubBuffer producer!!");
- return {};
+ return ErrorStatus(ENOMEM);
}
ALOGD_IF(
@@ -221,7 +233,7 @@
"ProducerQueueChannel::AllocateBuffer: failed to set producer channel "
"for new BufferHubBuffer: %s",
channel_status.GetErrorMessage().c_str());
- return {};
+ return ErrorStatus(ENOMEM);
}
// Register the newly allocated buffer's channel_id into the first empty
@@ -235,7 +247,7 @@
ALOGE(
"ProducerQueueChannel::AllocateBuffer: Cannot find empty slot for new "
"buffer allocation.");
- return {};
+ return ErrorStatus(E2BIG);
}
buffers_[slot] = producer_channel;
@@ -250,29 +262,29 @@
consumer_channel->RegisterNewBuffer(producer_channel, slot);
}
- return {std::move(buffer_handle), slot};
+ return {{std::move(buffer_handle), slot}};
}
-int ProducerQueueChannel::OnProducerQueueDetachBuffer(Message& /*message*/,
- size_t slot) {
+Status<void> ProducerQueueChannel::OnProducerQueueDetachBuffer(
+ Message& /*message*/, size_t slot) {
if (buffers_[slot].expired()) {
ALOGE(
"ProducerQueueChannel::OnProducerQueueDetachBuffer: trying to detach "
"an invalid buffer producer at slot %zu",
slot);
- return -EINVAL;
+ return ErrorStatus(EINVAL);
}
if (capacity_ == 0) {
ALOGE(
"ProducerQueueChannel::OnProducerQueueDetachBuffer: trying to detach a "
"buffer producer while the queue's capacity is already zero.");
- return -EINVAL;
+ return ErrorStatus(EINVAL);
}
buffers_[slot].reset();
capacity_--;
- return 0;
+ return {};
}
void ProducerQueueChannel::AddConsumer(ConsumerQueueChannel* channel) {
diff --git a/services/vr/bufferhubd/producer_queue_channel.h b/services/vr/bufferhubd/producer_queue_channel.h
index 49611d4..a12a37d 100644
--- a/services/vr/bufferhubd/producer_queue_channel.h
+++ b/services/vr/bufferhubd/producer_queue_channel.h
@@ -3,6 +3,7 @@
#include "buffer_hub.h"
+#include <pdx/status.h>
#include <private/dvr/bufferhub_rpc.h>
namespace android {
@@ -10,17 +11,14 @@
class ProducerQueueChannel : public BufferHubChannel {
public:
- using Message = pdx::Message;
- using RemoteChannelHandle = pdx::RemoteChannelHandle;
-
static std::shared_ptr<ProducerQueueChannel> Create(
BufferHubService* service, int channel_id, size_t meta_size_bytes,
int usage_set_mask, int usage_clear_mask, int usage_deny_set_mask,
int usage_deny_clear_mask, int* error);
~ProducerQueueChannel() override;
- bool HandleMessage(Message& message) override;
- void HandleImpulse(Message& message) override;
+ bool HandleMessage(pdx::Message& message) override;
+ void HandleImpulse(pdx::Message& message) override;
BufferInfo GetBufferInfo() const override;
@@ -28,19 +26,22 @@
// producer queue.
// Returns a handle for the service channel, as well as the size of the
// metadata associated with the queue.
- std::pair<RemoteChannelHandle, size_t> OnCreateConsumerQueue(
- Message& message);
+ pdx::Status<pdx::RemoteChannelHandle> OnCreateConsumerQueue(
+ pdx::Message& message);
+
+ pdx::Status<QueueInfo> OnGetQueueInfo(pdx::Message& message);
// Allocate a new BufferHubProducer according to the input spec. Client may
// handle this as if a new producer is created through kOpCreateBuffer.
- std::vector<std::pair<RemoteChannelHandle, size_t>>
- OnProducerQueueAllocateBuffers(Message& message, int width, int height,
+ pdx::Status<std::vector<std::pair<pdx::RemoteChannelHandle, size_t>>>
+ OnProducerQueueAllocateBuffers(pdx::Message& message, int width, int height,
int format, int usage, size_t slice_count,
size_t buffer_count);
// Detach a BufferHubProducer indicated by |slot|. Note that the buffer must
// be in Gain'ed state for the producer queue to detach.
- int OnProducerQueueDetachBuffer(Message& message, size_t slot);
+ pdx::Status<void> OnProducerQueueDetachBuffer(pdx::Message& message,
+ size_t slot);
void AddConsumer(ConsumerQueueChannel* channel);
void RemoveConsumer(ConsumerQueueChannel* channel);
@@ -56,10 +57,9 @@
// and our return type is a RemoteChannelHandle.
// Returns the remote channdel handle and the slot number for the newly
// allocated buffer.
- std::pair<RemoteChannelHandle, size_t> AllocateBuffer(Message& message,
- int width, int height,
- int format, int usage,
- size_t slice_count);
+ pdx::Status<std::pair<pdx::RemoteChannelHandle, size_t>> AllocateBuffer(
+ pdx::Message& message, int width, int height, int format, int usage,
+ size_t slice_count);
// Size of the meta data associated with all the buffers allocated from the
// queue. Now we assume the metadata size is immutable once the queue is
diff --git a/services/vr/sensord/pose_service.cpp b/services/vr/sensord/pose_service.cpp
index 7534732..e3f8171 100644
--- a/services/vr/sensord/pose_service.cpp
+++ b/services/vr/sensord/pose_service.cpp
@@ -65,8 +65,7 @@
static constexpr int kDatasetIdLength = 36;
static constexpr char kDatasetIdChars[] = "0123456789abcdef-";
-static constexpr int kLatencyWindowSize = 100;
-static constexpr double kLatencyWindowMass = 0.5;
+static constexpr int kLatencyWindowSize = 200;
// These are the flags used by BufferProducer::CreatePersistentUncachedBlob,
// plus PRIVATE_ADSP_HEAP to allow access from the DSP.
@@ -115,7 +114,7 @@
photon_timestamp_(0),
// Will be updated by external service, but start with a non-zero value:
display_period_ns_(16000000),
- sensor_latency_(kLatencyWindowSize, kLatencyWindowMass) {
+ sensor_latency_(kLatencyWindowSize) {
last_known_pose_ = {
.orientation = {1.0f, 0.0f, 0.0f, 0.0f},
.translation = {0.0f, 0.0f, 0.0f, 0.0f},
diff --git a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
index b5724ca..9ba01f9 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
+++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
@@ -211,19 +211,14 @@
queued_client_target = true;
} else {
if (!layer.info.buffer.get() || !layer.info.fence.get()) {
- ALOGE("Layer requested without valid buffer");
- return Error::BAD_LAYER;
+ ALOGV("Layer requested without valid buffer");
+ continue;
}
frame.push_back(layer.info);
}
}
- if (frame.empty()) {
- ALOGE("Requested frame with no layers");
- return Error::BAD_LAYER;
- }
-
out_frames->swap(frame);
return Error::NONE;
}
diff --git a/services/vr/vr_window_manager/display_view.cpp b/services/vr/vr_window_manager/display_view.cpp
index 52984b7..88768a0 100644
--- a/services/vr/vr_window_manager/display_view.cpp
+++ b/services/vr/vr_window_manager/display_view.cpp
@@ -219,6 +219,11 @@
visibility = ViewMode::Hidden;
current_vr_app_ = app;
}
+ } else if ((use_2dmode_ || !is_vr_active) && app != 0 &&
+ visibility == ViewMode::Hidden) {
+ // This is the case for the VR app launching a 2D intent of itself on some
+ // display.
+ visibility = ViewMode::App;
} else if (!current_vr_app_) {
// The VR app is running.
current_vr_app_ = app;