Merge "Use synchronous transactions to simplify BBQ test" into main
diff --git a/cmds/dumpstate/DumpstateUtil.cpp b/cmds/dumpstate/DumpstateUtil.cpp
index aa42541..4842312 100644
--- a/cmds/dumpstate/DumpstateUtil.cpp
+++ b/cmds/dumpstate/DumpstateUtil.cpp
@@ -207,6 +207,9 @@
int PropertiesHelper::dry_run_ = -1;
int PropertiesHelper::unroot_ = -1;
int PropertiesHelper::parallel_run_ = -1;
+#if !defined(__ANDROID_VNDK__)
+int PropertiesHelper::strict_run_ = -1;
+#endif
bool PropertiesHelper::IsUserBuild() {
if (build_type_.empty()) {
@@ -237,6 +240,16 @@
return parallel_run_ == 1;
}
+#if !defined(__ANDROID_VNDK__)
+bool PropertiesHelper::IsStrictRun() {
+ if (strict_run_ == -1) {
+ // Defaults to using stricter timeouts.
+ strict_run_ = android::base::GetBoolProperty("dumpstate.strict_run", true) ? 1 : 0;
+ }
+ return strict_run_ == 1;
+}
+#endif
+
int DumpFileToFd(int out_fd, const std::string& title, const std::string& path) {
android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC)));
if (fd.get() < 0) {
diff --git a/cmds/dumpstate/DumpstateUtil.h b/cmds/dumpstate/DumpstateUtil.h
index b00c46e..6049e3e 100644
--- a/cmds/dumpstate/DumpstateUtil.h
+++ b/cmds/dumpstate/DumpstateUtil.h
@@ -193,11 +193,23 @@
*/
static bool IsParallelRun();
+ /*
+ * Strict-run mode is determined by the `dumpstate.strict_run` sysprop which
+ * will default to true. This results in shortened timeouts for flaky
+ * sections.
+ */
+#if !defined(__ANDROID_VNDK__)
+ static bool IsStrictRun();
+#endif
+
private:
static std::string build_type_;
static int dry_run_;
static int unroot_;
static int parallel_run_;
+#if !defined(__ANDROID_VNDK__)
+ static int strict_run_;
+#endif
};
/*
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index ed7b1b9..e132b35 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -822,9 +822,12 @@
RunCommandToFd(STDOUT_FILENO, "", {"uptime", "-p"},
CommandOptions::WithTimeout(1).Always().Build());
printf("Bugreport format version: %s\n", version_.c_str());
- printf("Dumpstate info: id=%d pid=%d dry_run=%d parallel_run=%d args=%s bugreport_mode=%s\n",
- id_, pid_, PropertiesHelper::IsDryRun(), PropertiesHelper::IsParallelRun(),
- options_->args.c_str(), options_->bugreport_mode_string.c_str());
+ printf(
+ "Dumpstate info: id=%d pid=%d dry_run=%d parallel_run=%d strict_run=%d args=%s "
+ "bugreport_mode=%s\n",
+ id_, pid_, PropertiesHelper::IsDryRun(), PropertiesHelper::IsParallelRun(),
+ PropertiesHelper::IsStrictRun(), options_->args.c_str(),
+ options_->bugreport_mode_string.c_str());
printf("\n");
}
@@ -1046,7 +1049,8 @@
MYLOGE("Could not open %s to dump incident report.\n", path.c_str());
return;
}
- RunCommandToFd(fd, "", {"incident", "-u"}, CommandOptions::WithTimeout(20).Build());
+ RunCommandToFd(fd, "", {"incident", "-u"},
+ CommandOptions::WithTimeout(PropertiesHelper::IsStrictRun() ? 20 : 120).Build());
bool empty = 0 == lseek(fd, 0, SEEK_END);
if (!empty) {
// Use a different name from "incident.proto"
@@ -3141,6 +3145,12 @@
MYLOGI("Running on dry-run mode (to disable it, call 'setprop dumpstate.dry_run false')\n");
}
+ if (PropertiesHelper::IsStrictRun()) {
+ MYLOGI(
+ "Running on strict-run mode, which has shorter timeouts "
+ "(to disable, call 'setprop dumpstate.strict_run false')\n");
+ }
+
MYLOGI("dumpstate info: id=%d, args='%s', bugreport_mode= %s bugreport format version: %s\n",
id_, options_->args.c_str(), options_->bugreport_mode_string.c_str(), version_.c_str());
diff --git a/cmds/servicemanager/Android.bp b/cmds/servicemanager/Android.bp
index fb69513..d73a30b 100644
--- a/cmds/servicemanager/Android.bp
+++ b/cmds/servicemanager/Android.bp
@@ -93,22 +93,9 @@
libfuzzer_options: [
"max_len=50000",
],
- },
-}
-
-// Adding this new fuzzer to test the corpus generated by record_binder
-cc_fuzz {
- name: "servicemanager_test_fuzzer",
- defaults: [
- "servicemanager_defaults",
- "service_fuzzer_defaults",
- ],
- host_supported: true,
- srcs: ["fuzzers/ServiceManagerTestFuzzer.cpp"],
- fuzz_config: {
- libfuzzer_options: [
- "max_len=50000",
+ cc: [
+ "smoreland@google.com",
+ "waghpawan@google.com",
],
},
- corpus: ["fuzzers/servicemamanager_fuzzer_corpus/*"],
}
diff --git a/cmds/servicemanager/fuzzers/ServiceManagerTestFuzzer.cpp b/cmds/servicemanager/fuzzers/ServiceManagerTestFuzzer.cpp
deleted file mode 100644
index e19b6eb..0000000
--- a/cmds/servicemanager/fuzzers/ServiceManagerTestFuzzer.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2023 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 <fuzzbinder/libbinder_driver.h>
-#include <utils/StrongPointer.h>
-
-#include "Access.h"
-#include "ServiceManager.h"
-
-using ::android::Access;
-using ::android::Parcel;
-using ::android::ServiceManager;
-using ::android::sp;
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- FuzzedDataProvider provider(data, size);
- auto accessPtr = std::make_unique<Access>();
- auto serviceManager = sp<ServiceManager>::make(std::move(accessPtr));
-
- // Reserved bytes
- provider.ConsumeBytes<uint8_t>(8);
- uint32_t code = provider.ConsumeIntegral<uint32_t>();
- uint32_t flag = provider.ConsumeIntegral<uint32_t>();
- std::vector<uint8_t> parcelData = provider.ConsumeRemainingBytes<uint8_t>();
-
- Parcel inputParcel;
- inputParcel.setData(parcelData.data(), parcelData.size());
-
- Parcel reply;
- serviceManager->transact(code, inputParcel, &reply, flag);
-
- serviceManager->clear();
-
- return 0;
-}
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_1 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_1
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_1
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_10 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_10
deleted file mode 100644
index 07319f8..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_10
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_11 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_11
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_11
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_12 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_12
deleted file mode 100644
index 07319f8..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_12
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_13 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_13
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_13
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_14 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_14
deleted file mode 100644
index 07319f8..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_14
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_15 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_15
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_15
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_16 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_16
deleted file mode 100644
index 07319f8..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_16
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_17 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_17
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_17
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_18 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_18
deleted file mode 100644
index 88ad474..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_18
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_19 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_19
deleted file mode 100644
index fae15a2..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_19
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_2 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_2
deleted file mode 100644
index e69ab49..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_2
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_20 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_20
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_20
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_21 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_21
deleted file mode 100644
index 88ad474..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_21
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_22 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_22
deleted file mode 100644
index fae15a2..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_22
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_23 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_23
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_23
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_24 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_24
deleted file mode 100644
index 88ad474..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_24
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_25 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_25
deleted file mode 100644
index fae15a2..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_25
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_26 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_26
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_26
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_27 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_27
deleted file mode 100644
index 88ad474..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_27
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_28 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_28
deleted file mode 100644
index fae15a2..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_28
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_29 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_29
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_29
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_3 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_3
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_3
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_30 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_30
deleted file mode 100644
index 88ad474..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_30
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_31 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_31
deleted file mode 100644
index fae15a2..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_31
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_32 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_32
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_32
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_33 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_33
deleted file mode 100644
index 88ad474..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_33
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_34 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_34
deleted file mode 100644
index fae15a2..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_34
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_35 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_35
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_35
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_36 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_36
deleted file mode 100644
index 88ad474..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_36
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_37 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_37
deleted file mode 100644
index fae15a2..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_37
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_38 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_38
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_38
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_39 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_39
deleted file mode 100644
index b326907..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_39
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_4 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_4
deleted file mode 100644
index 05b27bf..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_4
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_40 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_40
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_40
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_41 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_41
deleted file mode 100644
index b326907..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_41
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_42 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_42
deleted file mode 100644
index cdaa1f0..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_42
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_43 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_43
deleted file mode 100644
index ff0941b..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_43
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_44 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_44
deleted file mode 100644
index cdaa1f0..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_44
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_45 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_45
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_45
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_46 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_46
deleted file mode 100644
index 7e5f948..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_46
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_5 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_5
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_5
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_6 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_6
deleted file mode 100644
index 07319f8..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_6
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_7 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_7
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_7
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_8 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_8
deleted file mode 100644
index 07319f8..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_8
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_9 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_9
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_9
+++ /dev/null
Binary files differ
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index 2143d93..3ce586b 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -341,6 +341,12 @@
}
prebuilt_etc {
+ name: "android.software.opengles.deqp.level-latest.prebuilt.xml",
+ src: "android.software.opengles.deqp.level-latest.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
name: "android.software.sip.voip.prebuilt.xml",
src: "android.software.sip.voip.xml",
defaults: ["frameworks_native_data_etc_defaults"],
@@ -371,6 +377,12 @@
}
prebuilt_etc {
+ name: "android.software.vulkan.deqp.level-latest.prebuilt.xml",
+ src: "android.software.vulkan.deqp.level-latest.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
name: "aosp_excluded_hardware.prebuilt.xml",
src: "aosp_excluded_hardware.xml",
defaults: ["frameworks_native_data_etc_defaults"],
diff --git a/data/etc/android.software.opengles.deqp.level-latest.xml b/data/etc/android.software.opengles.deqp.level-latest.xml
new file mode 100644
index 0000000..bd15eb6
--- /dev/null
+++ b/data/etc/android.software.opengles.deqp.level-latest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2023 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.
+-->
+
+<!-- This is the standard feature indicating that the device passes OpenGL ES
+ dEQP tests associated with the most recent level for this Android version. -->
+<permissions>
+ <feature name="android.software.opengles.deqp.level" version="132580097" />
+</permissions>
diff --git a/data/etc/android.software.vulkan.deqp.level-latest.xml b/data/etc/android.software.vulkan.deqp.level-latest.xml
new file mode 100644
index 0000000..87be070
--- /dev/null
+++ b/data/etc/android.software.vulkan.deqp.level-latest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2023 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.
+-->
+
+<!-- This is the standard feature indicating that the device passes Vulkan
+ dEQP tests associated with the most recent level for this Android version. -->
+<permissions>
+ <feature name="android.software.vulkan.deqp.level" version="132580097" />
+</permissions>
diff --git a/include/android/performance_hint.h b/include/android/performance_hint.h
index b494f89..cedd361 100644
--- a/include/android/performance_hint.h
+++ b/include/android/performance_hint.h
@@ -171,6 +171,7 @@
* @return 0 on success.
* EINVAL if the list of thread ids is empty or if any of the thread ids is not part of the thread group.
* EPIPE if communication with the system service has failed.
+ * EPERM if any thread id doesn't belong to the application.
*/
int APerformanceHint_setThreads(
APerformanceHintSession* session,
diff --git a/libs/binder/ndk/.clang-format b/libs/binder/ndk/.clang-format
index 9a9d936..6077414 100644
--- a/libs/binder/ndk/.clang-format
+++ b/libs/binder/ndk/.clang-format
@@ -2,9 +2,7 @@
ColumnLimit: 100
IndentWidth: 4
ContinuationIndentWidth: 8
-PointerAlignment: Left
TabWidth: 4
AllowShortFunctionsOnASingleLine: Inline
PointerAlignment: Left
-TabWidth: 4
UseTab: Never
diff --git a/libs/binder/ndk/include_cpp/android/binder_auto_utils.h b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
index d6937c2..ed53891 100644
--- a/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
@@ -115,17 +115,29 @@
*/
AIBinder** getR() { return &mBinder; }
- bool operator!=(const SpAIBinder& rhs) const { return get() != rhs.get(); }
- bool operator<(const SpAIBinder& rhs) const { return get() < rhs.get(); }
- bool operator<=(const SpAIBinder& rhs) const { return get() <= rhs.get(); }
- bool operator==(const SpAIBinder& rhs) const { return get() == rhs.get(); }
- bool operator>(const SpAIBinder& rhs) const { return get() > rhs.get(); }
- bool operator>=(const SpAIBinder& rhs) const { return get() >= rhs.get(); }
-
private:
AIBinder* mBinder = nullptr;
};
+#define SP_AIBINDER_COMPARE(_op_) \
+ static inline bool operator _op_(const SpAIBinder& lhs, const SpAIBinder& rhs) { \
+ return lhs.get() _op_ rhs.get(); \
+ } \
+ static inline bool operator _op_(const SpAIBinder& lhs, const AIBinder* rhs) { \
+ return lhs.get() _op_ rhs; \
+ } \
+ static inline bool operator _op_(const AIBinder* lhs, const SpAIBinder& rhs) { \
+ return lhs _op_ rhs.get(); \
+ }
+
+SP_AIBINDER_COMPARE(!=)
+SP_AIBINDER_COMPARE(<)
+SP_AIBINDER_COMPARE(<=)
+SP_AIBINDER_COMPARE(==)
+SP_AIBINDER_COMPARE(>)
+SP_AIBINDER_COMPARE(>=)
+#undef SP_AIBINDER_COMPARE
+
namespace impl {
/**
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index 27ce615..25b8e97 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -377,18 +377,24 @@
}
TEST(NdkBinder, GetTestServiceStressTest) {
- // libbinder has some complicated logic to make sure only one instance of
- // ABpBinder is associated with each binder.
-
constexpr size_t kNumThreads = 10;
constexpr size_t kNumCalls = 1000;
std::vector<std::thread> threads;
+ // this is not a lazy service, but we must make sure that it's started before calling
+ // checkService on it, since the other process serving it might not be started yet.
+ {
+ // getService, not waitForService, to take advantage of timeout
+ auto binder = ndk::SpAIBinder(AServiceManager_getService(IFoo::kSomeInstanceName));
+ ASSERT_NE(nullptr, binder.get());
+ }
+
for (size_t i = 0; i < kNumThreads; i++) {
threads.push_back(std::thread([&]() {
for (size_t j = 0; j < kNumCalls; j++) {
auto binder =
ndk::SpAIBinder(AServiceManager_checkService(IFoo::kSomeInstanceName));
+ ASSERT_NE(nullptr, binder.get());
EXPECT_EQ(STATUS_OK, AIBinder_ping(binder.get()));
}
}));
@@ -755,9 +761,9 @@
// local
ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder()}) {
// convert to platform binder
- EXPECT_NE(binder.get(), nullptr);
+ EXPECT_NE(binder, nullptr);
sp<IBinder> platformBinder = AIBinder_toPlatformBinder(binder.get());
- EXPECT_NE(platformBinder.get(), nullptr);
+ EXPECT_NE(platformBinder, nullptr);
auto proxy = interface_cast<IBinderNdkUnitTest>(platformBinder);
EXPECT_NE(proxy, nullptr);
@@ -768,7 +774,7 @@
// convert back
ndk::SpAIBinder backBinder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(platformBinder));
- EXPECT_EQ(backBinder.get(), binder.get());
+ EXPECT_EQ(backBinder, binder);
}
}
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index 38c7f7c..4c3c68e 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -249,12 +249,12 @@
CHECK_EQ(options.numIncomingConnectionsBySession.size(), options.numSessions);
}
- SocketType socketType = std::get<0>(GetParam());
- RpcSecurity rpcSecurity = std::get<1>(GetParam());
- uint32_t clientVersion = std::get<2>(GetParam());
- uint32_t serverVersion = std::get<3>(GetParam());
- bool singleThreaded = std::get<4>(GetParam());
- bool noKernel = std::get<5>(GetParam());
+ SocketType socketType = GetParam().type;
+ RpcSecurity rpcSecurity = GetParam().security;
+ uint32_t clientVersion = GetParam().clientVersion;
+ uint32_t serverVersion = GetParam().serverVersion;
+ bool singleThreaded = GetParam().singleThreaded;
+ bool noKernel = GetParam().noKernel;
std::string path = android::base::GetExecutableDirectory();
auto servicePath = android::base::StringPrintf("%s/binder_rpc_test_service%s%s", path.c_str(),
@@ -1121,12 +1121,27 @@
}
#ifdef BINDER_RPC_TO_TRUSTY_TEST
-INSTANTIATE_TEST_CASE_P(Trusty, BinderRpc,
- ::testing::Combine(::testing::Values(SocketType::TIPC),
- ::testing::Values(RpcSecurity::RAW),
- ::testing::ValuesIn(testVersions()),
- ::testing::ValuesIn(testVersions()),
- ::testing::Values(true), ::testing::Values(true)),
+
+static std::vector<BinderRpc::ParamType> getTrustyBinderRpcParams() {
+ std::vector<BinderRpc::ParamType> ret;
+
+ for (const auto& clientVersion : testVersions()) {
+ for (const auto& serverVersion : testVersions()) {
+ ret.push_back(BinderRpc::ParamType{
+ .type = SocketType::TIPC,
+ .security = RpcSecurity::RAW,
+ .clientVersion = clientVersion,
+ .serverVersion = serverVersion,
+ .singleThreaded = true,
+ .noKernel = true,
+ });
+ }
+ }
+
+ return ret;
+}
+
+INSTANTIATE_TEST_CASE_P(Trusty, BinderRpc, ::testing::ValuesIn(getTrustyBinderRpcParams()),
BinderRpc::PrintParamInfo);
#else // BINDER_RPC_TO_TRUSTY_TEST
bool testSupportVsockLoopback() {
@@ -1246,13 +1261,47 @@
return ret;
}
-INSTANTIATE_TEST_CASE_P(PerSocket, BinderRpc,
- ::testing::Combine(::testing::ValuesIn(testSocketTypes()),
- ::testing::ValuesIn(RpcSecurityValues()),
- ::testing::ValuesIn(testVersions()),
- ::testing::ValuesIn(testVersions()),
- ::testing::Values(false, true),
- ::testing::Values(false, true)),
+static std::vector<BinderRpc::ParamType> getBinderRpcParams() {
+ std::vector<BinderRpc::ParamType> ret;
+
+ constexpr bool full = false;
+
+ for (const auto& type : testSocketTypes()) {
+ if (full || type == SocketType::UNIX) {
+ for (const auto& security : RpcSecurityValues()) {
+ for (const auto& clientVersion : testVersions()) {
+ for (const auto& serverVersion : testVersions()) {
+ for (bool singleThreaded : {false, true}) {
+ for (bool noKernel : {false, true}) {
+ ret.push_back(BinderRpc::ParamType{
+ .type = type,
+ .security = security,
+ .clientVersion = clientVersion,
+ .serverVersion = serverVersion,
+ .singleThreaded = singleThreaded,
+ .noKernel = noKernel,
+ });
+ }
+ }
+ }
+ }
+ }
+ } else {
+ ret.push_back(BinderRpc::ParamType{
+ .type = type,
+ .security = RpcSecurity::RAW,
+ .clientVersion = RPC_WIRE_PROTOCOL_VERSION,
+ .serverVersion = RPC_WIRE_PROTOCOL_VERSION,
+ .singleThreaded = false,
+ .noKernel = false,
+ });
+ }
+ }
+
+ return ret;
+}
+
+INSTANTIATE_TEST_CASE_P(PerSocket, BinderRpc, ::testing::ValuesIn(getBinderRpcParams()),
BinderRpc::PrintParamInfo);
class BinderRpcServerRootObject
diff --git a/libs/binder/tests/binderRpcTestFixture.h b/libs/binder/tests/binderRpcTestFixture.h
index 0b8920b..2c9646b 100644
--- a/libs/binder/tests/binderRpcTestFixture.h
+++ b/libs/binder/tests/binderRpcTestFixture.h
@@ -106,15 +106,23 @@
}
};
-class BinderRpc : public ::testing::TestWithParam<
- std::tuple<SocketType, RpcSecurity, uint32_t, uint32_t, bool, bool>> {
+struct BinderRpcParam {
+ SocketType type;
+ RpcSecurity security;
+ uint32_t clientVersion;
+ uint32_t serverVersion;
+ bool singleThreaded;
+ bool noKernel;
+};
+class BinderRpc : public ::testing::TestWithParam<BinderRpcParam> {
public:
- SocketType socketType() const { return std::get<0>(GetParam()); }
- RpcSecurity rpcSecurity() const { return std::get<1>(GetParam()); }
- uint32_t clientVersion() const { return std::get<2>(GetParam()); }
- uint32_t serverVersion() const { return std::get<3>(GetParam()); }
- bool serverSingleThreaded() const { return std::get<4>(GetParam()); }
- bool noKernel() const { return std::get<5>(GetParam()); }
+ // TODO: avoid unnecessary layer of indirection
+ SocketType socketType() const { return GetParam().type; }
+ RpcSecurity rpcSecurity() const { return GetParam().security; }
+ uint32_t clientVersion() const { return GetParam().clientVersion; }
+ uint32_t serverVersion() const { return GetParam().serverVersion; }
+ bool serverSingleThreaded() const { return GetParam().singleThreaded; }
+ bool noKernel() const { return GetParam().noKernel; }
bool clientOrServerSingleThreaded() const {
return !kEnableRpcThreads || serverSingleThreaded();
@@ -148,15 +156,16 @@
}
static std::string PrintParamInfo(const testing::TestParamInfo<ParamType>& info) {
- auto [type, security, clientVersion, serverVersion, singleThreaded, noKernel] = info.param;
- auto ret = PrintToString(type) + "_" + newFactory(security)->toCString() + "_clientV" +
- std::to_string(clientVersion) + "_serverV" + std::to_string(serverVersion);
- if (singleThreaded) {
+ auto ret = PrintToString(info.param.type) + "_" +
+ newFactory(info.param.security)->toCString() + "_clientV" +
+ std::to_string(info.param.clientVersion) + "_serverV" +
+ std::to_string(info.param.serverVersion);
+ if (info.param.singleThreaded) {
ret += "_single_threaded";
} else {
ret += "_multi_threaded";
}
- if (noKernel) {
+ if (info.param.noKernel) {
ret += "_no_kernel";
} else {
ret += "_with_kernel";
diff --git a/libs/binder/tests/binderRpcTestTrusty.cpp b/libs/binder/tests/binderRpcTestTrusty.cpp
index 28be10d..fcb83bd 100644
--- a/libs/binder/tests/binderRpcTestTrusty.cpp
+++ b/libs/binder/tests/binderRpcTestTrusty.cpp
@@ -57,9 +57,9 @@
[](size_t n) { return n != 0; }),
"Non-zero incoming connections on Trusty");
- RpcSecurity rpcSecurity = std::get<1>(GetParam());
- uint32_t clientVersion = std::get<2>(GetParam());
- uint32_t serverVersion = std::get<3>(GetParam());
+ RpcSecurity rpcSecurity = GetParam().security;
+ uint32_t clientVersion = GetParam().clientVersion;
+ uint32_t serverVersion = GetParam().serverVersion;
auto ret = std::make_unique<TrustyProcessSession>();
@@ -89,12 +89,27 @@
return ret;
}
-INSTANTIATE_TEST_CASE_P(Trusty, BinderRpc,
- ::testing::Combine(::testing::Values(SocketType::TIPC),
- ::testing::Values(RpcSecurity::RAW),
- ::testing::ValuesIn(testVersions()),
- ::testing::ValuesIn(testVersions()),
- ::testing::Values(false), ::testing::Values(true)),
+static std::vector<BinderRpc::ParamType> getTrustyBinderRpcParams() {
+ std::vector<BinderRpc::ParamType> ret;
+
+ for (const auto& clientVersion : testVersions()) {
+ for (const auto& serverVersion : testVersions()) {
+ ret.push_back(BinderRpc::ParamType{
+ .type = SocketType::TIPC,
+ .security = RpcSecurity::RAW,
+ .clientVersion = clientVersion,
+ .serverVersion = serverVersion,
+ // TODO: should we test both versions here?
+ .singleThreaded = false,
+ .noKernel = true,
+ });
+ }
+ }
+
+ return ret;
+}
+
+INSTANTIATE_TEST_CASE_P(Trusty, BinderRpc, ::testing::ValuesIn(getTrustyBinderRpcParams()),
BinderRpc::PrintParamInfo);
} // namespace android
diff --git a/libs/binder/tests/binderRpcUniversalTests.cpp b/libs/binder/tests/binderRpcUniversalTests.cpp
index 1f46010..e43508e 100644
--- a/libs/binder/tests/binderRpcUniversalTests.cpp
+++ b/libs/binder/tests/binderRpcUniversalTests.cpp
@@ -84,7 +84,7 @@
GTEST_SKIP() << "This test requires a multi-threaded service";
}
- SocketType type = std::get<0>(GetParam());
+ SocketType type = GetParam().type;
if (type == SocketType::PRECONNECTED || type == SocketType::UNIX ||
type == SocketType::UNIX_BOOTSTRAP || type == SocketType::UNIX_RAW) {
// we can't get port numbers for unix sockets
diff --git a/libs/binder/tests/rpc_fuzzer/main.cpp b/libs/binder/tests/rpc_fuzzer/main.cpp
index b8ae84d..dcc8b8e 100644
--- a/libs/binder/tests/rpc_fuzzer/main.cpp
+++ b/libs/binder/tests/rpc_fuzzer/main.cpp
@@ -135,7 +135,7 @@
// b/260736889 - limit arbitrarily, due to thread resource exhaustion, which currently
// aborts. Servers should consider RpcServer::setConnectionFilter instead.
- constexpr size_t kMaxConnections = 1000;
+ constexpr size_t kMaxConnections = 10;
while (provider.remaining_bytes() > 0) {
if (connections.empty() ||
diff --git a/libs/binder/trusty/fuzzer/Android.bp b/libs/binder/trusty/fuzzer/Android.bp
new file mode 100644
index 0000000..2f1f54b
--- /dev/null
+++ b/libs/binder/trusty/fuzzer/Android.bp
@@ -0,0 +1,39 @@
+// Copyright (C) 2023 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.
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_fuzz {
+ name: "trusty_binder_fuzzer",
+ defaults: ["trusty_fuzzer_defaults"],
+ srcs: [":trusty_tipc_fuzzer"],
+ cflags: [
+ "-DTRUSTY_APP_PORT=\"com.android.trusty.binder.test.service\"",
+ "-DTRUSTY_APP_UUID=\"d42f06c5-9dc5-455b-9914-cf094116cfa8\"",
+ "-DTRUSTY_APP_FILENAME=\"binder-test-service.syms.elf\"",
+ ],
+}
+
+cc_fuzz {
+ name: "trusty_binder_rpc_fuzzer",
+ defaults: ["trusty_fuzzer_defaults"],
+ srcs: [":trusty_tipc_fuzzer"],
+ cflags: [
+ "-DTRUSTY_APP_PORT=\"com.android.trusty.binderRpcTestService.V0\"",
+ "-DTRUSTY_APP_UUID=\"87e424e5-69d7-4bbd-8b7c-7e24812cbc94\"",
+ "-DTRUSTY_APP_FILENAME=\"binderRpcTestService.syms.elf\"",
+ ],
+}
diff --git a/libs/fakeservicemanager/FakeServiceManager.cpp b/libs/fakeservicemanager/FakeServiceManager.cpp
index 3272bbc..80661c1 100644
--- a/libs/fakeservicemanager/FakeServiceManager.cpp
+++ b/libs/fakeservicemanager/FakeServiceManager.cpp
@@ -26,6 +26,8 @@
}
sp<IBinder> FakeServiceManager::checkService( const String16& name) const {
+ std::lock_guard<std::mutex> l(mMutex);
+
auto it = mNameToService.find(name);
if (it == mNameToService.end()) {
return nullptr;
@@ -36,6 +38,8 @@
status_t FakeServiceManager::addService(const String16& name, const sp<IBinder>& service,
bool /*allowIsolated*/,
int /*dumpsysFlags*/) {
+ std::lock_guard<std::mutex> l(mMutex);
+
if (service == nullptr) {
return UNEXPECTED_NULL;
}
@@ -44,6 +48,8 @@
}
Vector<String16> FakeServiceManager::listServices(int /*dumpsysFlags*/) {
+ std::lock_guard<std::mutex> l(mMutex);
+
Vector<String16> services;
for (auto const& [name, service] : mNameToService) {
(void) service;
@@ -61,10 +67,14 @@
}
bool FakeServiceManager::isDeclared(const String16& name) {
+ std::lock_guard<std::mutex> l(mMutex);
+
return mNameToService.find(name) != mNameToService.end();
}
Vector<String16> FakeServiceManager::getDeclaredInstances(const String16& name) {
+ std::lock_guard<std::mutex> l(mMutex);
+
Vector<String16> out;
const String16 prefix = name + String16("/");
for (const auto& [registeredName, service] : mNameToService) {
@@ -108,6 +118,8 @@
}
void FakeServiceManager::clear() {
+ std::lock_guard<std::mutex> l(mMutex);
+
mNameToService.clear();
}
} // namespace android
diff --git a/libs/fakeservicemanager/include/fakeservicemanager/FakeServiceManager.h b/libs/fakeservicemanager/include/fakeservicemanager/FakeServiceManager.h
index 97add24..f62241d 100644
--- a/libs/fakeservicemanager/include/fakeservicemanager/FakeServiceManager.h
+++ b/libs/fakeservicemanager/include/fakeservicemanager/FakeServiceManager.h
@@ -19,6 +19,7 @@
#include <binder/IServiceManager.h>
#include <map>
+#include <mutex>
#include <optional>
#include <vector>
@@ -68,6 +69,7 @@
void clear();
private:
+ mutable std::mutex mMutex;
std::map<String16, sp<IBinder>> mNameToService;
};
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index 732ca36..715822b 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -512,11 +512,7 @@
return mShouldUseAngle;
}
-// Set ANGLE information.
-// If path is "system", it means system ANGLE must be used for the process.
-// If shouldUseNativeDriver is true, it means native GLES drivers must be used for the process.
-// If path is set to nonempty and shouldUseNativeDriver is true, ANGLE will be used regardless.
-void GraphicsEnv::setAngleInfo(const std::string& path, const bool shouldUseNativeDriver,
+void GraphicsEnv::setAngleInfo(const std::string& path, const bool shouldUseSystemAngle,
const std::string& packageName,
const std::vector<std::string> eglFeatures) {
if (mShouldUseAngle) {
@@ -533,13 +529,8 @@
mAnglePath = std::move(path);
ALOGV("setting app package name to '%s'", packageName.c_str());
mPackageName = std::move(packageName);
- if (mAnglePath == "system") {
- mShouldUseSystemAngle = true;
- }
- if (!mAnglePath.empty()) {
- mShouldUseAngle = true;
- }
- mShouldUseNativeDriver = shouldUseNativeDriver;
+ mShouldUseAngle = true;
+ mShouldUseSystemAngle = shouldUseSystemAngle;
}
std::string& GraphicsEnv::getPackageName() {
@@ -616,10 +607,6 @@
return mShouldUseSystemAngle;
}
-bool GraphicsEnv::shouldUseNativeDriver() {
- return mShouldUseNativeDriver;
-}
-
/**
* APIs for debuggable layers
*/
diff --git a/libs/graphicsenv/IGpuService.cpp b/libs/graphicsenv/IGpuService.cpp
index 4c070ae..1c0439e 100644
--- a/libs/graphicsenv/IGpuService.cpp
+++ b/libs/graphicsenv/IGpuService.cpp
@@ -180,9 +180,9 @@
return reply->writeUtf8AsUtf16(driverPath);
}
case SHELL_COMMAND_TRANSACTION: {
- int in = data.readFileDescriptor();
- int out = data.readFileDescriptor();
- int err = data.readFileDescriptor();
+ int in = dup(data.readFileDescriptor());
+ int out = dup(data.readFileDescriptor());
+ int err = dup(data.readFileDescriptor());
std::vector<String16> args;
data.readString16Vector(&args);
@@ -195,6 +195,9 @@
status = shellCommand(in, out, err, args);
if (resultReceiver != nullptr) resultReceiver->send(status);
+ ::close(in);
+ ::close(out);
+ ::close(err);
return OK;
}
diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
index 6cce3f6..fbf2902 100644
--- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
+++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
@@ -108,10 +108,7 @@
// (libraries must be stored uncompressed and page aligned); such elements
// in the search path must have a '!' after the zip filename, e.g.
// /system/app/ANGLEPrebuilt/ANGLEPrebuilt.apk!/lib/arm64-v8a
- // If the search patch is "system", then it means the system ANGLE should be used.
- // If shouldUseNativeDriver is true, it means native GLES drivers must be used for the process.
- // If path is set to nonempty and shouldUseNativeDriver is true, ANGLE will be used regardless.
- void setAngleInfo(const std::string& path, const bool shouldUseNativeDriver,
+ void setAngleInfo(const std::string& path, const bool useSystemAngle,
const std::string& packageName, const std::vector<std::string> eglFeatures);
// Get the ANGLE driver namespace.
android_namespace_t* getAngleNamespace();
@@ -121,7 +118,6 @@
// Set the persist.graphics.egl system property value.
void nativeToggleAngleAsSystemDriver(bool enabled);
bool shouldUseSystemAngle();
- bool shouldUseNativeDriver();
/*
* Apis for debug layer
@@ -179,8 +175,6 @@
bool mShouldUseAngle = false;
// Whether loader should load system ANGLE.
bool mShouldUseSystemAngle = false;
- // Whether loader should load native GLES driver.
- bool mShouldUseNativeDriver = false;
// ANGLE namespace.
android_namespace_t* mAngleNamespace = nullptr;
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 808388f..b872541 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -418,6 +418,9 @@
EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
bool attachedByConsumer = false;
+ sp<IConsumerListener> listener;
+ bool callOnFrameDequeued = false;
+ uint64_t bufferId = 0; // Only used if callOnFrameDequeued == true
{ // Autolock scope
std::unique_lock<std::mutex> lock(mCore->mMutex);
@@ -561,10 +564,11 @@
}
if (!(returnFlags & BUFFER_NEEDS_REALLOCATION)) {
- if (mCore->mConsumerListener != nullptr) {
- mCore->mConsumerListener->onFrameDequeued(mSlots[*outSlot].mGraphicBuffer->getId());
- }
+ callOnFrameDequeued = true;
+ bufferId = mSlots[*outSlot].mGraphicBuffer->getId();
}
+
+ listener = mCore->mConsumerListener;
} // Autolock scope
if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
@@ -581,10 +585,8 @@
if (error == NO_ERROR && !mCore->mIsAbandoned) {
graphicBuffer->setGenerationNumber(mCore->mGenerationNumber);
mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
- if (mCore->mConsumerListener != nullptr) {
- mCore->mConsumerListener->onFrameDequeued(
- mSlots[*outSlot].mGraphicBuffer->getId());
- }
+ callOnFrameDequeued = true;
+ bufferId = mSlots[*outSlot].mGraphicBuffer->getId();
}
mCore->mIsAllocating = false;
@@ -608,6 +610,10 @@
} // Autolock scope
}
+ if (listener != nullptr && callOnFrameDequeued) {
+ listener->onFrameDequeued(bufferId);
+ }
+
if (attachedByConsumer) {
returnFlags |= BUFFER_NEEDS_REALLOCATION;
}
@@ -647,6 +653,8 @@
BQ_LOGV("detachBuffer: slot %d", slot);
sp<IConsumerListener> listener;
+ bool callOnFrameDetached = false;
+ uint64_t bufferId = 0; // Only used if callOnFrameDetached is true
{
std::lock_guard<std::mutex> lock(mCore->mMutex);
@@ -684,8 +692,9 @@
listener = mCore->mConsumerListener;
auto gb = mSlots[slot].mGraphicBuffer;
- if (listener != nullptr && gb != nullptr) {
- listener->onFrameDetached(gb->getId());
+ if (gb != nullptr) {
+ callOnFrameDetached = true;
+ bufferId = gb->getId();
}
mSlots[slot].mBufferState.detachProducer();
mCore->mActiveBuffers.erase(slot);
@@ -695,6 +704,10 @@
VALIDATE_CONSISTENCY();
}
+ if (listener != nullptr && callOnFrameDetached) {
+ listener->onFrameDetached(bufferId);
+ }
+
if (listener != nullptr) {
listener->onBuffersReleased();
}
@@ -1105,58 +1118,71 @@
status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
ATRACE_CALL();
BQ_LOGV("cancelBuffer: slot %d", slot);
- std::lock_guard<std::mutex> lock(mCore->mMutex);
- if (mCore->mIsAbandoned) {
- BQ_LOGE("cancelBuffer: BufferQueue has been abandoned");
- return NO_INIT;
+ sp<IConsumerListener> listener;
+ bool callOnFrameCancelled = false;
+ uint64_t bufferId = 0; // Only used if callOnFrameCancelled == true
+ {
+ std::lock_guard<std::mutex> lock(mCore->mMutex);
+
+ if (mCore->mIsAbandoned) {
+ BQ_LOGE("cancelBuffer: BufferQueue has been abandoned");
+ return NO_INIT;
+ }
+
+ if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
+ BQ_LOGE("cancelBuffer: BufferQueue has no connected producer");
+ return NO_INIT;
+ }
+
+ if (mCore->mSharedBufferMode) {
+ BQ_LOGE("cancelBuffer: cannot cancel a buffer in shared buffer mode");
+ return BAD_VALUE;
+ }
+
+ if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
+ BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", slot,
+ BufferQueueDefs::NUM_BUFFER_SLOTS);
+ return BAD_VALUE;
+ } else if (!mSlots[slot].mBufferState.isDequeued()) {
+ BQ_LOGE("cancelBuffer: slot %d is not owned by the producer "
+ "(state = %s)",
+ slot, mSlots[slot].mBufferState.string());
+ return BAD_VALUE;
+ } else if (fence == nullptr) {
+ BQ_LOGE("cancelBuffer: fence is NULL");
+ return BAD_VALUE;
+ }
+
+ mSlots[slot].mBufferState.cancel();
+
+ // After leaving shared buffer mode, the shared buffer will still be around.
+ // Mark it as no longer shared if this operation causes it to be free.
+ if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) {
+ mSlots[slot].mBufferState.mShared = false;
+ }
+
+ // Don't put the shared buffer on the free list.
+ if (!mSlots[slot].mBufferState.isShared()) {
+ mCore->mActiveBuffers.erase(slot);
+ mCore->mFreeBuffers.push_back(slot);
+ }
+
+ auto gb = mSlots[slot].mGraphicBuffer;
+ if (gb != nullptr) {
+ callOnFrameCancelled = true;
+ bufferId = gb->getId();
+ }
+ mSlots[slot].mFence = fence;
+ mCore->mDequeueCondition.notify_all();
+ listener = mCore->mConsumerListener;
+ VALIDATE_CONSISTENCY();
}
- if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
- BQ_LOGE("cancelBuffer: BufferQueue has no connected producer");
- return NO_INIT;
+ if (listener != nullptr && callOnFrameCancelled) {
+ listener->onFrameCancelled(bufferId);
}
- if (mCore->mSharedBufferMode) {
- BQ_LOGE("cancelBuffer: cannot cancel a buffer in shared buffer mode");
- return BAD_VALUE;
- }
-
- if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
- BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)",
- slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
- return BAD_VALUE;
- } else if (!mSlots[slot].mBufferState.isDequeued()) {
- BQ_LOGE("cancelBuffer: slot %d is not owned by the producer "
- "(state = %s)", slot, mSlots[slot].mBufferState.string());
- return BAD_VALUE;
- } else if (fence == nullptr) {
- BQ_LOGE("cancelBuffer: fence is NULL");
- return BAD_VALUE;
- }
-
- mSlots[slot].mBufferState.cancel();
-
- // After leaving shared buffer mode, the shared buffer will still be around.
- // Mark it as no longer shared if this operation causes it to be free.
- if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) {
- mSlots[slot].mBufferState.mShared = false;
- }
-
- // Don't put the shared buffer on the free list.
- if (!mSlots[slot].mBufferState.isShared()) {
- mCore->mActiveBuffers.erase(slot);
- mCore->mFreeBuffers.push_back(slot);
- }
-
- auto gb = mSlots[slot].mGraphicBuffer;
- if (mCore->mConsumerListener != nullptr && gb != nullptr) {
- mCore->mConsumerListener->onFrameCancelled(gb->getId());
- }
- mSlots[slot].mFence = fence;
- mCore->mDequeueCondition.notify_all();
- VALIDATE_CONSISTENCY();
-
return NO_ERROR;
}
diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp
index e092aa6..9618502 100644
--- a/libs/gui/tests/BLASTBufferQueue_test.cpp
+++ b/libs/gui/tests/BLASTBufferQueue_test.cpp
@@ -1333,43 +1333,6 @@
ASSERT_EQ(queuesToNativeWindow, 1);
}
-// Test a slow producer doesn't hold up a faster producer from the same client. Essentially tests
-// BBQ uses separate transaction queues.
-TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) {
- sp<SurfaceControl> bgSurface =
- mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
- ISurfaceComposerClient::eFXSurfaceBufferState);
- ASSERT_NE(nullptr, bgSurface.get());
- Transaction t;
- t.setLayerStack(bgSurface, ui::DEFAULT_LAYER_STACK)
- .show(bgSurface)
- .setDataspace(bgSurface, ui::Dataspace::V0_SRGB)
- .setLayer(bgSurface, std::numeric_limits<int32_t>::max() - 1)
- .apply();
-
- BLASTBufferQueueHelper slowAdapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
- sp<IGraphicBufferProducer> slowIgbProducer;
- setUpProducer(slowAdapter, slowIgbProducer);
- nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
- queueBuffer(slowIgbProducer, 0 /* r */, 255 /* g */, 0 /* b */, presentTimeDelay);
-
- BLASTBufferQueueHelper fastAdapter(bgSurface, mDisplayWidth, mDisplayHeight);
- sp<IGraphicBufferProducer> fastIgbProducer;
- setUpProducer(fastAdapter, fastIgbProducer);
- uint8_t r = 255;
- uint8_t g = 0;
- uint8_t b = 0;
- queueBuffer(fastIgbProducer, r, g, b, 0 /* presentTimeDelay */);
- fastAdapter.waitForCallbacks();
-
- // capture screen and verify that it is red
- ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
-
- ASSERT_NO_FATAL_FAILURE(
- checkScreenCapture(r, g, b,
- {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
-}
-
TEST_F(BLASTBufferQueueTest, TransformHint) {
// Transform hint is provided to BBQ via the surface control passed by WM
mSurfaceControl->setTransformHint(ui::Transform::ROT_90);
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index d585881..0168877 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -21,8 +21,10 @@
#include "MockConsumer.h"
#include <gui/BufferItem.h>
+#include <gui/BufferItemConsumer.h>
#include <gui/BufferQueue.h>
#include <gui/IProducerListener.h>
+#include <gui/Surface.h>
#include <ui/GraphicBuffer.h>
@@ -37,6 +39,7 @@
#include <gtest/gtest.h>
+#include <future>
#include <thread>
using namespace std::chrono_literals;
@@ -1258,4 +1261,86 @@
ASSERT_EQ(NO_INIT, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
}
+class Latch {
+public:
+ explicit Latch(int expected) : mExpected(expected) {}
+ Latch(const Latch&) = delete;
+ Latch& operator=(const Latch&) = delete;
+
+ void CountDown() {
+ std::unique_lock<std::mutex> lock(mLock);
+ mExpected--;
+ if (mExpected <= 0) {
+ mCV.notify_all();
+ }
+ }
+
+ void Wait() {
+ std::unique_lock<std::mutex> lock(mLock);
+ mCV.wait(lock, [&] { return mExpected == 0; });
+ }
+
+private:
+ int mExpected;
+ std::mutex mLock;
+ std::condition_variable mCV;
+};
+
+struct OneshotOnDequeuedListener final : public BufferItemConsumer::FrameAvailableListener {
+ OneshotOnDequeuedListener(std::function<void()>&& oneshot)
+ : mOneshotRunnable(std::move(oneshot)) {}
+
+ std::function<void()> mOneshotRunnable;
+
+ void run() {
+ if (mOneshotRunnable) {
+ mOneshotRunnable();
+ mOneshotRunnable = nullptr;
+ }
+ }
+
+ void onFrameDequeued(const uint64_t) override { run(); }
+
+ void onFrameAvailable(const BufferItem&) override {}
+};
+
+// See b/270004534
+TEST(BufferQueueThreading, TestProducerDequeueConsumerDestroy) {
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+
+ sp<BufferItemConsumer> bufferConsumer =
+ sp<BufferItemConsumer>::make(consumer, GRALLOC_USAGE_SW_READ_OFTEN, 2);
+ ASSERT_NE(nullptr, bufferConsumer.get());
+ sp<Surface> surface = sp<Surface>::make(producer);
+ native_window_set_buffers_format(surface.get(), PIXEL_FORMAT_RGBA_8888);
+ native_window_set_buffers_dimensions(surface.get(), 100, 100);
+
+ Latch triggerDisconnect(1);
+ Latch resumeCallback(1);
+ auto luckyListener = sp<OneshotOnDequeuedListener>::make([&]() {
+ triggerDisconnect.CountDown();
+ resumeCallback.Wait();
+ });
+ bufferConsumer->setFrameAvailableListener(luckyListener);
+
+ std::future<void> disconnecter = std::async(std::launch::async, [&]() {
+ triggerDisconnect.Wait();
+ luckyListener = nullptr;
+ bufferConsumer = nullptr;
+ resumeCallback.CountDown();
+ });
+
+ std::future<void> render = std::async(std::launch::async, [=]() {
+ ANativeWindow_Buffer buffer;
+ surface->lock(&buffer, nullptr);
+ surface->unlockAndPost();
+ });
+
+ ASSERT_EQ(std::future_status::ready, render.wait_for(1s));
+ EXPECT_EQ(nullptr, luckyListener.get());
+ EXPECT_EQ(nullptr, bufferConsumer.get());
+}
+
} // namespace android
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 4d5bd5b..662e9fe 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -24,6 +24,7 @@
#include <memory>
+#include <android/gui/BnWindowInfosReportedListener.h>
#include <android/keycodes.h>
#include <android/native_window.h>
@@ -74,6 +75,26 @@
static const int LAYER_BASE = INT32_MAX - 10;
static constexpr std::chrono::nanoseconds DISPATCHING_TIMEOUT = 5s;
+class SynchronousWindowInfosReportedListener : public gui::BnWindowInfosReportedListener {
+public:
+ binder::Status onWindowInfosReported() override {
+ std::lock_guard<std::mutex> lock{mMutex};
+ mWindowInfosReported = true;
+ mConditionVariable.notify_one();
+ return binder::Status::ok();
+ }
+
+ void wait() {
+ std::unique_lock<std::mutex> lock{mMutex};
+ mConditionVariable.wait(lock, [&] { return mWindowInfosReported; });
+ }
+
+private:
+ std::mutex mMutex;
+ std::condition_variable mConditionVariable;
+ bool mWindowInfosReported{false};
+};
+
class InputSurface {
public:
InputSurface(const sp<SurfaceControl> &sc, int width, int height, bool noInputChannel = false) {
@@ -264,7 +285,10 @@
t.setPosition(mSurfaceControl, x, y);
t.setCrop(mSurfaceControl, crop);
t.setAlpha(mSurfaceControl, 1);
- t.apply(true);
+ auto reportedListener = sp<SynchronousWindowInfosReportedListener>::make();
+ t.addWindowInfosReportedListener(reportedListener);
+ t.apply();
+ reportedListener->wait();
}
void requestFocus(int displayId = ADISPLAY_ID_DEFAULT) {
diff --git a/libs/ultrahdr/gainmapmath.cpp b/libs/ultrahdr/gainmapmath.cpp
index ee15363..8015a4e 100644
--- a/libs/ultrahdr/gainmapmath.cpp
+++ b/libs/ultrahdr/gainmapmath.cpp
@@ -547,13 +547,13 @@
uint8_t& u_uint = reinterpret_cast<uint8_t*>(image->data)[pixel_count + pixel_uv_idx];
uint8_t& v_uint = reinterpret_cast<uint8_t*>(image->data)[pixel_count * 5 / 4 + pixel_uv_idx];
- y1_uint = static_cast<uint8_t>(floor(yuv1.y * 255.0f + 0.5f));
- y2_uint = static_cast<uint8_t>(floor(yuv2.y * 255.0f + 0.5f));
- y3_uint = static_cast<uint8_t>(floor(yuv3.y * 255.0f + 0.5f));
- y4_uint = static_cast<uint8_t>(floor(yuv4.y * 255.0f + 0.5f));
+ y1_uint = static_cast<uint8_t>(CLIP3((yuv1.y * 255.0f + 0.5f), 0, 255));
+ y2_uint = static_cast<uint8_t>(CLIP3((yuv2.y * 255.0f + 0.5f), 0, 255));
+ y3_uint = static_cast<uint8_t>(CLIP3((yuv3.y * 255.0f + 0.5f), 0, 255));
+ y4_uint = static_cast<uint8_t>(CLIP3((yuv4.y * 255.0f + 0.5f), 0, 255));
- u_uint = static_cast<uint8_t>(floor(new_uv.u * 255.0f + 128.0f + 0.5f));
- v_uint = static_cast<uint8_t>(floor(new_uv.v * 255.0f + 128.0f + 0.5f));
+ u_uint = static_cast<uint8_t>(CLIP3((new_uv.u * 255.0f + 128.0f + 0.5f), 0, 255));
+ v_uint = static_cast<uint8_t>(CLIP3((new_uv.v * 255.0f + 128.0f + 0.5f), 0, 255));
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/libs/ultrahdr/jpegdecoderhelper.cpp b/libs/ultrahdr/jpegdecoderhelper.cpp
index fef5444..33bf9ef 100644
--- a/libs/ultrahdr/jpegdecoderhelper.cpp
+++ b/libs/ultrahdr/jpegdecoderhelper.cpp
@@ -227,10 +227,20 @@
mHeight = cinfo.image_height;
if (decodeToRGBA) {
- if (cinfo.jpeg_color_space == JCS_GRAYSCALE) {
- // We don't intend to support decoding grayscale to RGBA
- status = false;
- ALOGE("%s: decoding grayscale to RGBA is unsupported", __func__);
+ // The primary image is expected to be yuv420 sampling
+ if (cinfo.jpeg_color_space != JCS_YCbCr) {
+ status = false;
+ ALOGE("%s: decodeToRGBA unexpected jpeg color space ", __func__);
+ goto CleanUp;
+ }
+ if (cinfo.comp_info[0].h_samp_factor != 2 ||
+ cinfo.comp_info[1].h_samp_factor != 1 ||
+ cinfo.comp_info[2].h_samp_factor != 1 ||
+ cinfo.comp_info[0].v_samp_factor != 2 ||
+ cinfo.comp_info[1].v_samp_factor != 1 ||
+ cinfo.comp_info[2].v_samp_factor != 1 ) {
+ status = false;
+ ALOGE("%s: decodeToRGBA unexpected primary image sub-sampling", __func__);
goto CleanUp;
}
// 4 bytes per pixel
@@ -251,12 +261,16 @@
mResultBuffer.resize(cinfo.image_width * cinfo.image_height * 3 / 2, 0);
} else if (cinfo.jpeg_color_space == JCS_GRAYSCALE) {
mResultBuffer.resize(cinfo.image_width * cinfo.image_height, 0);
+ } else {
+ status = false;
+ ALOGE("%s: decodeToYUV unexpected jpeg color space", __func__);
+ goto CleanUp;
}
cinfo.out_color_space = cinfo.jpeg_color_space;
cinfo.raw_data_out = TRUE;
}
- cinfo.dct_method = JDCT_IFAST;
+ cinfo.dct_method = JDCT_ISLOW;
jpeg_start_decompress(&cinfo);
diff --git a/libs/ultrahdr/jpegencoderhelper.cpp b/libs/ultrahdr/jpegencoderhelper.cpp
index a03547b..de621bd 100644
--- a/libs/ultrahdr/jpegencoderhelper.cpp
+++ b/libs/ultrahdr/jpegencoderhelper.cpp
@@ -140,7 +140,7 @@
jpeg_set_quality(cinfo, quality, TRUE);
jpeg_set_colorspace(cinfo, isSingleChannel ? JCS_GRAYSCALE : JCS_YCbCr);
cinfo->raw_data_in = TRUE;
- cinfo->dct_method = JDCT_IFAST;
+ cinfo->dct_method = JDCT_ISLOW;
if (!isSingleChannel) {
// Configure sampling factors. The sampling factor is JPEG subsampling 420 because the
diff --git a/libs/ultrahdr/tests/Android.bp b/libs/ultrahdr/tests/Android.bp
index 5944130..004a582 100644
--- a/libs/ultrahdr/tests/Android.bp
+++ b/libs/ultrahdr/tests/Android.bp
@@ -22,7 +22,7 @@
}
cc_test {
- name: "libultrahdr_test",
+ name: "ultrahdr_unit_test",
test_suites: ["device-tests"],
srcs: [
"gainmapmath_test.cpp",
@@ -45,7 +45,7 @@
}
cc_test {
- name: "libjpegencoderhelper_test",
+ name: "jpegencoderhelper_test",
test_suites: ["device-tests"],
srcs: [
"jpegencoderhelper_test.cpp",
@@ -61,7 +61,7 @@
}
cc_test {
- name: "libjpegdecoderhelper_test",
+ name: "jpegdecoderhelper_test",
test_suites: ["device-tests"],
srcs: [
"jpegdecoderhelper_test.cpp",
diff --git a/libs/ultrahdr/tests/data/raw_p010_image_with_stride.p010 b/libs/ultrahdr/tests/data/raw_p010_image_with_stride.p010
deleted file mode 100644
index e7a5dc8..0000000
--- a/libs/ultrahdr/tests/data/raw_p010_image_with_stride.p010
+++ /dev/null
Binary files differ
diff --git a/libs/ultrahdr/tests/jpegr_test.cpp b/libs/ultrahdr/tests/jpegr_test.cpp
index 41d55ec..7837bcf 100644
--- a/libs/ultrahdr/tests/jpegr_test.cpp
+++ b/libs/ultrahdr/tests/jpegr_test.cpp
@@ -14,810 +14,1232 @@
* limitations under the License.
*/
+#include <sys/time.h>
+#include <fstream>
+#include <iostream>
+
+#include <ultrahdr/gainmapmath.h>
#include <ultrahdr/jpegr.h>
#include <ultrahdr/jpegrutils.h>
-#include <ultrahdr/gainmapmath.h>
-#include <fcntl.h>
-#include <fstream>
+
#include <gtest/gtest.h>
-#include <sys/time.h>
#include <utils/Log.h>
-#define RAW_P010_IMAGE "/sdcard/Documents/raw_p010_image.p010"
-#define RAW_P010_IMAGE_WITH_STRIDE "/sdcard/Documents/raw_p010_image_with_stride.p010"
-#define RAW_YUV420_IMAGE "/sdcard/Documents/raw_yuv420_image.yuv420"
-#define JPEG_IMAGE "/sdcard/Documents/jpeg_image.jpg"
-#define TEST_IMAGE_WIDTH 1280
-#define TEST_IMAGE_HEIGHT 720
-#define TEST_IMAGE_STRIDE 1288
-#define DEFAULT_JPEG_QUALITY 90
-
-#define SAVE_ENCODING_RESULT true
-#define SAVE_DECODING_RESULT true
-#define SAVE_INPUT_RGBA true
+//#define DUMP_OUTPUT
namespace android::ultrahdr {
-struct Timer {
- struct timeval StartingTime;
- struct timeval EndingTime;
- struct timeval ElapsedMicroseconds;
-};
+// resources used by unit tests
+const char* kYCbCrP010FileName = "raw_p010_image.p010";
+const char* kYCbCr420FileName = "raw_yuv420_image.yuv420";
+const char* kSdrJpgFileName = "jpeg_image.jpg";
+const int kImageWidth = 1280;
+const int kImageHeight = 720;
+const int kQuality = 90;
-void timerStart(Timer *t) {
- gettimeofday(&t->StartingTime, nullptr);
-}
+// Wrapper to describe the input type
+typedef enum {
+ YCbCr_p010 = 0,
+ YCbCr_420 = 1,
+} UhdrInputFormat;
-void timerStop(Timer *t) {
- gettimeofday(&t->EndingTime, nullptr);
-}
-
-int64_t elapsedTime(Timer *t) {
- t->ElapsedMicroseconds.tv_sec = t->EndingTime.tv_sec - t->StartingTime.tv_sec;
- t->ElapsedMicroseconds.tv_usec = t->EndingTime.tv_usec - t->StartingTime.tv_usec;
- return t->ElapsedMicroseconds.tv_sec * 1000000 + t->ElapsedMicroseconds.tv_usec;
-}
-
-static size_t getFileSize(int fd) {
- struct stat st;
- if (fstat(fd, &st) < 0) {
- ALOGW("%s : fstat failed", __func__);
- return 0;
- }
- return st.st_size; // bytes
-}
-
-static bool loadFile(const char filename[], void*& result, int* fileLength) {
- int fd = open(filename, O_CLOEXEC);
- if (fd < 0) {
- return false;
- }
- int length = getFileSize(fd);
- if (length == 0) {
- close(fd);
- return false;
- }
- if (fileLength != nullptr) {
- *fileLength = length;
- }
- result = malloc(length);
- if (read(fd, result, length) != static_cast<ssize_t>(length)) {
- close(fd);
- return false;
- }
- close(fd);
- return true;
-}
-
-static bool loadP010Image(const char *filename, jr_uncompressed_ptr img,
- bool isUVContiguous) {
- int fd = open(filename, O_CLOEXEC);
- if (fd < 0) {
- return false;
- }
- const int bpp = 2;
- int lumaStride = img->luma_stride == 0 ? img->width : img->luma_stride;
- int lumaSize = bpp * lumaStride * img->height;
- int chromaSize = bpp * (img->height / 2) *
- (isUVContiguous ? lumaStride : img->chroma_stride);
- img->data = malloc(lumaSize + (isUVContiguous ? chromaSize : 0));
- if (img->data == nullptr) {
- ALOGE("loadP010Image(): failed to allocate memory for luma data.");
- return false;
- }
- uint8_t *mem = static_cast<uint8_t *>(img->data);
- for (int i = 0; i < img->height; i++) {
- if (read(fd, mem, img->width * bpp) != img->width * bpp) {
- close(fd);
- return false;
- }
- mem += lumaStride * bpp;
- }
- int chromaStride = lumaStride;
- if (!isUVContiguous) {
- img->chroma_data = malloc(chromaSize);
- if (img->chroma_data == nullptr) {
- ALOGE("loadP010Image(): failed to allocate memory for chroma data.");
- return false;
- }
- mem = static_cast<uint8_t *>(img->chroma_data);
- chromaStride = img->chroma_stride;
- }
- for (int i = 0; i < img->height / 2; i++) {
- if (read(fd, mem, img->width * bpp) != img->width * bpp) {
- close(fd);
- return false;
- }
- mem += chromaStride * bpp;
- }
- close(fd);
- return true;
-}
-
-class JpegRTest : public testing::Test {
+/**
+ * Wrapper class for raw resource
+ * Sample usage:
+ * UhdrUnCompressedStructWrapper rawImg(width, height, YCbCr_p010);
+ * rawImg.setImageColorGamut(colorGamut));
+ * rawImg.setImageStride(strideLuma, strideChroma); // optional
+ * rawImg.setChromaMode(false); // optional
+ * rawImg.allocateMemory();
+ * rawImg.loadRawResource(kYCbCrP010FileName);
+ */
+class UhdrUnCompressedStructWrapper {
public:
- JpegRTest();
- ~JpegRTest();
+ UhdrUnCompressedStructWrapper(uint32_t width, uint32_t height, UhdrInputFormat format);
+ ~UhdrUnCompressedStructWrapper() = default;
-protected:
- virtual void SetUp();
- virtual void TearDown();
+ bool setChromaMode(bool isChromaContiguous);
+ bool setImageStride(int lumaStride, int chromaStride);
+ bool setImageColorGamut(ultrahdr_color_gamut colorGamut);
+ bool allocateMemory();
+ bool loadRawResource(const char* fileName);
+ jr_uncompressed_ptr getImageHandle();
- struct jpegr_uncompressed_struct mRawP010Image{};
- struct jpegr_uncompressed_struct mRawP010ImageWithStride{};
- struct jpegr_uncompressed_struct mRawP010ImageWithChromaData{};
- struct jpegr_uncompressed_struct mRawYuv420Image{};
- struct jpegr_compressed_struct mJpegImage{};
-};
-
-JpegRTest::JpegRTest() {}
-JpegRTest::~JpegRTest() {}
-
-void JpegRTest::SetUp() {}
-void JpegRTest::TearDown() {
- free(mRawP010Image.data);
- free(mRawP010Image.chroma_data);
- free(mRawP010ImageWithStride.data);
- free(mRawP010ImageWithStride.chroma_data);
- free(mRawP010ImageWithChromaData.data);
- free(mRawP010ImageWithChromaData.chroma_data);
- free(mRawYuv420Image.data);
- free(mJpegImage.data);
-}
-
-class JpegRBenchmark : public JpegR {
-public:
- void BenchmarkGenerateGainMap(jr_uncompressed_ptr yuv420Image, jr_uncompressed_ptr p010Image,
- ultrahdr_metadata_ptr metadata, jr_uncompressed_ptr map);
- void BenchmarkApplyGainMap(jr_uncompressed_ptr yuv420Image, jr_uncompressed_ptr map,
- ultrahdr_metadata_ptr metadata, jr_uncompressed_ptr dest);
private:
- const int kProfileCount = 10;
+ std::unique_ptr<uint8_t[]> mLumaData;
+ std::unique_ptr<uint8_t[]> mChromaData;
+ jpegr_uncompressed_struct mImg;
+ UhdrInputFormat mFormat;
+ bool mIsChromaContiguous;
};
-void JpegRBenchmark::BenchmarkGenerateGainMap(jr_uncompressed_ptr yuv420Image,
- jr_uncompressed_ptr p010Image,
- ultrahdr_metadata_ptr metadata,
- jr_uncompressed_ptr map) {
- ASSERT_EQ(yuv420Image->width, p010Image->width);
- ASSERT_EQ(yuv420Image->height, p010Image->height);
+/**
+ * Wrapper class for compressed resource
+ * Sample usage:
+ * UhdrCompressedStructWrapper jpgImg(width, height);
+ * rawImg.allocateMemory();
+ */
+class UhdrCompressedStructWrapper {
+public:
+ UhdrCompressedStructWrapper(uint32_t width, uint32_t height);
+ ~UhdrCompressedStructWrapper() = default;
- Timer genRecMapTime;
+ bool allocateMemory();
+ jr_compressed_ptr getImageHandle();
- timerStart(&genRecMapTime);
- for (auto i = 0; i < kProfileCount; i++) {
- ASSERT_EQ(OK, generateGainMap(
- yuv420Image, p010Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, metadata, map));
- if (i != kProfileCount - 1) delete[] static_cast<uint8_t *>(map->data);
+private:
+ std::unique_ptr<uint8_t[]> mData;
+ jpegr_compressed_struct mImg{};
+ uint32_t mWidth;
+ uint32_t mHeight;
+};
+
+UhdrUnCompressedStructWrapper::UhdrUnCompressedStructWrapper(uint32_t width, uint32_t height,
+ UhdrInputFormat format) {
+ mImg.data = nullptr;
+ mImg.width = width;
+ mImg.height = height;
+ mImg.colorGamut = ULTRAHDR_COLORGAMUT_UNSPECIFIED;
+ mImg.chroma_data = nullptr;
+ mImg.luma_stride = 0;
+ mImg.chroma_stride = 0;
+ mFormat = format;
+ mIsChromaContiguous = true;
+}
+
+bool UhdrUnCompressedStructWrapper::setChromaMode(bool isChromaContiguous) {
+ if (mLumaData.get() != nullptr) {
+ std::cerr << "Object has sailed, no further modifications are allowed" << std::endl;
+ return false;
}
- timerStop(&genRecMapTime);
-
- ALOGE("Generate Gain Map:- Res = %i x %i, time = %f ms",
- yuv420Image->width, yuv420Image->height,
- elapsedTime(&genRecMapTime) / (kProfileCount * 1000.f));
-
+ mIsChromaContiguous = isChromaContiguous;
+ return true;
}
-void JpegRBenchmark::BenchmarkApplyGainMap(jr_uncompressed_ptr yuv420Image,
- jr_uncompressed_ptr map,
- ultrahdr_metadata_ptr metadata,
- jr_uncompressed_ptr dest) {
- Timer applyRecMapTime;
-
- timerStart(&applyRecMapTime);
- for (auto i = 0; i < kProfileCount; i++) {
- ASSERT_EQ(OK, applyGainMap(yuv420Image, map, metadata, ULTRAHDR_OUTPUT_HDR_HLG,
- metadata->maxContentBoost /* displayBoost */, dest));
+bool UhdrUnCompressedStructWrapper::setImageStride(int lumaStride, int chromaStride) {
+ if (mLumaData.get() != nullptr) {
+ std::cerr << "Object has sailed, no further modifications are allowed" << std::endl;
+ return false;
}
- timerStop(&applyRecMapTime);
-
- ALOGE("Apply Gain Map:- Res = %i x %i, time = %f ms",
- yuv420Image->width, yuv420Image->height,
- elapsedTime(&applyRecMapTime) / (kProfileCount * 1000.f));
+ if (lumaStride != 0) {
+ if (lumaStride < mImg.width) {
+ std::cerr << "Bad luma stride received" << std::endl;
+ return false;
+ }
+ mImg.luma_stride = lumaStride;
+ }
+ if (chromaStride != 0) {
+ if (mFormat == YCbCr_p010 && chromaStride < mImg.width) {
+ std::cerr << "Bad chroma stride received for format YCbCrP010" << std::endl;
+ return false;
+ }
+ if (mFormat == YCbCr_420 && chromaStride < (mImg.width >> 1)) {
+ std::cerr << "Bad chroma stride received for format YCbCr420" << std::endl;
+ return false;
+ }
+ mImg.chroma_stride = chromaStride;
+ }
+ return true;
}
-TEST_F(JpegRTest, build) {
- // Force all of the gain map lib to be linked by calling all public functions.
- JpegR jpegRCodec;
- jpegRCodec.encodeJPEGR(nullptr, static_cast<ultrahdr_transfer_function>(0), nullptr, 0, nullptr);
- jpegRCodec.encodeJPEGR(nullptr, nullptr, static_cast<ultrahdr_transfer_function>(0),
- nullptr, 0, nullptr);
- jpegRCodec.encodeJPEGR(nullptr, nullptr, nullptr, static_cast<ultrahdr_transfer_function>(0),
- nullptr);
- jpegRCodec.encodeJPEGR(nullptr, nullptr, static_cast<ultrahdr_transfer_function>(0), nullptr);
- jpegRCodec.decodeJPEGR(nullptr, nullptr);
+bool UhdrUnCompressedStructWrapper::setImageColorGamut(ultrahdr_color_gamut colorGamut) {
+ if (mLumaData.get() != nullptr) {
+ std::cerr << "Object has sailed, no further modifications are allowed" << std::endl;
+ return false;
+ }
+ mImg.colorGamut = colorGamut;
+ return true;
}
-/* Test Encode API-0 invalid arguments */
-TEST_F(JpegRTest, encodeAPI0ForInvalidArgs) {
- int ret;
+bool UhdrUnCompressedStructWrapper::allocateMemory() {
+ if (mImg.width == 0 || (mImg.width % 2 != 0) || mImg.height == 0 || (mImg.height % 2 != 0) ||
+ (mFormat != YCbCr_p010 && mFormat != YCbCr_420)) {
+ std::cerr << "Object in bad state, mem alloc failed" << std::endl;
+ return false;
+ }
+ int lumaStride = mImg.luma_stride == 0 ? mImg.width : mImg.luma_stride;
+ int lumaSize = lumaStride * mImg.height * (mFormat == YCbCr_p010 ? 2 : 1);
+ int chromaSize = (mImg.height >> 1) * (mFormat == YCbCr_p010 ? 2 : 1);
+ if (mIsChromaContiguous) {
+ chromaSize *= lumaStride;
+ } else {
+ if (mImg.chroma_stride == 0) {
+ std::cerr << "Object in bad state, mem alloc failed" << std::endl;
+ return false;
+ }
+ if (mFormat == YCbCr_p010) {
+ chromaSize *= mImg.chroma_stride;
+ } else {
+ chromaSize *= (mImg.chroma_stride * 2);
+ }
+ }
+ if (mIsChromaContiguous) {
+ mLumaData = std::make_unique<uint8_t[]>(lumaSize + chromaSize);
+ mImg.data = mLumaData.get();
+ mImg.chroma_data = nullptr;
+ } else {
+ mLumaData = std::make_unique<uint8_t[]>(lumaSize);
+ mImg.data = mLumaData.get();
+ mChromaData = std::make_unique<uint8_t[]>(chromaSize);
+ mImg.chroma_data = mChromaData.get();
+ }
+ return true;
+}
- // we are not really compressing anything so lets keep allocs to a minimum
- jpegr_compressed_struct jpegR;
- jpegR.maxLength = 16 * sizeof(uint8_t);
- jpegR.data = malloc(jpegR.maxLength);
+bool UhdrUnCompressedStructWrapper::loadRawResource(const char* fileName) {
+ if (!mImg.data) {
+ std::cerr << "memory is not allocated, read not possible" << std::endl;
+ return false;
+ }
+ std::ifstream ifd(fileName, std::ios::binary | std::ios::ate);
+ if (ifd.good()) {
+ int bpp = mFormat == YCbCr_p010 ? 2 : 1;
+ int size = ifd.tellg();
+ int length = mImg.width * mImg.height * bpp * 3 / 2; // 2x2 subsampling
+ if (size < length) {
+ std::cerr << "requested to read " << length << " bytes from file : " << fileName
+ << ", file contains only " << length << " bytes" << std::endl;
+ return false;
+ }
+ ifd.seekg(0, std::ios::beg);
+ int lumaStride = mImg.luma_stride == 0 ? mImg.width : mImg.luma_stride;
+ char* mem = static_cast<char*>(mImg.data);
+ for (int i = 0; i < mImg.height; i++) {
+ ifd.read(mem, mImg.width * bpp);
+ mem += lumaStride * bpp;
+ }
+ if (!mIsChromaContiguous) {
+ mem = static_cast<char*>(mImg.chroma_data);
+ }
+ int chromaStride;
+ if (mIsChromaContiguous) {
+ chromaStride = mFormat == YCbCr_p010 ? lumaStride : lumaStride / 2;
+ } else {
+ if (mFormat == YCbCr_p010) {
+ chromaStride = mImg.chroma_stride == 0 ? lumaStride : mImg.chroma_stride;
+ } else {
+ chromaStride = mImg.chroma_stride == 0 ? (lumaStride / 2) : mImg.chroma_stride;
+ }
+ }
+ if (mFormat == YCbCr_p010) {
+ for (int i = 0; i < mImg.height / 2; i++) {
+ ifd.read(mem, mImg.width * 2);
+ mem += chromaStride * 2;
+ }
+ } else {
+ for (int i = 0; i < mImg.height / 2; i++) {
+ ifd.read(mem, (mImg.width / 2));
+ mem += chromaStride;
+ }
+ for (int i = 0; i < mImg.height / 2; i++) {
+ ifd.read(mem, (mImg.width / 2));
+ mem += chromaStride;
+ }
+ }
+ return true;
+ }
+ std::cerr << "unable to open file : " << fileName << std::endl;
+ return false;
+}
- JpegR jpegRCodec;
+jr_uncompressed_ptr UhdrUnCompressedStructWrapper::getImageHandle() {
+ return &mImg;
+}
- // we are not really compressing anything so lets keep allocs to a minimum
- mRawP010ImageWithStride.data = malloc(16);
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
- mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
+UhdrCompressedStructWrapper::UhdrCompressedStructWrapper(uint32_t width, uint32_t height) {
+ mWidth = width;
+ mHeight = height;
+}
- // test quality factor
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
- -1, nullptr)) << "fail, API allows bad jpeg quality factor";
+bool UhdrCompressedStructWrapper::allocateMemory() {
+ if (mWidth == 0 || (mWidth % 2 != 0) || mHeight == 0 || (mHeight % 2 != 0)) {
+ std::cerr << "Object in bad state, mem alloc failed" << std::endl;
+ return false;
+ }
+ int maxLength = std::max(8 * 1024 /* min size 8kb */, (int)(mWidth * mHeight * 3 * 2));
+ mData = std::make_unique<uint8_t[]>(maxLength);
+ mImg.data = mData.get();
+ mImg.length = 0;
+ mImg.maxLength = maxLength;
+ return true;
+}
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
- 101, nullptr)) << "fail, API allows bad jpeg quality factor";
+jr_compressed_ptr UhdrCompressedStructWrapper::getImageHandle() {
+ return &mImg;
+}
- // test hdr transfer function
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED, &jpegR,
- DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad hdr transfer function";
+static bool writeFile(const char* filename, void*& result, int length) {
+ std::ofstream ofd(filename, std::ios::binary);
+ if (ofd.is_open()) {
+ ofd.write(static_cast<char*>(result), length);
+ return true;
+ }
+ std::cerr << "unable to write to file : " << filename << std::endl;
+ return false;
+}
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride,
- static_cast<ultrahdr_transfer_function>(ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
- &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad hdr transfer function";
+static bool readFile(const char* fileName, void*& result, int maxLength, int& length) {
+ std::ifstream ifd(fileName, std::ios::binary | std::ios::ate);
+ if (ifd.good()) {
+ length = ifd.tellg();
+ if (length > maxLength) {
+ std::cerr << "not enough space to read file" << std::endl;
+ return false;
+ }
+ ifd.seekg(0, std::ios::beg);
+ ifd.read(static_cast<char*>(result), length);
+ return true;
+ }
+ std::cerr << "unable to read file : " << fileName << std::endl;
+ return false;
+}
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride,
- static_cast<ultrahdr_transfer_function>(-10),
- &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad hdr transfer function";
+void decodeJpegRImg(jr_compressed_ptr img, [[maybe_unused]] const char* outFileName) {
+ std::vector<uint8_t> iccData(0);
+ std::vector<uint8_t> exifData(0);
+ jpegr_info_struct info{0, 0, &iccData, &exifData};
+ JpegR jpegHdr;
+ ASSERT_EQ(OK, jpegHdr.getJPEGRInfo(img, &info));
+ ASSERT_EQ(kImageWidth, info.width);
+ ASSERT_EQ(kImageHeight, info.height);
+ size_t outSize = info.width * info.height * 8;
+ std::unique_ptr<uint8_t[]> data = std::make_unique<uint8_t[]>(outSize);
+ jpegr_uncompressed_struct destImage{};
+ destImage.data = data.get();
+ ASSERT_EQ(OK, jpegHdr.decodeJPEGR(img, &destImage));
+ ASSERT_EQ(kImageWidth, destImage.width);
+ ASSERT_EQ(kImageHeight, destImage.height);
+#ifdef DUMP_OUTPUT
+ if (!writeFile(outFileName, destImage.data, outSize)) {
+ std::cerr << "unable to write output file" << std::endl;
+ }
+#endif
+}
+
+// ============================================================================
+// Unit Tests
+// ============================================================================
+
+// Test Encode API-0 invalid arguments
+TEST(JpegRTest, EncodeAPI0WithInvalidArgs) {
+ JpegR uHdrLib;
+
+ UhdrCompressedStructWrapper jpgImg(16, 16);
+ ASSERT_TRUE(jpgImg.allocateMemory());
+
+ // test quality factor and transfer function
+ {
+ UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
+
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), -1, nullptr),
+ OK)
+ << "fail, API allows bad jpeg quality factor";
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), 101, nullptr),
+ OK)
+ << "fail, API allows bad jpeg quality factor";
+
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad hdr transfer function";
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(),
+ static_cast<ultrahdr_transfer_function>(
+ ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad hdr transfer function";
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(),
+ static_cast<ultrahdr_transfer_function>(-10),
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad hdr transfer function";
+ }
// test dest
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, nullptr,
- DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows nullptr dest";
+ {
+ UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
+
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG, nullptr, kQuality,
+ nullptr),
+ OK)
+ << "fail, API allows nullptr dest";
+ UhdrCompressedStructWrapper jpgImg2(16, 16);
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg2.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows nullptr dest";
+ }
// test p010 input
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- nullptr, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
- DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows nullptr p010 image";
+ {
+ ASSERT_NE(uHdrLib.encodeJPEGR(nullptr, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows nullptr p010 image";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
- DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad p010 color gamut";
+ UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows nullptr p010 image";
+ }
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.colorGamut = static_cast<ultrahdr_color_gamut>(
- ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
- DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad p010 color gamut";
+ {
+ UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED));
+ ASSERT_TRUE(rawImg.allocateMemory());
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad p010 color gamut";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH - 1;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
- DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image width";
+ UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_p010);
+ ASSERT_TRUE(rawImg2.setImageColorGamut(
+ static_cast<ultrahdr_color_gamut>(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1)));
+ ASSERT_TRUE(rawImg2.allocateMemory());
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg2.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad p010 color gamut";
+ }
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT - 1;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
- DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image height";
+ {
+ const int kWidth = 32, kHeight = 32;
+ UhdrUnCompressedStructWrapper rawImg(kWidth, kHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
+ auto rawImgP010 = rawImg.getImageHandle();
- mRawP010ImageWithStride.width = 0;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
- DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image width";
+ rawImgP010->width = kWidth - 1;
+ rawImgP010->height = kHeight;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad image width";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = 0;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
- DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image height";
+ rawImgP010->width = kWidth;
+ rawImgP010->height = kHeight - 1;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad image height";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.luma_stride = TEST_IMAGE_WIDTH - 2;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
- DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad luma stride";
+ rawImgP010->width = 0;
+ rawImgP010->height = kHeight;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad image width";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
- mRawP010ImageWithStride.chroma_data = mRawP010ImageWithStride.data;
- mRawP010ImageWithStride.chroma_stride = TEST_IMAGE_WIDTH - 2;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
- DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad chroma stride";
+ rawImgP010->width = kWidth;
+ rawImgP010->height = 0;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad image height";
- mRawP010ImageWithStride.chroma_data = nullptr;
+ rawImgP010->width = kWidth;
+ rawImgP010->height = kHeight;
+ rawImgP010->luma_stride = kWidth - 2;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad luma stride";
- free(jpegR.data);
+ rawImgP010->width = kWidth;
+ rawImgP010->height = kHeight;
+ rawImgP010->luma_stride = kWidth + 64;
+ rawImgP010->chroma_data = rawImgP010->data;
+ rawImgP010->chroma_stride = kWidth - 2;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad chroma stride";
+ }
}
/* Test Encode API-1 invalid arguments */
-TEST_F(JpegRTest, encodeAPI1ForInvalidArgs) {
- int ret;
+TEST(JpegRTest, EncodeAPI1WithInvalidArgs) {
+ JpegR uHdrLib;
- // we are not really compressing anything so lets keep allocs to a minimum
- jpegr_compressed_struct jpegR;
- jpegR.maxLength = 16 * sizeof(uint8_t);
- jpegR.data = malloc(jpegR.maxLength);
+ UhdrCompressedStructWrapper jpgImg(16, 16);
+ ASSERT_TRUE(jpgImg.allocateMemory());
- JpegR jpegRCodec;
+ // test quality factor and transfer function
+ {
+ UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
+ UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_420);
+ ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
+ ASSERT_TRUE(rawImg2.allocateMemory());
- // we are not really compressing anything so lets keep allocs to a minimum
- mRawP010ImageWithStride.data = malloc(16);
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
- mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), -1, nullptr),
+ OK)
+ << "fail, API allows bad jpeg quality factor";
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), 101, nullptr),
+ OK)
+ << "fail, API allows bad jpeg quality factor";
- // we are not really compressing anything so lets keep allocs to a minimum
- mRawYuv420Image.data = malloc(16);
- mRawYuv420Image.width = TEST_IMAGE_WIDTH;
- mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
- mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
-
- // test quality factor
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR, -1, nullptr)) << "fail, API allows bad jpeg quality factor";
-
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR, 101, nullptr)) << "fail, API allows bad jpeg quality factor";
-
- // test hdr transfer function
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image,
- ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED, &jpegR, DEFAULT_JPEG_QUALITY,
- nullptr)) << "fail, API allows bad hdr transfer function";
-
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image,
- static_cast<ultrahdr_transfer_function>(ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
- &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad hdr transfer function";
-
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image,
- static_cast<ultrahdr_transfer_function>(-10),
- &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad hdr transfer function";
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad hdr transfer function";
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
+ static_cast<ultrahdr_transfer_function>(
+ ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad hdr transfer function";
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
+ static_cast<ultrahdr_transfer_function>(-10),
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad hdr transfer function";
+ }
// test dest
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- nullptr, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows nullptr dest";
+ {
+ UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
+ UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_420);
+ ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
+ ASSERT_TRUE(rawImg2.allocateMemory());
+
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG, nullptr, kQuality,
+ nullptr),
+ OK)
+ << "fail, API allows nullptr dest";
+ UhdrCompressedStructWrapper jpgImg2(16, 16);
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg2.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows nullptr dest";
+ }
// test p010 input
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- nullptr, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
- DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows nullptr p010 image";
+ {
+ UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_420);
+ ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
+ ASSERT_TRUE(rawImg2.allocateMemory());
+ ASSERT_NE(uHdrLib.encodeJPEGR(nullptr, rawImg2.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows nullptr p010 image";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad p010 color gamut";
+ UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows nullptr p010 image";
+ }
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.colorGamut = static_cast<ultrahdr_color_gamut>(
- ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad p010 color gamut";
+ {
+ const int kWidth = 32, kHeight = 32;
+ UhdrUnCompressedStructWrapper rawImg(kWidth, kHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
+ auto rawImgP010 = rawImg.getImageHandle();
+ UhdrUnCompressedStructWrapper rawImg2(kWidth, kHeight, YCbCr_420);
+ ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
+ ASSERT_TRUE(rawImg2.allocateMemory());
+ auto rawImg420 = rawImg2.getImageHandle();
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH - 1;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image width";
+ rawImgP010->width = kWidth;
+ rawImgP010->height = kHeight;
+ rawImgP010->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad p010 color gamut";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT - 1;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image height";
+ rawImgP010->width = kWidth;
+ rawImgP010->height = kHeight;
+ rawImgP010->colorGamut =
+ static_cast<ultrahdr_color_gamut>(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad p010 color gamut";
- mRawP010ImageWithStride.width = 0;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image width";
+ rawImgP010->width = kWidth - 1;
+ rawImgP010->height = kHeight;
+ rawImgP010->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad image width";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = 0;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image height";
+ rawImgP010->width = kWidth;
+ rawImgP010->height = kHeight - 1;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad image height";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.luma_stride = TEST_IMAGE_WIDTH - 2;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad luma stride";
+ rawImgP010->width = 0;
+ rawImgP010->height = kHeight;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad image width";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
- mRawP010ImageWithStride.chroma_data = mRawP010ImageWithStride.data;
- mRawP010ImageWithStride.chroma_stride = TEST_IMAGE_WIDTH - 2;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad chroma stride";
+ rawImgP010->width = kWidth;
+ rawImgP010->height = 0;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad image height";
+
+ rawImgP010->width = kWidth;
+ rawImgP010->height = kHeight;
+ rawImgP010->luma_stride = kWidth - 2;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad luma stride";
+
+ rawImgP010->width = kWidth;
+ rawImgP010->height = kHeight;
+ rawImgP010->luma_stride = kWidth + 64;
+ rawImgP010->chroma_data = rawImgP010->data;
+ rawImgP010->chroma_stride = kWidth - 2;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad chroma stride";
+ }
// test 420 input
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
- mRawP010ImageWithStride.chroma_data = nullptr;
- mRawP010ImageWithStride.chroma_stride = 0;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, nullptr, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
- DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows nullptr for 420 image";
+ {
+ UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), nullptr,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows nullptr 420 image";
- mRawYuv420Image.width = TEST_IMAGE_WIDTH;
- mRawYuv420Image.height = TEST_IMAGE_HEIGHT - 2;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad 420 image width";
+ UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_420);
+ ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows nullptr 420 image";
+ }
+ {
+ const int kWidth = 32, kHeight = 32;
+ UhdrUnCompressedStructWrapper rawImg(kWidth, kHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
+ auto rawImgP010 = rawImg.getImageHandle();
+ UhdrUnCompressedStructWrapper rawImg2(kWidth, kHeight, YCbCr_420);
+ ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
+ ASSERT_TRUE(rawImg2.allocateMemory());
+ auto rawImg420 = rawImg2.getImageHandle();
- mRawYuv420Image.width = TEST_IMAGE_WIDTH - 2;
- mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad 420 image height";
+ rawImg420->width = kWidth;
+ rawImg420->height = kHeight;
+ rawImg420->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad 420 color gamut";
- mRawYuv420Image.width = TEST_IMAGE_WIDTH;
- mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
- mRawYuv420Image.luma_stride = TEST_IMAGE_STRIDE;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad luma stride for 420";
+ rawImg420->width = kWidth;
+ rawImg420->height = kHeight;
+ rawImg420->colorGamut =
+ static_cast<ultrahdr_color_gamut>(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad 420 color gamut";
- mRawYuv420Image.width = TEST_IMAGE_WIDTH;
- mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
- mRawYuv420Image.luma_stride = 0;
- mRawYuv420Image.chroma_data = mRawYuv420Image.data;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows chroma pointer for 420";
+ rawImg420->width = kWidth - 1;
+ rawImg420->height = kHeight;
+ rawImg420->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad image width for 420";
- mRawYuv420Image.width = TEST_IMAGE_WIDTH;
- mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
- mRawYuv420Image.luma_stride = 0;
- mRawYuv420Image.chroma_data = nullptr;
- mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad 420 color gamut";
+ rawImg420->width = kWidth;
+ rawImg420->height = kHeight - 1;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad image height for 420";
- mRawYuv420Image.colorGamut = static_cast<ultrahdr_color_gamut>(
- ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad 420 color gamut";
+ rawImg420->width = 0;
+ rawImg420->height = kHeight;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad image width for 420";
- free(jpegR.data);
+ rawImg420->width = kWidth;
+ rawImg420->height = 0;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad image height for 420";
+
+ rawImg420->width = kWidth;
+ rawImg420->height = kHeight;
+ rawImg420->luma_stride = kWidth;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows luma stride for 420";
+
+ rawImg420->width = kWidth;
+ rawImg420->height = kHeight;
+ rawImg420->luma_stride = 0;
+ rawImg420->chroma_data = rawImgP010->data;
+ rawImg420->chroma_stride = kWidth;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK)
+ << "fail, API allows bad chroma pointer for 420";
+ }
}
/* Test Encode API-2 invalid arguments */
-TEST_F(JpegRTest, encodeAPI2ForInvalidArgs) {
- int ret;
+TEST(JpegRTest, EncodeAPI2WithInvalidArgs) {
+ JpegR uHdrLib;
- // we are not really compressing anything so lets keep allocs to a minimum
- jpegr_compressed_struct jpegR;
- jpegR.maxLength = 16 * sizeof(uint8_t);
- jpegR.data = malloc(jpegR.maxLength);
+ UhdrCompressedStructWrapper jpgImg(16, 16);
+ ASSERT_TRUE(jpgImg.allocateMemory());
- JpegR jpegRCodec;
+ // test quality factor and transfer function
+ {
+ UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
+ UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_420);
+ ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
+ ASSERT_TRUE(rawImg2.allocateMemory());
- // we are not really compressing anything so lets keep allocs to a minimum
- mRawP010ImageWithStride.data = malloc(16);
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
- mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
-
- // we are not really compressing anything so lets keep allocs to a minimum
- mRawYuv420Image.data = malloc(16);
- mRawYuv420Image.width = TEST_IMAGE_WIDTH;
- mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
- mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
-
- // test hdr transfer function
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
- ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED,
- &jpegR)) << "fail, API allows bad hdr transfer function";
-
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
- static_cast<ultrahdr_transfer_function>(ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
- &jpegR)) << "fail, API allows bad hdr transfer function";
-
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
- static_cast<ultrahdr_transfer_function>(-10),
- &jpegR)) << "fail, API allows bad hdr transfer function";
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
+ jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad hdr transfer function";
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
+ jpgImg.getImageHandle(),
+ static_cast<ultrahdr_transfer_function>(
+ ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad hdr transfer function";
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
+ jpgImg.getImageHandle(),
+ static_cast<ultrahdr_transfer_function>(-10),
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad hdr transfer function";
+ }
// test dest
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
- ultrahdr_transfer_function::ULTRAHDR_TF_HLG, nullptr)) << "fail, API allows nullptr dest";
+ {
+ UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
+ UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_420);
+ ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
+ ASSERT_TRUE(rawImg2.allocateMemory());
+
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
+ jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG, nullptr),
+ OK)
+ << "fail, API allows nullptr dest";
+ UhdrCompressedStructWrapper jpgImg2(16, 16);
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
+ jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg2.getImageHandle()),
+ OK)
+ << "fail, API allows nullptr dest";
+ }
+
+ // test compressed image
+ {
+ UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
+ UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_420);
+ ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
+ ASSERT_TRUE(rawImg2.allocateMemory());
+
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(), nullptr,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows nullptr for compressed image";
+ UhdrCompressedStructWrapper jpgImg2(16, 16);
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
+ jpgImg2.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows nullptr for compressed image";
+ }
// test p010 input
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- nullptr, &mRawYuv420Image, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows nullptr p010 image";
+ {
+ UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_420);
+ ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
+ ASSERT_TRUE(rawImg2.allocateMemory());
+ ASSERT_NE(uHdrLib.encodeJPEGR(nullptr, rawImg2.getImageHandle(), jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows nullptr p010 image";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
- ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows bad p010 color gamut";
+ UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
+ jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows nullptr p010 image";
+ }
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.colorGamut = static_cast<ultrahdr_color_gamut>(
- ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
- ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows bad p010 color gamut";
+ {
+ const int kWidth = 32, kHeight = 32;
+ UhdrUnCompressedStructWrapper rawImg(kWidth, kHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
+ auto rawImgP010 = rawImg.getImageHandle();
+ UhdrUnCompressedStructWrapper rawImg2(kWidth, kHeight, YCbCr_420);
+ ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
+ ASSERT_TRUE(rawImg2.allocateMemory());
+ auto rawImg420 = rawImg2.getImageHandle();
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH - 1;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
- ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR)) << "fail, API allows bad image width";
+ rawImgP010->width = kWidth;
+ rawImgP010->height = kHeight;
+ rawImgP010->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad p010 color gamut";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT - 1;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
- ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR)) << "fail, API allows bad image height";
+ rawImgP010->width = kWidth;
+ rawImgP010->height = kHeight;
+ rawImgP010->colorGamut =
+ static_cast<ultrahdr_color_gamut>(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad p010 color gamut";
- mRawP010ImageWithStride.width = 0;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
- ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR)) << "fail, API allows bad image width";
+ rawImgP010->width = kWidth - 1;
+ rawImgP010->height = kHeight;
+ rawImgP010->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad image width";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = 0;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
- ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR)) << "fail, API allows bad image height";
+ rawImgP010->width = kWidth;
+ rawImgP010->height = kHeight - 1;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad image height";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.luma_stride = TEST_IMAGE_WIDTH - 2;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
- ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR)) << "fail, API allows bad luma stride";
+ rawImgP010->width = 0;
+ rawImgP010->height = kHeight;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad image width";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
- mRawP010ImageWithStride.chroma_data = mRawP010ImageWithStride.data;
- mRawP010ImageWithStride.chroma_stride = TEST_IMAGE_WIDTH - 2;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
- ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows bad chroma stride";
+ rawImgP010->width = kWidth;
+ rawImgP010->height = 0;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad image height";
+
+ rawImgP010->width = kWidth;
+ rawImgP010->height = kHeight;
+ rawImgP010->luma_stride = kWidth - 2;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad luma stride";
+
+ rawImgP010->width = kWidth;
+ rawImgP010->height = kHeight;
+ rawImgP010->luma_stride = kWidth + 64;
+ rawImgP010->chroma_data = rawImgP010->data;
+ rawImgP010->chroma_stride = kWidth - 2;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad chroma stride";
+ }
// test 420 input
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
- mRawP010ImageWithStride.chroma_data = nullptr;
- mRawP010ImageWithStride.chroma_stride = 0;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, nullptr, &jpegR,
- ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows nullptr for 420 image";
+ {
+ UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), nullptr, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows nullptr 420 image";
- mRawYuv420Image.width = TEST_IMAGE_WIDTH;
- mRawYuv420Image.height = TEST_IMAGE_HEIGHT - 2;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
- ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows bad 420 image width";
+ UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_420);
+ ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
+ jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows nullptr 420 image";
+ }
+ {
+ const int kWidth = 32, kHeight = 32;
+ UhdrUnCompressedStructWrapper rawImg(kWidth, kHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
+ auto rawImgP010 = rawImg.getImageHandle();
+ UhdrUnCompressedStructWrapper rawImg2(kWidth, kHeight, YCbCr_420);
+ ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
+ ASSERT_TRUE(rawImg2.allocateMemory());
+ auto rawImg420 = rawImg2.getImageHandle();
- mRawYuv420Image.width = TEST_IMAGE_WIDTH - 2;
- mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
- ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows bad 420 image height";
+ rawImg420->width = kWidth;
+ rawImg420->height = kHeight;
+ rawImg420->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad 420 color gamut";
- mRawYuv420Image.width = TEST_IMAGE_WIDTH;
- mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
- mRawYuv420Image.luma_stride = TEST_IMAGE_STRIDE;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
- ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows bad luma stride for 420";
+ rawImg420->width = kWidth;
+ rawImg420->height = kHeight;
+ rawImg420->colorGamut =
+ static_cast<ultrahdr_color_gamut>(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad 420 color gamut";
- mRawYuv420Image.width = TEST_IMAGE_WIDTH;
- mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
- mRawYuv420Image.luma_stride = 0;
- mRawYuv420Image.chroma_data = mRawYuv420Image.data;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
- ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows chroma pointer for 420";
+ rawImg420->width = kWidth - 1;
+ rawImg420->height = kHeight;
+ rawImg420->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad image width for 420";
- mRawYuv420Image.width = TEST_IMAGE_WIDTH;
- mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
- mRawYuv420Image.luma_stride = 0;
- mRawYuv420Image.chroma_data = nullptr;
- mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
- ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows bad 420 color gamut";
+ rawImg420->width = kWidth;
+ rawImg420->height = kHeight - 1;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad image height for 420";
- mRawYuv420Image.colorGamut = static_cast<ultrahdr_color_gamut>(
- ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
- ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows bad 420 color gamut";
+ rawImg420->width = 0;
+ rawImg420->height = kHeight;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad image width for 420";
- // bad compressed image
- mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &mRawYuv420Image, nullptr,
- ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows bad 420 color gamut";
+ rawImg420->width = kWidth;
+ rawImg420->height = 0;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad image height for 420";
- free(jpegR.data);
+ rawImg420->width = kWidth;
+ rawImg420->height = kHeight;
+ rawImg420->luma_stride = kWidth;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows luma stride for 420";
+
+ rawImg420->width = kWidth;
+ rawImg420->height = kHeight;
+ rawImg420->luma_stride = 0;
+ rawImg420->chroma_data = rawImgP010->data;
+ rawImg420->chroma_stride = kWidth;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad chroma pointer for 420";
+ }
}
/* Test Encode API-3 invalid arguments */
-TEST_F(JpegRTest, encodeAPI3ForInvalidArgs) {
- int ret;
+TEST(JpegRTest, EncodeAPI3WithInvalidArgs) {
+ JpegR uHdrLib;
- // we are not really compressing anything so lets keep allocs to a minimum
- jpegr_compressed_struct jpegR;
- jpegR.maxLength = 16 * sizeof(uint8_t);
- jpegR.data = malloc(jpegR.maxLength);
+ UhdrCompressedStructWrapper jpgImg(16, 16);
+ ASSERT_TRUE(jpgImg.allocateMemory());
- JpegR jpegRCodec;
+ // test quality factor and transfer function
+ {
+ UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
- // we are not really compressing anything so lets keep allocs to a minimum
- mRawP010ImageWithStride.data = malloc(16);
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
- mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
-
- // test hdr transfer function
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED,
- &jpegR)) << "fail, API allows bad hdr transfer function";
-
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &jpegR,
- static_cast<ultrahdr_transfer_function>(ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
- &jpegR)) << "fail, API allows bad hdr transfer function";
-
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &jpegR, static_cast<ultrahdr_transfer_function>(-10),
- &jpegR)) << "fail, API allows bad hdr transfer function";
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad hdr transfer function";
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), jpgImg.getImageHandle(),
+ static_cast<ultrahdr_transfer_function>(
+ ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad hdr transfer function";
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), jpgImg.getImageHandle(),
+ static_cast<ultrahdr_transfer_function>(-10),
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad hdr transfer function";
+ }
// test dest
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- nullptr)) << "fail, API allows nullptr dest";
+ {
+ UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
+
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG, nullptr),
+ OK)
+ << "fail, API allows nullptr dest";
+ UhdrCompressedStructWrapper jpgImg2(16, 16);
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg2.getImageHandle()),
+ OK)
+ << "fail, API allows nullptr dest";
+ }
+
+ // test compressed image
+ {
+ UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
+
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), nullptr,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows nullptr for compressed image";
+ UhdrCompressedStructWrapper jpgImg2(16, 16);
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), jpgImg2.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows nullptr for compressed image";
+ }
// test p010 input
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- nullptr, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows nullptr p010 image";
+ {
+ ASSERT_NE(uHdrLib.encodeJPEGR(nullptr, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows nullptr p010 image";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows bad p010 color gamut";
+ UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows nullptr p010 image";
+ }
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.colorGamut = static_cast<ultrahdr_color_gamut>(
- ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows bad p010 color gamut";
+ {
+ const int kWidth = 32, kHeight = 32;
+ UhdrUnCompressedStructWrapper rawImg(kWidth, kHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
+ auto rawImgP010 = rawImg.getImageHandle();
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH - 1;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows bad image width";
+ rawImgP010->width = kWidth;
+ rawImgP010->height = kHeight;
+ rawImgP010->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad p010 color gamut";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT - 1;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows bad image height";
+ rawImgP010->width = kWidth;
+ rawImgP010->height = kHeight;
+ rawImgP010->colorGamut =
+ static_cast<ultrahdr_color_gamut>(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad p010 color gamut";
- mRawP010ImageWithStride.width = 0;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows bad image width";
+ rawImgP010->width = kWidth - 1;
+ rawImgP010->height = kHeight;
+ rawImgP010->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad image width";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = 0;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows bad image height";
+ rawImgP010->width = kWidth;
+ rawImgP010->height = kHeight - 1;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad image height";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.luma_stride = TEST_IMAGE_WIDTH - 2;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows bad luma stride";
+ rawImgP010->width = 0;
+ rawImgP010->height = kHeight;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad image width";
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
- mRawP010ImageWithStride.chroma_data = mRawP010ImageWithStride.data;
- mRawP010ImageWithStride.chroma_stride = TEST_IMAGE_WIDTH - 2;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows bad chroma stride";
- mRawP010ImageWithStride.chroma_data = nullptr;
+ rawImgP010->width = kWidth;
+ rawImgP010->height = 0;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad image height";
- // bad compressed image
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, nullptr, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR)) << "fail, API allows bad 420 color gamut";
+ rawImgP010->width = kWidth;
+ rawImgP010->height = kHeight;
+ rawImgP010->luma_stride = kWidth - 2;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad luma stride";
- free(jpegR.data);
+ rawImgP010->width = kWidth;
+ rawImgP010->height = kHeight;
+ rawImgP010->luma_stride = kWidth + 64;
+ rawImgP010->chroma_data = rawImgP010->data;
+ rawImgP010->chroma_stride = kWidth - 2;
+ ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, jpgImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad chroma stride";
+ }
}
/* Test Encode API-4 invalid arguments */
-TEST_F(JpegRTest, encodeAPI4ForInvalidArgs) {
- int ret;
-
- // we are not really compressing anything so lets keep allocs to a minimum
- jpegr_compressed_struct jpegR;
- jpegR.maxLength = 16 * sizeof(uint8_t);
- jpegR.data = malloc(jpegR.maxLength);
-
- JpegR jpegRCodec;
+TEST(JpegRTest, EncodeAPI4WithInvalidArgs) {
+ UhdrCompressedStructWrapper jpgImg(16, 16);
+ ASSERT_TRUE(jpgImg.allocateMemory());
+ UhdrCompressedStructWrapper jpgImg2(16, 16);
+ JpegR uHdrLib;
// test dest
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &jpegR, &jpegR, nullptr, nullptr)) << "fail, API allows nullptr dest";
+ ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg.getImageHandle(), nullptr, nullptr),
+ OK)
+ << "fail, API allows nullptr dest";
+ ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg.getImageHandle(), nullptr,
+ jpgImg2.getImageHandle()),
+ OK)
+ << "fail, API allows nullptr dest";
// test primary image
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- nullptr, &jpegR, nullptr, &jpegR)) << "fail, API allows nullptr primary image";
+ ASSERT_NE(uHdrLib.encodeJPEGR(nullptr, jpgImg.getImageHandle(), nullptr, jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows nullptr primary image";
+ ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg2.getImageHandle(), jpgImg.getImageHandle(), nullptr,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows nullptr primary image";
// test gain map
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &jpegR, nullptr, nullptr, &jpegR)) << "fail, API allows nullptr gainmap image";
+ ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), nullptr, nullptr, jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows nullptr gain map image";
+ ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg2.getImageHandle(), nullptr,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows nullptr gain map image";
// test metadata
ultrahdr_metadata_struct good_metadata;
@@ -832,82 +1254,95 @@
ultrahdr_metadata_struct metadata = good_metadata;
metadata.version = "1.1";
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata version";
+ ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg.getImageHandle(), &metadata,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad metadata version";
metadata = good_metadata;
metadata.minContentBoost = 3.0f;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata content boost";
+ ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg.getImageHandle(), &metadata,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad metadata content boost";
metadata = good_metadata;
metadata.gamma = -0.1f;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata gamma";
+ ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg.getImageHandle(), &metadata,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad metadata gamma";
metadata = good_metadata;
metadata.offsetSdr = -0.1f;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata offset sdr";
+ ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg.getImageHandle(), &metadata,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad metadata offset sdr";
metadata = good_metadata;
metadata.offsetHdr = -0.1f;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata offset hdr";
+ ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg.getImageHandle(), &metadata,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad metadata offset hdr";
metadata = good_metadata;
metadata.hdrCapacityMax = 0.5f;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata hdr capacity max";
+ ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg.getImageHandle(), &metadata,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad metadata hdr capacity max";
metadata = good_metadata;
metadata.hdrCapacityMin = 0.5f;
- EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
- &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata hdr capacity min";
-
- free(jpegR.data);
+ ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg.getImageHandle(), &metadata,
+ jpgImg.getImageHandle()),
+ OK)
+ << "fail, API allows bad metadata hdr capacity min";
}
/* Test Decode API invalid arguments */
-TEST_F(JpegRTest, decodeAPIForInvalidArgs) {
- int ret;
+TEST(JpegRTest, DecodeAPIWithInvalidArgs) {
+ JpegR uHdrLib;
- // we are not really compressing anything so lets keep allocs to a minimum
- jpegr_compressed_struct jpegR;
- jpegR.maxLength = 16 * sizeof(uint8_t);
- jpegR.data = malloc(jpegR.maxLength);
-
- // we are not really decoding anything so lets keep allocs to a minimum
- mRawP010Image.data = malloc(16);
-
- JpegR jpegRCodec;
+ UhdrCompressedStructWrapper jpgImg(16, 16);
+ jpegr_uncompressed_struct destImage{};
+ size_t outSize = 16 * 16 * 8;
+ std::unique_ptr<uint8_t[]> data = std::make_unique<uint8_t[]>(outSize);
+ destImage.data = data.get();
// test jpegr image
- EXPECT_NE(OK, jpegRCodec.decodeJPEGR(
- nullptr, &mRawP010Image)) << "fail, API allows nullptr for jpegr img";
+ ASSERT_NE(uHdrLib.decodeJPEGR(nullptr, &destImage), OK)
+ << "fail, API allows nullptr for jpegr img";
+ ASSERT_NE(uHdrLib.decodeJPEGR(jpgImg.getImageHandle(), &destImage), OK)
+ << "fail, API allows nullptr for jpegr img";
+ ASSERT_TRUE(jpgImg.allocateMemory());
// test dest image
- EXPECT_NE(OK, jpegRCodec.decodeJPEGR(
- &jpegR, nullptr)) << "fail, API allows nullptr for dest";
+ ASSERT_NE(uHdrLib.decodeJPEGR(jpgImg.getImageHandle(), nullptr), OK)
+ << "fail, API allows nullptr for dest";
+ destImage.data = nullptr;
+ ASSERT_NE(uHdrLib.decodeJPEGR(jpgImg.getImageHandle(), &destImage), OK)
+ << "fail, API allows nullptr for dest";
+ destImage.data = data.get();
// test max display boost
- EXPECT_NE(OK, jpegRCodec.decodeJPEGR(
- &jpegR, &mRawP010Image, 0.5)) << "fail, API allows invalid max display boost";
+ ASSERT_NE(uHdrLib.decodeJPEGR(jpgImg.getImageHandle(), &destImage, 0.5), OK)
+ << "fail, API allows invalid max display boost";
// test output format
- EXPECT_NE(OK, jpegRCodec.decodeJPEGR(
- &jpegR, &mRawP010Image, 0.5, nullptr,
- static_cast<ultrahdr_output_format>(-1))) << "fail, API allows invalid output format";
-
- EXPECT_NE(OK, jpegRCodec.decodeJPEGR(
- &jpegR, &mRawP010Image, 0.5, nullptr,
- static_cast<ultrahdr_output_format>(ULTRAHDR_OUTPUT_MAX + 1)))
- << "fail, API allows invalid output format";
-
- free(jpegR.data);
+ ASSERT_NE(uHdrLib.decodeJPEGR(jpgImg.getImageHandle(), &destImage, FLT_MAX, nullptr,
+ static_cast<ultrahdr_output_format>(-1)),
+ OK)
+ << "fail, API allows invalid output format";
+ ASSERT_NE(uHdrLib.decodeJPEGR(jpgImg.getImageHandle(), &destImage, FLT_MAX, nullptr,
+ static_cast<ultrahdr_output_format>(ULTRAHDR_OUTPUT_MAX + 1)),
+ OK)
+ << "fail, API allows invalid output format";
}
-TEST_F(JpegRTest, writeXmpThenRead) {
+TEST(JpegRTest, writeXmpThenRead) {
ultrahdr_metadata_struct metadata_expected;
metadata_expected.version = "1.0";
metadata_expected.maxContentBoost = 1.25f;
@@ -918,16 +1353,16 @@
metadata_expected.hdrCapacityMin = 1.0f;
metadata_expected.hdrCapacityMax = metadata_expected.maxContentBoost;
const std::string nameSpace = "http://ns.adobe.com/xap/1.0/\0";
- const int nameSpaceLength = nameSpace.size() + 1; // need to count the null terminator
+ const int nameSpaceLength = nameSpace.size() + 1; // need to count the null terminator
std::string xmp = generateXmpForSecondaryImage(metadata_expected);
std::vector<uint8_t> xmpData;
xmpData.reserve(nameSpaceLength + xmp.size());
xmpData.insert(xmpData.end(), reinterpret_cast<const uint8_t*>(nameSpace.c_str()),
- reinterpret_cast<const uint8_t*>(nameSpace.c_str()) + nameSpaceLength);
+ reinterpret_cast<const uint8_t*>(nameSpace.c_str()) + nameSpaceLength);
xmpData.insert(xmpData.end(), reinterpret_cast<const uint8_t*>(xmp.c_str()),
- reinterpret_cast<const uint8_t*>(xmp.c_str()) + xmp.size());
+ reinterpret_cast<const uint8_t*>(xmp.c_str()) + xmp.size());
ultrahdr_metadata_struct metadata_read;
EXPECT_TRUE(getMetadataFromXMP(xmpData.data(), xmpData.size(), &metadata_read));
@@ -940,436 +1375,441 @@
EXPECT_FLOAT_EQ(metadata_expected.hdrCapacityMax, metadata_read.hdrCapacityMax);
}
-/* Test Encode API-0 */
-TEST_F(JpegRTest, encodeFromP010) {
- int ret;
-
- mRawP010Image.width = TEST_IMAGE_WIDTH;
- mRawP010Image.height = TEST_IMAGE_HEIGHT;
- mRawP010Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
- // Load input files.
- if (!loadP010Image(RAW_P010_IMAGE, &mRawP010Image, true)) {
- FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
+/* Test Encode API-0 and Decode */
+TEST(JpegRTest, EncodeAPI0AndDecodeTest) {
+ // reference encode
+ UhdrUnCompressedStructWrapper rawImg(kImageWidth, kImageHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg.allocateMemory());
+ ASSERT_TRUE(rawImg.loadRawResource(kYCbCrP010FileName));
+ UhdrCompressedStructWrapper jpgImg(kImageWidth, kImageHeight);
+ ASSERT_TRUE(jpgImg.allocateMemory());
+ JpegR uHdrLib;
+ ASSERT_EQ(uHdrLib.encodeJPEGR(rawImg.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK);
+ // encode with luma stride set
+ {
+ UhdrUnCompressedStructWrapper rawImg2(kImageWidth, kImageHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg2.setImageStride(kImageWidth + 128, 0));
+ ASSERT_TRUE(rawImg2.allocateMemory());
+ ASSERT_TRUE(rawImg2.loadRawResource(kYCbCrP010FileName));
+ UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
+ ASSERT_TRUE(jpgImg2.allocateMemory());
+ ASSERT_EQ(uHdrLib.encodeJPEGR(rawImg2.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg2.getImageHandle(), kQuality, nullptr),
+ OK);
+ auto jpg1 = jpgImg.getImageHandle();
+ auto jpg2 = jpgImg2.getImageHandle();
+ ASSERT_EQ(jpg1->length, jpg2->length);
+ ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
+ }
+ // encode with luma and chroma stride set
+ {
+ UhdrUnCompressedStructWrapper rawImg2(kImageWidth, kImageHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg2.setImageStride(kImageWidth + 128, kImageWidth + 256));
+ ASSERT_TRUE(rawImg2.setChromaMode(false));
+ ASSERT_TRUE(rawImg2.allocateMemory());
+ ASSERT_TRUE(rawImg2.loadRawResource(kYCbCrP010FileName));
+ UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
+ ASSERT_TRUE(jpgImg2.allocateMemory());
+ ASSERT_EQ(uHdrLib.encodeJPEGR(rawImg2.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg2.getImageHandle(), kQuality, nullptr),
+ OK);
+ auto jpg1 = jpgImg.getImageHandle();
+ auto jpg2 = jpgImg2.getImageHandle();
+ ASSERT_EQ(jpg1->length, jpg2->length);
+ ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
+ }
+ // encode with chroma stride set
+ {
+ UhdrUnCompressedStructWrapper rawImg2(kImageWidth, kImageHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg2.setImageStride(0, kImageWidth + 64));
+ ASSERT_TRUE(rawImg2.setChromaMode(false));
+ ASSERT_TRUE(rawImg2.allocateMemory());
+ ASSERT_TRUE(rawImg2.loadRawResource(kYCbCrP010FileName));
+ UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
+ ASSERT_TRUE(jpgImg2.allocateMemory());
+ ASSERT_EQ(uHdrLib.encodeJPEGR(rawImg2.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg2.getImageHandle(), kQuality, nullptr),
+ OK);
+ auto jpg1 = jpgImg.getImageHandle();
+ auto jpg2 = jpgImg2.getImageHandle();
+ ASSERT_EQ(jpg1->length, jpg2->length);
+ ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
}
- JpegR jpegRCodec;
-
- jpegr_compressed_struct jpegR;
- jpegR.maxLength = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * sizeof(uint8_t);
- jpegR.data = malloc(jpegR.maxLength);
- ret = jpegRCodec.encodeJPEGR(
- &mRawP010Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR, DEFAULT_JPEG_QUALITY,
- nullptr);
- if (ret != OK) {
- FAIL() << "Error code is " << ret;
+ auto jpg1 = jpgImg.getImageHandle();
+#ifdef DUMP_OUTPUT
+ if (!writeFile("encode_api0_output.jpeg", jpg1->data, jpg1->length)) {
+ std::cerr << "unable to write output file" << std::endl;
}
+#endif
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.luma_stride = TEST_IMAGE_WIDTH + 128;
- mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
- // Load input files.
- if (!loadP010Image(RAW_P010_IMAGE, &mRawP010ImageWithStride, true)) {
- FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
- }
-
- jpegr_compressed_struct jpegRWithStride;
- jpegRWithStride.maxLength = jpegR.length;
- jpegRWithStride.data = malloc(jpegRWithStride.maxLength);
- ret = jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegRWithStride,
- DEFAULT_JPEG_QUALITY, nullptr);
- if (ret != OK) {
- FAIL() << "Error code is " << ret;
- }
- ASSERT_EQ(jpegR.length, jpegRWithStride.length)
- << "Same input is yielding different output";
- ASSERT_EQ(0, memcmp(jpegR.data, jpegRWithStride.data, jpegR.length))
- << "Same input is yielding different output";
-
- mRawP010ImageWithChromaData.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithChromaData.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithChromaData.luma_stride = TEST_IMAGE_WIDTH + 64;
- mRawP010ImageWithChromaData.chroma_stride = TEST_IMAGE_WIDTH + 256;
- mRawP010ImageWithChromaData.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
- // Load input files.
- if (!loadP010Image(RAW_P010_IMAGE, &mRawP010ImageWithChromaData, false)) {
- FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
- }
- jpegr_compressed_struct jpegRWithChromaData;
- jpegRWithChromaData.maxLength = jpegR.length;
- jpegRWithChromaData.data = malloc(jpegRWithChromaData.maxLength);
- ret = jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithChromaData, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegRWithChromaData, DEFAULT_JPEG_QUALITY, nullptr);
- if (ret != OK) {
- FAIL() << "Error code is " << ret;
- }
- ASSERT_EQ(jpegR.length, jpegRWithChromaData.length)
- << "Same input is yielding different output";
- ASSERT_EQ(0, memcmp(jpegR.data, jpegRWithChromaData.data, jpegR.length))
- << "Same input is yielding different output";
-
- free(jpegR.data);
- free(jpegRWithStride.data);
- free(jpegRWithChromaData.data);
+ ASSERT_NO_FATAL_FAILURE(decodeJpegRImg(jpg1, "decode_api0_output.rgb"));
}
-/* Test Encode API-0 and decode */
-TEST_F(JpegRTest, encodeFromP010ThenDecode) {
- int ret;
-
- // Load input files.
- if (!loadFile(RAW_P010_IMAGE, mRawP010Image.data, nullptr)) {
- FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
+/* Test Encode API-1 and Decode */
+TEST(JpegRTest, EncodeAPI1AndDecodeTest) {
+ UhdrUnCompressedStructWrapper rawImgP010(kImageWidth, kImageHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImgP010.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImgP010.allocateMemory());
+ ASSERT_TRUE(rawImgP010.loadRawResource(kYCbCrP010FileName));
+ UhdrUnCompressedStructWrapper rawImg420(kImageWidth, kImageHeight, YCbCr_420);
+ ASSERT_TRUE(rawImg420.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
+ ASSERT_TRUE(rawImg420.allocateMemory());
+ ASSERT_TRUE(rawImg420.loadRawResource(kYCbCr420FileName));
+ UhdrCompressedStructWrapper jpgImg(kImageWidth, kImageHeight);
+ ASSERT_TRUE(jpgImg.allocateMemory());
+ JpegR uHdrLib;
+ ASSERT_EQ(uHdrLib.encodeJPEGR(rawImgP010.getImageHandle(), rawImg420.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle(), kQuality, nullptr),
+ OK);
+ // encode with luma stride set
+ {
+ UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg2P010.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg2P010.setImageStride(kImageWidth + 128, 0));
+ ASSERT_TRUE(rawImg2P010.allocateMemory());
+ ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
+ UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
+ ASSERT_TRUE(jpgImg2.allocateMemory());
+ ASSERT_EQ(uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), rawImg420.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg2.getImageHandle(), kQuality, nullptr),
+ OK);
+ auto jpg1 = jpgImg.getImageHandle();
+ auto jpg2 = jpgImg2.getImageHandle();
+ ASSERT_EQ(jpg1->length, jpg2->length);
+ ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
}
- mRawP010Image.width = TEST_IMAGE_WIDTH;
- mRawP010Image.height = TEST_IMAGE_HEIGHT;
- mRawP010Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
-
- JpegR jpegRCodec;
-
- jpegr_compressed_struct jpegR;
- jpegR.maxLength = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * sizeof(uint8_t);
- jpegR.data = malloc(jpegR.maxLength);
- ret = jpegRCodec.encodeJPEGR(
- &mRawP010Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR, DEFAULT_JPEG_QUALITY,
- nullptr);
- if (ret != OK) {
- FAIL() << "Error code is " << ret;
+ // encode with luma and chroma stride set
+ {
+ UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg2P010.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg2P010.setImageStride(kImageWidth + 128, kImageWidth + 256));
+ ASSERT_TRUE(rawImg2P010.setChromaMode(false));
+ ASSERT_TRUE(rawImg2P010.allocateMemory());
+ ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
+ UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
+ ASSERT_TRUE(jpgImg2.allocateMemory());
+ ASSERT_EQ(uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), rawImg420.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg2.getImageHandle(), kQuality, nullptr),
+ OK);
+ auto jpg1 = jpgImg.getImageHandle();
+ auto jpg2 = jpgImg2.getImageHandle();
+ ASSERT_EQ(jpg1->length, jpg2->length);
+ ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
}
- if (SAVE_ENCODING_RESULT) {
- // Output image data to file
- std::string filePath = "/sdcard/Documents/encoded_from_p010_input.jpgr";
- std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
- if (!imageFile.is_open()) {
- ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
- }
- imageFile.write((const char*)jpegR.data, jpegR.length);
+ // encode with chroma stride set
+ {
+ UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg2P010.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg2P010.setImageStride(0, kImageWidth + 64));
+ ASSERT_TRUE(rawImg2P010.setChromaMode(false));
+ ASSERT_TRUE(rawImg2P010.allocateMemory());
+ ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
+ UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
+ ASSERT_TRUE(jpgImg2.allocateMemory());
+ ASSERT_EQ(uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), rawImg420.getImageHandle(),
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg2.getImageHandle(), kQuality, nullptr),
+ OK);
+ auto jpg1 = jpgImg.getImageHandle();
+ auto jpg2 = jpgImg2.getImageHandle();
+ ASSERT_EQ(jpg1->length, jpg2->length);
+ ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
}
- jpegr_uncompressed_struct decodedJpegR;
- int decodedJpegRSize = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * 8;
- decodedJpegR.data = malloc(decodedJpegRSize);
- ret = jpegRCodec.decodeJPEGR(&jpegR, &decodedJpegR);
- if (ret != OK) {
- FAIL() << "Error code is " << ret;
- }
- if (SAVE_DECODING_RESULT) {
- // Output image data to file
- std::string filePath = "/sdcard/Documents/decoded_from_p010_input.rgb";
- std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
- if (!imageFile.is_open()) {
- ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
- }
- imageFile.write((const char*)decodedJpegR.data, decodedJpegRSize);
- }
+ auto jpg1 = jpgImg.getImageHandle();
- free(jpegR.data);
- free(decodedJpegR.data);
+#ifdef DUMP_OUTPUT
+ if (!writeFile("encode_api1_output.jpeg", jpg1->data, jpg1->length)) {
+ std::cerr << "unable to write output file" << std::endl;
+ }
+#endif
+
+ ASSERT_NO_FATAL_FAILURE(decodeJpegRImg(jpg1, "decode_api1_output.rgb"));
}
-/* Test Encode API-0 (with stride) and decode */
-TEST_F(JpegRTest, encodeFromP010WithStrideThenDecode) {
- int ret;
-
- // Load input files.
- if (!loadFile(RAW_P010_IMAGE_WITH_STRIDE, mRawP010ImageWithStride.data, nullptr)) {
- FAIL() << "Load file " << RAW_P010_IMAGE_WITH_STRIDE << " failed";
+/* Test Encode API-2 and Decode */
+TEST(JpegRTest, EncodeAPI2AndDecodeTest) {
+ UhdrUnCompressedStructWrapper rawImgP010(kImageWidth, kImageHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImgP010.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImgP010.allocateMemory());
+ ASSERT_TRUE(rawImgP010.loadRawResource(kYCbCrP010FileName));
+ UhdrUnCompressedStructWrapper rawImg420(kImageWidth, kImageHeight, YCbCr_420);
+ ASSERT_TRUE(rawImg420.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
+ ASSERT_TRUE(rawImg420.allocateMemory());
+ ASSERT_TRUE(rawImg420.loadRawResource(kYCbCr420FileName));
+ UhdrCompressedStructWrapper jpgImg(kImageWidth, kImageHeight);
+ ASSERT_TRUE(jpgImg.allocateMemory());
+ UhdrCompressedStructWrapper jpgSdr(kImageWidth, kImageHeight);
+ ASSERT_TRUE(jpgSdr.allocateMemory());
+ auto sdr = jpgSdr.getImageHandle();
+ ASSERT_TRUE(readFile(kSdrJpgFileName, sdr->data, sdr->maxLength, sdr->length));
+ JpegR uHdrLib;
+ ASSERT_EQ(uHdrLib.encodeJPEGR(rawImgP010.getImageHandle(), rawImg420.getImageHandle(), sdr,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK);
+ // encode with luma stride set
+ {
+ UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg2P010.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg2P010.setImageStride(kImageWidth + 128, 0));
+ ASSERT_TRUE(rawImg2P010.allocateMemory());
+ ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
+ UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
+ ASSERT_TRUE(jpgImg2.allocateMemory());
+ ASSERT_EQ(uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), rawImg420.getImageHandle(), sdr,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg2.getImageHandle()),
+ OK);
+ auto jpg1 = jpgImg.getImageHandle();
+ auto jpg2 = jpgImg2.getImageHandle();
+ ASSERT_EQ(jpg1->length, jpg2->length);
+ ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
}
- mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
- mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
- mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
- mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
-
- JpegR jpegRCodec;
-
- jpegr_compressed_struct jpegR;
- jpegR.maxLength = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * sizeof(uint8_t);
- jpegR.data = malloc(jpegR.maxLength);
- ret = jpegRCodec.encodeJPEGR(
- &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
- DEFAULT_JPEG_QUALITY, nullptr);
- if (ret != OK) {
- FAIL() << "Error code is " << ret;
+ // encode with luma and chroma stride set
+ {
+ UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg2P010.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg2P010.setImageStride(kImageWidth + 128, kImageWidth + 256));
+ ASSERT_TRUE(rawImg2P010.setChromaMode(false));
+ ASSERT_TRUE(rawImg2P010.allocateMemory());
+ ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
+ UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
+ ASSERT_TRUE(jpgImg2.allocateMemory());
+ ASSERT_EQ(uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), rawImg420.getImageHandle(), sdr,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg2.getImageHandle()),
+ OK);
+ auto jpg1 = jpgImg.getImageHandle();
+ auto jpg2 = jpgImg2.getImageHandle();
+ ASSERT_EQ(jpg1->length, jpg2->length);
+ ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
}
- if (SAVE_ENCODING_RESULT) {
- // Output image data to file
- std::string filePath = "/sdcard/Documents/encoded_from_p010_input.jpgr";
- std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
- if (!imageFile.is_open()) {
- ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
- }
- imageFile.write((const char*)jpegR.data, jpegR.length);
+ // encode with chroma stride set
+ {
+ UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg2P010.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg2P010.setImageStride(0, kImageWidth + 64));
+ ASSERT_TRUE(rawImg2P010.setChromaMode(false));
+ ASSERT_TRUE(rawImg2P010.allocateMemory());
+ ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
+ UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
+ ASSERT_TRUE(jpgImg2.allocateMemory());
+ ASSERT_EQ(uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), rawImg420.getImageHandle(), sdr,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg2.getImageHandle()),
+ OK);
+ auto jpg1 = jpgImg.getImageHandle();
+ auto jpg2 = jpgImg2.getImageHandle();
+ ASSERT_EQ(jpg1->length, jpg2->length);
+ ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
}
- jpegr_uncompressed_struct decodedJpegR;
- int decodedJpegRSize = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * 8;
- decodedJpegR.data = malloc(decodedJpegRSize);
- ret = jpegRCodec.decodeJPEGR(&jpegR, &decodedJpegR);
- if (ret != OK) {
- FAIL() << "Error code is " << ret;
- }
- if (SAVE_DECODING_RESULT) {
- // Output image data to file
- std::string filePath = "/sdcard/Documents/decoded_from_p010_input.rgb";
- std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
- if (!imageFile.is_open()) {
- ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
- }
- imageFile.write((const char*)decodedJpegR.data, decodedJpegRSize);
- }
+ auto jpg1 = jpgImg.getImageHandle();
- free(jpegR.data);
- free(decodedJpegR.data);
+#ifdef DUMP_OUTPUT
+ if (!writeFile("encode_api2_output.jpeg", jpg1->data, jpg1->length)) {
+ std::cerr << "unable to write output file" << std::endl;
+ }
+#endif
+
+ ASSERT_NO_FATAL_FAILURE(decodeJpegRImg(jpg1, "decode_api2_output.rgb"));
}
-/* Test Encode API-1 and decode */
-TEST_F(JpegRTest, encodeFromRawHdrAndSdrThenDecode) {
- int ret;
-
- // Load input files.
- if (!loadFile(RAW_P010_IMAGE, mRawP010Image.data, nullptr)) {
- FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
+/* Test Encode API-3 and Decode */
+TEST(JpegRTest, EncodeAPI3AndDecodeTest) {
+ UhdrUnCompressedStructWrapper rawImgP010(kImageWidth, kImageHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImgP010.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImgP010.allocateMemory());
+ ASSERT_TRUE(rawImgP010.loadRawResource(kYCbCrP010FileName));
+ UhdrCompressedStructWrapper jpgImg(kImageWidth, kImageHeight);
+ ASSERT_TRUE(jpgImg.allocateMemory());
+ UhdrCompressedStructWrapper jpgSdr(kImageWidth, kImageHeight);
+ ASSERT_TRUE(jpgSdr.allocateMemory());
+ auto sdr = jpgSdr.getImageHandle();
+ ASSERT_TRUE(readFile(kSdrJpgFileName, sdr->data, sdr->maxLength, sdr->length));
+ JpegR uHdrLib;
+ ASSERT_EQ(uHdrLib.encodeJPEGR(rawImgP010.getImageHandle(), sdr,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg.getImageHandle()),
+ OK);
+ // encode with luma stride set
+ {
+ UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg2P010.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg2P010.setImageStride(kImageWidth + 128, 0));
+ ASSERT_TRUE(rawImg2P010.allocateMemory());
+ ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
+ UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
+ ASSERT_TRUE(jpgImg2.allocateMemory());
+ ASSERT_EQ(uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), sdr,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg2.getImageHandle()),
+ OK);
+ auto jpg1 = jpgImg.getImageHandle();
+ auto jpg2 = jpgImg2.getImageHandle();
+ ASSERT_EQ(jpg1->length, jpg2->length);
+ ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
}
- mRawP010Image.width = TEST_IMAGE_WIDTH;
- mRawP010Image.height = TEST_IMAGE_HEIGHT;
- mRawP010Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
-
- if (!loadFile(RAW_YUV420_IMAGE, mRawYuv420Image.data, nullptr)) {
- FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
+ // encode with luma and chroma stride set
+ {
+ UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg2P010.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg2P010.setImageStride(kImageWidth + 128, kImageWidth + 256));
+ ASSERT_TRUE(rawImg2P010.setChromaMode(false));
+ ASSERT_TRUE(rawImg2P010.allocateMemory());
+ ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
+ UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
+ ASSERT_TRUE(jpgImg2.allocateMemory());
+ ASSERT_EQ(uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), sdr,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg2.getImageHandle()),
+ OK);
+ auto jpg1 = jpgImg.getImageHandle();
+ auto jpg2 = jpgImg2.getImageHandle();
+ ASSERT_EQ(jpg1->length, jpg2->length);
+ ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
}
- mRawYuv420Image.width = TEST_IMAGE_WIDTH;
- mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
- mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
-
- JpegR jpegRCodec;
-
- jpegr_compressed_struct jpegR;
- jpegR.maxLength = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * sizeof(uint8_t);
- jpegR.data = malloc(jpegR.maxLength);
- ret = jpegRCodec.encodeJPEGR(
- &mRawP010Image, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
- DEFAULT_JPEG_QUALITY, nullptr);
- if (ret != OK) {
- FAIL() << "Error code is " << ret;
- }
- if (SAVE_ENCODING_RESULT) {
- // Output image data to file
- std::string filePath = "/sdcard/Documents/encoded_from_p010_yuv420p_input.jpgr";
- std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
- if (!imageFile.is_open()) {
- ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
- }
- imageFile.write((const char*)jpegR.data, jpegR.length);
+ // encode with chroma stride set
+ {
+ UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImg2P010.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImg2P010.setImageStride(0, kImageWidth + 64));
+ ASSERT_TRUE(rawImg2P010.setChromaMode(false));
+ ASSERT_TRUE(rawImg2P010.allocateMemory());
+ ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
+ UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
+ ASSERT_TRUE(jpgImg2.allocateMemory());
+ ASSERT_EQ(uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), sdr,
+ ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ jpgImg2.getImageHandle()),
+ OK);
+ auto jpg1 = jpgImg.getImageHandle();
+ auto jpg2 = jpgImg2.getImageHandle();
+ ASSERT_EQ(jpg1->length, jpg2->length);
+ ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
}
- jpegr_uncompressed_struct decodedJpegR;
- int decodedJpegRSize = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * 8;
- decodedJpegR.data = malloc(decodedJpegRSize);
- ret = jpegRCodec.decodeJPEGR(&jpegR, &decodedJpegR);
- if (ret != OK) {
- FAIL() << "Error code is " << ret;
- }
- if (SAVE_DECODING_RESULT) {
- // Output image data to file
- std::string filePath = "/sdcard/Documents/decoded_from_p010_yuv420p_input.rgb";
- std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
- if (!imageFile.is_open()) {
- ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
- }
- imageFile.write((const char*)decodedJpegR.data, decodedJpegRSize);
- }
+ auto jpg1 = jpgImg.getImageHandle();
- free(jpegR.data);
- free(decodedJpegR.data);
+#ifdef DUMP_OUTPUT
+ if (!writeFile("encode_api3_output.jpeg", jpg1->data, jpg1->length)) {
+ std::cerr << "unable to write output file" << std::endl;
+ }
+#endif
+
+ ASSERT_NO_FATAL_FAILURE(decodeJpegRImg(jpg1, "decode_api3_output.rgb"));
}
-/* Test Encode API-2 and decode */
-TEST_F(JpegRTest, encodeFromRawHdrAndSdrAndJpegThenDecode) {
- int ret;
+// ============================================================================
+// Profiling
+// ============================================================================
- // Load input files.
- if (!loadFile(RAW_P010_IMAGE, mRawP010Image.data, nullptr)) {
- FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
- }
- mRawP010Image.width = TEST_IMAGE_WIDTH;
- mRawP010Image.height = TEST_IMAGE_HEIGHT;
- mRawP010Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
+class Profiler {
+public:
+ void timerStart() { gettimeofday(&mStartingTime, nullptr); }
- if (!loadFile(RAW_YUV420_IMAGE, mRawYuv420Image.data, nullptr)) {
- FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
- }
- mRawYuv420Image.width = TEST_IMAGE_WIDTH;
- mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
- mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
+ void timerStop() { gettimeofday(&mEndingTime, nullptr); }
- if (!loadFile(JPEG_IMAGE, mJpegImage.data, &mJpegImage.length)) {
- FAIL() << "Load file " << JPEG_IMAGE << " failed";
- }
- mJpegImage.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
-
- JpegR jpegRCodec;
-
- jpegr_compressed_struct jpegR;
- jpegR.maxLength = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * sizeof(uint8_t);
- jpegR.data = malloc(jpegR.maxLength);
- ret = jpegRCodec.encodeJPEGR(
- &mRawP010Image, &mRawYuv420Image, &mJpegImage, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
- &jpegR);
- if (ret != OK) {
- FAIL() << "Error code is " << ret;
- }
- if (SAVE_ENCODING_RESULT) {
- // Output image data to file
- std::string filePath = "/sdcard/Documents/encoded_from_p010_yuv420p_jpeg_input.jpgr";
- std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
- if (!imageFile.is_open()) {
- ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
- }
- imageFile.write((const char*)jpegR.data, jpegR.length);
+ int64_t elapsedTime() {
+ struct timeval elapsedMicroseconds;
+ elapsedMicroseconds.tv_sec = mEndingTime.tv_sec - mStartingTime.tv_sec;
+ elapsedMicroseconds.tv_usec = mEndingTime.tv_usec - mStartingTime.tv_usec;
+ return elapsedMicroseconds.tv_sec * 1000000 + elapsedMicroseconds.tv_usec;
}
- jpegr_uncompressed_struct decodedJpegR;
- int decodedJpegRSize = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * 8;
- decodedJpegR.data = malloc(decodedJpegRSize);
- ret = jpegRCodec.decodeJPEGR(&jpegR, &decodedJpegR);
- if (ret != OK) {
- FAIL() << "Error code is " << ret;
- }
- if (SAVE_DECODING_RESULT) {
- // Output image data to file
- std::string filePath = "/sdcard/Documents/decoded_from_p010_yuv420p_jpeg_input.rgb";
- std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
- if (!imageFile.is_open()) {
- ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
- }
- imageFile.write((const char*)decodedJpegR.data, decodedJpegRSize);
- }
+private:
+ struct timeval mStartingTime;
+ struct timeval mEndingTime;
+};
- free(jpegR.data);
- free(decodedJpegR.data);
+class JpegRBenchmark : public JpegR {
+public:
+ void BenchmarkGenerateGainMap(jr_uncompressed_ptr yuv420Image, jr_uncompressed_ptr p010Image,
+ ultrahdr_metadata_ptr metadata, jr_uncompressed_ptr map);
+ void BenchmarkApplyGainMap(jr_uncompressed_ptr yuv420Image, jr_uncompressed_ptr map,
+ ultrahdr_metadata_ptr metadata, jr_uncompressed_ptr dest);
+
+private:
+ const int kProfileCount = 10;
+};
+
+void JpegRBenchmark::BenchmarkGenerateGainMap(jr_uncompressed_ptr yuv420Image,
+ jr_uncompressed_ptr p010Image,
+ ultrahdr_metadata_ptr metadata,
+ jr_uncompressed_ptr map) {
+ ASSERT_EQ(yuv420Image->width, p010Image->width);
+ ASSERT_EQ(yuv420Image->height, p010Image->height);
+ Profiler profileGenerateMap;
+ profileGenerateMap.timerStart();
+ for (auto i = 0; i < kProfileCount; i++) {
+ ASSERT_EQ(OK,
+ generateGainMap(yuv420Image, p010Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
+ metadata, map));
+ if (i != kProfileCount - 1) delete[] static_cast<uint8_t*>(map->data);
+ }
+ profileGenerateMap.timerStop();
+ ALOGE("Generate Gain Map:- Res = %i x %i, time = %f ms", yuv420Image->width, yuv420Image->height,
+ profileGenerateMap.elapsedTime() / (kProfileCount * 1000.f));
}
-/* Test Encode API-3 and decode */
-TEST_F(JpegRTest, encodeFromJpegThenDecode) {
- int ret;
-
- // Load input files.
- if (!loadFile(RAW_P010_IMAGE, mRawP010Image.data, nullptr)) {
- FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
+void JpegRBenchmark::BenchmarkApplyGainMap(jr_uncompressed_ptr yuv420Image, jr_uncompressed_ptr map,
+ ultrahdr_metadata_ptr metadata,
+ jr_uncompressed_ptr dest) {
+ Profiler profileRecMap;
+ profileRecMap.timerStart();
+ for (auto i = 0; i < kProfileCount; i++) {
+ ASSERT_EQ(OK,
+ applyGainMap(yuv420Image, map, metadata, ULTRAHDR_OUTPUT_HDR_HLG,
+ metadata->maxContentBoost /* displayBoost */, dest));
}
- mRawP010Image.width = TEST_IMAGE_WIDTH;
- mRawP010Image.height = TEST_IMAGE_HEIGHT;
- mRawP010Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
-
- if (SAVE_INPUT_RGBA) {
- size_t rgbaSize = mRawP010Image.width * mRawP010Image.height * sizeof(uint32_t);
- uint32_t *data = (uint32_t *)malloc(rgbaSize);
-
- for (size_t y = 0; y < mRawP010Image.height; ++y) {
- for (size_t x = 0; x < mRawP010Image.width; ++x) {
- Color hdr_yuv_gamma = getP010Pixel(&mRawP010Image, x, y);
- Color hdr_rgb_gamma = bt2100YuvToRgb(hdr_yuv_gamma);
- uint32_t rgba1010102 = colorToRgba1010102(hdr_rgb_gamma);
- size_t pixel_idx = x + y * mRawP010Image.width;
- reinterpret_cast<uint32_t*>(data)[pixel_idx] = rgba1010102;
- }
- }
-
- // Output image data to file
- std::string filePath = "/sdcard/Documents/input_from_p010.rgb10";
- std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
- if (!imageFile.is_open()) {
- ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
- }
- imageFile.write((const char*)data, rgbaSize);
- free(data);
- }
- if (!loadFile(JPEG_IMAGE, mJpegImage.data, &mJpegImage.length)) {
- FAIL() << "Load file " << JPEG_IMAGE << " failed";
- }
- mJpegImage.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
-
- JpegR jpegRCodec;
-
- jpegr_compressed_struct jpegR;
- jpegR.maxLength = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * sizeof(uint8_t);
- jpegR.data = malloc(jpegR.maxLength);
- ret = jpegRCodec.encodeJPEGR(
- &mRawP010Image, &mJpegImage, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR);
- if (ret != OK) {
- FAIL() << "Error code is " << ret;
- }
- if (SAVE_ENCODING_RESULT) {
- // Output image data to file
- std::string filePath = "/sdcard/Documents/encoded_from_p010_jpeg_input.jpgr";
- std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
- if (!imageFile.is_open()) {
- ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
- }
- imageFile.write((const char*)jpegR.data, jpegR.length);
- }
-
- jpegr_uncompressed_struct decodedJpegR;
- int decodedJpegRSize = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * 8;
- decodedJpegR.data = malloc(decodedJpegRSize);
- ret = jpegRCodec.decodeJPEGR(&jpegR, &decodedJpegR);
- if (ret != OK) {
- FAIL() << "Error code is " << ret;
- }
- if (SAVE_DECODING_RESULT) {
- // Output image data to file
- std::string filePath = "/sdcard/Documents/decoded_from_p010_jpeg_input.rgb";
- std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
- if (!imageFile.is_open()) {
- ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
- }
- imageFile.write((const char*)decodedJpegR.data, decodedJpegRSize);
- }
-
- free(jpegR.data);
- free(decodedJpegR.data);
+ profileRecMap.timerStop();
+ ALOGE("Apply Gain Map:- Res = %i x %i, time = %f ms", yuv420Image->width, yuv420Image->height,
+ profileRecMap.elapsedTime() / (kProfileCount * 1000.f));
}
-TEST_F(JpegRTest, ProfileGainMapFuncs) {
- const size_t kWidth = TEST_IMAGE_WIDTH;
- const size_t kHeight = TEST_IMAGE_HEIGHT;
-
- // Load input files.
- if (!loadFile(RAW_P010_IMAGE, mRawP010Image.data, nullptr)) {
- FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
- }
- mRawP010Image.width = kWidth;
- mRawP010Image.height = kHeight;
- mRawP010Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
-
- if (!loadFile(RAW_YUV420_IMAGE, mRawYuv420Image.data, nullptr)) {
- FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
- }
- mRawYuv420Image.width = kWidth;
- mRawYuv420Image.height = kHeight;
- mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
-
+TEST(JpegRTest, ProfileGainMapFuncs) {
+ UhdrUnCompressedStructWrapper rawImgP010(kImageWidth, kImageHeight, YCbCr_p010);
+ ASSERT_TRUE(rawImgP010.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
+ ASSERT_TRUE(rawImgP010.allocateMemory());
+ ASSERT_TRUE(rawImgP010.loadRawResource(kYCbCrP010FileName));
+ UhdrUnCompressedStructWrapper rawImg420(kImageWidth, kImageHeight, YCbCr_420);
+ ASSERT_TRUE(rawImg420.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
+ ASSERT_TRUE(rawImg420.allocateMemory());
+ ASSERT_TRUE(rawImg420.loadRawResource(kYCbCr420FileName));
+ ultrahdr_metadata_struct metadata = {.version = "1.0"};
+ jpegr_uncompressed_struct map = {.data = NULL,
+ .width = 0,
+ .height = 0,
+ .colorGamut = ULTRAHDR_COLORGAMUT_UNSPECIFIED};
JpegRBenchmark benchmark;
+ ASSERT_NO_FATAL_FAILURE(benchmark.BenchmarkGenerateGainMap(rawImg420.getImageHandle(),
+ rawImgP010.getImageHandle(), &metadata,
+ &map));
- ultrahdr_metadata_struct metadata = { .version = "1.0" };
-
- jpegr_uncompressed_struct map = { .data = NULL,
+ const int dstSize = kImageWidth * kImageWidth * 4;
+ auto bufferDst = std::make_unique<uint8_t[]>(dstSize);
+ jpegr_uncompressed_struct dest = {.data = bufferDst.get(),
.width = 0,
.height = 0,
- .colorGamut = ULTRAHDR_COLORGAMUT_UNSPECIFIED };
+ .colorGamut = ULTRAHDR_COLORGAMUT_UNSPECIFIED};
- benchmark.BenchmarkGenerateGainMap(&mRawYuv420Image, &mRawP010Image, &metadata, &map);
-
- const int dstSize = mRawYuv420Image.width * mRawYuv420Image.height * 4;
- auto bufferDst = std::make_unique<uint8_t[]>(dstSize);
- jpegr_uncompressed_struct dest = { .data = bufferDst.get(),
- .width = 0,
- .height = 0,
- .colorGamut = ULTRAHDR_COLORGAMUT_UNSPECIFIED };
-
- benchmark.BenchmarkApplyGainMap(&mRawYuv420Image, &map, &metadata, &dest);
+ ASSERT_NO_FATAL_FAILURE(
+ benchmark.BenchmarkApplyGainMap(rawImg420.getImageHandle(), &map, &metadata, &dest));
}
} // namespace android::ultrahdr
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 654e5b7..8d0eb59 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -169,11 +169,6 @@
}
}
- // Return true if native GLES drivers should be used and ANGLE is already loaded.
- if (android::GraphicsEnv::getInstance().shouldUseNativeDriver() && cnx->angleLoaded) {
- return true;
- }
-
// Return true if updated driver namespace is set.
ns = android::GraphicsEnv::getInstance().getDriverNamespace();
if (ns) {
@@ -245,28 +240,16 @@
if (!hnd) {
// Secondly, try to load from driver apk.
hnd = attempt_to_load_updated_driver(cnx);
-
- // If updated driver apk is set but fail to load, abort here.
- LOG_ALWAYS_FATAL_IF(android::GraphicsEnv::getInstance().getDriverNamespace(),
- "couldn't find an OpenGL ES implementation from %s",
- android::GraphicsEnv::getInstance().getDriverPath().c_str());
}
- // Attempt to load native GLES drivers specified by ro.hardware.egl if native is selected.
- // If native is selected but fail to load, abort.
- if (!hnd && android::GraphicsEnv::getInstance().shouldUseNativeDriver()) {
- auto driverSuffix = base::GetProperty(RO_DRIVER_SUFFIX_PROPERTY, "");
- LOG_ALWAYS_FATAL_IF(driverSuffix.empty(),
- "Native GLES driver is selected but not specified in %s",
- RO_DRIVER_SUFFIX_PROPERTY);
- hnd = attempt_to_load_system_driver(cnx, driverSuffix.c_str(), true);
- LOG_ALWAYS_FATAL_IF(!hnd, "Native GLES driver is selected but failed to load. %s=%s",
- RO_DRIVER_SUFFIX_PROPERTY, driverSuffix.c_str());
- }
-
- // Finally, try to load default driver.
bool failToLoadFromDriverSuffixProperty = false;
if (!hnd) {
+ // If updated driver apk is set but fail to load, abort here.
+ if (android::GraphicsEnv::getInstance().getDriverNamespace()) {
+ LOG_ALWAYS_FATAL("couldn't find an OpenGL ES implementation from %s",
+ android::GraphicsEnv::getInstance().getDriverPath().c_str());
+ }
+ // Finally, try to load system driver.
// Start by searching for the library name appended by the system
// properties of the GLES userspace driver in both locations.
// i.e.:
diff --git a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
index 986dabb..eca0f86 100644
--- a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
@@ -350,6 +350,7 @@
dump += addLinePrefix(mPropertyProvider.dump(), INDENT4);
dump += INDENT3 "Captured event converter:\n";
dump += addLinePrefix(mCapturedEventConverter.dump(), INDENT4);
+ dump += StringPrintf(INDENT3 "DisplayId: %s\n", toString(mDisplayId).c_str());
}
std::list<NotifyArgs> TouchpadInputMapper::reconfigure(nsecs_t when,
@@ -361,13 +362,31 @@
}
if (!changes.any() || changes.test(InputReaderConfiguration::Change::DISPLAY_INFO)) {
- std::optional<int32_t> displayId = mPointerController->getDisplayId();
+ mDisplayId = ADISPLAY_ID_NONE;
+ if (auto viewport = mDeviceContext.getAssociatedViewport(); viewport) {
+ // This InputDevice is associated with a viewport.
+ // Only generate events for the associated display.
+ const bool mismatchedPointerDisplay =
+ (viewport->displayId != mPointerController->getDisplayId());
+ if (mismatchedPointerDisplay) {
+ ALOGW("Touchpad \"%s\" associated viewport display does not match pointer "
+ "controller",
+ mDeviceContext.getName().c_str());
+ }
+ mDisplayId = mismatchedPointerDisplay ? std::nullopt
+ : std::make_optional(viewport->displayId);
+ } else {
+ // The InputDevice is not associated with a viewport, but it controls the mouse pointer.
+ mDisplayId = mPointerController->getDisplayId();
+ }
+
ui::Rotation orientation = ui::ROTATION_0;
- if (displayId.has_value()) {
- if (auto viewport = config.getDisplayViewportById(*displayId); viewport) {
+ if (mDisplayId.has_value()) {
+ if (auto viewport = config.getDisplayViewportById(*mDisplayId); viewport) {
orientation = getInverseRotation(viewport->orientation);
}
}
+ mGestureConverter.setDisplayId(mDisplayId);
mGestureConverter.setOrientation(orientation);
}
if (!changes.any() || changes.test(InputReaderConfiguration::Change::TOUCHPAD_SETTINGS)) {
@@ -497,13 +516,19 @@
std::list<NotifyArgs> TouchpadInputMapper::processGestures(nsecs_t when, nsecs_t readTime) {
std::list<NotifyArgs> out = {};
- MetricsAccumulator& metricsAccumulator = MetricsAccumulator::getInstance();
- for (Gesture& gesture : mGesturesToProcess) {
- out += mGestureConverter.handleGesture(when, readTime, gesture);
- metricsAccumulator.processGesture(mMetricsId, gesture);
+ if (mDisplayId) {
+ MetricsAccumulator& metricsAccumulator = MetricsAccumulator::getInstance();
+ for (Gesture& gesture : mGesturesToProcess) {
+ out += mGestureConverter.handleGesture(when, readTime, gesture);
+ metricsAccumulator.processGesture(mMetricsId, gesture);
+ }
}
mGesturesToProcess.clear();
return out;
}
+std::optional<int32_t> TouchpadInputMapper::getAssociatedDisplayId() {
+ return mDisplayId;
+}
+
} // namespace android
diff --git a/services/inputflinger/reader/mapper/TouchpadInputMapper.h b/services/inputflinger/reader/mapper/TouchpadInputMapper.h
index 73ca5af..47d712e 100644
--- a/services/inputflinger/reader/mapper/TouchpadInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchpadInputMapper.h
@@ -64,6 +64,8 @@
using MetricsIdentifier = std::tuple<uint16_t /*busId*/, uint16_t /*vendorId*/,
uint16_t /*productId*/, uint16_t /*version*/>;
+ std::optional<int32_t> getAssociatedDisplayId() override;
+
private:
void resetGestureInterpreter(nsecs_t when);
explicit TouchpadInputMapper(InputDeviceContext& deviceContext,
@@ -102,6 +104,11 @@
std::set<int32_t> mLastFrameTrackingIds;
// Tracking IDs for touches that have at some point been reported as palms by the touchpad.
std::set<int32_t> mPalmTrackingIds;
+
+ // The display that events generated by this mapper should target. This can be set to
+ // ADISPLAY_ID_NONE to target the focused display. If there is no display target (i.e.
+ // std::nullopt), all events will be ignored.
+ std::optional<int32_t> mDisplayId;
};
} // namespace android
diff --git a/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp b/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp
index 3abf2bd..7006e9e 100644
--- a/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp
+++ b/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp
@@ -124,6 +124,11 @@
std::list<NotifyArgs> GestureConverter::handleGesture(nsecs_t when, nsecs_t readTime,
const Gesture& gesture) {
+ if (!mDisplayId) {
+ // Ignore gestures when there is no target display configured.
+ return {};
+ }
+
switch (gesture.type) {
case kGestureTypeMove:
return {handleMove(when, readTime, gesture)};
@@ -556,7 +561,7 @@
readTime,
mDeviceId,
SOURCE,
- mPointerController->getDisplayId(),
+ *mDisplayId,
/* policyFlags= */ POLICY_FLAG_WAKE,
action,
/* actionButton= */ actionButton,
diff --git a/services/inputflinger/reader/mapper/gestures/GestureConverter.h b/services/inputflinger/reader/mapper/gestures/GestureConverter.h
index 3ea3790..e6cf617 100644
--- a/services/inputflinger/reader/mapper/gestures/GestureConverter.h
+++ b/services/inputflinger/reader/mapper/gestures/GestureConverter.h
@@ -46,6 +46,8 @@
void setOrientation(ui::Rotation orientation) { mOrientation = orientation; }
[[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when);
+ void setDisplayId(std::optional<int32_t> displayId) { mDisplayId = displayId; }
+
void populateMotionRanges(InputDeviceInfo& info) const;
[[nodiscard]] std::list<NotifyArgs> handleGesture(nsecs_t when, nsecs_t readTime,
@@ -84,6 +86,7 @@
InputReaderContext& mReaderContext;
std::shared_ptr<PointerControllerInterface> mPointerController;
+ std::optional<int32_t> mDisplayId;
ui::Rotation mOrientation = ui::ROTATION_0;
RawAbsoluteAxisInfo mXAxisInfo;
RawAbsoluteAxisInfo mYAxisInfo;
diff --git a/services/inputflinger/tests/GestureConverter_test.cpp b/services/inputflinger/tests/GestureConverter_test.cpp
index 4df0f69..74ce359 100644
--- a/services/inputflinger/tests/GestureConverter_test.cpp
+++ b/services/inputflinger/tests/GestureConverter_test.cpp
@@ -19,6 +19,7 @@
#include <EventHub.h>
#include <gestures/GestureConverter.h>
#include <gtest/gtest.h>
+#include <gui/constants.h>
#include "FakeEventHub.h"
#include "FakeInputReaderPolicy.h"
@@ -85,6 +86,7 @@
TEST_F(GestureConverterTest, Move) {
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
@@ -93,8 +95,8 @@
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
WithCoords(POINTER_X - 5, POINTER_Y + 10), WithRelativeMotion(-5, 10),
- WithToolType(ToolType::FINGER), WithButtonState(0),
- WithPressure(0.0f)));
+ WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(POINTER_X - 5, POINTER_Y + 10));
}
@@ -103,6 +105,7 @@
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
converter.setOrientation(ui::ROTATION_90);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
@@ -111,8 +114,8 @@
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
WithCoords(POINTER_X + 10, POINTER_Y + 5), WithRelativeMotion(10, 5),
- WithToolType(ToolType::FINGER), WithButtonState(0),
- WithPressure(0.0f)));
+ WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(POINTER_X + 10, POINTER_Y + 5));
}
@@ -120,6 +123,7 @@
TEST_F(GestureConverterTest, ButtonsChange) {
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
// Press left and right buttons at once
Gesture downGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
@@ -132,23 +136,23 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY |
AMOTION_EVENT_BUTTON_SECONDARY),
- WithCoords(POINTER_X, POINTER_Y),
- WithToolType(ToolType::FINGER)));
+ WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
- WithCoords(POINTER_X, POINTER_Y),
- WithToolType(ToolType::FINGER)));
+ WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY),
WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY |
AMOTION_EVENT_BUTTON_SECONDARY),
- WithCoords(POINTER_X, POINTER_Y),
- WithToolType(ToolType::FINGER)));
+ WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
// Then release the left button
Gesture leftUpGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
@@ -161,8 +165,8 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY),
- WithCoords(POINTER_X, POINTER_Y),
- WithToolType(ToolType::FINGER)));
+ WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
// Finally release the right button
Gesture rightUpGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
@@ -174,22 +178,24 @@
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY), WithButtonState(0),
- WithCoords(POINTER_X, POINTER_Y),
- WithToolType(ToolType::FINGER)));
+ WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0),
- WithCoords(POINTER_X, POINTER_Y),
- WithToolType(ToolType::FINGER)));
+ WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithButtonState(0),
- WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER)));
+ WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
}
TEST_F(GestureConverterTest, DragWithButton) {
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
// Press the button
Gesture downGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
@@ -201,15 +207,15 @@
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
- WithCoords(POINTER_X, POINTER_Y),
- WithToolType(ToolType::FINGER)));
+ WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
- WithCoords(POINTER_X, POINTER_Y),
- WithToolType(ToolType::FINGER)));
+ WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
// Move
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
@@ -219,8 +225,8 @@
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
WithCoords(POINTER_X - 5, POINTER_Y + 10), WithRelativeMotion(-5, 10),
- WithToolType(ToolType::FINGER),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f)));
+ WithToolType(ToolType::FINGER), WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(POINTER_X - 5, POINTER_Y + 10));
@@ -234,23 +240,25 @@
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(0),
- WithCoords(POINTER_X - 5, POINTER_Y + 10),
- WithToolType(ToolType::FINGER)));
+ WithCoords(POINTER_X - 5, POINTER_Y + 10), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0),
- WithCoords(POINTER_X - 5, POINTER_Y + 10),
- WithToolType(ToolType::FINGER)));
+ WithCoords(POINTER_X - 5, POINTER_Y + 10), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithButtonState(0),
- WithCoords(POINTER_X - 5, POINTER_Y + 10), WithToolType(ToolType::FINGER)));
+ WithCoords(POINTER_X - 5, POINTER_Y + 10), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
}
TEST_F(GestureConverterTest, Scroll) {
const nsecs_t downTime = 12345;
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
std::list<NotifyArgs> args = converter.handleGesture(downTime, READ_TIME, startGesture);
@@ -261,7 +269,8 @@
WithGestureScrollDistance(0, 0, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
WithToolType(ToolType::FINGER), WithDownTime(downTime),
- WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE)));
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
@@ -269,7 +278,8 @@
WithGestureScrollDistance(0, 10, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
WithToolType(ToolType::FINGER),
- WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE)));
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
Gesture continueGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -5);
args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture);
@@ -280,7 +290,8 @@
WithGestureScrollDistance(0, 5, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
WithToolType(ToolType::FINGER),
- WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE)));
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
GESTURES_FLING_START);
@@ -292,7 +303,8 @@
WithGestureScrollDistance(0, 0, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
WithToolType(ToolType::FINGER),
- WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE)));
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
}
TEST_F(GestureConverterTest, Scroll_Rotated) {
@@ -300,6 +312,7 @@
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
converter.setOrientation(ui::ROTATION_90);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
std::list<NotifyArgs> args = converter.handleGesture(downTime, READ_TIME, startGesture);
@@ -309,14 +322,15 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithCoords(POINTER_X, POINTER_Y),
WithGestureScrollDistance(0, 0, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER), WithDownTime(downTime)));
+ WithToolType(ToolType::FINGER), WithDownTime(downTime),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
WithCoords(POINTER_X - 10, POINTER_Y),
WithGestureScrollDistance(0, 10, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER)));
+ WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
Gesture continueGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -5);
args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture);
@@ -326,7 +340,7 @@
WithCoords(POINTER_X - 15, POINTER_Y),
WithGestureScrollDistance(0, 5, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER)));
+ WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
GESTURES_FLING_START);
@@ -337,12 +351,13 @@
WithCoords(POINTER_X - 15, POINTER_Y),
WithGestureScrollDistance(0, 0, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER)));
+ WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
}
TEST_F(GestureConverterTest, Scroll_ClearsClassificationAfterGesture) {
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
@@ -358,12 +373,14 @@
args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
ASSERT_EQ(1u, args.size());
EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- WithMotionClassification(MotionClassification::NONE));
+ AllOf(WithMotionClassification(MotionClassification::NONE),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
}
TEST_F(GestureConverterTest, Scroll_ClearsScrollDistanceAfterGesture) {
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
@@ -387,6 +404,7 @@
TEST_F(GestureConverterTest, ThreeFingerSwipe_ClearsClassificationAfterGesture) {
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0,
/*dy=*/0);
@@ -406,6 +424,7 @@
TEST_F(GestureConverterTest, ThreeFingerSwipe_ClearsGestureAxesAfterGesture) {
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/5,
/*dy=*/5);
@@ -431,6 +450,7 @@
// only checks movement in one dimension.
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dx= */ 0,
/* dy= */ 10);
@@ -444,7 +464,8 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithGestureOffset(0, 0, EPSILON),
WithGestureSwipeFingerCount(3),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(1u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
PointerCoords finger0Start = arg.pointerCoords[0];
args.pop_front();
arg = std::get<NotifyMotionArgs>(args.front());
@@ -453,7 +474,8 @@
1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(3),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(2u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
PointerCoords finger1Start = arg.pointerCoords[1];
args.pop_front();
arg = std::get<NotifyMotionArgs>(args.front());
@@ -462,7 +484,8 @@
2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(3),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(3u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
PointerCoords finger2Start = arg.pointerCoords[2];
args.pop_front();
@@ -471,7 +494,8 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
WithGestureOffset(0, -0.01, EPSILON), WithGestureSwipeFingerCount(3),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(3u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX());
EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX());
EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX());
@@ -488,7 +512,8 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
WithGestureOffset(0, -0.005, EPSILON), WithGestureSwipeFingerCount(3),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(3u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX());
EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX());
EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX());
@@ -504,26 +529,30 @@
2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(3),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(3u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(3),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(2u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON),
WithGestureSwipeFingerCount(3),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(1u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
}
TEST_F(GestureConverterTest, ThreeFingerSwipe_Rotated) {
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
converter.setOrientation(ui::ROTATION_90);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dx= */ 0,
/* dy= */ 10);
@@ -535,28 +564,31 @@
NotifyMotionArgs arg = std::get<NotifyMotionArgs>(args.front());
ASSERT_THAT(arg,
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithGestureOffset(0, 0, EPSILON),
- WithPointerCount(1u)));
+ WithPointerCount(1u), WithDisplayId(ADISPLAY_ID_DEFAULT)));
PointerCoords finger0Start = arg.pointerCoords[0];
args.pop_front();
arg = std::get<NotifyMotionArgs>(args.front());
ASSERT_THAT(arg,
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN |
1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON), WithPointerCount(2u)));
+ WithGestureOffset(0, 0, EPSILON), WithPointerCount(2u),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
PointerCoords finger1Start = arg.pointerCoords[1];
args.pop_front();
arg = std::get<NotifyMotionArgs>(args.front());
ASSERT_THAT(arg,
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN |
2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON), WithPointerCount(3u)));
+ WithGestureOffset(0, 0, EPSILON), WithPointerCount(3u),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
PointerCoords finger2Start = arg.pointerCoords[2];
args.pop_front();
arg = std::get<NotifyMotionArgs>(args.front());
ASSERT_THAT(arg,
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
- WithGestureOffset(0, -0.01, EPSILON), WithPointerCount(3u)));
+ WithGestureOffset(0, -0.01, EPSILON), WithPointerCount(3u),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX() - 10);
EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX() - 10);
EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX() - 10);
@@ -571,7 +603,8 @@
arg = std::get<NotifyMotionArgs>(args.front());
ASSERT_THAT(arg,
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
- WithGestureOffset(0, -0.005, EPSILON), WithPointerCount(3u)));
+ WithGestureOffset(0, -0.005, EPSILON), WithPointerCount(3u),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX() - 15);
EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX() - 15);
EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX() - 15);
@@ -585,21 +618,24 @@
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON), WithPointerCount(3u)));
+ WithGestureOffset(0, 0, EPSILON), WithPointerCount(3u),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON), WithPointerCount(2u)));
+ WithGestureOffset(0, 0, EPSILON), WithPointerCount(2u),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON),
- WithPointerCount(1u)));
+ WithPointerCount(1u), WithDisplayId(ADISPLAY_ID_DEFAULT)));
}
TEST_F(GestureConverterTest, FourFingerSwipe_Horizontal) {
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureFourFingerSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* dx= */ 10, /* dy= */ 0);
@@ -613,7 +649,8 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithGestureOffset(0, 0, EPSILON),
WithGestureSwipeFingerCount(4),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(1u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
PointerCoords finger0Start = arg.pointerCoords[0];
args.pop_front();
arg = std::get<NotifyMotionArgs>(args.front());
@@ -622,7 +659,8 @@
1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(4),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(2u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
PointerCoords finger1Start = arg.pointerCoords[1];
args.pop_front();
arg = std::get<NotifyMotionArgs>(args.front());
@@ -631,7 +669,8 @@
2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(4),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(3u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
PointerCoords finger2Start = arg.pointerCoords[2];
args.pop_front();
arg = std::get<NotifyMotionArgs>(args.front());
@@ -640,7 +679,8 @@
3 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(4),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(4u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(4u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
PointerCoords finger3Start = arg.pointerCoords[3];
args.pop_front();
@@ -649,7 +689,8 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
WithGestureOffset(0.01, 0, EPSILON), WithGestureSwipeFingerCount(4),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(4u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(4u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX() + 10);
EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX() + 10);
EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX() + 10);
@@ -668,7 +709,8 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
WithGestureOffset(0.005, 0, EPSILON), WithGestureSwipeFingerCount(4),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(4u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(4u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX() + 15);
EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX() + 15);
EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX() + 15);
@@ -686,32 +728,37 @@
3 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(4),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(4u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(4u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(4),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(3u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(4),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(2u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON),
WithGestureSwipeFingerCount(4),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(1u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
}
TEST_F(GestureConverterTest, Pinch_Inwards) {
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dz= */ 1,
GESTURES_ZOOM_START);
@@ -722,7 +769,7 @@
WithMotionClassification(MotionClassification::PINCH),
WithGesturePinchScaleFactor(1.0f, EPSILON),
WithCoords(POINTER_X - 100, POINTER_Y), WithPointerCount(1u),
- WithToolType(ToolType::FINGER)));
+ WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN |
@@ -730,7 +777,7 @@
WithMotionClassification(MotionClassification::PINCH),
WithGesturePinchScaleFactor(1.0f, EPSILON),
WithPointerCoords(1, POINTER_X + 100, POINTER_Y), WithPointerCount(2u),
- WithToolType(ToolType::FINGER)));
+ WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
Gesture updateGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* dz= */ 0.8, GESTURES_ZOOM_UPDATE);
@@ -742,7 +789,7 @@
WithGesturePinchScaleFactor(0.8f, EPSILON),
WithPointerCoords(0, POINTER_X - 80, POINTER_Y),
WithPointerCoords(1, POINTER_X + 80, POINTER_Y), WithPointerCount(2u),
- WithToolType(ToolType::FINGER)));
+ WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
Gesture endGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dz= */ 1,
GESTURES_ZOOM_END);
@@ -753,18 +800,19 @@
1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithMotionClassification(MotionClassification::PINCH),
WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(2u),
- WithToolType(ToolType::FINGER)));
+ WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
WithMotionClassification(MotionClassification::PINCH),
WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(1u),
- WithToolType(ToolType::FINGER)));
+ WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
}
TEST_F(GestureConverterTest, Pinch_Outwards) {
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dz= */ 1,
GESTURES_ZOOM_START);
@@ -775,7 +823,7 @@
WithMotionClassification(MotionClassification::PINCH),
WithGesturePinchScaleFactor(1.0f, EPSILON),
WithCoords(POINTER_X - 100, POINTER_Y), WithPointerCount(1u),
- WithToolType(ToolType::FINGER)));
+ WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN |
@@ -783,7 +831,7 @@
WithMotionClassification(MotionClassification::PINCH),
WithGesturePinchScaleFactor(1.0f, EPSILON),
WithPointerCoords(1, POINTER_X + 100, POINTER_Y), WithPointerCount(2u),
- WithToolType(ToolType::FINGER)));
+ WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
Gesture updateGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* dz= */ 1.2, GESTURES_ZOOM_UPDATE);
@@ -795,7 +843,7 @@
WithGesturePinchScaleFactor(1.2f, EPSILON),
WithPointerCoords(0, POINTER_X - 120, POINTER_Y),
WithPointerCoords(1, POINTER_X + 120, POINTER_Y), WithPointerCount(2u),
- WithToolType(ToolType::FINGER)));
+ WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
Gesture endGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dz= */ 1,
GESTURES_ZOOM_END);
@@ -806,18 +854,19 @@
1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithMotionClassification(MotionClassification::PINCH),
WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(2u),
- WithToolType(ToolType::FINGER)));
+ WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
WithMotionClassification(MotionClassification::PINCH),
WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(1u),
- WithToolType(ToolType::FINGER)));
+ WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
}
TEST_F(GestureConverterTest, Pinch_ClearsClassificationAfterGesture) {
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
GESTURES_ZOOM_START);
@@ -841,6 +890,7 @@
TEST_F(GestureConverterTest, Pinch_ClearsScaleFactorAfterGesture) {
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
GESTURES_ZOOM_START);
@@ -866,6 +916,7 @@
TEST_F(GestureConverterTest, ResetWithButtonPressed) {
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture downGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/*down=*/GESTURES_BUTTON_LEFT | GESTURES_BUTTON_RIGHT,
@@ -879,24 +930,25 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY),
- WithCoords(POINTER_X, POINTER_Y),
- WithToolType(ToolType::FINGER)));
+ WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY), WithButtonState(0),
- WithCoords(POINTER_X, POINTER_Y),
- WithToolType(ToolType::FINGER)));
+ WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0),
- WithCoords(POINTER_X, POINTER_Y),
- WithToolType(ToolType::FINGER)));
+ WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
}
TEST_F(GestureConverterTest, ResetDuringScroll) {
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
(void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
@@ -909,12 +961,14 @@
WithGestureScrollDistance(0, 0, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
WithToolType(ToolType::FINGER),
- WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE)));
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
}
TEST_F(GestureConverterTest, ResetDuringThreeFingerSwipe) {
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0,
/*dy=*/10);
@@ -927,24 +981,28 @@
2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(3u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(2u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(1u), WithToolType(ToolType::FINGER)));
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
}
TEST_F(GestureConverterTest, ResetDuringPinch) {
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
GESTURES_ZOOM_START);
@@ -957,18 +1015,19 @@
1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithMotionClassification(MotionClassification::PINCH),
WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(2u),
- WithToolType(ToolType::FINGER)));
+ WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
WithMotionClassification(MotionClassification::PINCH),
WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(1u),
- WithToolType(ToolType::FINGER)));
+ WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
}
TEST_F(GestureConverterTest, FlingTapDown) {
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture tapDownGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/*vx=*/0.f, /*vy=*/0.f, GESTURES_FLING_TAP_DOWN);
@@ -977,7 +1036,8 @@
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0.f, 0.f),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f)));
+ WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(POINTER_X, POINTER_Y));
ASSERT_TRUE(mFakePointerController->isPointerShown());
@@ -987,6 +1047,7 @@
// Tap should produce button press/release events
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* vx= */ 0,
/* vy= */ 0, GESTURES_FLING_TAP_DOWN);
@@ -996,7 +1057,8 @@
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0, 0),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f)));
+ WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
Gesture tapGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_LEFT,
@@ -1007,7 +1069,8 @@
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithCoords(POINTER_X, POINTER_Y),
WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f)));
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
@@ -1015,29 +1078,32 @@
WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0.f, 0.f),
WithToolType(ToolType::FINGER), WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
- WithPressure(1.0f)));
+ WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(0),
WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0.f, 0.f),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(1.0f)));
+ WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(1.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithCoords(POINTER_X, POINTER_Y),
WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(0), WithPressure(0.0f)));
+ WithButtonState(0), WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0, 0),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f)));
+ WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
}
TEST_F(GestureConverterTest, Click) {
// Click should produce button press/release events
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* vx= */ 0,
/* vy= */ 0, GESTURES_FLING_TAP_DOWN);
@@ -1047,7 +1113,8 @@
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0, 0),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f)));
+ WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
Gesture buttonDownGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_LEFT,
@@ -1058,7 +1125,8 @@
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithCoords(POINTER_X, POINTER_Y),
WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f)));
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
@@ -1066,7 +1134,7 @@
WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0.f, 0.f),
WithToolType(ToolType::FINGER), WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
- WithPressure(1.0f)));
+ WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
Gesture buttonUpGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_NONE,
@@ -1078,17 +1146,19 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(0),
WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0.f, 0.f),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(1.0f)));
+ WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(1.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithCoords(POINTER_X, POINTER_Y),
WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(0), WithPressure(0.0f)));
+ WithButtonState(0), WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0, 0),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f)));
+ WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
}
TEST_F(GestureConverterTest, TapWithTapToClickDisabled) {
@@ -1097,6 +1167,7 @@
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* vx= */ 0,
/* vy= */ 0, GESTURES_FLING_TAP_DOWN);
@@ -1106,7 +1177,8 @@
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0, 0),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f)));
+ WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
Gesture tapGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
@@ -1127,6 +1199,7 @@
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* vx= */ 0,
/* vy= */ 0, GESTURES_FLING_TAP_DOWN);
@@ -1136,7 +1209,8 @@
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0, 0),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f)));
+ WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
Gesture buttonDownGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_LEFT,
@@ -1147,7 +1221,8 @@
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithCoords(POINTER_X, POINTER_Y),
WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f)));
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
@@ -1155,7 +1230,7 @@
WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0.f, 0.f),
WithToolType(ToolType::FINGER), WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
- WithPressure(1.0f)));
+ WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
Gesture buttonUpGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_NONE,
@@ -1167,17 +1242,19 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(0),
WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0.f, 0.f),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(1.0f)));
+ WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(1.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithCoords(POINTER_X, POINTER_Y),
WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(0), WithPressure(0.0f)));
+ WithButtonState(0), WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0, 0),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f)));
+ WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
// Future taps should be re-enabled
ASSERT_FALSE(mReader->getContext()->isPreventingTouchpadTaps());
@@ -1189,6 +1266,7 @@
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
@@ -1197,7 +1275,8 @@
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
WithCoords(POINTER_X - 5, POINTER_Y + 10), WithRelativeMotion(-5, 10),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f)));
+ WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(POINTER_X - 5, POINTER_Y + 10));
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 90d7541..398d602 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -1055,12 +1055,7 @@
if (count < 0) {
if(count == DEAD_OBJECT && device.isReconnecting()) {
device.reconnect();
- // There are no "real" events at this point, but do not skip the rest of the loop
- // if there are pending runtime events.
- Mutex::Autolock _l(&mLock);
- if (mRuntimeSensorEventQueue.empty()) {
- continue;
- }
+ continue;
} else {
ALOGE("sensor poll failed (%s)", strerror(-count));
break;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9de623f..9f24dd6 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -68,6 +68,7 @@
#include <gui/LayerMetadata.h>
#include <gui/LayerState.h>
#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
#include <gui/TraceUtils.h>
#include <hidl/ServiceManagement.h>
#include <layerproto/LayerProtoParser.h>
@@ -91,13 +92,12 @@
#include <ui/LayerStack.h>
#include <ui/PixelFormat.h>
#include <ui/StaticDisplayInfo.h>
+#include <unistd.h>
#include <utils/StopWatch.h>
#include <utils/String16.h>
#include <utils/String8.h>
#include <utils/Timers.h>
#include <utils/misc.h>
-
-#include <unistd.h>
#include <algorithm>
#include <cerrno>
#include <cinttypes>
@@ -6522,9 +6522,9 @@
code == IBinder::SYSPROPS_TRANSACTION) {
return OK;
}
- // Numbers from 1000 to 1043 are currently used for backdoors. The code
+ // Numbers from 1000 to 1044 are currently used for backdoors. The code
// in onTransact verifies that the user is root, and has access to use SF.
- if (code >= 1000 && code <= 1043) {
+ if (code >= 1000 && code <= 1044) {
ALOGV("Accessing SurfaceFlinger through backdoor code: %u", code);
return OK;
}
@@ -7003,6 +7003,73 @@
future.wait();
return NO_ERROR;
}
+
+ case 1044: { // Enable/Disable mirroring from one display to another
+ /*
+ * Mirror one display onto another.
+ * Ensure the source and destination displays are on.
+ * Commands:
+ * 0: Mirror one display to another
+ * 1: Disable mirroring to a previously mirrored display
+ * 2: Disable mirroring on previously mirrored displays
+ *
+ * Ex:
+ * Get the display ids:
+ * adb shell dumpsys SurfaceFlinger --display-id
+ * Mirror first display to the second:
+ * adb shell service call SurfaceFlinger 1044 i64 0 i64 4619827677550801152 i64
+ * 4619827677550801153
+ * Stop mirroring:
+ * adb shell service call SurfaceFlinger 1044 i64 1
+ */
+
+ int64_t arg0 = data.readInt64();
+
+ switch (arg0) {
+ case 0: {
+ // Mirror arg1 to arg2
+ int64_t arg1 = data.readInt64();
+ int64_t arg2 = data.readInt64();
+ // Enable mirroring for one display
+ const auto display1id = DisplayId::fromValue(arg1);
+ auto mirrorRoot = SurfaceComposerClient::getDefault()->mirrorDisplay(
+ display1id.value());
+ auto id2 = DisplayId::fromValue<PhysicalDisplayId>(arg2);
+ const auto token2 = getPhysicalDisplayToken(*id2);
+ ui::LayerStack layerStack;
+ {
+ Mutex::Autolock lock(mStateLock);
+ sp<DisplayDevice> display = getDisplayDeviceLocked(token2);
+ layerStack = display->getLayerStack();
+ }
+ SurfaceComposerClient::Transaction t;
+ t.setDisplayLayerStack(token2, layerStack);
+ t.setLayer(mirrorRoot, INT_MAX); // Top-most layer
+ t.setLayerStack(mirrorRoot, layerStack);
+ t.apply();
+
+ mMirrorMapForDebug.emplace_or_replace(arg2, mirrorRoot);
+ break;
+ }
+
+ case 1: {
+ // Disable mirroring for arg1
+ int64_t arg1 = data.readInt64();
+ mMirrorMapForDebug.erase(arg1);
+ break;
+ }
+
+ case 2: {
+ // Disable mirroring for all displays
+ mMirrorMapForDebug.clear();
+ break;
+ }
+
+ default:
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+ }
}
}
return err;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 4374f94..b07910d 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1443,6 +1443,10 @@
// WindowInfo ids visible during the last commit.
std::unordered_set<int32_t> mVisibleWindowIds;
+
+ // Mirroring
+ // Map of displayid to mirrorRoot
+ ftl::SmallMap<int64_t, sp<SurfaceControl>, 3> mMirrorMapForDebug;
};
class SurfaceComposerAIDL : public gui::BnSurfaceComposer {
diff --git a/services/surfaceflinger/TEST_MAPPING b/services/surfaceflinger/TEST_MAPPING
index bfa5997..5512734 100644
--- a/services/surfaceflinger/TEST_MAPPING
+++ b/services/surfaceflinger/TEST_MAPPING
@@ -15,7 +15,16 @@
"name": "libscheduler_test"
},
{
- "name": "CtsGraphicsTestCases"
+ "name": "CtsGraphicsTestCases",
+ // flaky on mixed gsi builds
+ "options": [
+ {
+ "exclude-filter": "android.graphics.cts.CameraGpuTest#testCameraImageCaptureAndRendering"
+ },
+ {
+ "exclude-filter": "android.graphics.cts.AnimatorLeakTest#testPauseResume"
+ }
+ ]
},
{
"name": "CtsSurfaceControlTests"
diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
index 644b8c7..1f2a1ed 100644
--- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
@@ -306,6 +306,47 @@
~FakeExternalTexture() = default;
};
+TEST_F(TransactionApplicationTest, ApplyTokensUseDifferentQueues) {
+ auto applyToken1 = sp<BBinder>::make();
+ auto applyToken2 = sp<BBinder>::make();
+
+ // Transaction 1 has a buffer with an unfired fence. It should not be ready to be applied.
+ TransactionState transaction1;
+ transaction1.applyToken = applyToken1;
+ transaction1.id = 42069;
+ transaction1.states.emplace_back();
+ transaction1.states[0].state.what |= layer_state_t::eBufferChanged;
+ transaction1.states[0].state.bufferData =
+ std::make_shared<fake::BufferData>(/* bufferId */ 1, /* width */ 1, /* height */ 1,
+ /* pixelFormat */ 0, /* outUsage */ 0);
+ transaction1.states[0].externalTexture =
+ std::make_shared<FakeExternalTexture>(*transaction1.states[0].state.bufferData);
+ transaction1.states[0].state.surface =
+ sp<Layer>::make(LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}))
+ ->getHandle();
+ auto fence = sp<mock::MockFence>::make();
+ EXPECT_CALL(*fence, getStatus()).WillRepeatedly(Return(Fence::Status::Unsignaled));
+ transaction1.states[0].state.bufferData->acquireFence = std::move(fence);
+ transaction1.states[0].state.bufferData->flags = BufferData::BufferDataChange::fenceChanged;
+ transaction1.isAutoTimestamp = true;
+
+ // Transaction 2 should be ready to be applied.
+ TransactionState transaction2;
+ transaction2.applyToken = applyToken2;
+ transaction2.id = 2;
+ transaction2.isAutoTimestamp = true;
+
+ mFlinger.setTransactionStateInternal(transaction1);
+ mFlinger.setTransactionStateInternal(transaction2);
+ mFlinger.flushTransactionQueues();
+ auto transactionQueues = mFlinger.getPendingTransactionQueue();
+
+ // Transaction 1 is still in its queue.
+ EXPECT_EQ(transactionQueues[applyToken1].size(), 1u);
+ // Transaction 2 has been dequeued.
+ EXPECT_EQ(transactionQueues[applyToken2].size(), 0u);
+}
+
class LatchUnsignaledTest : public TransactionApplicationTest {
public:
void TearDown() override {
diff --git a/services/vibratorservice/TEST_MAPPING b/services/vibratorservice/TEST_MAPPING
index 1eb3a58..7e382a3 100644
--- a/services/vibratorservice/TEST_MAPPING
+++ b/services/vibratorservice/TEST_MAPPING
@@ -1,6 +1,21 @@
{
"presubmit": [
{
+ "name": "libvibratorservice_test",
+ "options": [
+ // TODO(b/293603710): Fix flakiness
+ {
+ "exclude-filter": "VibratorCallbackSchedulerTest#TestScheduleRunsOnlyAfterDelay"
+ },
+ // TODO(b/293623689): Fix flakiness
+ {
+ "exclude-filter": "VibratorCallbackSchedulerTest#TestScheduleMultipleCallbacksRunsInDelayOrder"
+ }
+ ]
+ }
+ ],
+ "postsubmit": [
+ {
"name": "libvibratorservice_test"
}
],