Merge "Prevent runtime restart for crashed clients to framework sensorservice." into oc-dev
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 20b960d..3e0f6f0 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -1152,6 +1152,9 @@
}
}
+#if HACK_FOR_37193650
+ extStats->dataSize = extStats->dataSize;
+#else
int extGid = multiuser_get_ext_gid(userId, appId);
if (extGid != -1) {
if (quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), device.c_str(), extGid,
@@ -1166,6 +1169,7 @@
extStats->dataSize += dq.dqb_curspace;
}
}
+#endif
int sharedGid = multiuser_get_shared_gid(userId, appId);
if (sharedGid != -1) {
@@ -1363,6 +1367,17 @@
collectQuotaStats(device, userId, appId, &stats, &extStats);
ATRACE_END();
+#if HACK_FOR_37193650
+ ATRACE_BEGIN("external");
+ for (size_t i = 0; i < packageNames.size(); i++) {
+ const char* pkgname = packageNames[i].c_str();
+ auto extPath = create_data_media_package_path(uuid_, userId, "data", pkgname);
+ calculate_tree_size(extPath, &extStats.dataSize);
+ auto mediaPath = create_data_media_package_path(uuid_, userId, "media", pkgname);
+ calculate_tree_size(mediaPath, &extStats.dataSize);
+ }
+ ATRACE_END();
+#endif
} else {
ATRACE_BEGIN("code");
for (auto codePath : codePaths) {
@@ -1447,6 +1462,12 @@
flags &= ~FLAG_USE_QUOTA;
}
+#if HACK_FOR_37193650
+ if (userId != 0) {
+ flags &= ~FLAG_USE_QUOTA;
+ }
+#endif
+
if (flags & FLAG_USE_QUOTA) {
struct dqblk dq;
@@ -1508,6 +1529,7 @@
for (auto appId : appIds) {
if (appId >= AID_APP_START) {
collectQuotaStats(device, userId, appId, &stats, &extStats);
+
#if MEASURE_DEBUG
// Sleep to make sure we don't lose logs
usleep(1);
@@ -1729,7 +1751,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 +1767,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/installd/utils.h b/cmds/installd/utils.h
index dd94da9..5db547e 100644
--- a/cmds/installd/utils.h
+++ b/cmds/installd/utils.h
@@ -32,6 +32,7 @@
#define MEASURE_DEBUG 0
#define FIXUP_DEBUG 0
+#define HACK_FOR_37193650 1
namespace android {
namespace installd {
diff --git a/cmds/service/Android.bp b/cmds/service/Android.bp
index 8cffb3c..b703ed4 100644
--- a/cmds/service/Android.bp
+++ b/cmds/service/Android.bp
@@ -9,5 +9,18 @@
],
cflags: ["-DXP_UNIX"],
- //shared_libs: ["librt"],
+}
+
+cc_binary {
+ name: "vndservice",
+
+ proprietary: true,
+ srcs: ["service.cpp"],
+
+ shared_libs: [
+ "libutils",
+ "libbinder",
+ ],
+
+ cflags: ["-DXP_UNIX", "-DVENDORSERVICES"],
}
diff --git a/cmds/service/service.cpp b/cmds/service/service.cpp
index 428b87c..bc11256 100644
--- a/cmds/service/service.cpp
+++ b/cmds/service/service.cpp
@@ -68,13 +68,6 @@
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;
int result = 0;
@@ -95,6 +88,15 @@
break;
}
}
+#ifdef VENDORSERVICES
+ ProcessState::initWithDriver("/dev/vndbinder");
+#endif
+ 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/data/etc/android.software.activities_on_secondary_displays.xml b/data/etc/android.software.activities_on_secondary_displays.xml
new file mode 100644
index 0000000..db1bdb5
--- /dev/null
+++ b/data/etc/android.software.activities_on_secondary_displays.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<permissions>
+ <feature name="android.software.activities_on_secondary_displays" />
+</permissions>
diff --git a/data/etc/android.software.cts.xml b/data/etc/android.software.cts.xml
new file mode 100644
index 0000000..0414c9a
--- /dev/null
+++ b/data/etc/android.software.cts.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<permissions>
+ <!-- This is Android and fully CTS compatible. Basically this is for CTS tests to use. -->
+ <feature name="android.software.cts" />
+</permissions>
diff --git a/data/etc/handheld_core_hardware.xml b/data/etc/handheld_core_hardware.xml
index b5287ac..9229f82 100644
--- a/data/etc/handheld_core_hardware.xml
+++ b/data/etc/handheld_core_hardware.xml
@@ -46,6 +46,7 @@
<feature name="android.software.home_screen" />
<feature name="android.software.input_methods" />
<feature name="android.software.picture_in_picture" />
+ <feature name="android.software.activities_on_secondary_displays" />
<feature name="android.software.print" />
<feature name="android.software.companion_device_setup" />
diff --git a/data/etc/tablet_core_hardware.xml b/data/etc/tablet_core_hardware.xml
index 51ea1ca..64e32ff 100644
--- a/data/etc/tablet_core_hardware.xml
+++ b/data/etc/tablet_core_hardware.xml
@@ -46,6 +46,7 @@
<feature name="android.software.home_screen" />
<feature name="android.software.input_methods" />
<feature name="android.software.picture_in_picture" />
+ <feature name="android.software.activities_on_secondary_displays" />
<feature name="android.software.print" />
<feature name="android.software.companion_device_setup" />
diff --git a/include/binder/ProcessState.h b/include/binder/ProcessState.h
index 05e9d09..1ef045d 100644
--- a/include/binder/ProcessState.h
+++ b/include/binder/ProcessState.h
@@ -69,6 +69,8 @@
status_t setThreadPoolMaxThreadCount(size_t maxThreads);
void giveThreadPoolName();
+ String8 getDriverName();
+
private:
friend class IPCThreadState;
@@ -86,6 +88,7 @@
handle_entry* lookupHandleLocked(int32_t handle);
+ String8 mDriverName;
int mDriverFD;
void* mVMStart;
diff --git a/include/media/openmax/OMX_AsString.h b/include/media/openmax/OMX_AsString.h
index 6b21979..56d7cc8 100644
--- a/include/media/openmax/OMX_AsString.h
+++ b/include/media/openmax/OMX_AsString.h
@@ -557,6 +557,7 @@
case OMX_IndexConfigPriority: return "ConfigPriority";
case OMX_IndexConfigOperatingRate: return "ConfigOperatingRate";
case OMX_IndexParamConsumerUsageBits: return "ParamConsumerUsageBits";
+ case OMX_IndexConfigLatency: return "ConfigLatency";
default: return asString((OMX_INDEXTYPE)i, def);
}
}
diff --git a/include/media/openmax/OMX_IndexExt.h b/include/media/openmax/OMX_IndexExt.h
index eccecaa..5a029d0 100644
--- a/include/media/openmax/OMX_IndexExt.h
+++ b/include/media/openmax/OMX_IndexExt.h
@@ -96,6 +96,7 @@
OMX_IndexConfigPriority, /**< reference: OMX_PARAM_U32TYPE */
OMX_IndexConfigOperatingRate, /**< reference: OMX_PARAM_U32TYPE in Q16 format for video and in Hz for audio */
OMX_IndexParamConsumerUsageBits, /**< reference: OMX_PARAM_U32TYPE */
+ OMX_IndexConfigLatency, /**< reference: OMX_PARAM_U32TYPE */
OMX_IndexExtOtherEndUnused,
/* Time configurations */
diff --git a/include/ui/Gralloc2.h b/include/ui/Gralloc2.h
new file mode 100644
index 0000000..c59d327
--- /dev/null
+++ b/include/ui/Gralloc2.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UI_GRALLOC2_H
+#define ANDROID_UI_GRALLOC2_H
+
+#include <string>
+
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <system/window.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+namespace Gralloc2 {
+
+using hardware::graphics::allocator::V2_0::IAllocator;
+using hardware::graphics::common::V1_0::BufferUsage;
+using hardware::graphics::common::V1_0::PixelFormat;
+using hardware::graphics::mapper::V2_0::BufferDescriptor;
+using hardware::graphics::mapper::V2_0::Error;
+using hardware::graphics::mapper::V2_0::IMapper;
+using hardware::graphics::mapper::V2_0::YCbCrLayout;
+
+// A wrapper to IMapper
+class Mapper {
+public:
+ Mapper();
+
+ // this will be removed and Mapper will be always valid
+ bool valid() const { return (mMapper != nullptr); }
+
+ Error createDescriptor(
+ const IMapper::BufferDescriptorInfo& descriptorInfo,
+ BufferDescriptor* outDescriptor) const;
+
+ // Import a buffer that is from another HAL, another process, or is
+ // cloned.
+ //
+ // The returned handle must be freed with freeBuffer.
+ Error importBuffer(const hardware::hidl_handle& rawHandle,
+ buffer_handle_t* outBufferHandle) const;
+
+ void freeBuffer(buffer_handle_t bufferHandle) const;
+
+ // The ownership of acquireFence is always transferred to the callee, even
+ // on errors.
+ Error lock(buffer_handle_t bufferHandle, uint64_t usage,
+ const IMapper::Rect& accessRegion,
+ int acquireFence, void** outData) const;
+
+ // The ownership of acquireFence is always transferred to the callee, even
+ // on errors.
+ Error lock(buffer_handle_t bufferHandle, uint64_t usage,
+ const IMapper::Rect& accessRegion,
+ int acquireFence, YCbCrLayout* outLayout) const;
+
+ // unlock returns a fence sync object (or -1) and the fence sync object is
+ // owned by the caller
+ int unlock(buffer_handle_t bufferHandle) const;
+
+private:
+ sp<IMapper> mMapper;
+};
+
+// A wrapper to IAllocator
+class Allocator {
+public:
+ // An allocator relies on a mapper, and that mapper must be alive at all
+ // time.
+ Allocator(const Mapper& mapper);
+
+ // this will be removed and Allocator will be always valid
+ bool valid() const { return (mAllocator != nullptr); }
+
+ std::string dumpDebugInfo() const;
+
+ /*
+ * The returned buffers are already imported and must not be imported
+ * again. outBufferHandles must point to a space that can contain at
+ * least "count" buffer_handle_t.
+ */
+ Error allocate(BufferDescriptor descriptor, uint32_t count,
+ uint32_t* outStride, buffer_handle_t* outBufferHandles) const;
+
+ Error allocate(BufferDescriptor descriptor,
+ uint32_t* outStride, buffer_handle_t* outBufferHandle) const
+ {
+ return allocate(descriptor, 1, outStride, outBufferHandle);
+ }
+
+ Error allocate(const IMapper::BufferDescriptorInfo& descriptorInfo, uint32_t count,
+ uint32_t* outStride, buffer_handle_t* outBufferHandles) const
+ {
+ BufferDescriptor descriptor;
+ Error error = mMapper.createDescriptor(descriptorInfo, &descriptor);
+ if (error == Error::NONE) {
+ error = allocate(descriptor, count, outStride, outBufferHandles);
+ }
+ return error;
+ }
+
+ Error allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
+ uint32_t* outStride, buffer_handle_t* outBufferHandle) const
+ {
+ return allocate(descriptorInfo, 1, outStride, outBufferHandle);
+ }
+
+private:
+ const Mapper& mMapper;
+ sp<IAllocator> mAllocator;
+};
+
+} // namespace Gralloc2
+
+} // namespace android
+
+#endif // ANDROID_UI_GRALLOC2_H
diff --git a/include/ui/GrallocAllocator.h b/include/ui/GrallocAllocator.h
deleted file mode 100644
index dd0f9e0..0000000
--- a/include/ui/GrallocAllocator.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_UI_GRALLOC_ALLOCATOR_H
-#define ANDROID_UI_GRALLOC_ALLOCATOR_H
-
-#include <string>
-
-#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-#include <utils/StrongPointer.h>
-
-namespace android {
-
-namespace Gralloc2 {
-
-using hardware::graphics::allocator::V2_0::Error;
-using hardware::graphics::allocator::V2_0::ProducerUsage;
-using hardware::graphics::allocator::V2_0::ConsumerUsage;
-using hardware::graphics::allocator::V2_0::BufferDescriptor;
-using hardware::graphics::allocator::V2_0::Buffer;
-using hardware::graphics::allocator::V2_0::IAllocator;
-using hardware::graphics::allocator::V2_0::IAllocatorClient;
-using hardware::graphics::common::V1_0::PixelFormat;
-
-// Allocator is a wrapper to IAllocator, a proxy to server-side allocator.
-class Allocator {
-public:
- Allocator();
-
- // this will be removed and Allocator will be always valid
- bool valid() const { return (mAllocator != nullptr); }
-
- std::string dumpDebugInfo() const;
-
- Error createBufferDescriptor(
- const IAllocatorClient::BufferDescriptorInfo& descriptorInfo,
- BufferDescriptor* outDescriptor) const;
- void destroyBufferDescriptor(BufferDescriptor descriptor) const;
-
- Error allocate(BufferDescriptor descriptor, Buffer* outBuffer) const;
- void free(Buffer buffer) const;
-
- Error exportHandle(BufferDescriptor descriptor, Buffer buffer,
- native_handle_t** outBufferHandle) const;
-
-private:
- sp<IAllocator> mAllocator;
- sp<IAllocatorClient> mClient;
-};
-
-} // namespace Gralloc2
-
-} // namespace android
-
-#endif // ANDROID_UI_GRALLOC_ALLOCATOR_H
diff --git a/include/ui/GrallocMapper.h b/include/ui/GrallocMapper.h
deleted file mode 100644
index 5a0d64b..0000000
--- a/include/ui/GrallocMapper.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_UI_GRALLOC_MAPPER_H
-#define ANDROID_UI_GRALLOC_MAPPER_H
-
-#include <android/hardware/graphics/mapper/2.0/IMapper.h>
-#include <system/window.h>
-
-namespace android {
-
-namespace Gralloc2 {
-
-using hardware::graphics::allocator::V2_0::Error;
-using hardware::graphics::allocator::V2_0::ProducerUsage;
-using hardware::graphics::allocator::V2_0::ConsumerUsage;
-using hardware::graphics::common::V1_0::PixelFormat;
-using hardware::graphics::mapper::V2_0::FlexLayout;
-using hardware::graphics::mapper::V2_0::BackingStore;
-using hardware::graphics::mapper::V2_0::IMapper;
-
-// Mapper is a wrapper to IMapper, a client-side graphics buffer mapper.
-class Mapper {
-public:
- Mapper();
-
- // this will be removed and Mapper will be always valid
- bool valid() const { return (mMapper != nullptr); }
-
- Error retain(buffer_handle_t handle) const;
- void release(buffer_handle_t handle) const;
-
- Error getDimensions(buffer_handle_t handle,
- uint32_t* outWidth, uint32_t* outHeight) const;
- Error getFormat(buffer_handle_t handle, int32_t* outFormat) const;
- Error getLayerCount(buffer_handle_t handle, uint32_t* outLayerCount) const;
- Error getProducerUsage(buffer_handle_t handle,
- uint64_t* outProducerUsage) const;
- Error getConsumerUsage(buffer_handle_t handle,
- uint64_t* outConsumerUsage) const;
- Error getBackingStore(buffer_handle_t handle,
- uint64_t* outBackingStore) const;
- Error getStride(buffer_handle_t handle, uint32_t* outStride) const;
-
- Error lock(buffer_handle_t handle, uint64_t producerUsage,
- uint64_t consumerUsage, const IMapper::Rect& accessRegion,
- int acquireFence, void** outData) const;
- Error lock(buffer_handle_t handle, uint64_t producerUsage,
- uint64_t consumerUsage, const IMapper::Rect& accessRegion,
- int acquireFence, FlexLayout* outLayout) const;
- int unlock(buffer_handle_t handle) const;
-
-private:
- sp<IMapper> mMapper;
-};
-
-} // namespace Gralloc2
-
-} // namespace android
-
-#endif // ANDROID_UI_GRALLOC_MAPPER_H
diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h
index e97122b..95eb8fd 100644
--- a/include/ui/GraphicBufferAllocator.h
+++ b/include/ui/GraphicBufferAllocator.h
@@ -96,8 +96,8 @@
GraphicBufferAllocator();
~GraphicBufferAllocator();
- const std::unique_ptr<const Gralloc2::Allocator> mAllocator;
GraphicBufferMapper& mMapper;
+ const std::unique_ptr<const Gralloc2::Allocator> mAllocator;
std::unique_ptr<Gralloc1::Loader> mLoader;
std::unique_ptr<Gralloc1::Device> mDevice;
diff --git a/include/ui/GraphicBufferMapper.h b/include/ui/GraphicBufferMapper.h
index b6d4021..d69f8fc 100644
--- a/include/ui/GraphicBufferMapper.h
+++ b/include/ui/GraphicBufferMapper.h
@@ -47,31 +47,15 @@
public:
static inline GraphicBufferMapper& get() { return getInstance(); }
- // This may NOT work on devices without a valid Gralloc2::Mapper.
- status_t registerBuffer(buffer_handle_t handle);
+ // The imported outHandle must be freed with freeBuffer when no longer
+ // needed. rawHandle is owned by the caller.
+ status_t importBuffer(buffer_handle_t rawHandle,
+ buffer_handle_t* outHandle);
- status_t registerBuffer(const GraphicBuffer* buffer);
+ // This is temporary and will be removed soon
+ status_t importBuffer(const GraphicBuffer* buffer);
- status_t unregisterBuffer(buffer_handle_t handle);
-
- status_t getDimensions(buffer_handle_t handle,
- uint32_t* outWidth, uint32_t* outHeight) const;
-
- status_t getFormat(buffer_handle_t handle, int32_t* outFormat) const;
-
- status_t getLayerCount(buffer_handle_t handle,
- uint32_t* outLayerCount) const;
-
- status_t getProducerUsage(buffer_handle_t handle,
- uint64_t* outProducerUsage) const;
-
- status_t getConsumerUsage(buffer_handle_t handle,
- uint64_t* outConsumerUsage) const;
-
- status_t getBackingStore(buffer_handle_t handle,
- uint64_t* outBackingStore) const;
-
- status_t getStride(buffer_handle_t handle, uint32_t* outStride) const;
+ status_t freeBuffer(buffer_handle_t handle);
status_t lock(buffer_handle_t handle,
uint32_t usage, const Rect& bounds, void** vaddr);
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 3aeff2e..c7a0f43 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -23,6 +23,7 @@
#include <binder/Parcel.h>
#include <utils/String8.h>
#include <utils/SystemClock.h>
+#include <utils/CallStack.h>
#include <private/binder/Static.h>
@@ -136,7 +137,12 @@
unsigned n;
for (n = 0; n < 5; n++){
if (n > 0) {
- ALOGI("Waiting for service %s...", String8(name).string());
+ if (!strcmp(ProcessState::self()->getDriverName().c_str(), "/dev/vndbinder")) {
+ ALOGI("Waiting for vendor service %s...", String8(name).string());
+ CallStack stack(LOG_TAG);
+ } else {
+ ALOGI("Waiting for service %s...", String8(name).string());
+ }
sleep(1);
}
sp<IBinder> svc = checkService(name);
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 5c4cfe2..9ccf07c 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -317,6 +317,10 @@
androidSetThreadName( makeBinderThreadName().string() );
}
+String8 ProcessState::getDriverName() {
+ return mDriverName;
+}
+
static int open_driver(const char *driver)
{
int fd = open(driver, O_RDWR | O_CLOEXEC);
@@ -346,7 +350,8 @@
}
ProcessState::ProcessState(const char *driver)
- : mDriverFD(open_driver(driver))
+ : mDriverName(String8(driver))
+ , mDriverFD(open_driver(driver))
, mVMStart(MAP_FAILED)
, mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
, mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
@@ -367,6 +372,7 @@
ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
close(mDriverFD);
mDriverFD = -1;
+ mDriverName.clear();
}
}
diff --git a/libs/binder/tests/binderValueTypeTest.cpp b/libs/binder/tests/binderValueTypeTest.cpp
index 1a05a52..c8f4697 100644
--- a/libs/binder/tests/binderValueTypeTest.cpp
+++ b/libs/binder/tests/binderValueTypeTest.cpp
@@ -106,6 +106,6 @@
value_a.swap(value_b);
ASSERT_FALSE(value_b.empty());
ASSERT_TRUE(value_a.empty());
- ASSERT_TRUE(value_a.getInt(&int_x));
+ ASSERT_TRUE(value_b.getInt(&int_x));
ASSERT_EQ(31337, int_x);
}
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/nativewindow/Android.bp b/libs/nativewindow/Android.bp
index 90fb4b6..6c8221d 100644
--- a/libs/nativewindow/Android.bp
+++ b/libs/nativewindow/Android.bp
@@ -21,7 +21,7 @@
}
ndk_library {
- name: "libnativewindow.ndk",
+ name: "libnativewindow",
symbol_file: "libnativewindow.map.txt",
// Android O
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 310d25e..ba37391 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -51,8 +51,7 @@
"FrameStats.cpp",
"Gralloc1.cpp",
"Gralloc1On0Adapter.cpp",
- "GrallocAllocator.cpp",
- "GrallocMapper.cpp",
+ "Gralloc2.cpp",
"GraphicBuffer.cpp",
"GraphicBufferAllocator.cpp",
"GraphicBufferMapper.cpp",
diff --git a/libs/ui/Gralloc2.cpp b/libs/ui/Gralloc2.cpp
new file mode 100644
index 0000000..75f5686
--- /dev/null
+++ b/libs/ui/Gralloc2.cpp
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Gralloc2"
+
+#include <ui/Gralloc2.h>
+
+#include <log/log.h>
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wzero-length-array"
+#include <sync/sync.h>
+#pragma clang diagnostic pop
+
+namespace android {
+
+namespace Gralloc2 {
+
+static constexpr Error kTransactionError = Error::NO_RESOURCES;
+
+Mapper::Mapper()
+{
+ mMapper = IMapper::getService();
+ if (mMapper != nullptr && mMapper->isRemote()) {
+ LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
+ }
+}
+
+Error Mapper::createDescriptor(
+ const IMapper::BufferDescriptorInfo& descriptorInfo,
+ BufferDescriptor* outDescriptor) const
+{
+ Error error;
+ auto ret = mMapper->createDescriptor(descriptorInfo,
+ [&](const auto& tmpError, const auto& tmpDescriptor)
+ {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outDescriptor = tmpDescriptor;
+ });
+
+ return (ret.isOk()) ? error : kTransactionError;
+}
+
+Error Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
+ buffer_handle_t* outBufferHandle) const
+{
+ Error error;
+ auto ret = mMapper->importBuffer(rawHandle,
+ [&](const auto& tmpError, const auto& tmpBuffer)
+ {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
+ });
+
+ return (ret.isOk()) ? error : kTransactionError;
+}
+
+void Mapper::freeBuffer(buffer_handle_t bufferHandle) const
+{
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+ auto ret = mMapper->freeBuffer(buffer);
+
+ auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
+ ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d",
+ buffer, error);
+}
+
+Error Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage,
+ const IMapper::Rect& accessRegion,
+ int acquireFence, void** outData) const
+{
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ // put acquireFence in a hidl_handle
+ hardware::hidl_handle acquireFenceHandle;
+ NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
+ if (acquireFence >= 0) {
+ auto h = native_handle_init(acquireFenceStorage, 1, 0);
+ h->data[0] = acquireFence;
+ acquireFenceHandle = h;
+ }
+
+ Error error;
+ auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
+ [&](const auto& tmpError, const auto& tmpData)
+ {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outData = tmpData;
+ });
+
+ // we own acquireFence even on errors
+ if (acquireFence >= 0) {
+ close(acquireFence);
+ }
+
+ return (ret.isOk()) ? error : kTransactionError;
+}
+
+Error Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage,
+ const IMapper::Rect& accessRegion,
+ int acquireFence, YCbCrLayout* outLayout) const
+{
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ // put acquireFence in a hidl_handle
+ hardware::hidl_handle acquireFenceHandle;
+ NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
+ if (acquireFence >= 0) {
+ auto h = native_handle_init(acquireFenceStorage, 1, 0);
+ h->data[0] = acquireFence;
+ acquireFenceHandle = h;
+ }
+
+ Error error;
+ auto ret = mMapper->lockYCbCr(buffer, usage, accessRegion,
+ acquireFenceHandle,
+ [&](const auto& tmpError, const auto& tmpLayout)
+ {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outLayout = tmpLayout;
+ });
+
+ // we own acquireFence even on errors
+ if (acquireFence >= 0) {
+ close(acquireFence);
+ }
+
+ return (ret.isOk()) ? error : kTransactionError;
+}
+
+int Mapper::unlock(buffer_handle_t bufferHandle) const
+{
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ int releaseFence = -1;
+ Error error;
+ auto ret = mMapper->unlock(buffer,
+ [&](const auto& tmpError, const auto& tmpReleaseFence)
+ {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ auto fenceHandle = tmpReleaseFence.getNativeHandle();
+ if (fenceHandle && fenceHandle->numFds == 1) {
+ int fd = dup(fenceHandle->data[0]);
+ if (fd >= 0) {
+ releaseFence = fd;
+ } else {
+ ALOGD("failed to dup unlock release fence");
+ sync_wait(fenceHandle->data[0], -1);
+ }
+ }
+ });
+
+ if (!ret.isOk()) {
+ error = kTransactionError;
+ }
+
+ if (error != Error::NONE) {
+ ALOGE("unlock(%p) failed with %d", buffer, error);
+ }
+
+ return releaseFence;
+}
+
+Allocator::Allocator(const Mapper& mapper)
+ : mMapper(mapper)
+{
+ if (mMapper.valid()) {
+ mAllocator = IAllocator::getService();
+ }
+}
+
+std::string Allocator::dumpDebugInfo() const
+{
+ std::string debugInfo;
+
+ mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) {
+ debugInfo = tmpDebugInfo.c_str();
+ });
+
+ return debugInfo;
+}
+
+Error Allocator::allocate(BufferDescriptor descriptor, uint32_t count,
+ uint32_t* outStride, buffer_handle_t* outBufferHandles) const
+{
+ Error error;
+ auto ret = mAllocator->allocate(descriptor, count,
+ [&](const auto& tmpError, const auto& tmpStride,
+ const auto& tmpBuffers) {
+ error = tmpError;
+ if (tmpError != Error::NONE) {
+ return;
+ }
+
+ // import buffers
+ for (uint32_t i = 0; i < count; i++) {
+ error = mMapper.importBuffer(tmpBuffers[i],
+ &outBufferHandles[i]);
+ if (error != Error::NONE) {
+ for (uint32_t j = 0; j < i; j++) {
+ mMapper.freeBuffer(outBufferHandles[j]);
+ outBufferHandles[j] = nullptr;
+ }
+ return;
+ }
+ }
+
+ *outStride = tmpStride;
+ });
+
+ return (ret.isOk()) ? error : kTransactionError;
+}
+
+} // namespace Gralloc2
+
+} // namespace android
diff --git a/libs/ui/GrallocAllocator.cpp b/libs/ui/GrallocAllocator.cpp
deleted file mode 100644
index 7af55e7..0000000
--- a/libs/ui/GrallocAllocator.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "GrallocAllocator"
-
-#include <ui/GrallocAllocator.h>
-
-#include <log/log.h>
-
-namespace android {
-
-namespace Gralloc2 {
-
-// assume NO_RESOURCES when Status::isOk returns false
-constexpr Error kDefaultError = Error::NO_RESOURCES;
-
-Allocator::Allocator()
-{
- mAllocator = IAllocator::getService();
- if (mAllocator != nullptr) {
- mAllocator->createClient(
- [&](const auto& tmpError, const auto& tmpClient) {
- if (tmpError == Error::NONE) {
- mClient = tmpClient;
- }
- });
- if (mClient == nullptr) {
- mAllocator.clear();
- }
- }
-}
-
-std::string Allocator::dumpDebugInfo() const
-{
- std::string info;
-
- mAllocator->dumpDebugInfo([&](const auto& tmpInfo) {
- info = tmpInfo.c_str();
- });
-
- return info;
-}
-
-Error Allocator::createBufferDescriptor(
- const IAllocatorClient::BufferDescriptorInfo& descriptorInfo,
- BufferDescriptor* outDescriptor) const
-{
- Error error = kDefaultError;
- mClient->createDescriptor(descriptorInfo,
- [&](const auto& tmpError, const auto& tmpDescriptor) {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outDescriptor = tmpDescriptor;
- });
-
- return error;
-}
-
-void Allocator::destroyBufferDescriptor(BufferDescriptor descriptor) const
-{
- mClient->destroyDescriptor(descriptor);
-}
-
-Error Allocator::allocate(BufferDescriptor descriptor,
- Buffer* outBuffer) const
-{
- hardware::hidl_vec<BufferDescriptor> descriptors;
- descriptors.setToExternal(&descriptor, 1);
-
- Error error = kDefaultError;
- auto status = mClient->allocate(descriptors,
- [&](const auto& tmpError, const auto& tmpBuffers) {
- error = tmpError;
- if (tmpError != Error::NONE) {
- return;
- }
-
- *outBuffer = tmpBuffers[0];
- });
-
- return error;
-}
-
-void Allocator::free(Buffer buffer) const
-{
- mClient->free(buffer);
-}
-
-Error Allocator::exportHandle(BufferDescriptor descriptor, Buffer buffer,
- native_handle_t** outBufferHandle) const
-{
- Error error = kDefaultError;
- auto status = mClient->exportHandle(descriptor, buffer,
- [&](const auto& tmpError, const auto& tmpBufferHandle) {
- error = tmpError;
- if (tmpError != Error::NONE) {
- return;
- }
-
- *outBufferHandle = native_handle_clone(tmpBufferHandle);
- if (!*outBufferHandle) {
- error = Error::NO_RESOURCES;
- }
- });
-
- return error;
-}
-
-} // namespace Gralloc2
-
-} // namespace android
diff --git a/libs/ui/GrallocMapper.cpp b/libs/ui/GrallocMapper.cpp
deleted file mode 100644
index 8095247..0000000
--- a/libs/ui/GrallocMapper.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "GrallocMapper"
-
-#include <ui/GrallocMapper.h>
-
-#include <log/log.h>
-
-namespace android {
-
-namespace Gralloc2 {
-
-static constexpr Error kDefaultError = Error::NO_RESOURCES;
-
-Mapper::Mapper()
-{
- mMapper = IMapper::getService();
- if (mMapper != nullptr && mMapper->isRemote()) {
- LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
- }
-}
-
-Error Mapper::retain(buffer_handle_t handle) const
-{
- auto ret = mMapper->retain(handle);
- return (ret.isOk()) ? static_cast<Error>(ret) : kDefaultError;
-}
-
-void Mapper::release(buffer_handle_t handle) const
-{
- auto ret = mMapper->release(handle);
-
- auto error = (ret.isOk()) ? static_cast<Error>(ret) : kDefaultError;
- ALOGE_IF(error != Error::NONE,
- "release(%p) failed with %d", handle, error);
-}
-
-Error Mapper::getDimensions(buffer_handle_t handle,
- uint32_t* outWidth, uint32_t* outHeight) const
-{
- Error error = kDefaultError;
- mMapper->getDimensions(handle,
- [&](const auto& tmpError, const auto& tmpWidth,
- const auto& tmpHeight)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outWidth = tmpWidth;
- *outHeight = tmpHeight;
- });
-
- return error;
-}
-
-Error Mapper::getFormat(buffer_handle_t handle, int32_t* outFormat) const
-{
- Error error = kDefaultError;
- mMapper->getFormat(handle,
- [&](const auto& tmpError, const auto& tmpFormat)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outFormat = static_cast<int32_t>(tmpFormat);
- });
-
- return error;
-}
-
-Error Mapper::getLayerCount(buffer_handle_t handle,
- uint32_t* outLayerCount) const
-{
- Error error = kDefaultError;
- mMapper->getLayerCount(handle,
- [&](const auto& tmpError, const auto& tmpLayerCount)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outLayerCount = tmpLayerCount;
- });
-
- return error;
-}
-
-Error Mapper::getProducerUsage(buffer_handle_t handle,
- uint64_t* outProducerUsage) const
-{
- Error error = kDefaultError;
- mMapper->getProducerUsageMask(handle,
- [&](const auto& tmpError, const auto& tmpProducerUsage)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outProducerUsage = tmpProducerUsage;
- });
-
- return error;
-}
-
-Error Mapper::getConsumerUsage(buffer_handle_t handle,
- uint64_t* outConsumerUsage) const
-{
- Error error = kDefaultError;
- mMapper->getConsumerUsageMask(handle,
- [&](const auto& tmpError, const auto& tmpConsumerUsage)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outConsumerUsage = tmpConsumerUsage;
- });
-
- return error;
-}
-
-Error Mapper::getBackingStore(buffer_handle_t handle,
- uint64_t* outBackingStore) const
-{
- Error error = kDefaultError;
- mMapper->getBackingStore(handle,
- [&](const auto& tmpError, const auto& tmpStore)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outBackingStore = tmpStore;
- });
-
- return error;
-}
-
-Error Mapper::getStride(buffer_handle_t handle, uint32_t* outStride) const
-{
- Error error = kDefaultError;
- mMapper->getStride(handle,
- [&](const auto& tmpError, const auto& tmpStride)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outStride = tmpStride;
- });
-
- return error;
-}
-
-Error Mapper::lock(buffer_handle_t handle,
- uint64_t producerUsage,
- uint64_t consumerUsage,
- const IMapper::Rect& accessRegion,
- int acquireFence, void** outData) const
-{
- hardware::hidl_handle acquireFenceHandle;
-
- NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
- if (acquireFence >= 0) {
- auto h = native_handle_init(acquireFenceStorage, 1, 0);
- h->data[0] = acquireFence;
- acquireFenceHandle = h;
- }
-
- Error error = kDefaultError;
- mMapper->lock(handle, producerUsage, consumerUsage,
- accessRegion, acquireFenceHandle,
- [&](const auto& tmpError, const auto& tmpData)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outData = tmpData;
- });
-
- if (error == Error::NONE && acquireFence >= 0) {
- close(acquireFence);
- }
-
- return error;
-}
-
-Error Mapper::lock(buffer_handle_t handle,
- uint64_t producerUsage,
- uint64_t consumerUsage,
- const IMapper::Rect& accessRegion,
- int acquireFence, FlexLayout* outLayout) const
-{
- hardware::hidl_handle acquireFenceHandle;
-
- NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
- if (acquireFence >= 0) {
- auto h = native_handle_init(acquireFenceStorage, 1, 0);
- h->data[0] = acquireFence;
- acquireFenceHandle = h;
- }
-
- Error error = kDefaultError;
- mMapper->lockFlex(handle, producerUsage, consumerUsage,
- accessRegion, acquireFenceHandle,
- [&](const auto& tmpError, const auto& tmpLayout)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outLayout = tmpLayout;
- });
-
- if (error == Error::NONE && acquireFence >= 0) {
- close(acquireFence);
- }
-
- return error;
-}
-
-int Mapper::unlock(buffer_handle_t handle) const
-{
- int releaseFence = -1;
-
- Error error = kDefaultError;
- mMapper->unlock(handle,
- [&](const auto& tmpError, const auto& tmpReleaseFence)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- auto fenceHandle = tmpReleaseFence.getNativeHandle();
- if (fenceHandle && fenceHandle->numFds == 1) {
- int fd = dup(fenceHandle->data[0]);
- if (fd >= 0) {
- releaseFence = fd;
- } else {
- error = Error::NO_RESOURCES;
- }
- } else {
- releaseFence = -1;
- }
- });
-
- if (error != Error::NONE) {
- ALOGE("unlock(%p) failed with %d", handle, error);
- releaseFence = -1;
- }
-
- return releaseFence;
-}
-
-} // namespace Gralloc2
-
-} // namespace android
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index d21758d..eb5c7b6 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -22,7 +22,7 @@
#include <grallocusage/GrallocUsageConversion.h>
-#include <ui/GrallocMapper.h>
+#include <ui/Gralloc2.h>
#include <ui/GraphicBufferAllocator.h>
#include <ui/GraphicBufferMapper.h>
@@ -104,11 +104,7 @@
void GraphicBuffer::free_handle()
{
if (mOwner == ownHandle) {
- mBufferMapper.unregisterBuffer(handle);
- if (!mBufferMapper.getGrallocMapper().valid()) {
- native_handle_close(handle);
- native_handle_delete(const_cast<native_handle*>(handle));
- }
+ mBufferMapper.freeBuffer(handle);
} else if (mOwner == ownData) {
GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
allocator.free(handle);
@@ -217,7 +213,7 @@
mOwner = (method == WRAP_HANDLE) ? ownNone : ownHandle;
if (method == TAKE_UNREGISTERED_HANDLE) {
- status_t err = mBufferMapper.registerBuffer(this);
+ status_t err = mBufferMapper.importBuffer(this);
if (err != NO_ERROR) {
// clean up cloned handle
if (clone) {
@@ -451,7 +447,7 @@
mOwner = ownHandle;
if (handle != 0) {
- status_t err = mBufferMapper.registerBuffer(this);
+ status_t err = mBufferMapper.importBuffer(this);
if (err != NO_ERROR) {
width = height = stride = format = layerCount = usage = 0;
handle = NULL;
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index 3f18bbc..1f6c537 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -22,13 +22,14 @@
#include <stdio.h>
+#include <grallocusage/GrallocUsageConversion.h>
+
#include <log/log.h>
#include <utils/Singleton.h>
#include <utils/String8.h>
#include <utils/Trace.h>
-#include <ui/GrallocAllocator.h>
-#include <ui/GrallocMapper.h>
+#include <ui/Gralloc2.h>
#include <ui/GraphicBufferMapper.h>
namespace android {
@@ -41,8 +42,9 @@
GraphicBufferAllocator::alloc_rec_t> GraphicBufferAllocator::sAllocList;
GraphicBufferAllocator::GraphicBufferAllocator()
- : mAllocator(std::make_unique<Gralloc2::Allocator>()),
- mMapper(GraphicBufferMapper::getInstance())
+ : mMapper(GraphicBufferMapper::getInstance()),
+ mAllocator(std::make_unique<Gralloc2::Allocator>(
+ mMapper.getGrallocMapper()))
{
if (!mAllocator->valid()) {
mLoader = std::make_unique<Gralloc1::Loader>();
@@ -102,109 +104,6 @@
ALOGD("%s", s.string());
}
-namespace {
-
-class HalBuffer {
-public:
- HalBuffer(const Gralloc2::Allocator* allocator,
- uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount, uint64_t producerUsage,
- uint64_t consumerUsage)
- : mAllocator(allocator), mBufferValid(false)
- {
- Gralloc2::IAllocatorClient::BufferDescriptorInfo info = {};
- info.width = width;
- info.height = height;
- info.format = static_cast<Gralloc2::PixelFormat>(format);
- info.layerCount = layerCount;
- info.producerUsageMask = producerUsage;
- info.consumerUsageMask = consumerUsage;
-
- Gralloc2::BufferDescriptor descriptor;
- auto error = mAllocator->createBufferDescriptor(info, &descriptor);
- if (error != Gralloc2::Error::NONE) {
- ALOGE("Failed to create desc (%u x %u) layerCount %u format %d producerUsage %" PRIx64
- " consumerUsage %" PRIx64 ": %d",
- width, height, layerCount, format, producerUsage,
- consumerUsage, error);
- return;
- }
-
- error = mAllocator->allocate(descriptor, &mBuffer);
- if (error == Gralloc2::Error::NOT_SHARED) {
- error = Gralloc2::Error::NONE;
- }
-
- if (error != Gralloc2::Error::NONE) {
- ALOGE("Failed to allocate (%u x %u) layerCount %u format %d producerUsage %" PRIx64
- " consumerUsage %" PRIx64 ": %d",
- width, height, layerCount, format, producerUsage,
- consumerUsage, error);
- mAllocator->destroyBufferDescriptor(descriptor);
- return;
- }
-
- error = mAllocator->exportHandle(descriptor, mBuffer, &mHandle);
- if (error != Gralloc2::Error::NONE) {
- ALOGE("Failed to export handle");
- mAllocator->free(mBuffer);
- mAllocator->destroyBufferDescriptor(descriptor);
- return;
- }
-
- mAllocator->destroyBufferDescriptor(descriptor);
-
- mBufferValid = true;
- }
-
- ~HalBuffer()
- {
- if (mBufferValid) {
- if (mHandle) {
- native_handle_close(mHandle);
- native_handle_delete(mHandle);
- }
-
- mAllocator->free(mBuffer);
- }
- }
-
- bool exportHandle(GraphicBufferMapper& mapper,
- buffer_handle_t* handle, uint32_t* stride)
- {
- if (!mBufferValid) {
- return false;
- }
-
- if (mapper.registerBuffer(mHandle)) {
- return false;
- }
-
- *handle = mHandle;
-
- auto error = mapper.getGrallocMapper().getStride(mHandle, stride);
- if (error != Gralloc2::Error::NONE) {
- ALOGW("Failed to get stride from buffer: %d", error);
- *stride = 0;
- }
-
- mHandle = nullptr;
- mAllocator->free(mBuffer);
- mBufferValid = false;
-
- return true;
- }
-
-private:
- const Gralloc2::Allocator* mAllocator;
-
- bool mBufferValid;
- Gralloc2::Buffer mBuffer;
- native_handle_t* mHandle;
-};
-
-} // namespace
-
status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height,
PixelFormat format, uint32_t layerCount, uint64_t producerUsage,
uint64_t consumerUsage, buffer_handle_t* handle, uint32_t* stride,
@@ -223,12 +122,18 @@
gralloc1_error_t error;
if (mAllocator->valid()) {
- HalBuffer buffer(mAllocator.get(), width, height, format, layerCount,
- producerUsage, consumerUsage);
- if (!buffer.exportHandle(mMapper, handle, stride)) {
+ Gralloc2::IMapper::BufferDescriptorInfo info = {};
+ info.width = width;
+ info.height = height;
+ info.layerCount = layerCount;
+ info.format = static_cast<Gralloc2::PixelFormat>(format);
+ info.usage = static_cast<uint64_t>(android_convertGralloc1To0Usage(
+ producerUsage, consumerUsage));
+ error = static_cast<gralloc1_error_t>(mAllocator->allocate(info,
+ stride, handle));
+ if (error != GRALLOC1_ERROR_NONE) {
return NO_MEMORY;
}
- error = GRALLOC1_ERROR_NONE;
} else {
auto descriptor = mDevice->createDescriptor();
error = descriptor->setDimensions(width, height);
@@ -310,8 +215,7 @@
gralloc1_error_t error;
if (mAllocator->valid()) {
- error = static_cast<gralloc1_error_t>(
- mMapper.unregisterBuffer(handle));
+ error = static_cast<gralloc1_error_t>(mMapper.freeBuffer(handle));
} else {
error = mDevice->release(handle);
}
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 656472f..2f4d5fb 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -20,6 +20,8 @@
#include <ui/GraphicBufferMapper.h>
+#include <grallocusage/GrallocUsageConversion.h>
+
// We would eliminate the non-conforming zero-length array, but we can't since
// this is effectively included from the Linux kernel
#pragma clang diagnostic push
@@ -30,7 +32,7 @@
#include <utils/Log.h>
#include <utils/Trace.h>
-#include <ui/GrallocMapper.h>
+#include <ui/Gralloc2.h>
#include <ui/GraphicBuffer.h>
#include <system/graphics.h>
@@ -49,63 +51,82 @@
}
}
-
-
-status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle)
+status_t GraphicBufferMapper::importBuffer(buffer_handle_t rawHandle,
+ buffer_handle_t* outHandle)
{
ATRACE_CALL();
+ Gralloc2::Error error;
+ if (mMapper->valid()) {
+ error = mMapper->importBuffer(hardware::hidl_handle(rawHandle),
+ outHandle);
+ } else {
+ error = Gralloc2::Error::UNSUPPORTED;
+ }
+
+ ALOGW_IF(error != Gralloc2::Error::NONE, "importBuffer(%p) failed: %d",
+ rawHandle, error);
+
+ return static_cast<status_t>(error);
+}
+
+status_t GraphicBufferMapper::importBuffer(const GraphicBuffer* buffer)
+{
+ ATRACE_CALL();
+
+ ANativeWindowBuffer* nativeBuffer = buffer->getNativeBuffer();
+ buffer_handle_t rawHandle = nativeBuffer->handle;
+
gralloc1_error_t error;
if (mMapper->valid()) {
- error = static_cast<gralloc1_error_t>(mMapper->retain(handle));
+ buffer_handle_t importedHandle;
+ error = static_cast<gralloc1_error_t>(mMapper->importBuffer(
+ hardware::hidl_handle(rawHandle), &importedHandle));
+ if (error == GRALLOC1_ERROR_NONE) {
+ nativeBuffer->handle = importedHandle;
+ }
} else {
- // This always returns GRALLOC1_BAD_HANDLE when handle is from a
- // remote process and mDevice is backed by Gralloc1On0Adapter.
- error = mDevice->retain(handle);
- if (error == GRALLOC1_ERROR_BAD_HANDLE &&
- mDevice->hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
- ALOGE("registerBuffer by handle is not supported with "
- "Gralloc1On0Adapter");
+ native_handle_t* clonedHandle = native_handle_clone(rawHandle);
+ if (clonedHandle) {
+ nativeBuffer->handle = clonedHandle;
+ error = mDevice->retain(buffer);
+ if (error != GRALLOC1_ERROR_NONE) {
+ nativeBuffer->handle = rawHandle;
+ native_handle_close(clonedHandle);
+ native_handle_delete(clonedHandle);
+ }
+ } else {
+ error = GRALLOC1_ERROR_NO_RESOURCES;
}
}
- ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
- handle, error);
-
- return error;
-}
-
-status_t GraphicBufferMapper::registerBuffer(const GraphicBuffer* buffer)
-{
- ATRACE_CALL();
-
- gralloc1_error_t error;
- if (mMapper->valid()) {
- error = static_cast<gralloc1_error_t>(
- mMapper->retain(buffer->getNativeBuffer()->handle));
- } else {
- error = mDevice->retain(buffer);
+ // the raw handle is owned by GraphicBuffer and is now replaced
+ if (error == GRALLOC1_ERROR_NONE) {
+ native_handle_close(rawHandle);
+ native_handle_delete(const_cast<native_handle_t*>(rawHandle));
}
- ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
- buffer->getNativeBuffer()->handle, error);
+ ALOGW_IF(error != GRALLOC1_ERROR_NONE, "importBuffer(%p) failed: %d",
+ rawHandle, error);
return error;
}
-status_t GraphicBufferMapper::unregisterBuffer(buffer_handle_t handle)
+status_t GraphicBufferMapper::freeBuffer(buffer_handle_t handle)
{
ATRACE_CALL();
gralloc1_error_t error;
if (mMapper->valid()) {
- mMapper->release(handle);
+ mMapper->freeBuffer(handle);
error = GRALLOC1_ERROR_NONE;
} else {
error = mDevice->release(handle);
+ native_handle_close(handle);
+ native_handle_delete(const_cast<native_handle_t*>(handle));
}
- ALOGW_IF(error != GRALLOC1_ERROR_NONE, "unregisterBuffer(%p): failed %d",
+ ALOGW_IF(error != GRALLOC1_ERROR_NONE, "freeBuffer(%p): failed %d",
handle, error);
return error;
@@ -120,138 +141,13 @@
return outRect;
}
-
-status_t GraphicBufferMapper::getDimensions(buffer_handle_t handle,
- uint32_t* outWidth, uint32_t* outHeight) const
-{
- ATRACE_CALL();
-
- gralloc1_error_t error;
- if (mMapper->valid()) {
- mMapper->getDimensions(handle, outWidth, outHeight);
- error = GRALLOC1_ERROR_NONE;
- } else {
- error = mDevice->getDimensions(handle, outWidth, outHeight);
- }
-
- ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getDimensions(%p, ...): failed %d",
- handle, error);
-
- return error;
-}
-
-status_t GraphicBufferMapper::getFormat(buffer_handle_t handle,
- int32_t* outFormat) const
-{
- ATRACE_CALL();
-
- gralloc1_error_t error;
- if (mMapper->valid()) {
- mMapper->getFormat(handle, outFormat);
- error = GRALLOC1_ERROR_NONE;
- } else {
- error = mDevice->getFormat(handle, outFormat);
- }
-
- ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getFormat(%p, ...): failed %d",
- handle, error);
-
- return error;
-}
-
-status_t GraphicBufferMapper::getLayerCount(buffer_handle_t handle,
- uint32_t* outLayerCount) const
-{
- ATRACE_CALL();
-
- gralloc1_error_t error;
- if (mMapper->valid()) {
- mMapper->getLayerCount(handle, outLayerCount);
- error = GRALLOC1_ERROR_NONE;
- } else {
- error = mDevice->getLayerCount(handle, outLayerCount);
- }
-
- ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getLayerCount(%p, ...): failed %d",
- handle, error);
-
- return error;
-}
-
-status_t GraphicBufferMapper::getProducerUsage(buffer_handle_t handle,
- uint64_t* outProducerUsage) const
-{
- ATRACE_CALL();
-
- gralloc1_error_t error;
- if (mMapper->valid()) {
- mMapper->getProducerUsage(handle, outProducerUsage);
- error = GRALLOC1_ERROR_NONE;
- } else {
- error = mDevice->getProducerUsage(handle, outProducerUsage);
- }
-
- ALOGW_IF(error != GRALLOC1_ERROR_NONE,
- "getProducerUsage(%p, ...): failed %d", handle, error);
-
- return error;
-}
-
-status_t GraphicBufferMapper::getConsumerUsage(buffer_handle_t handle,
- uint64_t* outConsumerUsage) const
-{
- ATRACE_CALL();
-
- gralloc1_error_t error;
- if (mMapper->valid()) {
- mMapper->getConsumerUsage(handle, outConsumerUsage);
- error = GRALLOC1_ERROR_NONE;
- } else {
- error = mDevice->getConsumerUsage(handle, outConsumerUsage);
- }
-
- ALOGW_IF(error != GRALLOC1_ERROR_NONE,
- "getConsumerUsage(%p, ...): failed %d", handle, error);
-
- return error;
-}
-
-status_t GraphicBufferMapper::getBackingStore(buffer_handle_t handle,
- uint64_t* outBackingStore) const
-{
- ATRACE_CALL();
-
- gralloc1_error_t error;
- if (mMapper->valid()) {
- mMapper->getBackingStore(handle, outBackingStore);
- error = GRALLOC1_ERROR_NONE;
- } else {
- error = mDevice->getBackingStore(handle, outBackingStore);
- }
-
- ALOGW_IF(error != GRALLOC1_ERROR_NONE,
- "getBackingStore(%p, ...): failed %d", handle, error);
-
- return error;
-}
-
-status_t GraphicBufferMapper::getStride(buffer_handle_t handle,
- uint32_t* outStride) const
-{
- ATRACE_CALL();
-
- gralloc1_error_t error;
- if (mMapper->valid()) {
- mMapper->getStride(handle, outStride);
- error = GRALLOC1_ERROR_NONE;
- } else {
- error = mDevice->getStride(handle, outStride);
- }
-
- ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getStride(%p, ...): failed %d",
- handle, error);
-
- return error;
+static inline Gralloc2::IMapper::Rect asGralloc2Rect(const Rect& rect) {
+ Gralloc2::IMapper::Rect outRect{};
+ outRect.left = rect.left;
+ outRect.top = rect.top;
+ outRect.width = rect.width();
+ outRect.height = rect.height();
+ return outRect;
}
status_t GraphicBufferMapper::lock(buffer_handle_t handle, uint32_t usage,
@@ -289,15 +185,15 @@
{
ATRACE_CALL();
- gralloc1_rect_t accessRegion = asGralloc1Rect(bounds);
gralloc1_error_t error;
if (mMapper->valid()) {
- const Gralloc2::IMapper::Rect& accessRect =
- *reinterpret_cast<Gralloc2::IMapper::Rect*>(&accessRegion);
- error = static_cast<gralloc1_error_t>(mMapper->lock(
- handle, producerUsage, consumerUsage, accessRect,
- fenceFd, vaddr));
+ const uint64_t usage =
+ static_cast<uint64_t>(android_convertGralloc1To0Usage(
+ producerUsage, consumerUsage));
+ error = static_cast<gralloc1_error_t>(mMapper->lock(handle,
+ usage, asGralloc2Rect(bounds), fenceFd, vaddr));
} else {
+ gralloc1_rect_t accessRegion = asGralloc1Rect(bounds);
sp<Fence> fence = new Fence(fenceFd);
error = mDevice->lock(handle,
static_cast<gralloc1_producer_usage_t>(producerUsage),
@@ -346,22 +242,19 @@
gralloc1_error_t error;
if (mMapper->valid()) {
- const Gralloc2::IMapper::Rect& accessRect =
- *reinterpret_cast<Gralloc2::IMapper::Rect*>(&accessRegion);
- Gralloc2::FlexLayout layout{};
- error = static_cast<gralloc1_error_t>(mMapper->lock(
- handle, usage, usage, accessRect, fenceFd, &layout));
-
+ Gralloc2::YCbCrLayout layout;
+ error = static_cast<gralloc1_error_t>(mMapper->lock(handle, usage,
+ asGralloc2Rect(bounds), fenceFd, &layout));
if (error == GRALLOC1_ERROR_NONE) {
- planes.resize(layout.planes.size());
- memcpy(planes.data(), layout.planes.data(),
- sizeof(planes[0]) * planes.size());
-
- flexLayout.format = static_cast<android_flex_format_t>(
- layout.format);
- flexLayout.num_planes = static_cast<uint32_t>(planes.size());
- flexLayout.planes = planes.data();
+ ycbcr->y = layout.y;
+ ycbcr->cb = layout.cb;
+ ycbcr->cr = layout.cr;
+ ycbcr->ystride = static_cast<size_t>(layout.yStride);
+ ycbcr->cstride = static_cast<size_t>(layout.cStride);
+ ycbcr->chroma_step = static_cast<size_t>(layout.chromaStep);
}
+
+ return error;
} else {
sp<Fence> fence = new Fence(fenceFd);
diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp
index b55c212..6733505 100644
--- a/libs/ui/tests/Android.bp
+++ b/libs/ui/tests/Android.bp
@@ -25,9 +25,3 @@
shared_libs: ["libui"],
srcs: ["colorspace_test.cpp"],
}
-
-cc_test {
- name: "Gralloc1Mapper_test",
- shared_libs: ["libui", "libutils"],
- srcs: ["Gralloc1Mapper_test.cpp"],
-}
diff --git a/libs/ui/tests/Gralloc1Mapper_test.cpp b/libs/ui/tests/Gralloc1Mapper_test.cpp
deleted file mode 100644
index b7c9f0f..0000000
--- a/libs/ui/tests/Gralloc1Mapper_test.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Gralloc1Mapper_test"
-//#define LOG_NDEBUG 0
-
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <ui/GraphicBuffer.h>
-#include <ui/GraphicBufferMapper.h>
-#include <utils/Errors.h>
-
-#include <gtest/gtest.h>
-
-using namespace android;
-
-class Gralloc1MapperTest : public ::testing::Test
-{
-public:
- ~Gralloc1MapperTest() override = default;
-
-protected:
- void SetUp() override {
- buffer = new GraphicBuffer(4, 8, HAL_PIXEL_FORMAT_RGBA_8888, 1,
- GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN,
- GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN, "Gralloc1MapperTest");
- ASSERT_NE(nullptr, buffer.get());
-
- handle = static_cast<buffer_handle_t>(buffer->handle);
-
- mapper = &GraphicBufferMapper::get();
- }
-
- sp<GraphicBuffer> buffer;
- buffer_handle_t handle;
- GraphicBufferMapper* mapper;
-};
-
-TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getDimensions) {
- uint32_t width = 0;
- uint32_t height = 0;
- status_t err = mapper->getDimensions(handle, &width, &height);
- ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
- EXPECT_EQ(4U, width);
- EXPECT_EQ(8U, height);
-}
-
-TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getFormat) {
- int32_t value = 0;
- status_t err = mapper->getFormat(handle, &value);
- ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
- EXPECT_EQ(HAL_PIXEL_FORMAT_RGBA_8888, value);
-}
-
-TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getLayerCount) {
- uint32_t value = 0;
- status_t err = mapper->getLayerCount(handle, &value);
- if (err != GRALLOC1_ERROR_UNSUPPORTED) {
- EXPECT_EQ(1U, value);
- }
-}
-
-TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getProducerUsage) {
- uint64_t value = 0;
- status_t err = mapper->getProducerUsage(handle, &value);
- ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
- EXPECT_EQ(GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN, value);
-}
-
-TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getConsumerUsage) {
- uint64_t value = 0;
- status_t err = mapper->getConsumerUsage(handle, &value);
- ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
- EXPECT_EQ(GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN, value);
-}
-
-TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getBackingStore) {
- uint64_t value = 0;
- status_t err = mapper->getBackingStore(handle, &value);
- ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
-}
-
-TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getStride) {
- uint32_t value = 0;
- status_t err = mapper->getStride(handle, &value);
- ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
- // The stride should be at least the width of the buffer.
- EXPECT_LE(4U, value);
-}
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/libdvr/dvr_api.cpp b/libs/vr/libdvr/dvr_api.cpp
index f786c29..49702fd 100644
--- a/libs/vr/libdvr/dvr_api.cpp
+++ b/libs/vr/libdvr/dvr_api.cpp
@@ -108,6 +108,7 @@
dvr_api->hwc_frame_get_display_id = dvrHwcFrameGetDisplayId;
dvr_api->hwc_frame_get_display_width = dvrHwcFrameGetDisplayWidth;
dvr_api->hwc_frame_get_display_height = dvrHwcFrameGetDisplayHeight;
+ dvr_api->hwc_frame_get_display_removed = dvrHwcFrameGetDisplayRemoved;
dvr_api->hwc_frame_get_layer_count = dvrHwcFrameGetLayerCount;
dvr_api->hwc_frame_get_layer_id = dvrHwcFrameGetLayerId;
dvr_api->hwc_frame_get_layer_buffer = dvrHwcFrameGetLayerBuffer;
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/opengl/libs/Android.bp b/opengl/libs/Android.bp
index 6a62e8d..a895e63 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -23,28 +23,28 @@
// The headers modules are in frameworks/native/opengl/Android.bp.
ndk_library {
- name: "libEGL.ndk",
+ name: "libEGL",
symbol_file: "libEGL.map.txt",
first_version: "9",
unversioned_until: "current",
}
ndk_library {
- name: "libGLESv1_CM.ndk",
+ name: "libGLESv1_CM",
symbol_file: "libGLESv1_CM.map.txt",
first_version: "9",
unversioned_until: "current",
}
ndk_library {
- name: "libGLESv2.ndk",
+ name: "libGLESv2",
symbol_file: "libGLESv2.map.txt",
first_version: "9",
unversioned_until: "current",
}
ndk_library {
- name: "libGLESv3.ndk",
+ name: "libGLESv3",
symbol_file: "libGLESv3.map.txt",
first_version: "18",
unversioned_until: "current",
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 683e6ca..7d20ba1 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -33,6 +33,10 @@
#include "egl_trace.h"
#include "egldefs.h"
+extern "C" {
+ android_namespace_t* android_get_exported_namespace(const char*);
+}
+
// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------
@@ -106,6 +110,11 @@
return dlopen(path, mode);
}
+static void* do_android_dlopen_ext(const char* path, int mode, const android_dlextinfo* info) {
+ ATRACE_CALL();
+ return android_dlopen_ext(path, mode, info);
+}
+
// ----------------------------------------------------------------------------
Loader::driver_t::driver_t(void* gles)
@@ -414,6 +423,27 @@
}
const char* const driver_absolute_path = absolutePath.c_str();
+ // Try to load drivers from the 'sphal' namespace, if it exist. Fall back to
+ // the original routine when the namespace does not exist or the load from
+ // the namespace fails.
+ // See /system/core/rootdir/etc/ld.config.txt for the configuration of the
+ // sphal namespace.
+ android_namespace_t* sphal_namespace = android_get_exported_namespace("sphal");
+ if (sphal_namespace != NULL) {
+ const android_dlextinfo dlextinfo = {
+ .flags = ANDROID_DLEXT_USE_NAMESPACE,
+ .library_namespace = sphal_namespace,
+ };
+ void* dso = do_android_dlopen_ext(driver_absolute_path, RTLD_LOCAL | RTLD_NOW, &dlextinfo);
+ if (dso) {
+ ALOGD("loaded %s from sphal namespace", driver_absolute_path);
+ return dso;
+ }
+ else {
+ ALOGW("failed to load %s from sphal namespace: %s", driver_absolute_path, dlerror());
+ }
+ }
+
void* dso = do_dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL);
if (dso == 0) {
const char* err = dlerror();
@@ -426,11 +456,6 @@
return dso;
}
-static void* do_android_dlopen_ext(const char* path, int mode, const android_dlextinfo* info) {
- ATRACE_CALL();
- return android_dlopen_ext(path, mode, info);
-}
-
static const char* HAL_SUBNAME_KEY_PROPERTIES[2] = {
"ro.hardware.egl",
"ro.board.platform",
diff --git a/services/schedulerservice/Android.bp b/services/schedulerservice/Android.bp
new file mode 100644
index 0000000..1f1340c
--- /dev/null
+++ b/services/schedulerservice/Android.bp
@@ -0,0 +1,25 @@
+cc_library_shared {
+ name: "libschedulerservicehidl",
+ srcs: [
+ "SchedulingPolicyService.cpp",
+ ],
+ shared_libs: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libmediautils",
+ "liblog",
+ "libutils",
+ "android.hidl.base@1.0",
+ "android.frameworks.schedulerservice@1.0",
+ ],
+ header_libs: [
+ "libcutils_headers",
+ ],
+ export_include_dirs: [
+ "include/"
+ ],
+ local_include_dirs: [
+ "include/schedulerservice/",
+ ],
+}
diff --git a/services/schedulerservice/SchedulingPolicyService.cpp b/services/schedulerservice/SchedulingPolicyService.cpp
new file mode 100644
index 0000000..522a8c0
--- /dev/null
+++ b/services/schedulerservice/SchedulingPolicyService.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "schedulerservicehidl"
+
+#include "SchedulingPolicyService.h"
+
+#include <private/android_filesystem_config.h> // for AID_CAMERASERVER
+
+#include <log/log.h>
+#include <hwbinder/IPCThreadState.h>
+#include <mediautils/SchedulingPolicyService.h>
+
+namespace android {
+namespace frameworks {
+namespace schedulerservice {
+namespace V1_0 {
+namespace implementation {
+
+Return<bool> SchedulingPolicyService::requestPriority(int32_t pid, int32_t tid, int32_t priority) {
+ using ::android::hardware::IPCThreadState;
+
+ if (priority < static_cast<int32_t>(Priority::MIN) ||
+ priority > static_cast<int32_t>(Priority::MAX)) {
+ return false;
+ }
+
+ if (IPCThreadState::self()->getCallingUid() != AID_CAMERASERVER) {
+ return false;
+ }
+
+ // this should always be allowed since we are in system_server.
+ int value = ::android::requestPriority(pid, tid, priority, false /* isForApp */);
+ return value == 0 /* success */;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace schedulerservice
+} // namespace frameworks
+} // namespace android
diff --git a/services/schedulerservice/include/schedulerservice/SchedulingPolicyService.h b/services/schedulerservice/include/schedulerservice/SchedulingPolicyService.h
new file mode 100644
index 0000000..eb5a4ae
--- /dev/null
+++ b/services/schedulerservice/include/schedulerservice/SchedulingPolicyService.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <android/frameworks/schedulerservice/1.0/ISchedulingPolicyService.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace frameworks {
+namespace schedulerservice {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::frameworks::schedulerservice::V1_0::ISchedulingPolicyService;
+using ::android::hidl::base::V1_0::DebugInfo;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct SchedulingPolicyService : public ISchedulingPolicyService {
+ Return<bool> requestPriority(int32_t pid, int32_t tid, int32_t priority) override;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace schedulerservice
+} // namespace frameworks
+} // namespace android
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/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp
index 999d71e..6e4daa0 100644
--- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp
+++ b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp
@@ -10,35 +10,9 @@
namespace {
sp<GraphicBuffer> GetBufferFromHandle(native_handle_t* handle) {
- uint32_t width = 0, height = 0, stride = 0, layer_count = 1;
- uint64_t producer_usage = 0, consumer_usage = 0;
- int32_t format = 0;
-
- GraphicBufferMapper& mapper = GraphicBufferMapper::get();
- // Need to register |handle| otherwise we can't read its properties.
- if (mapper.registerBuffer(handle) != OK) {
- ALOGE("Failed to register buffer");
- return nullptr;
- }
-
- if (mapper.getDimensions(handle, &width, &height) ||
- mapper.getStride(handle, &stride) ||
- mapper.getFormat(handle, &format) ||
- mapper.getProducerUsage(handle, &producer_usage) ||
- mapper.getConsumerUsage(handle, &consumer_usage)) {
- ALOGE("Failed to read handle properties");
- return nullptr;
- }
-
- // This will only succeed if gralloc has GRALLOC1_CAPABILITY_LAYERED_BUFFERS
- // capability. Otherwise assume a count of 1.
- mapper.getLayerCount(handle, &layer_count);
-
- sp<GraphicBuffer> buffer = new GraphicBuffer(handle,
- GraphicBuffer::TAKE_HANDLE, width, height, format, layer_count,
- producer_usage, consumer_usage, stride);
-
- return buffer;
+ // Querying properties from |handle| is never properly supported.
+ ALOGE("Failed to read handle %p properties", handle);
+ return nullptr;
}
} // namespace
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/virtual_touchpad/main.cpp b/services/vr/virtual_touchpad/main.cpp
index 68f1d70..55ac9bf 100644
--- a/services/vr/virtual_touchpad/main.cpp
+++ b/services/vr/virtual_touchpad/main.cpp
@@ -8,8 +8,9 @@
int main() {
ALOGI("Starting");
- android::dvr::VirtualTouchpadService touchpad_service(
- std::move(android::dvr::VirtualTouchpadEvdev::Create()));
+ android::sp<android::dvr::VirtualTouchpadService> touchpad_service =
+ new android::dvr::VirtualTouchpadService(
+ android::dvr::VirtualTouchpadEvdev::Create());
signal(SIGPIPE, SIG_IGN);
android::sp<android::ProcessState> ps(android::ProcessState::self());
@@ -19,8 +20,8 @@
android::sp<android::IServiceManager> sm(android::defaultServiceManager());
const android::status_t service_status =
- sm->addService(android::String16(touchpad_service.SERVICE_NAME()),
- &touchpad_service, false /*allowIsolated*/);
+ sm->addService(android::String16(touchpad_service->SERVICE_NAME()),
+ touchpad_service, false /*allowIsolated*/);
if (service_status != android::OK) {
ALOGE("virtual touchpad service not added: %d",
static_cast<int>(service_status));
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 d142729..c60a4f5 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
+++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
@@ -44,40 +44,9 @@
const Config kDefaultConfigId = 1;
sp<GraphicBuffer> GetBufferFromHandle(const native_handle_t* handle) {
- uint32_t width = 0, height = 0, stride = 0, layer_count = 1;
- uint64_t producer_usage = 0, consumer_usage = 0;
- int32_t format = 0;
-
- GraphicBufferMapper& mapper = GraphicBufferMapper::get();
- // Need to register |handle| otherwise we can't read its properties.
- if (mapper.registerBuffer(handle) != OK) {
- ALOGE("Failed to register buffer");
- return nullptr;
- }
-
- if (mapper.getDimensions(handle, &width, &height) ||
- mapper.getStride(handle, &stride) ||
- mapper.getFormat(handle, &format) ||
- mapper.getProducerUsage(handle, &producer_usage) ||
- mapper.getConsumerUsage(handle, &consumer_usage)) {
- ALOGE("Failed to read handle properties");
- return nullptr;
- }
-
- // This will only succeed if gralloc has GRALLOC1_CAPABILITY_LAYERED_BUFFERS
- // capability. Otherwise assume a count of 1.
- mapper.getLayerCount(handle, &layer_count);
-
- // NOTE: Can't re-use |handle| since we don't own it.
- sp<GraphicBuffer> buffer = new GraphicBuffer(handle,
- GraphicBuffer::CLONE_HANDLE, width, height, format, layer_count,
- producer_usage, consumer_usage, stride);
- if (buffer->initCheck() != OK) {
- ALOGE("Failed to register cloned buffer");
- return nullptr;
- }
-
- return buffer;
+ // Querying properties from |handle| is never properly supported.
+ ALOGE("Failed to read handle %p properties", handle);
+ return nullptr;
}
void GetPrimaryDisplaySize(int32_t* width, int32_t* height) {
@@ -217,19 +186,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;
diff --git a/services/vr/vr_window_manager/vr_window_manager.cpp b/services/vr/vr_window_manager/vr_window_manager.cpp
index 6636dc5..9d7afe3 100644
--- a/services/vr/vr_window_manager/vr_window_manager.cpp
+++ b/services/vr/vr_window_manager/vr_window_manager.cpp
@@ -20,20 +20,20 @@
LOG_ALWAYS_FATAL_IF(app_status != 0, "failed to initialize: %d", app_status);
// Create vr_wm_binder.
- android::service::vr::VrWindowManagerBinder vr_wm_binder(app);
- const int status = vr_wm_binder.Initialize();
+ android::sp<android::service::vr::VrWindowManagerBinder> vr_wm_binder =
+ new android::service::vr::VrWindowManagerBinder(app);
+ const int status = vr_wm_binder->Initialize();
LOG_ALWAYS_FATAL_IF(status != 0, "initialization failed: %d", status);
android::sp<android::IServiceManager> sm(android::defaultServiceManager());
- const android::status_t vr_wm_binder_status =
- sm->addService(
- android::service::vr::VrWindowManagerBinder::SERVICE_NAME(),
- &vr_wm_binder, false /*allowIsolated*/);
+ const android::status_t vr_wm_binder_status = sm->addService(
+ android::service::vr::VrWindowManagerBinder::SERVICE_NAME(),
+ vr_wm_binder, false /*allowIsolated*/);
LOG_ALWAYS_FATAL_IF(vr_wm_binder_status != android::OK,
"vr_wm_binder service not added: %d",
static_cast<int>(vr_wm_binder_status));
- app.SetControllerDataProvider(&vr_wm_binder);
+ app.SetControllerDataProvider(vr_wm_binder.get());
android::hardware::ProcessState::self()->startThreadPool();
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp
index 9444da5..68f09c4 100644
--- a/vulkan/libvulkan/Android.bp
+++ b/vulkan/libvulkan/Android.bp
@@ -14,7 +14,7 @@
// Headers module is in frameworks/native/vulkan/Android.bp.
ndk_library {
- name: "libvulkan.ndk",
+ name: "libvulkan",
symbol_file: "libvulkan.map.txt",
first_version: "24",
unversioned_until: "current",
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 5fbf5f5..212d142 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -34,6 +34,11 @@
#include "driver.h"
#include "stubhal.h"
+// TODO(b/37049319) Get this from a header once one exists
+extern "C" {
+android_namespace_t* android_get_exported_namespace(const char*);
+}
+
// Set to true to enable exposing unratified extensions for development
static const bool kEnableUnratifiedExtensions = false;
@@ -150,14 +155,12 @@
"ro.board.platform",
}};
-int LoadUpdatedDriver(const hw_module_t** module) {
+int LoadDriver(android_namespace_t* library_namespace,
+ const hwvulkan_module_t** module) {
const android_dlextinfo dlextinfo = {
.flags = ANDROID_DLEXT_USE_NAMESPACE,
- .library_namespace = android::GraphicsEnv::getInstance().getDriverNamespace(),
+ .library_namespace = library_namespace,
};
- if (!dlextinfo.library_namespace)
- return -ENOENT;
-
void* so = nullptr;
char prop[PROPERTY_VALUE_MAX];
for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
@@ -171,7 +174,7 @@
if (!so)
return -ENOENT;
- hw_module_t* hmi = static_cast<hw_module_t*>(dlsym(so, HAL_MODULE_INFO_SYM_AS_STR));
+ auto hmi = static_cast<hw_module_t*>(dlsym(so, HAL_MODULE_INFO_SYM_AS_STR));
if (!hmi) {
ALOGE("couldn't find symbol '%s' in HAL library: %s", HAL_MODULE_INFO_SYM_AS_STR, dlerror());
dlclose(so);
@@ -183,11 +186,24 @@
return -EINVAL;
}
hmi->dso = so;
- *module = hmi;
- ALOGD("loaded updated driver");
+ *module = reinterpret_cast<const hwvulkan_module_t*>(hmi);
return 0;
}
+int LoadBuiltinDriver(const hwvulkan_module_t** module) {
+ auto ns = android_get_exported_namespace("sphal");
+ if (!ns)
+ return -ENOENT;
+ return LoadDriver(ns, module);
+}
+
+int LoadUpdatedDriver(const hwvulkan_module_t** module) {
+ auto ns = android::GraphicsEnv::getInstance().getDriverNamespace();
+ if (!ns)
+ return -ENOENT;
+ return LoadDriver(ns, module);
+}
+
bool Hal::Open() {
ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once");
@@ -197,9 +213,21 @@
int result;
const hwvulkan_module_t* module = nullptr;
- result = LoadUpdatedDriver(reinterpret_cast<const hw_module_t**>(&module));
+ result = LoadUpdatedDriver(&module);
if (result == -ENOENT) {
- result = hw_get_module(HWVULKAN_HARDWARE_MODULE_ID, reinterpret_cast<const hw_module_t**>(&module));
+ result = LoadBuiltinDriver(&module);
+ if (result != 0) {
+ // -ENOENT means the sphal namespace doesn't exist, not that there
+ // is a problem with the driver.
+ ALOGW_IF(
+ result != -ENOENT,
+ "Failed to load Vulkan driver into sphal namespace. This "
+ "usually means the driver has forbidden library dependencies."
+ "Please fix, this will soon stop working.");
+ result =
+ hw_get_module(HWVULKAN_HARDWARE_MODULE_ID,
+ reinterpret_cast<const hw_module_t**>(&module));
+ }
}
if (result != 0) {
ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result);