Merge "vkGetDeviceQueue2: fix the NULL check"
diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp
index e176871..5a82965 100644
--- a/cmds/installd/tests/installd_dexopt_test.cpp
+++ b/cmds/installd/tests/installd_dexopt_test.cpp
@@ -675,7 +675,8 @@
run_cmd("touch " + expected_profile_content);
run_cmd("profman --profile-file=" + cur_profile_ +
" --profile-file=" + ref_profile_ +
- " --reference-profile-file=" + expected_profile_content);
+ " --reference-profile-file=" + expected_profile_content +
+ " --apk=" + apk_path_);
ASSERT_TRUE(AreFilesEqual(expected_profile_content, snap_profile_));
diff --git a/cmds/lshal/Android.bp b/cmds/lshal/Android.bp
index 409c206..93d878b 100644
--- a/cmds/lshal/Android.bp
+++ b/cmds/lshal/Android.bp
@@ -24,6 +24,9 @@
"libhidl-gen-utils",
"libvintf",
],
+ static_libs: [
+ "libprocpartition",
+ ],
srcs: [
"DebugCommand.cpp",
"HelpCommand.cpp",
@@ -45,10 +48,14 @@
shared_libs: [
"libbase",
"libhidlbase",
+ "libhidl-gen-utils",
"libhidltransport",
"liblshal",
"libutils",
],
+ static_libs: [
+ "libprocpartition",
+ ],
cflags: ["-Wall", "-Werror"],
}
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index fab13a0..b9e0139 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -25,6 +25,7 @@
#include <sstream>
#include <regex>
+#include <android-base/file.h>
#include <android-base/parseint.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <hidl-hash/Hash.h>
@@ -32,6 +33,7 @@
#include <private/android_filesystem_config.h>
#include <sys/stat.h>
#include <vintf/HalManifest.h>
+#include <vintf/parse_string.h>
#include <vintf/parse_xml.h>
#include "Lshal.h"
@@ -48,6 +50,10 @@
namespace android {
namespace lshal {
+vintf::SchemaType toSchemaType(Partition p) {
+ return (p == Partition::SYSTEM) ? vintf::SchemaType::FRAMEWORK : vintf::SchemaType::DEVICE;
+}
+
NullableOStream<std::ostream> ListCommand::out() const {
return mLshal.out();
}
@@ -64,13 +70,7 @@
}
std::string ListCommand::parseCmdline(pid_t pid) const {
- std::ifstream ifs("/proc/" + std::to_string(pid) + "/cmdline");
- std::string cmdline;
- if (!ifs.is_open()) {
- return "";
- }
- ifs >> cmdline;
- return cmdline;
+ return android::procpartition::getCmdline(pid);
}
const std::string &ListCommand::getCmdline(pid_t pid) {
@@ -89,6 +89,42 @@
}), pids->end());
}
+Partition ListCommand::getPartition(pid_t pid) {
+ auto it = mPartitions.find(pid);
+ if (it != mPartitions.end()) {
+ return it->second;
+ }
+ Partition partition = android::procpartition::getPartition(pid);
+ mPartitions.emplace(pid, partition);
+ return partition;
+}
+
+// Give sensible defaults when nothing can be inferred from runtime.
+// process: Partition inferred from executable location or cmdline.
+Partition ListCommand::resolvePartition(Partition process, const FQName& fqName) const {
+ if (fqName.inPackage("vendor") ||
+ fqName.inPackage("com")) {
+ return Partition::VENDOR;
+ }
+
+ if (fqName.inPackage("android.frameworks") ||
+ fqName.inPackage("android.system") ||
+ fqName.inPackage("android.hidl")) {
+ return Partition::SYSTEM;
+ }
+
+ // Some android.hardware HALs are served from system. Check the value from executable
+ // location / cmdline first.
+ if (fqName.inPackage("android.hardware")) {
+ if (process != Partition::UNKNOWN) {
+ return process;
+ }
+ return Partition::VENDOR;
+ }
+
+ return process;
+}
+
static bool scanBinderContext(pid_t pid,
const std::string &contextName,
std::function<void(const std::string&)> eachLine) {
@@ -209,6 +245,9 @@
entry.clientCmdlines.push_back(this->getCmdline(pid));
}
}
+ for (TableEntry& entry : table) {
+ entry.partition = getPartition(entry.serverPid);
+ }
});
// use a double for loop here because lshal doesn't care about efficiency.
for (TableEntry &packageEntry : mImplementationsTable) {
@@ -256,18 +295,10 @@
void ListCommand::dumpVintf(const NullableOStream<std::ostream>& out) const {
using vintf::operator|=;
- out << "<!-- " << std::endl
- << " This is a skeleton device manifest. Notes: " << std::endl
- << " 1. android.hidl.*, android.frameworks.*, android.system.* are not included." << std::endl
- << " 2. If a HAL is supported in both hwbinder and passthrough transport, " << std::endl
- << " only hwbinder is shown." << std::endl
- << " 3. It is likely that HALs in passthrough transport does not have" << std::endl
- << " <interface> declared; users will have to write them by hand." << std::endl
- << " 4. A HAL with lower minor version can be overridden by a HAL with" << std::endl
- << " higher minor version if they have the same name and major version." << std::endl
- << "-->" << std::endl;
+ using vintf::operator<<;
vintf::HalManifest manifest;
+ manifest.setType(toSchemaType(mVintfPartition));
forEachTable([this, &manifest] (const Table &table) {
for (const TableEntry &entry : table) {
@@ -284,12 +315,23 @@
<< "' is not a valid FQName." << std::endl;
continue;
}
- // Strip out system libs.
- if (fqName.inPackage("android.hidl") ||
- fqName.inPackage("android.frameworks") ||
- fqName.inPackage("android.system")) {
+
+ if (fqName.package() == gIBaseFqName.package()) {
+ continue; // always remove IBase from manifest
+ }
+
+ Partition partition = resolvePartition(entry.partition, fqName);
+
+ if (partition == Partition::UNKNOWN) {
+ err() << "Warning: Cannot guess the partition of instance " << fqInstanceName
+ << ". It is removed from the generated manifest." << std::endl;
continue;
}
+
+ if (partition != mVintfPartition) {
+ continue; // strip out instances that is in a different partition.
+ }
+
std::string interfaceName =
&table == &mImplementationsTable ? "" : fqName.name();
std::string instanceName =
@@ -361,9 +403,22 @@
}
}
});
+ out << "<!-- " << std::endl
+ << " This is a skeleton " << manifest.type() << " manifest. Notes: " << std::endl
+ << INIT_VINTF_NOTES
+ << "-->" << std::endl;
out << vintf::gHalManifestConverter(manifest, vintf::SerializeFlag::HALS_ONLY);
}
+std::string ListCommand::INIT_VINTF_NOTES{
+ " 1. If a HAL is supported in both hwbinder and passthrough transport, \n"
+ " only hwbinder is shown.\n"
+ " 2. It is likely that HALs in passthrough transport does not have\n"
+ " <interface> declared; users will have to write them by hand.\n"
+ " 3. A HAL with lower minor version can be overridden by a HAL with\n"
+ " higher minor version if they have the same name and major version.\n"
+};
+
static Architecture fromBaseArchitecture(::android::hidl::base::V1_0::DebugInfo::Architecture a) {
switch (a) {
case ::android::hidl::base::V1_0::DebugInfo::Architecture::IS_64BIT:
@@ -710,9 +765,18 @@
// long options without short alternatives
mOptions.push_back({'\0', "init-vintf", no_argument, v++, [](ListCommand* thiz, const char* arg) {
thiz->mVintf = true;
+ if (thiz->mVintfPartition == Partition::UNKNOWN)
+ thiz->mVintfPartition = Partition::VENDOR;
if (arg) thiz->mFileOutputPath = arg;
return OK;
}, "form a skeleton HAL manifest to specified file,\nor stdout if no file specified."});
+ mOptions.push_back({'\0', "init-vintf-partition", required_argument, v++, [](ListCommand* thiz, const char* arg) {
+ if (!arg) return USAGE;
+ thiz->mVintfPartition = android::procpartition::parsePartition(arg);
+ if (thiz->mVintfPartition == Partition::UNKNOWN) return USAGE;
+ return OK;
+ }, "Specify the partition of the HAL manifest\ngenerated by --init-vintf.\n"
+ "Valid values are 'system', 'vendor', and 'odm'. Default is 'vendor'."});
mOptions.push_back({'\0', "sort", required_argument, v++, [](ListCommand* thiz, const char* arg) {
if (strcmp(arg, "interface") == 0 || strcmp(arg, "i") == 0) {
thiz->mSortColumn = TableEntry::sortByInterfaceName;
diff --git a/cmds/lshal/ListCommand.h b/cmds/lshal/ListCommand.h
index 7e252fc..1e85ea0 100644
--- a/cmds/lshal/ListCommand.h
+++ b/cmds/lshal/ListCommand.h
@@ -26,6 +26,7 @@
#include <android-base/macros.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <hidl-util/FQName.h>
#include "Command.h"
#include "NullableOStream.h"
@@ -75,6 +76,8 @@
// key: value returned by getopt_long
using RegisteredOptions = std::vector<RegisteredOption>;
+ static std::string INIT_VINTF_NOTES;
+
protected:
Status parseArgs(const Arg &arg);
Status fetch();
@@ -104,10 +107,14 @@
// Read and return /proc/{pid}/cmdline.
virtual std::string parseCmdline(pid_t pid) const;
// Return /proc/{pid}/cmdline if it exists, else empty string.
- const std::string &getCmdline(pid_t pid);
+ const std::string& getCmdline(pid_t pid);
// Call getCmdline on all pid in pids. If it returns empty string, the process might
// have died, and the pid is removed from pids.
void removeDeadProcesses(Pids *pids);
+
+ virtual Partition getPartition(pid_t pid);
+ Partition resolvePartition(Partition processPartition, const FQName& fqName) const;
+
void forEachTable(const std::function<void(Table &)> &f);
void forEachTable(const std::function<void(const Table &)> &f) const;
@@ -125,8 +132,9 @@
bool mEmitDebugInfo = false;
- // If true, output in VINTF format.
+ // If true, output in VINTF format. Output only entries from the specified partition.
bool mVintf = false;
+ Partition mVintfPartition = Partition::UNKNOWN;
// If true, explanatory text are not emitted.
bool mNeat = false;
@@ -139,6 +147,9 @@
// Cache for getPidInfo.
std::map<pid_t, PidInfo> mCachedPidInfos;
+ // Cache for getPartition.
+ std::map<pid_t, Partition> mPartitions;
+
RegisteredOptions mOptions;
// All selected columns
std::vector<TableColumnType> mSelectedColumns;
diff --git a/cmds/lshal/TableEntry.h b/cmds/lshal/TableEntry.h
index 69206cc..24ea438 100644
--- a/cmds/lshal/TableEntry.h
+++ b/cmds/lshal/TableEntry.h
@@ -23,11 +23,14 @@
#include <vector>
#include <iostream>
+#include <procpartition/procpartition.h>
+
#include "TextTable.h"
namespace android {
namespace lshal {
+using android::procpartition::Partition;
using Pids = std::vector<int32_t>;
enum : unsigned int {
@@ -77,6 +80,7 @@
Architecture arch{ARCH_UNKNOWN};
// empty: unknown, all zeros: unreleased, otherwise: released
std::string hash{};
+ Partition partition{Partition::UNKNOWN};
static bool sortByInterfaceName(const TableEntry &a, const TableEntry &b) {
return a.interfaceName < b.interfaceName;
diff --git a/cmds/lshal/libprocpartition/Android.bp b/cmds/lshal/libprocpartition/Android.bp
new file mode 100644
index 0000000..9592111
--- /dev/null
+++ b/cmds/lshal/libprocpartition/Android.bp
@@ -0,0 +1,30 @@
+// Copyright (C) 2018 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.
+
+cc_library_static {
+ name: "libprocpartition",
+ shared_libs: [
+ "libbase",
+ ],
+ srcs: [
+ "procpartition.cpp",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ export_include_dirs: [
+ "include",
+ ]
+}
diff --git a/cmds/lshal/libprocpartition/include/procpartition/procpartition.h b/cmds/lshal/libprocpartition/include/procpartition/procpartition.h
new file mode 100644
index 0000000..7e86432
--- /dev/null
+++ b/cmds/lshal/libprocpartition/include/procpartition/procpartition.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 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 FRAMEWORK_NATIVE_CMDS_LSHAL_PROCPARTITION_H_
+#define FRAMEWORK_NATIVE_CMDS_LSHAL_PROCPARTITION_H_
+
+#include <sys/types.h>
+
+#include <string>
+#include <iostream>
+
+namespace android {
+namespace procpartition {
+
+enum class Partition {
+ UNKNOWN = 0,
+ SYSTEM,
+ VENDOR,
+ ODM
+};
+
+std::ostream& operator<<(std::ostream& os, Partition p);
+Partition parsePartition(const std::string& s);
+
+// Return the path that /proc/<pid>/exe points to.
+std::string getExe(pid_t pid);
+// Return the content of /proc/<pid>/cmdline.
+std::string getCmdline(pid_t pid);
+// Infer the partition of a process from /proc/<pid>/exe and /proc/<pid>/cmdline.
+Partition getPartition(pid_t pid);
+
+} // namespace procpartition
+} // namespace android
+
+#endif // FRAMEWORK_NATIVE_CMDS_LSHAL_PROCPARTITION_H_
diff --git a/cmds/lshal/libprocpartition/procpartition.cpp b/cmds/lshal/libprocpartition/procpartition.cpp
new file mode 100644
index 0000000..8ca458a
--- /dev/null
+++ b/cmds/lshal/libprocpartition/procpartition.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#include <procpartition/procpartition.h>
+
+#include <android-base/file.h>
+
+namespace android {
+namespace procpartition {
+
+std::ostream& operator<<(std::ostream& os, Partition p) {
+ switch (p) {
+ case Partition::SYSTEM: return os << "system";
+ case Partition::VENDOR: return os << "vendor";
+ case Partition::ODM: return os << "odm";
+ case Partition::UNKNOWN: // fallthrough
+ default:
+ return os << "(unknown)";
+ }
+}
+
+std::string getExe(pid_t pid) {
+ std::string exe;
+ std::string real;
+ if (!android::base::Readlink("/proc/" + std::to_string(pid) + "/exe", &exe)) {
+ return "";
+ }
+ if (!android::base::Realpath(exe, &real)) {
+ return "";
+ }
+ return real;
+}
+
+std::string getCmdline(pid_t pid) {
+ std::string content;
+ if (!android::base::ReadFileToString("/proc/" + std::to_string(pid) + "/cmdline", &content,
+ false /* follow symlinks */)) {
+ return "";
+ }
+ return content;
+}
+
+Partition parsePartition(const std::string& s) {
+ if (s == "system") {
+ return Partition::SYSTEM;
+ }
+ if (s == "vendor") {
+ return Partition::VENDOR;
+ }
+ if (s == "odm") {
+ return Partition::ODM;
+ }
+ return Partition::UNKNOWN;
+}
+
+Partition getPartitionFromRealpath(const std::string& path) {
+ if (path == "/system/bin/app_process64" ||
+ path == "/system/bin/app_process32") {
+
+ return Partition::UNKNOWN; // cannot determine
+ }
+ size_t backslash = path.find_first_of('/', 1);
+ std::string partition = (backslash != std::string::npos) ? path.substr(1, backslash - 1) : path;
+
+ return parsePartition(partition);
+}
+
+Partition getPartitionFromCmdline(pid_t pid) {
+ const auto& cmdline = getCmdline(pid);
+ if (cmdline == "system_server") {
+ return Partition::SYSTEM;
+ }
+ if (cmdline.empty() || cmdline.front() != '/') {
+ return Partition::UNKNOWN;
+ }
+ return getPartitionFromRealpath(cmdline);
+}
+
+Partition getPartitionFromExe(pid_t pid) {
+ const auto& real = getExe(pid);
+ if (real.empty() || real.front() != '/') {
+ return Partition::UNKNOWN;
+ }
+ return getPartitionFromRealpath(real);
+}
+
+
+Partition getPartition(pid_t pid) {
+ Partition partition = getPartitionFromExe(pid);
+ if (partition == Partition::UNKNOWN) {
+ partition = getPartitionFromCmdline(pid);
+ }
+ return partition;
+}
+
+} // namespace procpartition
+} // namespace android
diff --git a/cmds/lshal/test.cpp b/cmds/lshal/test.cpp
index 9220fc0..4fa941e 100644
--- a/cmds/lshal/test.cpp
+++ b/cmds/lshal/test.cpp
@@ -206,6 +206,7 @@
MOCK_METHOD0(postprocess, void());
MOCK_CONST_METHOD2(getPidInfo, bool(pid_t, PidInfo*));
MOCK_CONST_METHOD1(parseCmdline, std::string(pid_t));
+ MOCK_METHOD1(getPartition, Partition(pid_t));
};
class ListParseArgsTest : public ::testing::Test {
@@ -333,6 +334,7 @@
table.setDescription("[fake description " + std::to_string(i++) + "]");
});
}));
+ ON_CALL(*mockList, getPartition(_)).WillByDefault(Return(Partition::VENDOR));
}
void initMockServiceManager() {
@@ -418,17 +420,7 @@
TEST_F(ListTest, DumpVintf) {
const std::string expected =
"<!-- \n"
- " This is a skeleton device manifest. Notes: \n"
- " 1. android.hidl.*, android.frameworks.*, android.system.* are not included.\n"
- " 2. If a HAL is supported in both hwbinder and passthrough transport, \n"
- " only hwbinder is shown.\n"
- " 3. It is likely that HALs in passthrough transport does not have\n"
- " <interface> declared; users will have to write them by hand.\n"
- " 4. A HAL with lower minor version can be overridden by a HAL with\n"
- " higher minor version if they have the same name and major version.\n"
- " 5. sepolicy version is set to 0.0. It is recommended that the entry\n"
- " is removed from the manifest file and written by assemble_vintf\n"
- " at build time.\n"
+ " This is a skeleton device manifest. Notes: \n" + ListCommand::INIT_VINTF_NOTES +
"-->\n"
"<manifest version=\"1.0\" type=\"device\">\n"
" <hal format=\"hidl\">\n"
@@ -477,9 +469,6 @@
" <transport arch=\"32\">passthrough</transport>\n"
" <version>6.0</version>\n"
" </hal>\n"
- " <sepolicy>\n"
- " <version>0.0</version>\n"
- " </sepolicy>\n"
"</manifest>\n";
optind = 1; // mimic Lshal::parseArg()
diff --git a/libs/vr/libdvr/tests/Android.bp b/libs/vr/libdvr/tests/Android.bp
index e8aa6b7..8c81e8d 100644
--- a/libs/vr/libdvr/tests/Android.bp
+++ b/libs/vr/libdvr/tests/Android.bp
@@ -36,7 +36,6 @@
cc_test {
srcs: [
- "dvr_buffer_queue-test.cpp",
"dvr_display_manager-test.cpp",
"dvr_named_buffer-test.cpp",
],
@@ -53,3 +52,25 @@
],
name: "dvr_api-test",
}
+
+cc_test {
+ srcs: [
+ "dvr_buffer_queue-test.cpp",
+ ],
+
+ header_libs: [
+ "libdvr_headers",
+ "libbase_headers",
+ ],
+ shared_libs: [
+ "liblog",
+ "libnativewindow",
+ ],
+ cflags: [
+ "-DLOG_TAG=\"dvr_buffer_queue-test\"",
+ "-DTRACE=0",
+ "-O0",
+ "-g",
+ ],
+ name: "dvr_buffer_queue-test",
+}
diff --git a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
index 62cd8d4..ff0588c 100644
--- a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
+++ b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
@@ -1,6 +1,7 @@
+#include <android-base/unique_fd.h>
#include <android/log.h>
#include <android/native_window.h>
-#include <android-base/unique_fd.h>
+#include <dlfcn.h>
#include <dvr/dvr_api.h>
#include <dvr/dvr_buffer_queue.h>
@@ -13,6 +14,8 @@
#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#endif
+#define ASSERT_NOT_NULL(x) ASSERT_TRUE((x) != nullptr)
+
#ifndef ALOGD_IF
#define ALOGD_IF(cond, ...) \
((__predict_false(cond)) ? ((void)ALOGD(__VA_ARGS__)) : (void)0)
@@ -40,11 +43,26 @@
}
protected:
+ void SetUp() override {
+ platform_handle_ = dlopen("libdvr.so", RTLD_NOW | RTLD_LOCAL);
+ ASSERT_NOT_NULL(platform_handle_) << "Dvr shared library missing.";
+
+ auto dvr_get_api = reinterpret_cast<decltype(&dvrGetApi)>(
+ dlsym(platform_handle_, "dvrGetApi"));
+ ASSERT_NOT_NULL(dvr_get_api) << "Platform library missing dvrGetApi.";
+
+ ASSERT_EQ(dvr_get_api(&api_, sizeof(api_), /*version=*/1), 0)
+ << "Unable to find compatible Dvr API.";
+ }
+
void TearDown() override {
if (write_queue_ != nullptr) {
- dvrWriteBufferQueueDestroy(write_queue_);
+ api_.WriteBufferQueueDestroy(write_queue_);
write_queue_ = nullptr;
}
+ if (platform_handle_ != nullptr) {
+ dlclose(platform_handle_);
+ }
}
void HandleBufferAvailable() {
@@ -61,88 +79,90 @@
DvrWriteBufferQueue* write_queue_{nullptr};
int buffer_available_count_{0};
int buffer_removed_count_{0};
+ void* platform_handle_{nullptr};
+ DvrApi_v1 api_{};
};
TEST_F(DvrBufferQueueTest, WriteQueueCreateDestroy) {
- int ret = dvrWriteBufferQueueCreate(
+ int ret = api_.WriteBufferQueueCreate(
kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
/*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
ASSERT_EQ(0, ret);
- dvrWriteBufferQueueDestroy(write_queue_);
+ api_.WriteBufferQueueDestroy(write_queue_);
write_queue_ = nullptr;
}
TEST_F(DvrBufferQueueTest, WriteQueueGetCapacity) {
- int ret = dvrWriteBufferQueueCreate(
+ int ret = api_.WriteBufferQueueCreate(
kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
ASSERT_EQ(0, ret);
- size_t capacity = dvrWriteBufferQueueGetCapacity(write_queue_);
+ size_t capacity = api_.WriteBufferQueueGetCapacity(write_queue_);
ALOGD_IF(TRACE, "TestWrite_QueueGetCapacity, capacity=%zu", capacity);
ASSERT_EQ(kQueueCapacity, capacity);
}
TEST_F(DvrBufferQueueTest, CreateReadQueueFromWriteQueue) {
- int ret = dvrWriteBufferQueueCreate(
+ int ret = api_.WriteBufferQueueCreate(
kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
/*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
ASSERT_EQ(0, ret);
DvrReadBufferQueue* read_queue = nullptr;
- ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
+ ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
ASSERT_EQ(0, ret);
ASSERT_NE(nullptr, read_queue);
- dvrReadBufferQueueDestroy(read_queue);
+ api_.ReadBufferQueueDestroy(read_queue);
}
TEST_F(DvrBufferQueueTest, CreateReadQueueFromReadQueue) {
- int ret = dvrWriteBufferQueueCreate(
+ int ret = api_.WriteBufferQueueCreate(
kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
/*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
ASSERT_EQ(0, ret);
DvrReadBufferQueue* read_queue1 = nullptr;
DvrReadBufferQueue* read_queue2 = nullptr;
- ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue1);
+ ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue1);
ASSERT_EQ(0, ret);
ASSERT_NE(nullptr, read_queue1);
- ret = dvrReadBufferQueueCreateReadQueue(read_queue1, &read_queue2);
+ ret = api_.ReadBufferQueueCreateReadQueue(read_queue1, &read_queue2);
ASSERT_EQ(0, ret);
ASSERT_NE(nullptr, read_queue2);
ASSERT_NE(read_queue1, read_queue2);
- dvrReadBufferQueueDestroy(read_queue1);
- dvrReadBufferQueueDestroy(read_queue2);
+ api_.ReadBufferQueueDestroy(read_queue1);
+ api_.ReadBufferQueueDestroy(read_queue2);
}
TEST_F(DvrBufferQueueTest, GainBuffer) {
- int ret = dvrWriteBufferQueueCreate(
+ int ret = api_.WriteBufferQueueCreate(
kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
ASSERT_EQ(ret, 0);
DvrWriteBuffer* wb = nullptr;
- EXPECT_FALSE(dvrWriteBufferIsValid(wb));
+ EXPECT_FALSE(api_.WriteBufferIsValid(wb));
DvrNativeBufferMetadata meta;
int fence_fd = -1;
- ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb, &meta,
- &fence_fd);
+ ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb, &meta,
+ &fence_fd);
ASSERT_EQ(ret, 0);
EXPECT_EQ(fence_fd, -1);
EXPECT_NE(wb, nullptr);
- EXPECT_TRUE(dvrWriteBufferIsValid(wb));
+ EXPECT_TRUE(api_.WriteBufferIsValid(wb));
}
TEST_F(DvrBufferQueueTest, AcquirePostGainRelease) {
- int ret = dvrWriteBufferQueueCreate(
+ int ret = api_.WriteBufferQueueCreate(
kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
ASSERT_EQ(ret, 0);
@@ -154,40 +174,40 @@
DvrNativeBufferMetadata meta2;
int fence_fd = -1;
- ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
+ ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
ASSERT_EQ(ret, 0);
ASSERT_NE(read_queue, nullptr);
- dvrReadBufferQueueSetBufferAvailableCallback(read_queue,
- &BufferAvailableCallback, this);
+ api_.ReadBufferQueueSetBufferAvailableCallback(
+ read_queue, &BufferAvailableCallback, this);
// Gain buffer for writing.
- ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb, &meta1,
- &fence_fd);
+ ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb,
+ &meta1, &fence_fd);
ASSERT_EQ(ret, 0);
ASSERT_NE(wb, nullptr);
- ASSERT_TRUE(dvrWriteBufferIsValid(wb));
+ ASSERT_TRUE(api_.WriteBufferIsValid(wb));
ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, gain buffer %p, fence_fd=%d",
wb, fence_fd);
android::base::unique_fd release_fence(fence_fd);
// Post buffer to the read_queue.
meta1.timestamp = 42;
- ret = dvrWriteBufferQueuePostBuffer(write_queue_, wb, &meta1, /*fence=*/-1);
+ ret = api_.WriteBufferQueuePostBuffer(write_queue_, wb, &meta1, /*fence=*/-1);
ASSERT_EQ(ret, 0);
- ASSERT_FALSE(dvrWriteBufferIsValid(wb));
+ ASSERT_FALSE(api_.WriteBufferIsValid(wb));
wb = nullptr;
// Acquire buffer for reading.
- ret = dvrReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10, &rb, &meta2,
- &fence_fd);
+ ret = api_.ReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10, &rb,
+ &meta2, &fence_fd);
ASSERT_EQ(ret, 0);
ASSERT_NE(rb, nullptr);
// Dequeue is successfully, BufferAvailableCallback should be fired once.
ASSERT_EQ(buffer_available_count_, 1);
- ASSERT_TRUE(dvrReadBufferIsValid(rb));
+ ASSERT_TRUE(api_.ReadBufferIsValid(rb));
// Metadata should be passed along from producer to consumer properly.
ASSERT_EQ(meta1.timestamp, meta2.timestamp);
@@ -198,31 +218,31 @@
android::base::unique_fd acquire_fence(fence_fd);
// Release buffer to the write_queue.
- ret = dvrReadBufferQueueReleaseBuffer(read_queue, rb, &meta2,
- /*release_fence_fd=*/-1);
+ ret = api_.ReadBufferQueueReleaseBuffer(read_queue, rb, &meta2,
+ /*release_fence_fd=*/-1);
ASSERT_EQ(ret, 0);
- ASSERT_FALSE(dvrReadBufferIsValid(rb));
+ ASSERT_FALSE(api_.ReadBufferIsValid(rb));
rb = nullptr;
// TODO(b/34387835) Currently buffer allocation has to happen after all queues
// are initialized.
- size_t capacity = dvrReadBufferQueueGetCapacity(read_queue);
+ size_t capacity = api_.ReadBufferQueueGetCapacity(read_queue);
ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, capacity=%zu", capacity);
ASSERT_EQ(kQueueCapacity, capacity);
- dvrReadBufferQueueDestroy(read_queue);
+ api_.ReadBufferQueueDestroy(read_queue);
}
TEST_F(DvrBufferQueueTest, GetANativeWindow) {
- int ret = dvrWriteBufferQueueCreate(
+ int ret = api_.WriteBufferQueueCreate(
kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
/*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
ASSERT_EQ(0, ret);
ASSERT_NE(nullptr, write_queue_);
ANativeWindow* window = nullptr;
- ret = dvrWriteBufferQueueGetANativeWindow(write_queue_, &window);
+ ret = api_.WriteBufferQueueGetANativeWindow(write_queue_, &window);
ASSERT_EQ(0, ret);
ASSERT_NE(nullptr, window);
@@ -238,7 +258,7 @@
// Before each dequeue operation, we resize the buffer queue and expect the
// queue always return buffer with desired dimension.
TEST_F(DvrBufferQueueTest, ResizeBuffer) {
- int ret = dvrWriteBufferQueueCreate(
+ int ret = api_.WriteBufferQueueCreate(
kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
ASSERT_EQ(0, ret);
@@ -255,37 +275,37 @@
AHardwareBuffer* ahb3 = nullptr;
AHardwareBuffer_Desc buffer_desc;
- ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
+ ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
ASSERT_EQ(0, ret);
ASSERT_NE(nullptr, read_queue);
- dvrReadBufferQueueSetBufferRemovedCallback(read_queue, &BufferRemovedCallback,
- this);
+ api_.ReadBufferQueueSetBufferRemovedCallback(read_queue,
+ &BufferRemovedCallback, this);
// Handle all pending events on the read queue.
- ret = dvrReadBufferQueueHandleEvents(read_queue);
+ ret = api_.ReadBufferQueueHandleEvents(read_queue);
ASSERT_EQ(0, ret);
- size_t capacity = dvrReadBufferQueueGetCapacity(read_queue);
+ size_t capacity = api_.ReadBufferQueueGetCapacity(read_queue);
ALOGD_IF(TRACE, "TestResizeBuffer, capacity=%zu", capacity);
ASSERT_EQ(kQueueCapacity, capacity);
// Resize before dequeuing.
constexpr uint32_t w1 = 10;
- ret = dvrWriteBufferQueueResizeBuffer(write_queue_, w1, kBufferHeight);
+ ret = api_.WriteBufferQueueResizeBuffer(write_queue_, w1, kBufferHeight);
ASSERT_EQ(0, ret);
// Gain first buffer for writing. All buffers will be resized.
- ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb1, &meta,
- &fence_fd);
+ ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb1,
+ &meta, &fence_fd);
ASSERT_EQ(0, ret);
- ASSERT_TRUE(dvrWriteBufferIsValid(wb1));
+ ASSERT_TRUE(api_.WriteBufferIsValid(wb1));
ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p", wb1);
android::base::unique_fd release_fence1(fence_fd);
// Check the buffer dimension.
- ret = dvrWriteBufferGetAHardwareBuffer(wb1, &ahb1);
+ ret = api_.WriteBufferGetAHardwareBuffer(wb1, &ahb1);
ASSERT_EQ(0, ret);
AHardwareBuffer_describe(ahb1, &buffer_desc);
ASSERT_EQ(w1, buffer_desc.width);
@@ -294,26 +314,26 @@
// For the first resize, all buffers are reallocated.
int expected_buffer_removed_count = kQueueCapacity;
- ret = dvrReadBufferQueueHandleEvents(read_queue);
+ ret = api_.ReadBufferQueueHandleEvents(read_queue);
ASSERT_EQ(0, ret);
ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);
// Resize the queue. We are testing with blob format, keep height to be 1.
constexpr uint32_t w2 = 20;
- ret = dvrWriteBufferQueueResizeBuffer(write_queue_, w2, kBufferHeight);
+ ret = api_.WriteBufferQueueResizeBuffer(write_queue_, w2, kBufferHeight);
ASSERT_EQ(0, ret);
// The next buffer we dequeued should have new width.
- ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb2, &meta,
- &fence_fd);
+ ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb2,
+ &meta, &fence_fd);
ASSERT_EQ(0, ret);
- ASSERT_TRUE(dvrWriteBufferIsValid(wb2));
+ ASSERT_TRUE(api_.WriteBufferIsValid(wb2));
ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb2,
fence_fd);
android::base::unique_fd release_fence2(fence_fd);
// Check the buffer dimension, should be new width
- ret = dvrWriteBufferGetAHardwareBuffer(wb2, &ahb2);
+ ret = api_.WriteBufferGetAHardwareBuffer(wb2, &ahb2);
ASSERT_EQ(0, ret);
AHardwareBuffer_describe(ahb2, &buffer_desc);
ASSERT_EQ(w2, buffer_desc.width);
@@ -321,26 +341,26 @@
// For the second resize, all but one buffers are reallocated.
expected_buffer_removed_count += (kQueueCapacity - 1);
- ret = dvrReadBufferQueueHandleEvents(read_queue);
+ ret = api_.ReadBufferQueueHandleEvents(read_queue);
ASSERT_EQ(0, ret);
ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);
// Resize the queue for the third time.
constexpr uint32_t w3 = 30;
- ret = dvrWriteBufferQueueResizeBuffer(write_queue_, w3, kBufferHeight);
+ ret = api_.WriteBufferQueueResizeBuffer(write_queue_, w3, kBufferHeight);
ASSERT_EQ(0, ret);
// The next buffer we dequeued should have new width.
- ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb3, &meta,
- &fence_fd);
+ ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb3,
+ &meta, &fence_fd);
ASSERT_EQ(0, ret);
- ASSERT_TRUE(dvrWriteBufferIsValid(wb3));
+ ASSERT_TRUE(api_.WriteBufferIsValid(wb3));
ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb3,
fence_fd);
android::base::unique_fd release_fence3(fence_fd);
// Check the buffer dimension, should be new width
- ret = dvrWriteBufferGetAHardwareBuffer(wb3, &ahb3);
+ ret = api_.WriteBufferGetAHardwareBuffer(wb3, &ahb3);
ASSERT_EQ(0, ret);
AHardwareBuffer_describe(ahb3, &buffer_desc);
ASSERT_EQ(w3, buffer_desc.width);
@@ -348,26 +368,26 @@
// For the third resize, all but two buffers are reallocated.
expected_buffer_removed_count += (kQueueCapacity - 2);
- ret = dvrReadBufferQueueHandleEvents(read_queue);
+ ret = api_.ReadBufferQueueHandleEvents(read_queue);
ASSERT_EQ(0, ret);
ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);
- dvrReadBufferQueueDestroy(read_queue);
+ api_.ReadBufferQueueDestroy(read_queue);
}
TEST_F(DvrBufferQueueTest, ReadQueueEventFd) {
- int ret = dvrWriteBufferQueueCreate(
+ int ret = api_.WriteBufferQueueCreate(
kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
ASSERT_EQ(0, ret);
DvrReadBufferQueue* read_queue = nullptr;
- ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
+ ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
ASSERT_EQ(0, ret);
ASSERT_NE(nullptr, read_queue);
- int event_fd = dvrReadBufferQueueGetEventFd(read_queue);
+ int event_fd = api_.ReadBufferQueueGetEventFd(read_queue);
ASSERT_GT(event_fd, 0);
}
@@ -375,14 +395,14 @@
// Dvr{Read,Write}Buffer(s) during their lifecycles. And for the same buffer_id,
// the corresponding AHardwareBuffer handle stays the same.
TEST_F(DvrBufferQueueTest, StableBufferIdAndHardwareBuffer) {
- int ret = dvrWriteBufferQueueCreate(
+ int ret = api_.WriteBufferQueueCreate(
kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
ASSERT_EQ(0, ret);
int fence_fd = -1;
DvrReadBufferQueue* read_queue = nullptr;
- EXPECT_EQ(0, dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue));
+ EXPECT_EQ(0, api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue));
// Read buffers.
std::array<DvrReadBuffer*, kQueueCapacity> rbs;
@@ -400,16 +420,16 @@
// This test runs the following operations many many times. Thus we prefer to
// use ASSERT_XXX rather than EXPECT_XXX to avoid spamming the output.
std::function<void(size_t i)> Gain = [&](size_t i) {
- int ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/10,
- &wbs[i], &metas[i], &fence_fd);
+ int ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/10,
+ &wbs[i], &metas[i], &fence_fd);
ASSERT_EQ(ret, 0);
ASSERT_LT(fence_fd, 0); // expect invalid fence.
- ASSERT_TRUE(dvrWriteBufferIsValid(wbs[i]));
- int buffer_id = dvrWriteBufferGetId(wbs[i]);
+ ASSERT_TRUE(api_.WriteBufferIsValid(wbs[i]));
+ int buffer_id = api_.WriteBufferGetId(wbs[i]);
ASSERT_GT(buffer_id, 0);
AHardwareBuffer* hb = nullptr;
- ASSERT_EQ(0, dvrWriteBufferGetAHardwareBuffer(wbs[i], &hb));
+ ASSERT_EQ(0, api_.WriteBufferGetAHardwareBuffer(wbs[i], &hb));
auto whb_it = whbs.find(buffer_id);
if (whb_it == whbs.end()) {
@@ -425,26 +445,26 @@
};
std::function<void(size_t i)> Post = [&](size_t i) {
- ASSERT_TRUE(dvrWriteBufferIsValid(wbs[i]));
+ ASSERT_TRUE(api_.WriteBufferIsValid(wbs[i]));
metas[i].timestamp++;
- int ret = dvrWriteBufferQueuePostBuffer(write_queue_, wbs[i], &metas[i],
- /*fence=*/-1);
+ int ret = api_.WriteBufferQueuePostBuffer(write_queue_, wbs[i], &metas[i],
+ /*fence=*/-1);
ASSERT_EQ(ret, 0);
};
std::function<void(size_t i)> Acquire = [&](size_t i) {
- int ret = dvrReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10,
- &rbs[i], &metas[i], &fence_fd);
+ int ret = api_.ReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10,
+ &rbs[i], &metas[i], &fence_fd);
ASSERT_EQ(ret, 0);
ASSERT_LT(fence_fd, 0); // expect invalid fence.
- ASSERT_TRUE(dvrReadBufferIsValid(rbs[i]));
+ ASSERT_TRUE(api_.ReadBufferIsValid(rbs[i]));
- int buffer_id = dvrReadBufferGetId(rbs[i]);
+ int buffer_id = api_.ReadBufferGetId(rbs[i]);
ASSERT_GT(buffer_id, 0);
AHardwareBuffer* hb = nullptr;
- ASSERT_EQ(0, dvrReadBufferGetAHardwareBuffer(rbs[i], &hb));
+ ASSERT_EQ(0, api_.ReadBufferGetAHardwareBuffer(rbs[i], &hb));
auto rhb_it = rhbs.find(buffer_id);
if (rhb_it == rhbs.end()) {
@@ -460,10 +480,10 @@
};
std::function<void(size_t i)> Release = [&](size_t i) {
- ASSERT_TRUE(dvrReadBufferIsValid(rbs[i]));
+ ASSERT_TRUE(api_.ReadBufferIsValid(rbs[i]));
- int ret = dvrReadBufferQueueReleaseBuffer(read_queue, rbs[i], &metas[i],
- /*release_fence_fd=*/-1);
+ int ret = api_.ReadBufferQueueReleaseBuffer(read_queue, rbs[i], &metas[i],
+ /*release_fence_fd=*/-1);
ASSERT_EQ(ret, 0);
};