Add getHashChain() to IBase.
am: 30b5d1ffe9
Change-Id: Ib5463e38698792e3a5f26099e4f90ce344aa3eca
diff --git a/Android.bp b/Android.bp
index 6db4821..1c68952 100644
--- a/Android.bp
+++ b/Android.bp
@@ -56,8 +56,10 @@
],
shared_libs: [
"libbase",
+ "libcrypto",
"liblog",
"libhidl-gen-utils",
+ "libssl",
],
}
diff --git a/ArrayType.cpp b/ArrayType.cpp
index 8b75c94..3d34a9f 100644
--- a/ArrayType.cpp
+++ b/ArrayType.cpp
@@ -96,6 +96,16 @@
CHECK(!"Should not be here");
}
+std::string ArrayType::getInternalDataCppType() const {
+ std::string result = mElementType->getCppStackType();
+ for (size_t i = 0; i < mSizes.size(); ++i) {
+ result += "[";
+ result += mSizes[i]->cppValue();
+ result += "]";
+ }
+ return result;
+}
+
std::string ArrayType::getJavaType(bool forInitializer) const {
std::string base =
mElementType->getJavaType(forInitializer);
diff --git a/ArrayType.h b/ArrayType.h
index ae58d28..3bb091f 100644
--- a/ArrayType.h
+++ b/ArrayType.h
@@ -44,6 +44,8 @@
std::string getCppType(StorageMode mode,
bool specifyNamespaces) const override;
+ std::string getInternalDataCppType() const;
+
void addNamedTypesToSet(std::set<const FQName> &set) const override;
std::string getJavaType(bool forInitializer) const override;
diff --git a/ConstantExpression.cpp b/ConstantExpression.cpp
index 850faf8..084f9df 100644
--- a/ConstantExpression.cpp
+++ b/ConstantExpression.cpp
@@ -152,19 +152,32 @@
ConstantExpression::ConstantExpression() {
}
+// static
ConstantExpression ConstantExpression::Zero(ScalarType::Kind kind) {
- ConstantExpression ce("0");
- CHECK(isSupported(kind));
- ce.mValueKind = kind;
- return ce;
-}
-ConstantExpression ConstantExpression::One(ScalarType::Kind kind) {
- ConstantExpression ce("1");
- CHECK(isSupported(kind));
- ce.mValueKind = kind;
+ ConstantExpression ce = ValueOf(kind, 0);
+ ce.mExpr = "0";
return ce;
}
+// static
+ConstantExpression ConstantExpression::One(ScalarType::Kind kind) {
+ ConstantExpression ce = ValueOf(kind, 1);
+ ce.mExpr = "1";
+ return ce;
+}
+
+// static
+ConstantExpression ConstantExpression::ValueOf(ScalarType::Kind kind, uint64_t value) {
+ ConstantExpression ce;
+ CHECK(isSupported(kind));
+
+ ce.mExpr = "";
+ ce.mType = kConstExprLiteral;
+ ce.mValueKind = kind;
+ ce.mValue = value;
+ ce.mTrivialDescription = true;
+ return ce;
+}
ConstantExpression::ConstantExpression(const ConstantExpression& other) {
*this = other;
}
diff --git a/ConstantExpression.h b/ConstantExpression.h
index 1f0524b..2c955d4 100644
--- a/ConstantExpression.h
+++ b/ConstantExpression.h
@@ -56,6 +56,7 @@
static ConstantExpression Zero(ScalarType::Kind kind);
static ConstantExpression One(ScalarType::Kind kind);
+ static ConstantExpression ValueOf(ScalarType::Kind kind, uint64_t value);
/* Evaluated result in a string form. */
std::string value() const;
diff --git a/Interface.cpp b/Interface.cpp
index 6cd6e94..d326703 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -17,17 +17,24 @@
#include "Interface.h"
#include "Annotation.h"
+#include "ArrayType.h"
+#include "ConstantExpression.h"
#include "DeathRecipientType.h"
#include "Method.h"
#include "ScalarType.h"
#include "StringType.h"
#include "VectorType.h"
+#include <unistd.h>
+
+#include <fstream>
+#include <iostream>
+#include <sstream>
+
#include <android-base/logging.h>
#include <hidl-util/Formatter.h>
#include <hidl-util/StringHelper.h>
-#include <iostream>
-#include <sstream>
+#include <openssl/sha.h>
namespace android {
@@ -58,6 +65,7 @@
HIDL_SET_HAL_INSTRUMENTATION_TRANSACTION = B_PACK_CHARS(0x0f, 'I', 'N', 'T'),
HIDL_GET_REF_INFO_TRANSACTION = B_PACK_CHARS(0x0f, 'R', 'E', 'F'),
HIDL_DEBUG_TRANSACTION = B_PACK_CHARS(0x0f, 'D', 'B', 'G'),
+ HIDL_HASH_CHAIN_TRANSACTION = B_PACK_CHARS(0x0f, 'H', 'S', 'H'),
LAST_HIDL_TRANSACTION = 0x0fffffff,
};
@@ -280,6 +288,75 @@
return true;
}
+static void sha256File(const std::string &path, uint8_t *outDigest) {
+ std::ifstream stream(path);
+ std::stringstream fileStream;
+ fileStream << stream.rdbuf();
+ std::string fileContent = fileStream.str();
+ SHA256(reinterpret_cast<const uint8_t *>(fileContent.c_str()),
+ fileContent.size(), outDigest);
+}
+
+static void emitDigestChain(
+ Formatter &out,
+ const std::string &prefix,
+ const std::vector<const Interface *> &chain,
+ std::function<std::string(const ConstantExpression &)> byteToString) {
+ out.join(chain.begin(), chain.end(), ",\n", [&] (const auto &iface) {
+ const std::string &filename = iface->location().begin().filename();
+ uint8_t digest[SHA256_DIGEST_LENGTH];
+ sha256File(filename, digest);
+ out << prefix;
+ out << "{";
+ out.join(digest, digest + SHA256_DIGEST_LENGTH, ",", [&](const auto &e) {
+ // Use ConstantExpression::cppValue / javaValue
+ // because Java used signed byte for uint8_t.
+ out << byteToString(ConstantExpression::ValueOf(ScalarType::Kind::KIND_UINT8, e));
+ });
+ out << "} /* ";
+ out.join(digest, digest + SHA256_DIGEST_LENGTH, "", [&](const auto &e) {
+ static const char hexes[] = "0123456789abcdef";
+ out << hexes[e >> 4] << hexes[e & 0xF];
+ });
+ out << " */";
+ });
+}
+
+bool Interface::fillHashChainMethod(Method *method) const {
+ if (method->name() != "getHashChain") {
+ return false;
+ }
+ const VectorType *chainType = static_cast<const VectorType *>(&method->results()[0]->type());
+ const ArrayType *digestType = static_cast<const ArrayType *>(chainType->getElementType());
+
+ method->fillImplementation(
+ HIDL_HASH_CHAIN_TRANSACTION,
+ { { IMPL_INTERFACE, [this, digestType](auto &out) {
+ std::vector<const Interface *> chain = typeChain();
+ out << "_hidl_cb(";
+ out.block([&] {
+ emitDigestChain(out, "(" + digestType->getInternalDataCppType() + ")",
+ chain, [](const auto &e){return e.cppValue();});
+ });
+ out << ");\n";
+ out << "return ::android::hardware::Void();\n";
+ } } }, /* cppImpl */
+ { { IMPL_INTERFACE, [this, digestType, chainType](auto &out) {
+ std::vector<const Interface *> chain = typeChain();
+ out << "return new "
+ << chainType->getJavaType(false /* forInitializer */)
+ << "(java.util.Arrays.asList(\n";
+ out.indent(2, [&] {
+ // No need for dimensions when elements are explicitly provided.
+ emitDigestChain(out, "new " + digestType->getJavaType(false /* forInitializer */),
+ chain, [](const auto &e){return e.javaValue();});
+ });
+ out << "));\n";
+ } } } /* javaImpl */
+ );
+ return true;
+}
+
bool Interface::fillGetDescriptorMethod(Method *method) const {
if (method->name() != "interfaceDescriptor") {
return false;
@@ -424,6 +501,7 @@
bool fillSuccess = fillPingMethod(method)
|| fillDescriptorChainMethod(method)
|| fillGetDescriptorMethod(method)
+ || fillHashChainMethod(method)
|| fillSyspropsChangedMethod(method)
|| fillLinkToDeathMethod(method)
|| fillUnlinkToDeathMethod(method)
diff --git a/Interface.h b/Interface.h
index 1b3ebb5..793226a 100644
--- a/Interface.h
+++ b/Interface.h
@@ -117,6 +117,7 @@
bool fillPingMethod(Method *method) const;
bool fillDescriptorChainMethod(Method *method) const;
bool fillGetDescriptorMethod(Method *method) const;
+ bool fillHashChainMethod(Method *method) const;
bool fillSyspropsChangedMethod(Method *method) const;
bool fillLinkToDeathMethod(Method *method) const;
bool fillUnlinkToDeathMethod(Method *method) const;
diff --git a/test/Android.bp b/test/Android.bp
index c392290..fbff8d0 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -23,6 +23,7 @@
"android.hardware.tests.foo@1.0",
"android.hardware.tests.bar@1.0",
"android.hardware.tests.baz@1.0",
+ "android.hardware.tests.hash@1.0",
"android.hardware.tests.inheritance@1.0",
"android.hardware.tests.pointer@1.0",
"android.hardware.tests.memory@1.0",
@@ -40,6 +41,7 @@
"android.hardware.tests.foo@1.0-impl",
"android.hardware.tests.bar@1.0-impl",
"android.hardware.tests.baz@1.0-impl",
+ "android.hardware.tests.hash@1.0-impl",
"android.hardware.tests.inheritance@1.0-impl",
"android.hardware.tests.pointer@1.0-impl",
"android.hardware.tests.memory@1.0-impl",
@@ -61,6 +63,7 @@
"android.hardware.tests.foo@1.0",
"android.hardware.tests.bar@1.0",
"android.hardware.tests.baz@1.0",
+ "android.hardware.tests.hash@1.0",
"android.hardware.tests.inheritance@1.0",
"android.hardware.tests.pointer@1.0",
"android.hardware.tests.memory@1.0",
diff --git a/test/hidl_test_client.cpp b/test/hidl_test_client.cpp
index 0dcfc32..76c87ed 100644
--- a/test/hidl_test_client.cpp
+++ b/test/hidl_test_client.cpp
@@ -20,6 +20,7 @@
#include <android/hardware/tests/bar/1.0/IComplicated.h>
#include <android/hardware/tests/bar/1.0/IImportRules.h>
#include <android/hardware/tests/baz/1.0/IBaz.h>
+#include <android/hardware/tests/hash/1.0/IHash.h>
#include <android/hardware/tests/inheritance/1.0/IFetcher.h>
#include <android/hardware/tests/inheritance/1.0/IGrandparent.h>
#include <android/hardware/tests/inheritance/1.0/IParent.h>
@@ -84,6 +85,7 @@
using ::android::hardware::tests::bar::V1_0::IBar;
using ::android::hardware::tests::bar::V1_0::IComplicated;
using ::android::hardware::tests::baz::V1_0::IBaz;
+using ::android::hardware::tests::hash::V1_0::IHash;
using ::android::hardware::tests::inheritance::V1_0::IFetcher;
using ::android::hardware::tests::inheritance::V1_0::IGrandparent;
using ::android::hardware::tests::inheritance::V1_0::IParent;
@@ -507,6 +509,21 @@
ASSERT_NE(manager, nullptr);
}
+TEST_F(HidlTest, HashTest) {
+ uint8_t ihash[32] = {74,38,204,105,102,117,11,15,207,7,238,198,29,35,30,62,100,
+ 216,131,182,3,61,162,241,215,211,6,20,251,143,125,161};
+ auto service = IHash::getService(mode == PASSTHROUGH /* getStub */);
+ EXPECT_OK(service->getHashChain([&] (const auto &chain) {
+ EXPECT_EQ(chain[0].size(), 32u);
+ EXPECT_ARRAYEQ(ihash, chain[0], 32);
+ EXPECT_OK(manager->getHashChain([&] (const auto &managerChain) {
+ EXPECT_EQ(chain[chain.size() - 1].size(), managerChain[managerChain.size() - 1].size());
+ EXPECT_ARRAYEQ(chain[chain.size() - 1], managerChain[managerChain.size() - 1],
+ chain[chain.size() - 1].size()) << "Hash for IBase doesn't match!";
+ }));
+ }));
+}
+
TEST_F(HidlTest, ServiceListTest) {
static const std::set<std::string> binderizedSet = {
"android.hardware.tests.pointer@1.0::IPointer/pointer",
diff --git a/test/hidl_test_servers.cpp b/test/hidl_test_servers.cpp
index 5aa46bd..21f9721 100644
--- a/test/hidl_test_servers.cpp
+++ b/test/hidl_test_servers.cpp
@@ -23,6 +23,7 @@
#include <android/hardware/tests/foo/1.0/BpHwSimple.h>
#include <android/hardware/tests/bar/1.0/IBar.h>
#include <android/hardware/tests/baz/1.0/IBaz.h>
+#include <android/hardware/tests/hash/1.0/IHash.h>
#include <android/hardware/tests/inheritance/1.0/IFetcher.h>
#include <android/hardware/tests/inheritance/1.0/IParent.h>
#include <android/hardware/tests/inheritance/1.0/IChild.h>
@@ -43,6 +44,7 @@
using ::android::hardware::tests::bar::V1_0::IBar;
using ::android::hardware::tests::baz::V1_0::IBaz;
+using ::android::hardware::tests::hash::V1_0::IHash;
using ::android::hardware::tests::inheritance::V1_0::IFetcher;
using ::android::hardware::tests::inheritance::V1_0::IParent;
using ::android::hardware::tests::inheritance::V1_0::IChild;
@@ -108,6 +110,7 @@
forkServer<IParent>("parent");
forkServer<IFetcher>("fetcher");
forkServer<IBar>("foo");
+ forkServer<IHash>("default");
forkServer<IBaz>("dyingBaz");
forkServer<IGraph>("graph");
forkServer<IPointer>("pointer");