Merge "audio HAL: add output flag indicating support for gapless transitions"
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index c7bfe08..a809a92 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -22,6 +22,8 @@
"libxml2",
],
shared_libs: [
+ "audioclient-types-aidl-unstable-cpp",
+ "libaudioclient_aidl_conversion",
"libbinder",
"libfmq",
],
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl
index fc35fa9..98fa4e8 100644
--- a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl
@@ -27,7 +27,7 @@
GAIN_TRANSIENT = 2,
GAIN_TRANSIENT_MAY_DUCK = 3,
GAIN_TRANSIENT_EXCLUSIVE = 4,
- LOSS = -1, // -1 * GAIN,
- LOSS_TRANSIENT = -2, // -1 * GAIN_TRANSIENT,
- LOSS_TRANSIENT_CAN_DUCK = -3, // -1 * GAIN_TRANSIENT_MAY_DUCK,
+ LOSS = -1 * GAIN,
+ LOSS_TRANSIENT = -1 * GAIN_TRANSIENT,
+ LOSS_TRANSIENT_CAN_DUCK = -1 * GAIN_TRANSIENT_MAY_DUCK,
}
\ No newline at end of file
diff --git a/automotive/can/1.0/default/libnl++/Android.bp b/automotive/can/1.0/default/libnl++/Android.bp
index 4042b16..90e1002 100644
--- a/automotive/can/1.0/default/libnl++/Android.bp
+++ b/automotive/can/1.0/default/libnl++/Android.bp
@@ -25,6 +25,7 @@
"protocols/generic/Generic.cpp",
"protocols/generic/GenericMessageBase.cpp",
"protocols/generic/Unknown.cpp",
+ "protocols/generic/families/Nl80211.cpp",
"protocols/route/Link.cpp",
"protocols/route/Route.cpp",
"protocols/route/structs.cpp",
diff --git a/automotive/can/1.0/default/libnl++/printer.cpp b/automotive/can/1.0/default/libnl++/printer.cpp
index e6cada2..f08897e 100644
--- a/automotive/can/1.0/default/libnl++/printer.cpp
+++ b/automotive/can/1.0/default/libnl++/printer.cpp
@@ -51,24 +51,24 @@
printFlag(NLM_F_DUMP_FILTERED, "DUMP_FILTERED");
switch (genre) {
- case protocols::MessageGenre::UNKNOWN:
+ case protocols::MessageGenre::Unknown:
break;
- case protocols::MessageGenre::GET:
+ case protocols::MessageGenre::Get:
printFlag(NLM_F_DUMP, "DUMP"); // ROOT | MATCH
printFlag(NLM_F_ROOT, "ROOT");
printFlag(NLM_F_MATCH, "MATCH");
printFlag(NLM_F_ATOMIC, "ATOMIC");
break;
- case protocols::MessageGenre::NEW:
+ case protocols::MessageGenre::New:
printFlag(NLM_F_REPLACE, "REPLACE");
printFlag(NLM_F_EXCL, "EXCL");
printFlag(NLM_F_CREATE, "CREATE");
printFlag(NLM_F_APPEND, "APPEND");
break;
- case protocols::MessageGenre::DELETE:
+ case protocols::MessageGenre::Delete:
printFlag(NLM_F_NONREC, "NONREC");
break;
- case protocols::MessageGenre::ACK:
+ case protocols::MessageGenre::Ack:
printFlag(NLM_F_CAPPED, "CAPPED");
printFlag(NLM_F_ACK_TLVS, "ACK_TLVS");
break;
@@ -99,11 +99,25 @@
static void toStream(std::stringstream& ss, const Buffer<nlattr> attr,
const protocols::AttributeMap& attrMap) {
using DataType = protocols::AttributeDefinition::DataType;
+ using Flags = protocols::AttributeDefinition::Flags;
const auto attrtype = attrMap[attr->nla_type];
- ss << attrtype.name << ": ";
+ ss << attrtype.name;
+
+ if (attrtype.dataType == DataType::Flag && attr.data<uint8_t>().getRaw().len() == 0) return;
+ ss << ": ";
+
+ if (attrtype.flags == Flags::Verbose) {
+ const auto raw = attr.data<uint8_t>();
+ ss << "{len=" << raw.getRaw().len();
+ ss << ", crc=" << std::hex << std::setw(4) << crc16(raw) << std::dec;
+ ss << "}";
+ return;
+ }
+
switch (attrtype.dataType) {
case DataType::Raw:
+ case DataType::Flag:
toStream(ss, attr.data<uint8_t>());
break;
case DataType::Nested: {
@@ -117,13 +131,19 @@
ss << '}';
break;
}
+ case DataType::StringNul:
case DataType::String: {
const auto str = attr.data<char>().getRaw();
- ss << '"' << printableOnly({str.ptr(), str.len()}) << '"';
+ auto len = str.len();
+ if (attrtype.dataType == DataType::StringNul && len > 0 && str.ptr()[len - 1] == '\0') {
+ len--;
+ }
+
+ ss << '"' << printableOnly({str.ptr(), len}) << '"';
break;
}
case DataType::Uint:
- ss << attr.data<uint32_t>().copyFirst();
+ ss << attr.data<uint64_t>().copyFirst();
break;
case DataType::Struct: {
const auto structToStream =
@@ -147,10 +167,12 @@
}
protocols::NetlinkProtocol& protocolDescr = *protocolMaybe;
- const auto msgDescMaybe = protocolDescr.getMessageDescriptor(hdr->nlmsg_type);
+ auto msgDescMaybe = protocolDescr.getMessageDescriptor(hdr->nlmsg_type);
const auto msgDetails =
protocols::MessageDescriptor::getMessageDetails(msgDescMaybe, hdr->nlmsg_type);
+ if (msgDescMaybe.has_value()) msgDescMaybe->get().track(hdr);
+
ss << "nlmsg{" << protocolDescr.getName() << " ";
ss << "hdr={";
diff --git a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp
index c93d865..aaf24a5 100644
--- a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp
@@ -56,15 +56,17 @@
MessageDescriptor::MessageDetails MessageDescriptor::getMessageDetails(nlmsgtype_t msgtype) const {
const auto it = mMessageDetails.find(msgtype);
- if (it == mMessageDetails.end()) return {std::to_string(msgtype), MessageGenre::UNKNOWN};
+ if (it == mMessageDetails.end()) return {std::to_string(msgtype), MessageGenre::Unknown};
return it->second;
}
MessageDescriptor::MessageDetails MessageDescriptor::getMessageDetails(
- const std::optional<std::reference_wrapper<const MessageDescriptor>>& msgDescMaybe,
+ const std::optional<std::reference_wrapper<MessageDescriptor>>& msgDescMaybe,
nlmsgtype_t msgtype) {
if (msgDescMaybe.has_value()) return msgDescMaybe->get().getMessageDetails(msgtype);
- return {std::to_string(msgtype), protocols::MessageGenre::UNKNOWN};
+ return {std::to_string(msgtype), protocols::MessageGenre::Unknown};
}
+void MessageDescriptor::track(const Buffer<nlmsghdr> /* hdr */) {}
+
} // namespace android::nl::protocols
diff --git a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h
index bd0e60f..8bed5e7 100644
--- a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h
+++ b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h
@@ -54,17 +54,64 @@
*/
struct AttributeDefinition {
enum class DataType : uint8_t {
+ /**
+ * Binary blob (or attribute of unknown type).
+ */
Raw,
+
+ /**
+ * Nested attribute (with or without NLA_F_NESTED).
+ */
Nested,
+
+ /**
+ * Non-null terminated string.
+ *
+ * The length of the string is determined by the size of an attribute.
+ */
String,
+
+ /**
+ * Null terminated string.
+ */
+ StringNul,
+
+ /**
+ * Unsigned integer of size 8, 16, 32 or 64 bits.
+ */
Uint,
+
+ /**
+ * Structure which printer is defined in ops ToStream variant.
+ */
Struct,
+
+ /**
+ * Flag attribute.
+ *
+ * The attribute doesn't have any contents. The flag is set when the attribute is present,
+ * it's not when it's absent from attribute list.
+ */
+ Flag,
+ };
+ enum class Flags : uint8_t {
+ Verbose = (1 << 0),
};
using ToStream = std::function<void(std::stringstream& ss, const Buffer<nlattr> attr)>;
std::string name;
DataType dataType = DataType::Raw;
std::variant<AttributeMap, ToStream> ops = AttributeMap{};
+
+ /**
+ * Attribute flags.
+ *
+ * It's not really a bitmask flag set (since you are not supposed to compare enum class by
+ * bitmask), but std::set<Flags> bumps compile time from 16s to 3m. Let's leave it as-is for
+ * now and revisit if we get some flags that can be used in pairs. When it happens, review all
+ * uses of the flags field to include the "&" operator and not "==".
+ */
+ Flags flags = {};
};
/**
@@ -74,11 +121,11 @@
* section in linux/netlink.h.
*/
enum class MessageGenre {
- UNKNOWN,
- GET,
- NEW,
- DELETE,
- ACK,
+ Unknown,
+ Get,
+ New,
+ Delete,
+ Ack,
};
/**
@@ -103,8 +150,15 @@
MessageDetails getMessageDetails(nlmsgtype_t msgtype) const;
virtual void dataToStream(std::stringstream& ss, const Buffer<nlmsghdr> hdr) const = 0;
+ /**
+ * Message tracking for stateful protocols (such as NETLINK_GENERIC).
+ *
+ * \param hdr Message to track
+ */
+ virtual void track(const Buffer<nlmsghdr> hdr);
+
static MessageDetails getMessageDetails(
- const std::optional<std::reference_wrapper<const MessageDescriptor>>& msgDescMaybe,
+ const std::optional<std::reference_wrapper<MessageDescriptor>>& msgDescMaybe,
nlmsgtype_t msgtype);
protected:
diff --git a/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp
index cd2e8c6..16208ab 100644
--- a/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp
@@ -32,7 +32,7 @@
return mName;
}
-const std::optional<std::reference_wrapper<const MessageDescriptor>>
+const std::optional<std::reference_wrapper<MessageDescriptor>>
NetlinkProtocol::getMessageDescriptor(nlmsgtype_t nlmsg_type) {
if (mMessageDescrs.count(nlmsg_type) == 0) return std::nullopt;
return *mMessageDescrs.find(nlmsg_type)->second;
@@ -41,7 +41,7 @@
NetlinkProtocol::MessageDescriptorMap NetlinkProtocol::toMap(
const NetlinkProtocol::MessageDescriptorList& descrs, int protocol) {
MessageDescriptorMap map;
- for (const auto& descr : descrs) {
+ for (auto& descr : descrs) {
for (const auto& [mtype, mdet] : descr->getMessageDetailsMap()) {
map.emplace(mtype, descr);
}
diff --git a/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h
index c969547..b173b91 100644
--- a/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h
+++ b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h
@@ -40,17 +40,17 @@
const std::string& getName() const;
- virtual const std::optional<std::reference_wrapper<const MessageDescriptor>>
- getMessageDescriptor(nlmsgtype_t nlmsg_type);
+ virtual const std::optional<std::reference_wrapper<MessageDescriptor>> getMessageDescriptor(
+ nlmsgtype_t nlmsg_type);
protected:
- typedef std::vector<std::shared_ptr<const MessageDescriptor>> MessageDescriptorList;
+ typedef std::vector<std::shared_ptr<MessageDescriptor>> MessageDescriptorList;
NetlinkProtocol(int protocol, const std::string& name,
const MessageDescriptorList&& messageDescrs);
private:
- typedef std::map<nlmsgtype_t, std::shared_ptr<const MessageDescriptor>> MessageDescriptorMap;
+ typedef std::map<nlmsgtype_t, std::shared_ptr<MessageDescriptor>> MessageDescriptorMap;
const int mProtocol;
const std::string mName;
diff --git a/automotive/can/1.0/default/libnl++/protocols/common/Empty.cpp b/automotive/can/1.0/default/libnl++/protocols/common/Empty.cpp
index 8a672d3..4b509c9 100644
--- a/automotive/can/1.0/default/libnl++/protocols/common/Empty.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/common/Empty.cpp
@@ -20,9 +20,9 @@
// clang-format off
Empty::Empty() : MessageDefinition<char>("nlmsg", {
- {NLMSG_NOOP, {"NOOP", MessageGenre::UNKNOWN}},
- {NLMSG_DONE, {"DONE", MessageGenre::UNKNOWN}},
- {NLMSG_OVERRUN, {"OVERRUN", MessageGenre::UNKNOWN}},
+ {NLMSG_NOOP, {"NOOP", MessageGenre::Unknown}},
+ {NLMSG_DONE, {"DONE", MessageGenre::Unknown}},
+ {NLMSG_OVERRUN, {"OVERRUN", MessageGenre::Unknown}},
}) {}
// clang-format on
diff --git a/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp b/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp
index 44708a3..77451ed 100644
--- a/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp
@@ -20,13 +20,15 @@
#include <libnl++/printer.h>
+#include <map>
+
namespace android::nl::protocols::base {
using DataType = AttributeDefinition::DataType;
// clang-format off
Error::Error(int protocol) : MessageDefinition<nlmsgerr>("nlmsg", {
- {NLMSG_ERROR, {"ERROR", MessageGenre::ACK}},
+ {NLMSG_ERROR, {"ERROR", MessageGenre::Ack}},
}, {
{NLMSGERR_ATTR_MSG, {"MSG", DataType::String}},
{NLMSGERR_ATTR_OFFS, {"OFFS", DataType::Uint}},
@@ -34,9 +36,156 @@
}), mProtocol(protocol) {}
// clang-format on
+std::map<int, std::string> errnoNames{
+ {EPERM, "EPERM"}, // Operation not permitted
+ {ENOENT, "ENOENT"}, // No such file or directory
+ {ESRCH, "ESRCH"}, // No such process
+ {EINTR, "EINTR"}, // Interrupted system call
+ {EIO, "EIO"}, // I/O error
+ {ENXIO, "ENXIO"}, // No such device or address
+ {E2BIG, "E2BIG"}, // Argument list too long
+ {ENOEXEC, "ENOEXEC"}, // Exec format error
+ {EBADF, "EBADF"}, // Bad file number
+ {ECHILD, "ECHILD"}, // No child processes
+ {EAGAIN, "EAGAIN"}, // Try again
+ {ENOMEM, "ENOMEM"}, // Out of memory
+ {EACCES, "EACCES"}, // Permission denied
+ {EFAULT, "EFAULT"}, // Bad address
+ {ENOTBLK, "ENOTBLK"}, // Block device required
+ {EBUSY, "EBUSY"}, // Device or resource busy
+ {EEXIST, "EEXIST"}, // File exists
+ {EXDEV, "EXDEV"}, // Cross-device link
+ {ENODEV, "ENODEV"}, // No such device
+ {ENOTDIR, "ENOTDIR"}, // Not a directory
+ {EISDIR, "EISDIR"}, // Is a directory
+ {EINVAL, "EINVAL"}, // Invalid argument
+ {ENFILE, "ENFILE"}, // File table overflow
+ {EMFILE, "EMFILE"}, // Too many open files
+ {ENOTTY, "ENOTTY"}, // Not a typewriter
+ {ETXTBSY, "ETXTBSY"}, // Text file busy
+ {EFBIG, "EFBIG"}, // File too large
+ {ENOSPC, "ENOSPC"}, // No space left on device
+ {ESPIPE, "ESPIPE"}, // Illegal seek
+ {EROFS, "EROFS"}, // Read-only file system
+ {EMLINK, "EMLINK"}, // Too many links
+ {EPIPE, "EPIPE"}, // Broken pipe
+ {EDOM, "EDOM"}, // Math argument out of domain of func
+ {ERANGE, "ERANGE"}, // Math result not representable
+ {EDEADLK, "EDEADLK"}, // Resource deadlock would occur
+ {ENAMETOOLONG, "ENAMETOOLONG"}, // File name too long
+ {ENOLCK, "ENOLCK"}, // No record locks available
+ {ENOSYS, "ENOSYS"}, // Invalid system call number
+ {ENOTEMPTY, "ENOTEMPTY"}, // Directory not empty
+ {ELOOP, "ELOOP"}, // Too many symbolic links encountered
+ {ENOMSG, "ENOMSG"}, // No message of desired type
+ {EIDRM, "EIDRM"}, // Identifier removed
+ {ECHRNG, "ECHRNG"}, // Channel number out of range
+ {EL2NSYNC, "EL2NSYNC"}, // Level 2 not synchronized
+ {EL3HLT, "EL3HLT"}, // Level 3 halted
+ {EL3RST, "EL3RST"}, // Level 3 reset
+ {ELNRNG, "ELNRNG"}, // Link number out of range
+ {EUNATCH, "EUNATCH"}, // Protocol driver not attached
+ {ENOCSI, "ENOCSI"}, // No CSI structure available
+ {EL2HLT, "EL2HLT"}, // Level 2 halted
+ {EBADE, "EBADE"}, // Invalid exchange
+ {EBADR, "EBADR"}, // Invalid request descriptor
+ {EXFULL, "EXFULL"}, // Exchange full
+ {ENOANO, "ENOANO"}, // No anode
+ {EBADRQC, "EBADRQC"}, // Invalid request code
+ {EBADSLT, "EBADSLT"}, // Invalid slot
+ {EBFONT, "EBFONT"}, // Bad font file format
+ {ENOSTR, "ENOSTR"}, // Device not a stream
+ {ENODATA, "ENODATA"}, // No data available
+ {ETIME, "ETIME"}, // Timer expired
+ {ENOSR, "ENOSR"}, // Out of streams resources
+ {ENONET, "ENONET"}, // Machine is not on the network
+ {ENOPKG, "ENOPKG"}, // Package not installed
+ {EREMOTE, "EREMOTE"}, // Object is remote
+ {ENOLINK, "ENOLINK"}, // Link has been severed
+ {EADV, "EADV"}, // Advertise error
+ {ESRMNT, "ESRMNT"}, // Srmount error
+ {ECOMM, "ECOMM"}, // Communication error on send
+ {EPROTO, "EPROTO"}, // Protocol error
+ {EMULTIHOP, "EMULTIHOP"}, // Multihop attempted
+ {EDOTDOT, "EDOTDOT"}, // RFS specific error
+ {EBADMSG, "EBADMSG"}, // Not a data message
+ {EOVERFLOW, "EOVERFLOW"}, // Value too large for defined data type
+ {ENOTUNIQ, "ENOTUNIQ"}, // Name not unique on network
+ {EBADFD, "EBADFD"}, // File descriptor in bad state
+ {EREMCHG, "EREMCHG"}, // Remote address changed
+ {ELIBACC, "ELIBACC"}, // Can not access a needed shared library
+ {ELIBBAD, "ELIBBAD"}, // Accessing a corrupted shared library
+ {ELIBSCN, "ELIBSCN"}, // .lib section in a.out corrupted
+ {ELIBMAX, "ELIBMAX"}, // Attempting to link in too many shared libraries
+ {ELIBEXEC, "ELIBEXEC"}, // Cannot exec a shared library directly
+ {EILSEQ, "EILSEQ"}, // Illegal byte sequence
+ {ERESTART, "ERESTART"}, // Interrupted system call should be restarted
+ {ESTRPIPE, "ESTRPIPE"}, // Streams pipe error
+ {EUSERS, "EUSERS"}, // Too many users
+ {ENOTSOCK, "ENOTSOCK"}, // Socket operation on non-socket
+ {EDESTADDRREQ, "EDESTADDRREQ"}, // Destination address required
+ {EMSGSIZE, "EMSGSIZE"}, // Message too long
+ {EPROTOTYPE, "EPROTOTYPE"}, // Protocol wrong type for socket
+ {ENOPROTOOPT, "ENOPROTOOPT"}, // Protocol not available
+ {EPROTONOSUPPORT, "EPROTONOSUPPORT"}, // Protocol not supported
+ {ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT"}, // Socket type not supported
+ {EOPNOTSUPP, "EOPNOTSUPP"}, // Operation not supported on transport endpoint
+ {EPFNOSUPPORT, "EPFNOSUPPORT"}, // Protocol family not supported
+ {EAFNOSUPPORT, "EAFNOSUPPORT"}, // Address family not supported by protocol
+ {EADDRINUSE, "EADDRINUSE"}, // Address already in use
+ {EADDRNOTAVAIL, "EADDRNOTAVAIL"}, // Cannot assign requested address
+ {ENETDOWN, "ENETDOWN"}, // Network is down
+ {ENETUNREACH, "ENETUNREACH"}, // Network is unreachable
+ {ENETRESET, "ENETRESET"}, // Network dropped connection because of reset
+ {ECONNABORTED, "ECONNABORTED"}, // Software caused connection abort
+ {ECONNRESET, "ECONNRESET"}, // Connection reset by peer
+ {ENOBUFS, "ENOBUFS"}, // No buffer space available
+ {EISCONN, "EISCONN"}, // Transport endpoint is already connected
+ {ENOTCONN, "ENOTCONN"}, // Transport endpoint is not connected
+ {ESHUTDOWN, "ESHUTDOWN"}, // Cannot send after transport endpoint shutdown
+ {ETOOMANYREFS, "ETOOMANYREFS"}, // Too many references: cannot splice
+ {ETIMEDOUT, "ETIMEDOUT"}, // Connection timed out
+ {ECONNREFUSED, "ECONNREFUSED"}, // Connection refused
+ {EHOSTDOWN, "EHOSTDOWN"}, // Host is down
+ {EHOSTUNREACH, "EHOSTUNREACH"}, // No route to host
+ {EALREADY, "EALREADY"}, // Operation already in progress
+ {EINPROGRESS, "EINPROGRESS"}, // Operation now in progress
+ {ESTALE, "ESTALE"}, // Stale file handle
+ {EUCLEAN, "EUCLEAN"}, // Structure needs cleaning
+ {ENOTNAM, "ENOTNAM"}, // Not a XENIX named type file
+ {ENAVAIL, "ENAVAIL"}, // No XENIX semaphores available
+ {EISNAM, "EISNAM"}, // Is a named type file
+ {EREMOTEIO, "EREMOTEIO"}, // Remote I/O error
+ {EDQUOT, "EDQUOT"}, // Quota exceeded
+ {ENOMEDIUM, "ENOMEDIUM"}, // No medium found
+ {EMEDIUMTYPE, "EMEDIUMTYPE"}, // Wrong medium type
+ {ECANCELED, "ECANCELED"}, // Operation Canceled
+ {ENOKEY, "ENOKEY"}, // Required key not available
+ {EKEYEXPIRED, "EKEYEXPIRED"}, // Key has expired
+ {EKEYREVOKED, "EKEYREVOKED"}, // Key has been revoked
+ {EKEYREJECTED, "EKEYREJECTED"}, // Key was rejected by service
+ {EOWNERDEAD, "EOWNERDEAD"}, // Owner died
+ {ENOTRECOVERABLE, "ENOTRECOVERABLE"}, // State not recoverable
+ {ERFKILL, "ERFKILL"}, // Operation not possible due to RF-kill
+ {EHWPOISON, "EHWPOISON"}, // Memory page has hardware error
+
+ // Duplicates: EWOULDBLOCK (Operation would block), EDEADLOCK
+};
+
void Error::toStream(std::stringstream& ss, const nlmsgerr& data) const {
- ss << "nlmsgerr{error=" << data.error
- << ", msg=" << toString({&data.msg, sizeof(data.msg)}, mProtocol, false) << "}";
+ ss << "nlmsgerr{";
+ if (data.error == 0) {
+ ss << "ACK";
+ } else {
+ ss << "error=";
+ const auto nameIt = errnoNames.find(-data.error);
+ if (nameIt == errnoNames.end()) {
+ ss << data.error;
+ } else {
+ ss << nameIt->second;
+ }
+ }
+ ss << ", msg=" << toString({&data.msg, sizeof(data.msg)}, mProtocol, false) << "}";
}
} // namespace android::nl::protocols::base
diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.cpp
index a3c6736..1e1ad12 100644
--- a/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.cpp
@@ -16,12 +16,19 @@
#include "Ctrl.h"
+#include "families/Nl80211.h"
+
+#include <libnl++/Message.h>
+
namespace android::nl::protocols::generic {
using DataType = AttributeDefinition::DataType;
+using Flags = AttributeDefinition::Flags;
// clang-format off
-Ctrl::Ctrl() : GenericMessageBase(GENL_ID_CTRL, "ID_CTRL", {
+Ctrl::Ctrl(Generic::FamilyRegister& familyRegister)
+ : GenericMessageBase(GENL_ID_CTRL, "ID_CTRL",
+{
{CTRL_CMD_NEWFAMILY, "NEWFAMILY"},
{CTRL_CMD_DELFAMILY, "DELFAMILY"},
{CTRL_CMD_GETFAMILY, "GETFAMILY"},
@@ -33,7 +40,7 @@
{CTRL_CMD_GETMCAST_GRP, "GETMCAST_GRP"},
}, {
{CTRL_ATTR_FAMILY_ID, {"FAMILY_ID", DataType::Uint}},
- {CTRL_ATTR_FAMILY_NAME, {"FAMILY_NAME", DataType::String}},
+ {CTRL_ATTR_FAMILY_NAME, {"FAMILY_NAME", DataType::StringNul}},
{CTRL_ATTR_VERSION, {"VERSION", DataType::Uint}},
{CTRL_ATTR_HDRSIZE, {"HDRSIZE", DataType::Uint}},
{CTRL_ATTR_MAXATTR, {"MAXATTR", DataType::Uint}},
@@ -42,14 +49,31 @@
{CTRL_ATTR_OP_ID, {"ID", DataType::Uint}},
{CTRL_ATTR_OP_FLAGS, {"FLAGS", DataType::Uint}},
}}},
- }}},
+ }, Flags::Verbose}},
{CTRL_ATTR_MCAST_GROUPS, {"MCAST_GROUPS", DataType::Nested, AttributeMap{
{std::nullopt, {"GRP", DataType::Nested, AttributeMap{
- {CTRL_ATTR_MCAST_GRP_NAME, {"NAME", DataType::String}},
+ {CTRL_ATTR_MCAST_GRP_NAME, {"NAME", DataType::StringNul}},
{CTRL_ATTR_MCAST_GRP_ID, {"ID", DataType::Uint}},
}}},
}}},
-}) {}
+}), mFamilyRegister(familyRegister) {}
// clang-format on
+void Ctrl::track(const Buffer<nlmsghdr> hdr) {
+ const auto msgMaybe = Message<genlmsghdr>::parse(hdr, {GENL_ID_CTRL});
+ if (!msgMaybe.has_value()) return;
+ const auto msg = *msgMaybe;
+
+ if (msg->cmd != CTRL_CMD_NEWFAMILY) return;
+ const auto familyId = msg.attributes.get<uint16_t>(CTRL_ATTR_FAMILY_ID);
+ const auto familyName = msg.attributes.get<std::string>(CTRL_ATTR_FAMILY_NAME);
+
+ /* For now, we support just a single family. But if you add more, please define proper
+ * abstraction and not hardcode every name and class here.
+ */
+ if (familyName == "nl80211") {
+ mFamilyRegister[familyId] = std::make_shared<families::Nl80211>(familyId);
+ }
+}
+
} // namespace android::nl::protocols::generic
diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.h b/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.h
index 6af87a8..b13df02 100644
--- a/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.h
+++ b/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.h
@@ -16,13 +16,19 @@
#pragma once
+#include "Generic.h"
#include "GenericMessageBase.h"
namespace android::nl::protocols::generic {
class Ctrl : public GenericMessageBase {
public:
- Ctrl();
+ Ctrl(Generic::FamilyRegister& familyRegister);
+
+ void track(const Buffer<nlmsghdr> hdr) override;
+
+ private:
+ Generic::FamilyRegister& mFamilyRegister;
};
} // namespace android::nl::protocols::generic
diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/Generic.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/Generic.cpp
index 1a24914..5e34a1f 100644
--- a/automotive/can/1.0/default/libnl++/protocols/generic/Generic.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/generic/Generic.cpp
@@ -21,11 +21,12 @@
namespace android::nl::protocols::generic {
-Generic::Generic() : NetlinkProtocol(NETLINK_GENERIC, "GENERIC", {std::make_shared<Ctrl>()}) {}
+Generic::Generic()
+ : NetlinkProtocol(NETLINK_GENERIC, "GENERIC", {std::make_shared<Ctrl>(mFamilyRegister)}) {}
-const std::optional<std::reference_wrapper<const MessageDescriptor>> Generic::getMessageDescriptor(
+const std::optional<std::reference_wrapper<MessageDescriptor>> Generic::getMessageDescriptor(
nlmsgtype_t nlmsg_type) {
- const auto desc = NetlinkProtocol::getMessageDescriptor(nlmsg_type);
+ auto desc = NetlinkProtocol::getMessageDescriptor(nlmsg_type);
if (desc.has_value()) return desc;
auto it = mFamilyRegister.find(nlmsg_type);
diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/Generic.h b/automotive/can/1.0/default/libnl++/protocols/generic/Generic.h
index 593c92d..2cdd584 100644
--- a/automotive/can/1.0/default/libnl++/protocols/generic/Generic.h
+++ b/automotive/can/1.0/default/libnl++/protocols/generic/Generic.h
@@ -25,13 +25,15 @@
*/
class Generic : public NetlinkProtocol {
public:
+ typedef std::map<nlmsgtype_t, std::shared_ptr<MessageDescriptor>> FamilyRegister;
+
Generic();
- const std::optional<std::reference_wrapper<const MessageDescriptor>> getMessageDescriptor(
+ const std::optional<std::reference_wrapper<MessageDescriptor>> getMessageDescriptor(
nlmsgtype_t nlmsg_type);
private:
- std::map<nlmsgtype_t, std::shared_ptr<const MessageDescriptor>> mFamilyRegister;
+ FamilyRegister mFamilyRegister;
};
} // namespace android::nl::protocols::generic
diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp
index 134638e..b7b811b 100644
--- a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp
@@ -22,16 +22,27 @@
nlmsgtype_t msgtype, const std::string&& msgname,
const std::initializer_list<GenericCommandNameMap::value_type> commandNames,
const std::initializer_list<AttributeMap::value_type> attrTypes)
- : MessageDefinition<genlmsghdr>(msgname, {{msgtype, {msgname, MessageGenre::UNKNOWN}}},
+ : MessageDefinition<genlmsghdr>(msgname, {{msgtype, {msgname, MessageGenre::Unknown}}},
attrTypes),
mCommandNames(commandNames) {}
void GenericMessageBase::toStream(std::stringstream& ss, const genlmsghdr& data) const {
+ const auto commandNameIt = mCommandNames.find(data.cmd);
+ const auto commandName = (commandNameIt == mCommandNames.end())
+ ? std::nullopt
+ : std::optional<std::string>(commandNameIt->second);
+
+ if (commandName.has_value() && data.version == 1 && data.reserved == 0) {
+ // short version
+ ss << *commandName;
+ return;
+ }
+
ss << "genlmsghdr{";
- if (mCommandNames.count(data.cmd) == 0) {
+ if (commandName.has_value()) {
ss << "cmd=" << unsigned(data.cmd);
} else {
- ss << "cmd=" << mCommandNames.find(data.cmd)->second;
+ ss << "cmd=" << *commandName;
}
ss << ", version=" << unsigned(data.version);
if (data.reserved != 0) ss << ", reserved=" << data.reserved;
diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/families/Nl80211.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/families/Nl80211.cpp
new file mode 100644
index 0000000..23ec66f
--- /dev/null
+++ b/automotive/can/1.0/default/libnl++/protocols/generic/families/Nl80211.cpp
@@ -0,0 +1,1009 @@
+/*
+ * Copyright (C) 2020 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 "Nl80211.h"
+
+#include "../../structs.h"
+#include "common.h"
+
+#include <linux/nl80211.h>
+
+#include <iomanip>
+
+namespace android::nl::protocols::generic::families {
+
+/**
+ * Reduce verbosity of printed Information Elements.
+ */
+static constexpr bool kCompactIE = true;
+
+enum {
+ // broken compatibility in Aug 2020
+ NL80211_ATTR_CNTDWN_OFFS_BEACON = NL80211_ATTR_CSA_C_OFF_BEACON,
+ NL80211_ATTR_CNTDWN_OFFS_PRESP = NL80211_ATTR_CSA_C_OFF_PRESP,
+
+ // new fields not available in current Android
+ NL80211_ATTR_FILS_DISCOVERY = NL80211_ATTR_HE_6GHZ_CAPABILITY + 1,
+ NL80211_ATTR_UNSOL_BCAST_PROBE_RESP,
+ NL80211_ATTR_S1G_CAPABILITY,
+ NL80211_ATTR_S1G_CAPABILITY_MASK,
+
+ NL80211_FREQUENCY_ATTR_1MHZ = NL80211_FREQUENCY_ATTR_OFFSET + 1,
+ NL80211_FREQUENCY_ATTR_2MHZ,
+ NL80211_FREQUENCY_ATTR_4MHZ,
+ NL80211_FREQUENCY_ATTR_8MHZ,
+ NL80211_FREQUENCY_ATTR_16MHZ,
+};
+
+enum ieee80211_eid {
+ WLAN_EID_SSID = 0,
+};
+
+using DataType = AttributeDefinition::DataType;
+using Flags = AttributeDefinition::Flags;
+
+static void informationElementsToStream(std::stringstream& ss, const Buffer<nlattr> attr);
+static void nl80211_pattern_supportToStream(std::stringstream& ss, const Buffer<nlattr> attr);
+
+static const AttributeMap iftypes{
+ {NL80211_IFTYPE_UNSPECIFIED, {"UNSPECIFIED", DataType::Flag}},
+ {NL80211_IFTYPE_ADHOC, {"ADHOC", DataType::Flag}},
+ {NL80211_IFTYPE_STATION, {"STATION", DataType::Flag}},
+ {NL80211_IFTYPE_AP, {"AP", DataType::Flag}},
+ {NL80211_IFTYPE_AP_VLAN, {"AP_VLAN", DataType::Flag}},
+ {NL80211_IFTYPE_WDS, {"WDS", DataType::Flag}},
+ {NL80211_IFTYPE_MONITOR, {"MONITOR", DataType::Flag}},
+ {NL80211_IFTYPE_MESH_POINT, {"MESH_POINT", DataType::Flag}},
+ {NL80211_IFTYPE_P2P_CLIENT, {"P2P_CLIENT", DataType::Flag}},
+ {NL80211_IFTYPE_P2P_GO, {"P2P_GO", DataType::Flag}},
+ {NL80211_IFTYPE_P2P_DEVICE, {"P2P_DEVICE", DataType::Flag}},
+ {NL80211_IFTYPE_OCB, {"OCB", DataType::Flag}},
+ {NL80211_IFTYPE_NAN, {"NAN", DataType::Flag}},
+};
+
+// clang-format off
+Nl80211::Nl80211(nlmsgtype_t familyId) : GenericMessageBase(familyId, "nl80211", {
+ /* Script to generate the (initial) top-level list from linux/nl80211.h:
+ * sed -e 's/^ NL80211_CMD_\(.*\),$/ {NL80211_CMD_\1, "\1"},/g'
+ */
+ {NL80211_CMD_UNSPEC, "UNSPEC"},
+
+ {NL80211_CMD_GET_WIPHY, "GET_WIPHY"},
+ {NL80211_CMD_SET_WIPHY, "SET_WIPHY"},
+ {NL80211_CMD_NEW_WIPHY, "NEW_WIPHY"},
+ {NL80211_CMD_DEL_WIPHY, "DEL_WIPHY"},
+
+ {NL80211_CMD_GET_INTERFACE, "GET_INTERFACE"},
+ {NL80211_CMD_SET_INTERFACE, "SET_INTERFACE"},
+ {NL80211_CMD_NEW_INTERFACE, "NEW_INTERFACE"},
+ {NL80211_CMD_DEL_INTERFACE, "DEL_INTERFACE"},
+
+ {NL80211_CMD_GET_KEY, "GET_KEY"},
+ {NL80211_CMD_SET_KEY, "SET_KEY"},
+ {NL80211_CMD_NEW_KEY, "NEW_KEY"},
+ {NL80211_CMD_DEL_KEY, "DEL_KEY"},
+
+ {NL80211_CMD_GET_BEACON, "GET_BEACON"},
+ {NL80211_CMD_SET_BEACON, "SET_BEACON"},
+ {NL80211_CMD_START_AP, "START_AP"},
+ {NL80211_CMD_STOP_AP, "STOP_AP"},
+
+ {NL80211_CMD_GET_STATION, "GET_STATION"},
+ {NL80211_CMD_SET_STATION, "SET_STATION"},
+ {NL80211_CMD_NEW_STATION, "NEW_STATION"},
+ {NL80211_CMD_DEL_STATION, "DEL_STATION"},
+
+ {NL80211_CMD_GET_MPATH, "GET_MPATH"},
+ {NL80211_CMD_SET_MPATH, "SET_MPATH"},
+ {NL80211_CMD_NEW_MPATH, "NEW_MPATH"},
+ {NL80211_CMD_DEL_MPATH, "DEL_MPATH"},
+
+ {NL80211_CMD_SET_BSS, "SET_BSS"},
+
+ {NL80211_CMD_SET_REG, "SET_REG"},
+ {NL80211_CMD_REQ_SET_REG, "REQ_SET_REG"},
+
+ {NL80211_CMD_GET_MESH_CONFIG, "GET_MESH_CONFIG"},
+ {NL80211_CMD_SET_MESH_CONFIG, "SET_MESH_CONFIG"},
+
+ {NL80211_CMD_SET_MGMT_EXTRA_IE, "SET_MGMT_EXTRA_IE"},
+
+ {NL80211_CMD_GET_REG, "GET_REG"},
+
+ {NL80211_CMD_GET_SCAN, "GET_SCAN"},
+ {NL80211_CMD_TRIGGER_SCAN, "TRIGGER_SCAN"},
+ {NL80211_CMD_NEW_SCAN_RESULTS, "NEW_SCAN_RESULTS"},
+ {NL80211_CMD_SCAN_ABORTED, "SCAN_ABORTED"},
+
+ {NL80211_CMD_REG_CHANGE, "REG_CHANGE"},
+
+ {NL80211_CMD_AUTHENTICATE, "AUTHENTICATE"},
+ {NL80211_CMD_ASSOCIATE, "ASSOCIATE"},
+ {NL80211_CMD_DEAUTHENTICATE, "DEAUTHENTICATE"},
+ {NL80211_CMD_DISASSOCIATE, "DISASSOCIATE"},
+
+ {NL80211_CMD_MICHAEL_MIC_FAILURE, "MICHAEL_MIC_FAILURE"},
+
+ {NL80211_CMD_REG_BEACON_HINT, "REG_BEACON_HINT"},
+
+ {NL80211_CMD_JOIN_IBSS, "JOIN_IBSS"},
+ {NL80211_CMD_LEAVE_IBSS, "LEAVE_IBSS"},
+
+ {NL80211_CMD_TESTMODE, "TESTMODE"},
+
+ {NL80211_CMD_CONNECT, "CONNECT"},
+ {NL80211_CMD_ROAM, "ROAM"},
+ {NL80211_CMD_DISCONNECT, "DISCONNECT"},
+
+ {NL80211_CMD_SET_WIPHY_NETNS, "SET_WIPHY_NETNS"},
+
+ {NL80211_CMD_GET_SURVEY, "GET_SURVEY"},
+ {NL80211_CMD_NEW_SURVEY_RESULTS, "NEW_SURVEY_RESULTS"},
+
+ {NL80211_CMD_SET_PMKSA, "SET_PMKSA"},
+ {NL80211_CMD_DEL_PMKSA, "DEL_PMKSA"},
+ {NL80211_CMD_FLUSH_PMKSA, "FLUSH_PMKSA"},
+
+ {NL80211_CMD_REMAIN_ON_CHANNEL, "REMAIN_ON_CHANNEL"},
+ {NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, "CANCEL_REMAIN_ON_CHANNEL"},
+
+ {NL80211_CMD_SET_TX_BITRATE_MASK, "SET_TX_BITRATE_MASK"},
+
+ {NL80211_CMD_REGISTER_FRAME, "REGISTER_FRAME"},
+ {NL80211_CMD_FRAME, "FRAME"},
+ {NL80211_CMD_FRAME_TX_STATUS, "FRAME_TX_STATUS"},
+
+ {NL80211_CMD_SET_POWER_SAVE, "SET_POWER_SAVE"},
+ {NL80211_CMD_GET_POWER_SAVE, "GET_POWER_SAVE"},
+
+ {NL80211_CMD_SET_CQM, "SET_CQM"},
+ {NL80211_CMD_NOTIFY_CQM, "NOTIFY_CQM"},
+
+ {NL80211_CMD_SET_CHANNEL, "SET_CHANNEL"},
+ {NL80211_CMD_SET_WDS_PEER, "SET_WDS_PEER"},
+
+ {NL80211_CMD_FRAME_WAIT_CANCEL, "FRAME_WAIT_CANCEL"},
+
+ {NL80211_CMD_JOIN_MESH, "JOIN_MESH"},
+ {NL80211_CMD_LEAVE_MESH, "LEAVE_MESH"},
+
+ {NL80211_CMD_UNPROT_DEAUTHENTICATE, "UNPROT_DEAUTHENTICATE"},
+ {NL80211_CMD_UNPROT_DISASSOCIATE, "UNPROT_DISASSOCIATE"},
+
+ {NL80211_CMD_NEW_PEER_CANDIDATE, "NEW_PEER_CANDIDATE"},
+
+ {NL80211_CMD_GET_WOWLAN, "GET_WOWLAN"},
+ {NL80211_CMD_SET_WOWLAN, "SET_WOWLAN"},
+
+ {NL80211_CMD_START_SCHED_SCAN, "START_SCHED_SCAN"},
+ {NL80211_CMD_STOP_SCHED_SCAN, "STOP_SCHED_SCAN"},
+ {NL80211_CMD_SCHED_SCAN_RESULTS, "SCHED_SCAN_RESULTS"},
+ {NL80211_CMD_SCHED_SCAN_STOPPED, "SCHED_SCAN_STOPPED"},
+
+ {NL80211_CMD_SET_REKEY_OFFLOAD, "SET_REKEY_OFFLOAD"},
+
+ {NL80211_CMD_PMKSA_CANDIDATE, "PMKSA_CANDIDATE"},
+
+ {NL80211_CMD_TDLS_OPER, "TDLS_OPER"},
+ {NL80211_CMD_TDLS_MGMT, "TDLS_MGMT"},
+
+ {NL80211_CMD_UNEXPECTED_FRAME, "UNEXPECTED_FRAME"},
+
+ {NL80211_CMD_PROBE_CLIENT, "PROBE_CLIENT"},
+
+ {NL80211_CMD_REGISTER_BEACONS, "REGISTER_BEACONS"},
+
+ {NL80211_CMD_UNEXPECTED_4ADDR_FRAME, "UNEXPECTED_4ADDR_FRAME"},
+
+ {NL80211_CMD_SET_NOACK_MAP, "SET_NOACK_MAP"},
+
+ {NL80211_CMD_CH_SWITCH_NOTIFY, "CH_SWITCH_NOTIFY"},
+
+ {NL80211_CMD_START_P2P_DEVICE, "START_P2P_DEVICE"},
+ {NL80211_CMD_STOP_P2P_DEVICE, "STOP_P2P_DEVICE"},
+
+ {NL80211_CMD_CONN_FAILED, "CONN_FAILED"},
+
+ {NL80211_CMD_SET_MCAST_RATE, "SET_MCAST_RATE"},
+
+ {NL80211_CMD_SET_MAC_ACL, "SET_MAC_ACL"},
+
+ {NL80211_CMD_RADAR_DETECT, "RADAR_DETECT"},
+
+ {NL80211_CMD_GET_PROTOCOL_FEATURES, "GET_PROTOCOL_FEATURES"},
+
+ {NL80211_CMD_UPDATE_FT_IES, "UPDATE_FT_IES"},
+ {NL80211_CMD_FT_EVENT, "FT_EVENT"},
+
+ {NL80211_CMD_CRIT_PROTOCOL_START, "CRIT_PROTOCOL_START"},
+ {NL80211_CMD_CRIT_PROTOCOL_STOP, "CRIT_PROTOCOL_STOP"},
+
+ {NL80211_CMD_GET_COALESCE, "GET_COALESCE"},
+ {NL80211_CMD_SET_COALESCE, "SET_COALESCE"},
+
+ {NL80211_CMD_CHANNEL_SWITCH, "CHANNEL_SWITCH"},
+
+ {NL80211_CMD_VENDOR, "VENDOR"},
+
+ {NL80211_CMD_SET_QOS_MAP, "SET_QOS_MAP"},
+
+ {NL80211_CMD_ADD_TX_TS, "ADD_TX_TS"},
+ {NL80211_CMD_DEL_TX_TS, "DEL_TX_TS"},
+
+ {NL80211_CMD_GET_MPP, "GET_MPP"},
+
+ {NL80211_CMD_JOIN_OCB, "JOIN_OCB"},
+ {NL80211_CMD_LEAVE_OCB, "LEAVE_OCB"},
+
+ {NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, "CH_SWITCH_STARTED_NOTIFY"},
+
+ {NL80211_CMD_TDLS_CHANNEL_SWITCH, "TDLS_CHANNEL_SWITCH"},
+ {NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH, "TDLS_CANCEL_CHANNEL_SWITCH"},
+
+ {NL80211_CMD_WIPHY_REG_CHANGE, "WIPHY_REG_CHANGE"},
+
+ {NL80211_CMD_ABORT_SCAN, "ABORT_SCAN"},
+
+ {NL80211_CMD_START_NAN, "START_NAN"},
+ {NL80211_CMD_STOP_NAN, "STOP_NAN"},
+ {NL80211_CMD_ADD_NAN_FUNCTION, "ADD_NAN_FUNCTION"},
+ {NL80211_CMD_DEL_NAN_FUNCTION, "DEL_NAN_FUNCTION"},
+ {NL80211_CMD_CHANGE_NAN_CONFIG, "CHANGE_NAN_CONFIG"},
+ {NL80211_CMD_NAN_MATCH, "NAN_MATCH"},
+
+ {NL80211_CMD_SET_MULTICAST_TO_UNICAST, "SET_MULTICAST_TO_UNICAST"},
+
+ {NL80211_CMD_UPDATE_CONNECT_PARAMS, "UPDATE_CONNECT_PARAMS"},
+
+ {NL80211_CMD_SET_PMK, "SET_PMK"},
+ {NL80211_CMD_DEL_PMK, "DEL_PMK"},
+
+ {NL80211_CMD_PORT_AUTHORIZED, "PORT_AUTHORIZED"},
+
+ {NL80211_CMD_RELOAD_REGDB, "RELOAD_REGDB"},
+
+ {NL80211_CMD_EXTERNAL_AUTH, "EXTERNAL_AUTH"},
+
+ {NL80211_CMD_STA_OPMODE_CHANGED, "STA_OPMODE_CHANGED"},
+
+ {NL80211_CMD_CONTROL_PORT_FRAME, "CONTROL_PORT_FRAME"},
+
+ {NL80211_CMD_GET_FTM_RESPONDER_STATS, "GET_FTM_RESPONDER_STATS"},
+
+ {NL80211_CMD_PEER_MEASUREMENT_START, "PEER_MEASUREMENT_START"},
+ {NL80211_CMD_PEER_MEASUREMENT_RESULT, "PEER_MEASUREMENT_RESULT"},
+ {NL80211_CMD_PEER_MEASUREMENT_COMPLETE, "PEER_MEASUREMENT_COMPLETE"},
+
+ {NL80211_CMD_NOTIFY_RADAR, "NOTIFY_RADAR"},
+
+ {NL80211_CMD_UPDATE_OWE_INFO, "UPDATE_OWE_INFO"},
+
+ {NL80211_CMD_PROBE_MESH_LINK, "PROBE_MESH_LINK"},
+
+ {NL80211_CMD_SET_TID_CONFIG, "SET_TID_CONFIG"},
+
+ {NL80211_CMD_UNPROT_BEACON, "UNPROT_BEACON"},
+
+ {NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS, "CONTROL_PORT_FRAME_TX_STATUS"},
+}, {
+ /* Script to generate the (initial) top-level list from linux/nl80211.h:
+ * sed -e 's/^\tNL80211_ATTR_\(.*\),$/ {NL80211_ATTR_\1, {"\1"}},/g'
+ */
+ {NL80211_ATTR_UNSPEC, {"UNSPEC"}},
+
+ {NL80211_ATTR_WIPHY, {"WIPHY", DataType::Uint}},
+ {NL80211_ATTR_WIPHY_NAME, {"WIPHY_NAME", DataType::StringNul}},
+
+ {NL80211_ATTR_IFINDEX, {"IFINDEX", DataType::Uint}},
+ {NL80211_ATTR_IFNAME, {"IFNAME", DataType::StringNul}},
+ {NL80211_ATTR_IFTYPE, {"IFTYPE", DataType::Uint}},
+
+ {NL80211_ATTR_MAC, {"MAC", DataType::Raw}},
+
+ {NL80211_ATTR_KEY_DATA, {"KEY_DATA"}},
+ {NL80211_ATTR_KEY_IDX, {"KEY_IDX"}},
+ {NL80211_ATTR_KEY_CIPHER, {"KEY_CIPHER"}},
+ {NL80211_ATTR_KEY_SEQ, {"KEY_SEQ"}},
+ {NL80211_ATTR_KEY_DEFAULT, {"KEY_DEFAULT"}},
+
+ {NL80211_ATTR_BEACON_INTERVAL, {"BEACON_INTERVAL"}},
+ {NL80211_ATTR_DTIM_PERIOD, {"DTIM_PERIOD"}},
+ {NL80211_ATTR_BEACON_HEAD, {"BEACON_HEAD"}},
+ {NL80211_ATTR_BEACON_TAIL, {"BEACON_TAIL"}},
+
+ {NL80211_ATTR_STA_AID, {"STA_AID"}},
+ {NL80211_ATTR_STA_FLAGS, {"STA_FLAGS"}},
+ {NL80211_ATTR_STA_LISTEN_INTERVAL, {"STA_LISTEN_INTERVAL"}},
+ {NL80211_ATTR_STA_SUPPORTED_RATES, {"STA_SUPPORTED_RATES"}},
+ {NL80211_ATTR_STA_VLAN, {"STA_VLAN"}},
+ {NL80211_ATTR_STA_INFO, {"STA_INFO"}},
+
+ {NL80211_ATTR_WIPHY_BANDS, {"WIPHY_BANDS", DataType::Nested, AttributeMap{
+ {std::nullopt, {"BAND", DataType::Nested, AttributeMap{
+ {NL80211_BAND_ATTR_FREQS, {"FREQS", DataType::Nested, AttributeMap{
+ {std::nullopt, {"FQ", DataType::Nested, AttributeMap{
+ {NL80211_FREQUENCY_ATTR_FREQ, {"FREQ", DataType::Uint}},
+ {NL80211_FREQUENCY_ATTR_DISABLED, {"DISABLED", DataType::Flag}},
+ {NL80211_FREQUENCY_ATTR_NO_IR, {"NO_IR", DataType::Flag}},
+ {__NL80211_FREQUENCY_ATTR_NO_IBSS, {"_NO_IBSS", DataType::Flag}},
+ {NL80211_FREQUENCY_ATTR_RADAR, {"RADAR", DataType::Flag}},
+ {NL80211_FREQUENCY_ATTR_MAX_TX_POWER, {"MAX_TX_POWER", DataType::Uint}},
+ {NL80211_FREQUENCY_ATTR_DFS_STATE, {"DFS_STATE", DataType::Uint}},
+ {NL80211_FREQUENCY_ATTR_DFS_TIME, {"DFS_TIME", DataType::Uint}},
+ {NL80211_FREQUENCY_ATTR_NO_HT40_MINUS, {"NO_HT40_MINUS", DataType::Flag}},
+ {NL80211_FREQUENCY_ATTR_NO_HT40_PLUS, {"NO_HT40_PLUS", DataType::Flag}},
+ {NL80211_FREQUENCY_ATTR_NO_80MHZ, {"NO_80MHZ", DataType::Flag}},
+ {NL80211_FREQUENCY_ATTR_NO_160MHZ, {"NO_160MHZ", DataType::Flag}},
+ {NL80211_FREQUENCY_ATTR_DFS_CAC_TIME, {"DFS_CAC_TIME", DataType::Uint}},
+ {NL80211_FREQUENCY_ATTR_INDOOR_ONLY, {"INDOOR_ONLY", DataType::Flag}},
+ {NL80211_FREQUENCY_ATTR_IR_CONCURRENT, {"IR_CONCURRENT", DataType::Flag}},
+ {NL80211_FREQUENCY_ATTR_NO_20MHZ, {"NO_20MHZ", DataType::Flag}},
+ {NL80211_FREQUENCY_ATTR_NO_10MHZ, {"NO_10MHZ", DataType::Flag}},
+ {NL80211_FREQUENCY_ATTR_WMM, {"WMM"}},
+ {NL80211_FREQUENCY_ATTR_NO_HE, {"NO_HE", DataType::Flag}},
+ {NL80211_FREQUENCY_ATTR_OFFSET, {"OFFSET", DataType::Uint}},
+ {NL80211_FREQUENCY_ATTR_1MHZ, {"1MHZ", DataType::Flag}},
+ {NL80211_FREQUENCY_ATTR_2MHZ, {"2MHZ", DataType::Flag}},
+ {NL80211_FREQUENCY_ATTR_4MHZ, {"4MHZ", DataType::Flag}},
+ {NL80211_FREQUENCY_ATTR_8MHZ, {"8MHZ", DataType::Flag}},
+ {NL80211_FREQUENCY_ATTR_16MHZ, {"16MHZ", DataType::Flag}},
+ }}},
+ }, Flags::Verbose}},
+ {NL80211_BAND_ATTR_RATES, {"RATES", DataType::Nested, AttributeMap{
+ {std::nullopt, {"RATE", DataType::Nested, AttributeMap{
+ {NL80211_BITRATE_ATTR_RATE, {"RATE", DataType::Uint}},
+ {NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE,
+ {"2GHZ_SHORTPREAMBLE", DataType::Flag}},
+ }}},
+ }}},
+
+ {NL80211_BAND_ATTR_HT_MCS_SET, {"HT_MCS_SET"}}, // struct ieee80211_mcs_info
+ {NL80211_BAND_ATTR_HT_CAPA, {"HT_CAPA", DataType::Uint}},
+ {NL80211_BAND_ATTR_HT_AMPDU_FACTOR, {"HT_AMPDU_FACTOR", DataType::Uint}},
+ {NL80211_BAND_ATTR_HT_AMPDU_DENSITY, {"HT_AMPDU_DENSITY", DataType::Uint}},
+
+ {NL80211_BAND_ATTR_VHT_MCS_SET, {"VHT_MCS_SET"}}, // struct ieee80211_vht_mcs_info
+ {NL80211_BAND_ATTR_VHT_CAPA, {"VHT_CAPA", DataType::Uint}},
+ {NL80211_BAND_ATTR_IFTYPE_DATA, {"IFTYPE_DATA"}},
+
+ {NL80211_BAND_ATTR_EDMG_CHANNELS, {"EDMG_CHANNELS"}},
+ {NL80211_BAND_ATTR_EDMG_BW_CONFIG, {"EDMG_BW_CONFIG"}},
+ }}},
+ }, Flags::Verbose}},
+
+ {NL80211_ATTR_MNTR_FLAGS, {"MNTR_FLAGS"}},
+
+ {NL80211_ATTR_MESH_ID, {"MESH_ID"}},
+ {NL80211_ATTR_STA_PLINK_ACTION, {"STA_PLINK_ACTION"}},
+ {NL80211_ATTR_MPATH_NEXT_HOP, {"MPATH_NEXT_HOP"}},
+ {NL80211_ATTR_MPATH_INFO, {"MPATH_INFO"}},
+
+ {NL80211_ATTR_BSS_CTS_PROT, {"BSS_CTS_PROT"}},
+ {NL80211_ATTR_BSS_SHORT_PREAMBLE, {"BSS_SHORT_PREAMBLE"}},
+ {NL80211_ATTR_BSS_SHORT_SLOT_TIME, {"BSS_SHORT_SLOT_TIME"}},
+
+ {NL80211_ATTR_HT_CAPABILITY, {"HT_CAPABILITY"}},
+
+ {NL80211_ATTR_SUPPORTED_IFTYPES, {"SUPPORTED_IFTYPES", DataType::Nested, iftypes}},
+
+ {NL80211_ATTR_REG_ALPHA2, {"REG_ALPHA2"}},
+ {NL80211_ATTR_REG_RULES, {"REG_RULES"}},
+
+ {NL80211_ATTR_MESH_CONFIG, {"MESH_CONFIG"}},
+
+ {NL80211_ATTR_BSS_BASIC_RATES, {"BSS_BASIC_RATES"}},
+
+ {NL80211_ATTR_WIPHY_TXQ_PARAMS, {"WIPHY_TXQ_PARAMS"}},
+ {NL80211_ATTR_WIPHY_FREQ, {"WIPHY_FREQ"}},
+ {NL80211_ATTR_WIPHY_CHANNEL_TYPE, {"WIPHY_CHANNEL_TYPE"}},
+
+ {NL80211_ATTR_KEY_DEFAULT_MGMT, {"KEY_DEFAULT_MGMT"}},
+
+ {NL80211_ATTR_MGMT_SUBTYPE, {"MGMT_SUBTYPE"}},
+ {NL80211_ATTR_IE, {"IE"}},
+
+ {NL80211_ATTR_MAX_NUM_SCAN_SSIDS, {"MAX_NUM_SCAN_SSIDS", DataType::Uint}},
+
+ {NL80211_ATTR_SCAN_FREQUENCIES, {"SCAN_FREQUENCIES", DataType::Nested, AttributeMap{
+ {std::nullopt, {"FQ", DataType::Uint}},
+ }, Flags::Verbose}},
+ {NL80211_ATTR_SCAN_SSIDS, {"SCAN_SSIDS", DataType::Nested, AttributeMap{
+ {std::nullopt, {"SSID", DataType::String}},
+ }}},
+ {NL80211_ATTR_GENERATION, {"GENERATION", DataType::Uint}},
+ {NL80211_ATTR_BSS, {"BSS", DataType::Nested, AttributeMap{
+ {NL80211_BSS_BSSID, {"BSSID", DataType::Raw}},
+ {NL80211_BSS_FREQUENCY, {"FREQUENCY", DataType::Uint}},
+ {NL80211_BSS_TSF, {"TSF", DataType::Uint}},
+ {NL80211_BSS_BEACON_INTERVAL, {"BEACON_INTERVAL", DataType::Uint}},
+ {NL80211_BSS_CAPABILITY, {"CAPABILITY", DataType::Uint}},
+ {NL80211_BSS_INFORMATION_ELEMENTS, {"INFORMATION_ELEMENTS",
+ DataType::Struct, informationElementsToStream}},
+ {NL80211_BSS_SIGNAL_MBM, {"SIGNAL_MBM", DataType::Uint}},
+ {NL80211_BSS_SIGNAL_UNSPEC, {"SIGNAL_UNSPEC", DataType::Uint}},
+ {NL80211_BSS_STATUS, {"STATUS", DataType::Uint}}, // enum nl80211_bss_status
+ {NL80211_BSS_SEEN_MS_AGO, {"SEEN_MS_AGO", DataType::Uint}},
+ {NL80211_BSS_BEACON_IES, {"BEACON_IES", DataType::Struct, informationElementsToStream}},
+ {NL80211_BSS_CHAN_WIDTH, {"CHAN_WIDTH", DataType::Uint}},
+ {NL80211_BSS_BEACON_TSF, {"BEACON_TSF", DataType::Uint}},
+ {NL80211_BSS_PRESP_DATA, {"PRESP_DATA", DataType::Flag}},
+ {NL80211_BSS_LAST_SEEN_BOOTTIME, {"LAST_SEEN_BOOTTIME", DataType::Uint}},
+ {NL80211_BSS_PAD, {"PAD"}},
+ {NL80211_BSS_PARENT_TSF, {"PARENT_TSF"}},
+ {NL80211_BSS_PARENT_BSSID, {"PARENT_BSSID"}},
+ {NL80211_BSS_CHAIN_SIGNAL, {"CHAIN_SIGNAL", DataType::Nested, AttributeMap{
+ {std::nullopt, {"SIG", DataType::Uint}},
+ }}},
+ {NL80211_BSS_FREQUENCY_OFFSET, {"FREQUENCY_OFFSET"}},
+ }}},
+
+ {NL80211_ATTR_REG_INITIATOR, {"REG_INITIATOR"}},
+ {NL80211_ATTR_REG_TYPE, {"REG_TYPE"}},
+
+ {NL80211_ATTR_SUPPORTED_COMMANDS, {"SUPPORTED_COMMANDS", DataType::Nested,AttributeMap{
+ {std::nullopt, {"CMD", DataType::Uint}}, // enum nl80211_commands
+ }}},
+
+ {NL80211_ATTR_FRAME, {"FRAME"}},
+ {NL80211_ATTR_SSID, {"SSID"}},
+ {NL80211_ATTR_AUTH_TYPE, {"AUTH_TYPE"}},
+ {NL80211_ATTR_REASON_CODE, {"REASON_CODE"}},
+
+ {NL80211_ATTR_KEY_TYPE, {"KEY_TYPE"}},
+
+ {NL80211_ATTR_MAX_SCAN_IE_LEN, {"MAX_SCAN_IE_LEN", DataType::Uint}},
+ {NL80211_ATTR_CIPHER_SUITES, {"CIPHER_SUITES", DataType::Struct, arrayToStream<int32_t>}},
+
+ {NL80211_ATTR_FREQ_BEFORE, {"FREQ_BEFORE"}},
+ {NL80211_ATTR_FREQ_AFTER, {"FREQ_AFTER"}},
+
+ {NL80211_ATTR_FREQ_FIXED, {"FREQ_FIXED"}},
+
+ {NL80211_ATTR_WIPHY_RETRY_SHORT, {"WIPHY_RETRY_SHORT", DataType::Uint}},
+ {NL80211_ATTR_WIPHY_RETRY_LONG, {"WIPHY_RETRY_LONG", DataType::Uint}},
+ {NL80211_ATTR_WIPHY_FRAG_THRESHOLD, {"WIPHY_FRAG_THRESHOLD", DataType::Uint}},
+ {NL80211_ATTR_WIPHY_RTS_THRESHOLD, {"WIPHY_RTS_THRESHOLD", DataType::Uint}},
+
+ {NL80211_ATTR_TIMED_OUT, {"TIMED_OUT"}},
+
+ {NL80211_ATTR_USE_MFP, {"USE_MFP"}},
+
+ {NL80211_ATTR_STA_FLAGS2, {"STA_FLAGS2"}},
+
+ {NL80211_ATTR_CONTROL_PORT, {"CONTROL_PORT"}},
+
+ {NL80211_ATTR_TESTDATA, {"TESTDATA"}},
+
+ {NL80211_ATTR_PRIVACY, {"PRIVACY"}},
+
+ {NL80211_ATTR_DISCONNECTED_BY_AP, {"DISCONNECTED_BY_AP"}},
+ {NL80211_ATTR_STATUS_CODE, {"STATUS_CODE"}},
+
+ {NL80211_ATTR_CIPHER_SUITES_PAIRWISE, {"CIPHER_SUITES_PAIRWISE"}},
+ {NL80211_ATTR_CIPHER_SUITE_GROUP, {"CIPHER_SUITE_GROUP"}},
+ {NL80211_ATTR_WPA_VERSIONS, {"WPA_VERSIONS"}},
+ {NL80211_ATTR_AKM_SUITES, {"AKM_SUITES"}},
+
+ {NL80211_ATTR_REQ_IE, {"REQ_IE"}},
+ {NL80211_ATTR_RESP_IE, {"RESP_IE"}},
+
+ {NL80211_ATTR_PREV_BSSID, {"PREV_BSSID"}},
+
+ {NL80211_ATTR_KEY, {"KEY"}},
+ {NL80211_ATTR_KEYS, {"KEYS"}},
+
+ {NL80211_ATTR_PID, {"PID"}},
+
+ {NL80211_ATTR_4ADDR, {"4ADDR"}},
+
+ {NL80211_ATTR_SURVEY_INFO, {"SURVEY_INFO"}},
+
+ {NL80211_ATTR_PMKID, {"PMKID"}},
+ {NL80211_ATTR_MAX_NUM_PMKIDS, {"MAX_NUM_PMKIDS", DataType::Uint}},
+
+ {NL80211_ATTR_DURATION, {"DURATION"}},
+
+ {NL80211_ATTR_COOKIE, {"COOKIE"}},
+
+ {NL80211_ATTR_WIPHY_COVERAGE_CLASS, {"WIPHY_COVERAGE_CLASS", DataType::Uint}},
+
+ {NL80211_ATTR_TX_RATES, {"TX_RATES"}},
+
+ {NL80211_ATTR_FRAME_MATCH, {"FRAME_MATCH"}},
+
+ {NL80211_ATTR_ACK, {"ACK"}},
+
+ {NL80211_ATTR_PS_STATE, {"PS_STATE"}},
+
+ {NL80211_ATTR_CQM, {"CQM"}},
+
+ {NL80211_ATTR_LOCAL_STATE_CHANGE, {"LOCAL_STATE_CHANGE"}},
+
+ {NL80211_ATTR_AP_ISOLATE, {"AP_ISOLATE"}},
+
+ {NL80211_ATTR_WIPHY_TX_POWER_SETTING, {"WIPHY_TX_POWER_SETTING"}},
+ {NL80211_ATTR_WIPHY_TX_POWER_LEVEL, {"WIPHY_TX_POWER_LEVEL"}},
+
+ {NL80211_ATTR_TX_FRAME_TYPES, {"TX_FRAME_TYPES", DataType::Nested, AttributeMap{
+ {std::nullopt, {"TFT", DataType::Nested, AttributeMap{
+ {NL80211_ATTR_FRAME_TYPE, {"FRAME_TYPE", DataType::Uint}},
+ }}},
+ }, Flags::Verbose}},
+ {NL80211_ATTR_RX_FRAME_TYPES, {"RX_FRAME_TYPES", DataType::Nested, AttributeMap{
+ {std::nullopt, {"RFT", DataType::Nested, AttributeMap{
+ {NL80211_ATTR_FRAME_TYPE, {"FRAME_TYPE", DataType::Uint}},
+ }}},
+ }, Flags::Verbose}},
+
+ {NL80211_ATTR_FRAME_TYPE, {"FRAME_TYPE", DataType::Uint}},
+
+ {NL80211_ATTR_CONTROL_PORT_ETHERTYPE, {"CONTROL_PORT_ETHERTYPE"}},
+ {NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, {"CONTROL_PORT_NO_ENCRYPT"}},
+
+ {NL80211_ATTR_SUPPORT_IBSS_RSN, {"SUPPORT_IBSS_RSN"}},
+
+ {NL80211_ATTR_WIPHY_ANTENNA_TX, {"WIPHY_ANTENNA_TX"}},
+ {NL80211_ATTR_WIPHY_ANTENNA_RX, {"WIPHY_ANTENNA_RX"}},
+
+ {NL80211_ATTR_MCAST_RATE, {"MCAST_RATE"}},
+
+ {NL80211_ATTR_OFFCHANNEL_TX_OK, {"OFFCHANNEL_TX_OK", DataType::Flag}},
+
+ {NL80211_ATTR_BSS_HT_OPMODE, {"BSS_HT_OPMODE"}},
+
+ {NL80211_ATTR_KEY_DEFAULT_TYPES, {"KEY_DEFAULT_TYPES"}},
+
+ {NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
+ {"MAX_REMAIN_ON_CHANNEL_DURATION", DataType::Uint}},
+
+ {NL80211_ATTR_MESH_SETUP, {"MESH_SETUP"}},
+
+ {NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, {"WIPHY_ANTENNA_AVAIL_TX", DataType::Uint}},
+ {NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, {"WIPHY_ANTENNA_AVAIL_RX", DataType::Uint}},
+
+ {NL80211_ATTR_SUPPORT_MESH_AUTH, {"SUPPORT_MESH_AUTH"}},
+ {NL80211_ATTR_STA_PLINK_STATE, {"STA_PLINK_STATE"}},
+
+ {NL80211_ATTR_WOWLAN_TRIGGERS, {"WOWLAN_TRIGGERS"}},
+ {NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED,
+ {"WOWLAN_TRIGGERS_SUPPORTED", DataType::Nested, AttributeMap{
+ {NL80211_WOWLAN_TRIG_ANY, {"ANY", DataType::Flag}},
+ {NL80211_WOWLAN_TRIG_DISCONNECT, {"DISCONNECT", DataType::Flag}},
+ {NL80211_WOWLAN_TRIG_MAGIC_PKT, {"MAGIC_PKT", DataType::Flag}},
+ {NL80211_WOWLAN_TRIG_PKT_PATTERN,
+ {"PKT_PATTERN", DataType::Struct, nl80211_pattern_supportToStream}},
+ {NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED, {"GTK_REKEY_SUPPORTED", DataType::Flag}},
+ {NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE, {"GTK_REKEY_FAILURE", DataType::Flag}},
+ {NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST, {"EAP_IDENT_REQUEST", DataType::Flag}},
+ {NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE, {"4WAY_HANDSHAKE", DataType::Flag}},
+ {NL80211_WOWLAN_TRIG_RFKILL_RELEASE, {"RFKILL_RELEASE", DataType::Flag}},
+ {NL80211_WOWLAN_TRIG_TCP_CONNECTION, {"TCP_CONNECTION", DataType::Nested, AttributeMap{
+ {NL80211_WOWLAN_TCP_SRC_IPV4, {"SRC_IPV4"}},
+ {NL80211_WOWLAN_TCP_DST_IPV4, {"DST_IPV4"}},
+ {NL80211_WOWLAN_TCP_DST_MAC, {"DST_MAC"}},
+ {NL80211_WOWLAN_TCP_SRC_PORT, {"SRC_PORT", DataType::Uint}},
+ {NL80211_WOWLAN_TCP_DST_PORT, {"DST_PORT", DataType::Uint}},
+ {NL80211_WOWLAN_TCP_DATA_PAYLOAD, {"DATA_PAYLOAD"}},
+ {NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ, {"DATA_PAYLOAD_SEQ"}},
+ {NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN, {"DATA_PAYLOAD_TOKEN"}},
+ {NL80211_WOWLAN_TCP_DATA_INTERVAL, {"DATA_INTERVAL", DataType::Uint}},
+ {NL80211_WOWLAN_TCP_WAKE_PAYLOAD, {"WAKE_PAYLOAD"}},
+ {NL80211_WOWLAN_TCP_WAKE_MASK, {"WAKE_MASK"}},
+ }}},
+ {NL80211_WOWLAN_TRIG_NET_DETECT, {"NET_DETECT", DataType::Uint}},
+
+ /* Not in WOWLAN_TRIGGERS_SUPPORTED:
+ * - NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211
+ * - NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN
+ * - NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023
+ * - NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN
+ * - NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH
+ * - NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST
+ * - NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS
+ * - NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS
+ */
+ }}},
+
+ {NL80211_ATTR_SCHED_SCAN_INTERVAL, {"SCHED_SCAN_INTERVAL"}},
+
+ {NL80211_ATTR_INTERFACE_COMBINATIONS, {"INTERFACE_COMBINATIONS", DataType::Nested, AttributeMap{
+ {std::nullopt, {"IC", DataType::Nested, AttributeMap{
+ {NL80211_IFACE_COMB_UNSPEC, {"UNSPEC"}},
+ {NL80211_IFACE_COMB_LIMITS, {"LIMITS", DataType::Nested, AttributeMap{
+ {std::nullopt, {"LT", DataType::Nested, AttributeMap{
+ {NL80211_IFACE_LIMIT_UNSPEC, {"UNSPEC"}},
+ {NL80211_IFACE_LIMIT_MAX, {"MAX", DataType::Uint}},
+ {NL80211_IFACE_LIMIT_TYPES, {"TYPES", DataType::Nested, iftypes}},
+ }}},
+ }}},
+ {NL80211_IFACE_COMB_MAXNUM, {"MAXNUM", DataType::Uint}},
+ {NL80211_IFACE_COMB_STA_AP_BI_MATCH, {"STA_AP_BI_MATCH", DataType::Flag}},
+ {NL80211_IFACE_COMB_NUM_CHANNELS, {"NUM_CHANNELS", DataType::Uint}},
+ {NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, {"RADAR_DETECT_WIDTHS", DataType::Uint}},
+ {NL80211_IFACE_COMB_RADAR_DETECT_REGIONS, {"RADAR_DETECT_REGIONS", DataType::Uint}},
+ {NL80211_IFACE_COMB_BI_MIN_GCD, {"BI_MIN_GCD"}},
+ }}},
+ }, Flags::Verbose}},
+ {NL80211_ATTR_SOFTWARE_IFTYPES, {"SOFTWARE_IFTYPES", DataType::Nested, iftypes}},
+
+ {NL80211_ATTR_REKEY_DATA, {"REKEY_DATA"}},
+
+ {NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS, {"MAX_NUM_SCHED_SCAN_SSIDS", DataType::Uint}},
+ {NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, {"MAX_SCHED_SCAN_IE_LEN", DataType::Uint}},
+
+ {NL80211_ATTR_SCAN_SUPP_RATES, {"SCAN_SUPP_RATES"}},
+
+ {NL80211_ATTR_HIDDEN_SSID, {"HIDDEN_SSID"}},
+
+ {NL80211_ATTR_IE_PROBE_RESP, {"IE_PROBE_RESP"}},
+ {NL80211_ATTR_IE_ASSOC_RESP, {"IE_ASSOC_RESP"}},
+
+ {NL80211_ATTR_STA_WME, {"STA_WME"}},
+ {NL80211_ATTR_SUPPORT_AP_UAPSD, {"SUPPORT_AP_UAPSD"}},
+
+ {NL80211_ATTR_ROAM_SUPPORT, {"ROAM_SUPPORT", DataType::Flag}},
+
+ {NL80211_ATTR_SCHED_SCAN_MATCH, {"SCHED_SCAN_MATCH"}},
+ {NL80211_ATTR_MAX_MATCH_SETS, {"MAX_MATCH_SETS", DataType::Uint}},
+
+ {NL80211_ATTR_PMKSA_CANDIDATE, {"PMKSA_CANDIDATE"}},
+
+ {NL80211_ATTR_TX_NO_CCK_RATE, {"TX_NO_CCK_RATE"}},
+
+ {NL80211_ATTR_TDLS_ACTION, {"TDLS_ACTION"}},
+ {NL80211_ATTR_TDLS_DIALOG_TOKEN, {"TDLS_DIALOG_TOKEN"}},
+ {NL80211_ATTR_TDLS_OPERATION, {"TDLS_OPERATION"}},
+ {NL80211_ATTR_TDLS_SUPPORT, {"TDLS_SUPPORT", DataType::Flag}},
+ {NL80211_ATTR_TDLS_EXTERNAL_SETUP, {"TDLS_EXTERNAL_SETUP", DataType::Flag}},
+
+ {NL80211_ATTR_DEVICE_AP_SME, {"DEVICE_AP_SME", DataType::Uint}},
+
+ {NL80211_ATTR_DONT_WAIT_FOR_ACK, {"DONT_WAIT_FOR_ACK"}},
+
+ {NL80211_ATTR_FEATURE_FLAGS, {"FEATURE_FLAGS", DataType::Uint}},
+
+ {NL80211_ATTR_PROBE_RESP_OFFLOAD, {"PROBE_RESP_OFFLOAD", DataType::Uint}},
+
+ {NL80211_ATTR_PROBE_RESP, {"PROBE_RESP"}},
+
+ {NL80211_ATTR_DFS_REGION, {"DFS_REGION"}},
+
+ {NL80211_ATTR_DISABLE_HT, {"DISABLE_HT"}},
+ {NL80211_ATTR_HT_CAPABILITY_MASK, {"HT_CAPABILITY_MASK"}},
+
+ {NL80211_ATTR_NOACK_MAP, {"NOACK_MAP"}},
+
+ {NL80211_ATTR_INACTIVITY_TIMEOUT, {"INACTIVITY_TIMEOUT"}},
+
+ {NL80211_ATTR_RX_SIGNAL_DBM, {"RX_SIGNAL_DBM"}},
+
+ {NL80211_ATTR_BG_SCAN_PERIOD, {"BG_SCAN_PERIOD"}},
+
+ {NL80211_ATTR_WDEV, {"WDEV", DataType::Uint}},
+
+ {NL80211_ATTR_USER_REG_HINT_TYPE, {"USER_REG_HINT_TYPE"}},
+
+ {NL80211_ATTR_CONN_FAILED_REASON, {"CONN_FAILED_REASON"}},
+
+ {NL80211_ATTR_AUTH_DATA, {"AUTH_DATA"}},
+
+ {NL80211_ATTR_VHT_CAPABILITY, {"VHT_CAPABILITY"}},
+
+ {NL80211_ATTR_SCAN_FLAGS, {"SCAN_FLAGS", DataType::Uint}},
+
+ {NL80211_ATTR_CHANNEL_WIDTH, {"CHANNEL_WIDTH"}},
+ {NL80211_ATTR_CENTER_FREQ1, {"CENTER_FREQ1"}},
+ {NL80211_ATTR_CENTER_FREQ2, {"CENTER_FREQ2"}},
+
+ {NL80211_ATTR_P2P_CTWINDOW, {"P2P_CTWINDOW"}},
+ {NL80211_ATTR_P2P_OPPPS, {"P2P_OPPPS"}},
+
+ {NL80211_ATTR_LOCAL_MESH_POWER_MODE, {"LOCAL_MESH_POWER_MODE"}},
+
+ {NL80211_ATTR_ACL_POLICY, {"ACL_POLICY"}},
+
+ {NL80211_ATTR_MAC_ADDRS, {"MAC_ADDRS"}},
+
+ {NL80211_ATTR_MAC_ACL_MAX, {"MAC_ACL_MAX", DataType::Uint}},
+
+ {NL80211_ATTR_RADAR_EVENT, {"RADAR_EVENT"}},
+
+ {NL80211_ATTR_EXT_CAPA, {"EXT_CAPA"}},
+ {NL80211_ATTR_EXT_CAPA_MASK, {"EXT_CAPA_MASK"}},
+
+ {NL80211_ATTR_STA_CAPABILITY, {"STA_CAPABILITY"}},
+ {NL80211_ATTR_STA_EXT_CAPABILITY, {"STA_EXT_CAPABILITY"}},
+
+ {NL80211_ATTR_PROTOCOL_FEATURES, {"PROTOCOL_FEATURES", DataType::Uint}},
+ {NL80211_ATTR_SPLIT_WIPHY_DUMP, {"SPLIT_WIPHY_DUMP", DataType::Flag}},
+
+ {NL80211_ATTR_DISABLE_VHT, {"DISABLE_VHT", DataType::Flag}},
+ {NL80211_ATTR_VHT_CAPABILITY_MASK, {"VHT_CAPABILITY_MASK"}},
+
+ {NL80211_ATTR_MDID, {"MDID"}},
+ {NL80211_ATTR_IE_RIC, {"IE_RIC"}},
+
+ {NL80211_ATTR_CRIT_PROT_ID, {"CRIT_PROT_ID"}},
+ {NL80211_ATTR_MAX_CRIT_PROT_DURATION, {"MAX_CRIT_PROT_DURATION"}},
+
+ {NL80211_ATTR_PEER_AID, {"PEER_AID"}},
+
+ {NL80211_ATTR_COALESCE_RULE, {"COALESCE_RULE"}},
+
+ {NL80211_ATTR_CH_SWITCH_COUNT, {"CH_SWITCH_COUNT"}},
+ {NL80211_ATTR_CH_SWITCH_BLOCK_TX, {"CH_SWITCH_BLOCK_TX"}},
+ {NL80211_ATTR_CSA_IES, {"CSA_IES"}},
+ {NL80211_ATTR_CNTDWN_OFFS_BEACON, {"CNTDWN_OFFS_BEACON"}},
+ {NL80211_ATTR_CNTDWN_OFFS_PRESP, {"CNTDWN_OFFS_PRESP"}},
+
+ {NL80211_ATTR_RXMGMT_FLAGS, {"RXMGMT_FLAGS"}},
+
+ {NL80211_ATTR_STA_SUPPORTED_CHANNELS, {"STA_SUPPORTED_CHANNELS"}},
+
+ {NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES, {"STA_SUPPORTED_OPER_CLASSES"}},
+
+ {NL80211_ATTR_HANDLE_DFS, {"HANDLE_DFS"}},
+
+ {NL80211_ATTR_SUPPORT_5_MHZ, {"SUPPORT_5_MHZ"}},
+ {NL80211_ATTR_SUPPORT_10_MHZ, {"SUPPORT_10_MHZ"}},
+
+ {NL80211_ATTR_OPMODE_NOTIF, {"OPMODE_NOTIF"}},
+
+ {NL80211_ATTR_VENDOR_ID, {"VENDOR_ID"}},
+ {NL80211_ATTR_VENDOR_SUBCMD, {"VENDOR_SUBCMD"}},
+ {NL80211_ATTR_VENDOR_DATA, {"VENDOR_DATA", DataType::Raw, AttributeMap{}, Flags::Verbose}},
+ {NL80211_ATTR_VENDOR_EVENTS, {"VENDOR_EVENTS", DataType::Nested, AttributeMap{},
+ Flags::Verbose}},
+
+ {NL80211_ATTR_QOS_MAP, {"QOS_MAP"}},
+
+ {NL80211_ATTR_MAC_HINT, {"MAC_HINT"}},
+ {NL80211_ATTR_WIPHY_FREQ_HINT, {"WIPHY_FREQ_HINT"}},
+
+ {NL80211_ATTR_MAX_AP_ASSOC_STA, {"MAX_AP_ASSOC_STA"}},
+
+ {NL80211_ATTR_TDLS_PEER_CAPABILITY, {"TDLS_PEER_CAPABILITY"}},
+
+ {NL80211_ATTR_SOCKET_OWNER, {"SOCKET_OWNER"}},
+
+ {NL80211_ATTR_CSA_C_OFFSETS_TX, {"CSA_C_OFFSETS_TX"}},
+ {NL80211_ATTR_MAX_CSA_COUNTERS, {"MAX_CSA_COUNTERS"}},
+
+ {NL80211_ATTR_TDLS_INITIATOR, {"TDLS_INITIATOR"}},
+
+ {NL80211_ATTR_USE_RRM, {"USE_RRM"}},
+
+ {NL80211_ATTR_WIPHY_DYN_ACK, {"WIPHY_DYN_ACK"}},
+
+ {NL80211_ATTR_TSID, {"TSID"}},
+ {NL80211_ATTR_USER_PRIO, {"USER_PRIO"}},
+ {NL80211_ATTR_ADMITTED_TIME, {"ADMITTED_TIME"}},
+
+ {NL80211_ATTR_SMPS_MODE, {"SMPS_MODE"}},
+
+ {NL80211_ATTR_OPER_CLASS, {"OPER_CLASS"}},
+
+ {NL80211_ATTR_MAC_MASK, {"MAC_MASK"}},
+
+ {NL80211_ATTR_WIPHY_SELF_MANAGED_REG, {"WIPHY_SELF_MANAGED_REG"}},
+
+ {NL80211_ATTR_EXT_FEATURES, {"EXT_FEATURES"}},
+
+ {NL80211_ATTR_SURVEY_RADIO_STATS, {"SURVEY_RADIO_STATS"}},
+
+ {NL80211_ATTR_NETNS_FD, {"NETNS_FD"}},
+
+ {NL80211_ATTR_SCHED_SCAN_DELAY, {"SCHED_SCAN_DELAY"}},
+
+ {NL80211_ATTR_REG_INDOOR, {"REG_INDOOR"}},
+
+ {NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS, {"MAX_NUM_SCHED_SCAN_PLANS", DataType::Uint}},
+ {NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL, {"MAX_SCAN_PLAN_INTERVAL", DataType::Uint}},
+ {NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS, {"MAX_SCAN_PLAN_ITERATIONS", DataType::Uint}},
+ {NL80211_ATTR_SCHED_SCAN_PLANS, {"SCHED_SCAN_PLANS"}},
+
+ {NL80211_ATTR_PBSS, {"PBSS"}},
+
+ {NL80211_ATTR_BSS_SELECT, {"BSS_SELECT"}},
+
+ {NL80211_ATTR_STA_SUPPORT_P2P_PS, {"STA_SUPPORT_P2P_PS"}},
+
+ {NL80211_ATTR_PAD, {"PAD"}},
+
+ {NL80211_ATTR_IFTYPE_EXT_CAPA, {"IFTYPE_EXT_CAPA"}},
+
+ {NL80211_ATTR_MU_MIMO_GROUP_DATA, {"MU_MIMO_GROUP_DATA"}},
+ {NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR, {"MU_MIMO_FOLLOW_MAC_ADDR"}},
+
+ {NL80211_ATTR_SCAN_START_TIME_TSF, {"SCAN_START_TIME_TSF"}},
+ {NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, {"SCAN_START_TIME_TSF_BSSID"}},
+ {NL80211_ATTR_MEASUREMENT_DURATION, {"MEASUREMENT_DURATION"}},
+ {NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY, {"MEASUREMENT_DURATION_MANDATORY"}},
+
+ {NL80211_ATTR_MESH_PEER_AID, {"MESH_PEER_AID"}},
+
+ {NL80211_ATTR_NAN_MASTER_PREF, {"NAN_MASTER_PREF"}},
+ {NL80211_ATTR_BANDS, {"BANDS"}},
+ {NL80211_ATTR_NAN_FUNC, {"NAN_FUNC"}},
+ {NL80211_ATTR_NAN_MATCH, {"NAN_MATCH"}},
+
+ {NL80211_ATTR_FILS_KEK, {"FILS_KEK"}},
+ {NL80211_ATTR_FILS_NONCES, {"FILS_NONCES"}},
+
+ {NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED, {"MULTICAST_TO_UNICAST_ENABLED"}},
+
+ {NL80211_ATTR_BSSID, {"BSSID"}},
+
+ {NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI, {"SCHED_SCAN_RELATIVE_RSSI"}},
+ {NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST, {"SCHED_SCAN_RSSI_ADJUST"}},
+
+ {NL80211_ATTR_TIMEOUT_REASON, {"TIMEOUT_REASON"}},
+
+ {NL80211_ATTR_FILS_ERP_USERNAME, {"FILS_ERP_USERNAME"}},
+ {NL80211_ATTR_FILS_ERP_REALM, {"FILS_ERP_REALM"}},
+ {NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM, {"FILS_ERP_NEXT_SEQ_NUM"}},
+ {NL80211_ATTR_FILS_ERP_RRK, {"FILS_ERP_RRK"}},
+ {NL80211_ATTR_FILS_CACHE_ID, {"FILS_CACHE_ID"}},
+
+ {NL80211_ATTR_PMK, {"PMK"}},
+
+ {NL80211_ATTR_SCHED_SCAN_MULTI, {"SCHED_SCAN_MULTI"}},
+ {NL80211_ATTR_SCHED_SCAN_MAX_REQS, {"SCHED_SCAN_MAX_REQS"}},
+
+ {NL80211_ATTR_WANT_1X_4WAY_HS, {"WANT_1X_4WAY_HS"}},
+ {NL80211_ATTR_PMKR0_NAME, {"PMKR0_NAME"}},
+ {NL80211_ATTR_PORT_AUTHORIZED, {"PORT_AUTHORIZED"}},
+
+ {NL80211_ATTR_EXTERNAL_AUTH_ACTION, {"EXTERNAL_AUTH_ACTION"}},
+ {NL80211_ATTR_EXTERNAL_AUTH_SUPPORT, {"EXTERNAL_AUTH_SUPPORT"}},
+
+ {NL80211_ATTR_NSS, {"NSS"}},
+ {NL80211_ATTR_ACK_SIGNAL, {"ACK_SIGNAL"}},
+
+ {NL80211_ATTR_CONTROL_PORT_OVER_NL80211, {"CONTROL_PORT_OVER_NL80211"}},
+
+ {NL80211_ATTR_TXQ_STATS, {"TXQ_STATS"}},
+ {NL80211_ATTR_TXQ_LIMIT, {"TXQ_LIMIT"}},
+ {NL80211_ATTR_TXQ_MEMORY_LIMIT, {"TXQ_MEMORY_LIMIT"}},
+ {NL80211_ATTR_TXQ_QUANTUM, {"TXQ_QUANTUM"}},
+
+ {NL80211_ATTR_HE_CAPABILITY, {"HE_CAPABILITY"}},
+
+ {NL80211_ATTR_FTM_RESPONDER, {"FTM_RESPONDER"}},
+
+ {NL80211_ATTR_FTM_RESPONDER_STATS, {"FTM_RESPONDER_STATS"}},
+
+ {NL80211_ATTR_TIMEOUT, {"TIMEOUT"}},
+
+ {NL80211_ATTR_PEER_MEASUREMENTS, {"PEER_MEASUREMENTS"}},
+
+ {NL80211_ATTR_AIRTIME_WEIGHT, {"AIRTIME_WEIGHT"}},
+ {NL80211_ATTR_STA_TX_POWER_SETTING, {"STA_TX_POWER_SETTING"}},
+ {NL80211_ATTR_STA_TX_POWER, {"STA_TX_POWER"}},
+
+ {NL80211_ATTR_SAE_PASSWORD, {"SAE_PASSWORD"}},
+
+ {NL80211_ATTR_TWT_RESPONDER, {"TWT_RESPONDER"}},
+
+ {NL80211_ATTR_HE_OBSS_PD, {"HE_OBSS_PD"}},
+
+ {NL80211_ATTR_WIPHY_EDMG_CHANNELS, {"WIPHY_EDMG_CHANNELS"}},
+ {NL80211_ATTR_WIPHY_EDMG_BW_CONFIG, {"WIPHY_EDMG_BW_CONFIG"}},
+
+ {NL80211_ATTR_VLAN_ID, {"VLAN_ID"}},
+
+ {NL80211_ATTR_HE_BSS_COLOR, {"HE_BSS_COLOR"}},
+
+ {NL80211_ATTR_IFTYPE_AKM_SUITES, {"IFTYPE_AKM_SUITES"}},
+
+ {NL80211_ATTR_TID_CONFIG, {"TID_CONFIG"}},
+
+ {NL80211_ATTR_CONTROL_PORT_NO_PREAUTH, {"CONTROL_PORT_NO_PREAUTH"}},
+
+ {NL80211_ATTR_PMK_LIFETIME, {"PMK_LIFETIME"}},
+ {NL80211_ATTR_PMK_REAUTH_THRESHOLD, {"PMK_REAUTH_THRESHOLD"}},
+
+ {NL80211_ATTR_RECEIVE_MULTICAST, {"RECEIVE_MULTICAST"}},
+ {NL80211_ATTR_WIPHY_FREQ_OFFSET, {"WIPHY_FREQ_OFFSET"}},
+ {NL80211_ATTR_CENTER_FREQ1_OFFSET, {"CENTER_FREQ1_OFFSET"}},
+ {NL80211_ATTR_SCAN_FREQ_KHZ, {"SCAN_FREQ_KHZ"}},
+
+ {NL80211_ATTR_HE_6GHZ_CAPABILITY, {"HE_6GHZ_CAPABILITY"}},
+
+ {NL80211_ATTR_FILS_DISCOVERY, {"FILS_DISCOVERY"}},
+
+ {NL80211_ATTR_UNSOL_BCAST_PROBE_RESP, {"UNSOL_BCAST_PROBE_RESP"}},
+
+ {NL80211_ATTR_S1G_CAPABILITY, {"S1G_CAPABILITY"}},
+ {NL80211_ATTR_S1G_CAPABILITY_MASK, {"S1G_CAPABILITY_MASK"}},
+}) {}
+// clang-format on
+
+static void informationElementsToStream(std::stringstream& ss, const Buffer<nlattr> attr) {
+ struct IEHeader {
+ uint8_t elementId;
+ uint8_t length;
+ } __attribute__((packed));
+ static_assert(sizeof(IEHeader) == 2);
+
+ const auto alldata = attr.data<uint8_t>();
+ const auto bytes = alldata.getRaw();
+
+ ss << '{';
+
+ if constexpr (kCompactIE) {
+ ss << "len=" << bytes.len() << ", ";
+ ss << "crc=" << std::hex << std::setw(4) << crc16(alldata) << std::dec << ", ";
+ }
+
+ bool first = true;
+ auto printComma = [&first, &ss]() {
+ // put separator at every but first entry
+ if (!first) ss << ", ";
+ first = false;
+ };
+
+ for (size_t offset = 0; offset < bytes.len();) {
+ const auto ptr = bytes.ptr() + offset;
+ const auto remainingLen = bytes.len() - offset;
+
+ // can we fit one more header?
+ if (sizeof(IEHeader) > remainingLen) break;
+ IEHeader ieHeader;
+ memcpy(&ieHeader, ptr, sizeof(IEHeader));
+ if (sizeof(IEHeader) + ieHeader.length > remainingLen) {
+ printComma();
+ ss << "ERR";
+ break;
+ }
+ offset += sizeof(IEHeader) + ieHeader.length;
+
+ const Buffer<uint8_t> data(ptr + sizeof(IEHeader), ieHeader.length);
+
+ if (ieHeader.elementId == WLAN_EID_SSID) {
+ printComma();
+
+ const auto str = data.getRaw();
+ const std::string ssid(reinterpret_cast<const char*>(str.ptr()), str.len());
+ ss << "SSID=\"" << printableOnly(ssid) << '"';
+
+ continue;
+ }
+
+ if constexpr (kCompactIE) continue;
+
+ // print entry ID:LENGTH/CRC16
+ printComma();
+ ss << (int)ieHeader.elementId << ':' << (int)ieHeader.length << '/';
+ ss << std::hex << std::setw(4) << crc16(data) << std::dec;
+ }
+ ss << '}';
+}
+
+static void nl80211_pattern_supportToStream(std::stringstream& ss, const Buffer<nlattr> attr) {
+ const auto& [ok, data] = attr.data<nl80211_pattern_support>().getFirst();
+ if (!ok) {
+ ss << "invalid structure";
+ return;
+ }
+ ss << '{' //
+ << data.max_patterns << ',' //
+ << data.min_pattern_len << ',' //
+ << data.max_pattern_len << ',' //
+ << data.max_pkt_offset << '}';
+}
+
+} // namespace android::nl::protocols::generic::families
diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/families/Nl80211.h b/automotive/can/1.0/default/libnl++/protocols/generic/families/Nl80211.h
new file mode 100644
index 0000000..8a9608c
--- /dev/null
+++ b/automotive/can/1.0/default/libnl++/protocols/generic/families/Nl80211.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "../GenericMessageBase.h"
+
+namespace android::nl::protocols::generic::families {
+
+class Nl80211 : public GenericMessageBase {
+ public:
+ Nl80211(nlmsgtype_t familyId);
+};
+
+} // namespace android::nl::protocols::generic::families
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp b/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp
index 7db487a..9cc05da 100644
--- a/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp
@@ -16,6 +16,7 @@
#include "Link.h"
+#include "../structs.h"
#include "structs.h"
#include <net/if.h>
@@ -26,9 +27,9 @@
// clang-format off
Link::Link() : MessageDefinition<ifinfomsg>("link", {
- {RTM_NEWLINK, {"NEWLINK", MessageGenre::NEW}},
- {RTM_DELLINK, {"DELLINK", MessageGenre::DELETE}},
- {RTM_GETLINK, {"GETLINK", MessageGenre::GET}},
+ {RTM_NEWLINK, {"NEWLINK", MessageGenre::New}},
+ {RTM_DELLINK, {"DELLINK", MessageGenre::Delete}},
+ {RTM_GETLINK, {"GETLINK", MessageGenre::Get}},
}, {
{IFLA_ADDRESS, {"ADDRESS"}},
{IFLA_BROADCAST, {"BROADCAST"}},
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/structs.h b/automotive/can/1.0/default/libnl++/protocols/route/structs.h
index b9d622a..fea2ce1 100644
--- a/automotive/can/1.0/default/libnl++/protocols/route/structs.h
+++ b/automotive/can/1.0/default/libnl++/protocols/route/structs.h
@@ -30,16 +30,6 @@
// ifla_cacheinfo
void ifla_cacheinfoToStream(std::stringstream& ss, const Buffer<nlattr> attr);
-template <typename T>
-void arrayToStream(std::stringstream& ss, const Buffer<nlattr> attr) {
- ss << '{';
- for (const auto it : attr.data<T>().getRaw()) {
- ss << it << ',';
- }
- ss.seekp(-1, std::ios_base::cur);
- ss << '}';
-}
-
// rtnl_link_stats or rtnl_link_stats64
template <typename T>
void statsToStream(std::stringstream& ss, const Buffer<nlattr> attr) {
diff --git a/automotive/can/1.0/default/libnl++/protocols/structs.h b/automotive/can/1.0/default/libnl++/protocols/structs.h
new file mode 100644
index 0000000..44c17b8
--- /dev/null
+++ b/automotive/can/1.0/default/libnl++/protocols/structs.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <sstream>
+
+namespace android::nl::protocols {
+
+template <typename T>
+void arrayToStream(std::stringstream& ss, const Buffer<nlattr> attr) {
+ ss << '{';
+ for (const auto it : attr.data<T>().getRaw()) {
+ ss << it << ',';
+ }
+ ss.seekp(-1, std::ios_base::cur);
+ ss << '}';
+}
+
+} // namespace android::nl::protocols
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index 8d1693a..bbb48e1 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -88,6 +88,7 @@
whole_static_libs: [
"android.hardware.automotive.vehicle@2.0-emulated-user-hal-lib",
"android.hardware.automotive.vehicle@2.0-manager-lib",
+ "libqemu_pipe",
],
shared_libs: [
"libbase",
@@ -95,7 +96,6 @@
"libprotobuf-cpp-lite",
],
static_libs: [
- "libqemu_pipe",
"android.hardware.automotive.vehicle@2.0-libproto-native",
],
}
@@ -210,6 +210,5 @@
"android.hardware.automotive.vehicle@2.0-manager-lib",
"android.hardware.automotive.vehicle@2.0-default-impl-lib",
"android.hardware.automotive.vehicle@2.0-libproto-native",
- "libqemu_pipe",
],
}
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index 5ecce46..8ef2b60 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -308,6 +308,19 @@
{.config =
{
+ .prop = toInt(VehicleProperty::SEAT_OCCUPANCY),
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = (SEAT_1_LEFT)},
+ VehicleAreaConfig{.areaId = (SEAT_1_RIGHT)}},
+ },
+ .initialAreaValues = {{SEAT_1_LEFT,
+ {.int32Values = {(int)VehicleSeatOccupancyState::VACANT}}},
+ {SEAT_1_RIGHT,
+ {.int32Values = {(int)VehicleSeatOccupancyState::VACANT}}}}},
+
+ {.config =
+ {
.prop = toInt(VehicleProperty::INFO_DRIVER_SEAT),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::STATIC,
diff --git a/biometrics/face/1.1/default/BiometricsFace.cpp b/biometrics/face/1.1/default/BiometricsFace.cpp
index 2143880..57b3a92 100644
--- a/biometrics/face/1.1/default/BiometricsFace.cpp
+++ b/biometrics/face/1.1/default/BiometricsFace.cpp
@@ -24,8 +24,8 @@
constexpr uint64_t kDeviceId = 123;
// Arbitrary value.
constexpr uint64_t kAuthenticatorId = 987;
-// Arbitrary value.
-constexpr uint64_t kLockoutDuration = 555;
+// Not locked out.
+constexpr uint64_t kLockoutDuration = 0;
BiometricsFace::BiometricsFace() : mRandom(std::mt19937::default_seed) {}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
index 88c066c..a05fad9 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
@@ -42,4 +42,8 @@
SENSOR_DIRTY = 21,
VENDOR = 22,
FIRST_FRAME_RECEIVED = 23,
+ DARK_GLASSES_DETECTED = 24,
+ FACE_COVERING_DETECTED = 25,
+ EYES_NOT_VISIBLE = 26,
+ MOUTH_NOT_VISIBLE = 27,
}
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
index 5897cdc..56a600f 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
@@ -218,6 +218,30 @@
/**
* The first frame from the camera has been received.
*/
- FIRST_FRAME_RECEIVED = 23
+ FIRST_FRAME_RECEIVED = 23,
+
+ /**
+ * Dark glasses detected. This can be useful for providing relevant feedback to the user and
+ * enabling an alternative authentication logic if the implementation supports it.
+ */
+ DARK_GLASSES_DETECTED = 24,
+
+ /**
+ * A face mask or face covering detected. This can be useful for providing relevant feedback to
+ * the user and enabling an alternative authentication logic if the implementation supports it.
+ */
+ FACE_COVERING_DETECTED = 25,
+
+ /**
+ * Either one or both eyes are not visible in the frame. Prefer to use DARK_GLASSES_DETECTED if
+ * the eyes are not visible due to dark glasses.
+ */
+ EYES_NOT_VISIBLE = 26,
+
+ /**
+ * The mouth is not visible in the frame. Prefer to use MASK_DETECTED if the mouth is not
+ * visible due to a mask.
+ */
+ MOUTH_NOT_VISIBLE = 27,
}
diff --git a/biometrics/fingerprint/2.1/default/README.md b/biometrics/fingerprint/2.1/default/README.md
new file mode 100644
index 0000000..c41664e
--- /dev/null
+++ b/biometrics/fingerprint/2.1/default/README.md
@@ -0,0 +1,6 @@
+## Default IBiometricsFingerprint@2.1 HAL ##
+---
+
+## Overview: ##
+
+Provides a default implementation that loads pre-HIDL HALs and exposes it to the framework.
\ No newline at end of file
diff --git a/biometrics/fingerprint/2.2/default/Android.bp b/biometrics/fingerprint/2.2/default/Android.bp
new file mode 100644
index 0000000..8931308
--- /dev/null
+++ b/biometrics/fingerprint/2.2/default/Android.bp
@@ -0,0 +1,22 @@
+cc_binary {
+ name: "android.hardware.biometrics.fingerprint@2.2-service.example",
+ defaults: ["hidl_defaults"],
+ init_rc: ["android.hardware.biometrics.fingerprint@2.2-service.rc"],
+ vintf_fragments: ["android.hardware.biometrics.fingerprint@2.2-service.xml"],
+ vendor: true,
+ relative_install_path: "hw",
+ srcs: [
+ "BiometricsFingerprint.cpp",
+ "service.cpp",
+ ],
+
+ shared_libs: [
+ "libcutils",
+ "liblog",
+ "libhidlbase",
+ "libhardware",
+ "libutils",
+ "android.hardware.biometrics.fingerprint@2.2",
+ ],
+
+}
diff --git a/biometrics/fingerprint/2.2/default/BiometricsFingerprint.cpp b/biometrics/fingerprint/2.2/default/BiometricsFingerprint.cpp
new file mode 100644
index 0000000..b07a17c
--- /dev/null
+++ b/biometrics/fingerprint/2.2/default/BiometricsFingerprint.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "android.hardware.biometrics.fingerprint@2.2-service"
+#define LOG_VERBOSE "android.hardware.biometrics.fingerprint@2.2-service"
+
+#include <hardware/hw_auth_token.h>
+
+#include <android/log.h>
+#include <hardware/hardware.h>
+#include <hardware/fingerprint.h>
+#include "BiometricsFingerprint.h"
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+namespace android {
+namespace hardware {
+namespace biometrics {
+namespace fingerprint {
+namespace V2_2 {
+namespace implementation {
+
+using RequestStatus = android::hardware::biometrics::fingerprint::V2_1::RequestStatus;
+using FingerprintError = android::hardware::biometrics::fingerprint::V2_1::FingerprintError;
+
+constexpr uint64_t kDeviceId = 1;
+
+BiometricsFingerprint::BiometricsFingerprint() {
+
+}
+
+BiometricsFingerprint::~BiometricsFingerprint() {
+
+}
+
+Return<uint64_t> BiometricsFingerprint::setNotify(
+ const sp<IBiometricsFingerprintClientCallback>& clientCallback) {
+ mClientCallback = clientCallback;
+ return kDeviceId;
+}
+
+Return<uint64_t> BiometricsFingerprint::preEnroll() {
+ // On a real implementation, this must be generated and stored in the TEE or its equivalent.
+ return rand();
+}
+
+Return<RequestStatus> BiometricsFingerprint::enroll(const hidl_array<uint8_t, 69>& /* hat */,
+ uint32_t /* gid */, uint32_t /* timeoutSec */) {
+ // On a real implementation, the HAT must be checked in the TEE or its equivalent.
+ mClientCallback->onError(kDeviceId, FingerprintError::ERROR_UNABLE_TO_PROCESS,
+ 0 /* vendorCode */);
+ return RequestStatus::SYS_OK;
+}
+
+Return<RequestStatus> BiometricsFingerprint::postEnroll() {
+ return RequestStatus::SYS_OK;
+}
+
+Return<uint64_t> BiometricsFingerprint::getAuthenticatorId() {
+ return 1;
+}
+
+Return<RequestStatus> BiometricsFingerprint::cancel() {
+ mClientCallback->onError(kDeviceId, FingerprintError::ERROR_CANCELED, 0 /* vendorCode */);
+ return RequestStatus::SYS_OK;
+}
+
+Return<RequestStatus> BiometricsFingerprint::enumerate() {
+ mClientCallback->onEnumerate(kDeviceId, 0 /* fingerId */, 0 /* groupId */,
+ 0 /* remaining */);
+ return RequestStatus::SYS_OK;
+}
+
+Return<RequestStatus> BiometricsFingerprint::remove(uint32_t gid, uint32_t fid) {
+ mClientCallback->onRemoved(kDeviceId, fid, gid, 0 /* remaining */);
+ return RequestStatus::SYS_OK;
+}
+
+Return<RequestStatus> BiometricsFingerprint::setActiveGroup(uint32_t /* gid */,
+ const hidl_string& storePath) {
+ // Return invalid for paths that the HAL is unable to write to.
+ std::string path = storePath.c_str();
+ if (path.compare("") == 0 || path.compare("/") == 0) {
+ return RequestStatus::SYS_EINVAL;
+ }
+ return RequestStatus::SYS_OK;
+}
+
+Return<RequestStatus> BiometricsFingerprint::authenticate(uint64_t /* operationId */,
+ uint32_t /* gid */) {
+ return RequestStatus::SYS_OK;
+}
+
+} // namespace implementation
+} // namespace V2_2
+} // namespace fingerprint
+} // namespace biometrics
+} // namespace hardware
+} // namespace android
diff --git a/biometrics/fingerprint/2.2/default/BiometricsFingerprint.h b/biometrics/fingerprint/2.2/default/BiometricsFingerprint.h
new file mode 100644
index 0000000..a6861b3
--- /dev/null
+++ b/biometrics/fingerprint/2.2/default/BiometricsFingerprint.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_2_BIOMETRICSFINGERPRINT_H
+#define ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_2_BIOMETRICSFINGERPRINT_H
+
+#include <log/log.h>
+#include <android/log.h>
+#include <hardware/hardware.h>
+#include <hardware/fingerprint.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <android/hardware/biometrics/fingerprint/2.2/IBiometricsFingerprint.h>
+
+namespace android {
+namespace hardware {
+namespace biometrics {
+namespace fingerprint {
+namespace V2_2 {
+namespace implementation {
+
+using ::android::hardware::biometrics::fingerprint::V2_2::IBiometricsFingerprint;
+using ::android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprintClientCallback;
+using ::android::hardware::biometrics::fingerprint::V2_1::RequestStatus;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+struct BiometricsFingerprint : public IBiometricsFingerprint {
+public:
+ BiometricsFingerprint();
+ ~BiometricsFingerprint();
+
+ // Methods from ::android::hardware::biometrics::fingerprint::V2_2::IBiometricsFingerprint follow.
+ Return<uint64_t> setNotify(const sp<IBiometricsFingerprintClientCallback>& clientCallback) override;
+ Return<uint64_t> preEnroll() override;
+ Return<RequestStatus> enroll(const hidl_array<uint8_t, 69>& hat, uint32_t gid, uint32_t timeoutSec) override;
+ Return<RequestStatus> postEnroll() override;
+ Return<uint64_t> getAuthenticatorId() override;
+ Return<RequestStatus> cancel() override;
+ Return<RequestStatus> enumerate() override;
+ Return<RequestStatus> remove(uint32_t gid, uint32_t fid) override;
+ Return<RequestStatus> setActiveGroup(uint32_t gid, const hidl_string& storePath) override;
+ Return<RequestStatus> authenticate(uint64_t operationId, uint32_t gid) override;
+
+private:
+ sp<IBiometricsFingerprintClientCallback> mClientCallback;
+
+};
+
+} // namespace implementation
+} // namespace V2_2
+} // namespace fingerprint
+} // namespace biometrics
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_2_BIOMETRICSFINGERPRINT_H
diff --git a/biometrics/fingerprint/2.2/default/android.hardware.biometrics.fingerprint@2.2-service.rc b/biometrics/fingerprint/2.2/default/android.hardware.biometrics.fingerprint@2.2-service.rc
new file mode 100644
index 0000000..1b406b0
--- /dev/null
+++ b/biometrics/fingerprint/2.2/default/android.hardware.biometrics.fingerprint@2.2-service.rc
@@ -0,0 +1,4 @@
+service vendor.fps_hal /vendor/bin/hw/android.hardware.biometrics.fingerprint@2.2-service.example
+ class hal
+ user nobody
+ group nobody
diff --git a/biometrics/fingerprint/2.2/default/android.hardware.biometrics.fingerprint@2.2-service.xml b/biometrics/fingerprint/2.2/default/android.hardware.biometrics.fingerprint@2.2-service.xml
new file mode 100644
index 0000000..5e69a1e
--- /dev/null
+++ b/biometrics/fingerprint/2.2/default/android.hardware.biometrics.fingerprint@2.2-service.xml
@@ -0,0 +1,27 @@
+<!--
+ ~ Copyright (C) 2020 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.
+ -->
+
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.biometrics.fingerprint</name>
+ <transport>hwbinder</transport>
+ <version>2.2</version>
+ <interface>
+ <name>IBiometricsFingerprint</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/biometrics/fingerprint/2.2/default/service.cpp b/biometrics/fingerprint/2.2/default/service.cpp
new file mode 100644
index 0000000..5bc69a0
--- /dev/null
+++ b/biometrics/fingerprint/2.2/default/service.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.biometrics.fingerprint@2.2-service"
+
+#include <android/log.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <android/hardware/biometrics/fingerprint/2.2/IBiometricsFingerprint.h>
+#include <android/hardware/biometrics/fingerprint/2.2/types.h>
+#include "BiometricsFingerprint.h"
+
+using android::hardware::biometrics::fingerprint::V2_2::IBiometricsFingerprint;
+using android::hardware::biometrics::fingerprint::V2_2::implementation::BiometricsFingerprint;
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::sp;
+
+int main() {
+ android::sp<IBiometricsFingerprint> bio = new BiometricsFingerprint();
+
+ configureRpcThreadpool(1, true /*callerWillJoin*/);
+
+ if (::android::OK != bio->registerAsService()) {
+ return 1;
+ }
+
+ joinRpcThreadpool();
+
+ return 0; // should never get here
+}
diff --git a/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h b/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h
index 5468658..ac17d6d 100644
--- a/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h
+++ b/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h
@@ -32,6 +32,7 @@
unsigned int GetNumberSlots();
unsigned int GetCurrentSlot();
bool MarkBootSuccessful();
+ unsigned int GetActiveBootSlot();
bool SetActiveBootSlot(unsigned int slot);
bool SetSlotAsUnbootable(unsigned int slot);
bool SetSlotBootable(unsigned int slot);
diff --git a/boot/1.1/default/boot_control/libboot_control.cpp b/boot/1.1/default/boot_control/libboot_control.cpp
index 2c6ccaf..9387c32 100644
--- a/boot/1.1/default/boot_control/libboot_control.cpp
+++ b/boot/1.1/default/boot_control/libboot_control.cpp
@@ -261,6 +261,24 @@
return UpdateAndSaveBootloaderControl(misc_device_, &bootctrl);
}
+unsigned int BootControl::GetActiveBootSlot() {
+ bootloader_control bootctrl;
+ if (!LoadBootloaderControl(misc_device_, &bootctrl)) return false;
+
+ // Use the current slot by default.
+ unsigned int active_boot_slot = current_slot_;
+ unsigned int max_priority = bootctrl.slot_info[current_slot_].priority;
+ // Find the slot with the highest priority.
+ for (unsigned int i = 0; i < num_slots_; ++i) {
+ if (bootctrl.slot_info[i].priority > max_priority) {
+ max_priority = bootctrl.slot_info[i].priority;
+ active_boot_slot = i;
+ }
+ }
+
+ return active_boot_slot;
+}
+
bool BootControl::SetActiveBootSlot(unsigned int slot) {
if (slot >= kMaxNumSlots || slot >= num_slots_) {
// Invalid slot number.
diff --git a/boot/1.2/Android.bp b/boot/1.2/Android.bp
new file mode 100644
index 0000000..e51c5cd
--- /dev/null
+++ b/boot/1.2/Android.bp
@@ -0,0 +1,15 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.boot@1.2",
+ root: "android.hardware",
+ srcs: [
+ "IBootControl.hal",
+ ],
+ interfaces: [
+ "android.hardware.boot@1.0",
+ "android.hardware.boot@1.1",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: true,
+}
diff --git a/boot/1.2/IBootControl.hal b/boot/1.2/IBootControl.hal
new file mode 100644
index 0000000..bb0ad13
--- /dev/null
+++ b/boot/1.2/IBootControl.hal
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2020 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 android.hardware.boot@1.2;
+
+import @1.0::IBootControl;
+import @1.0::Slot;
+import @1.1::IBootControl;
+
+interface IBootControl extends @1.1::IBootControl {
+
+ /**
+ * Returns the active slot to boot into on the next boot. If
+ * setActiveBootSlot() has been called, the getter function should return the
+ * same slot as the one provided in the last setActiveBootSlot() call.
+ * The returned value is always guaranteed to be strictly less than the
+ * value returned by getNumberSlots. Slots start at 0 and finish at
+ * getNumberSlots() - 1. For instance, a system with A/B must return 0 or 1.
+ */
+ getActiveBootSlot() generates (Slot slot);
+};
+
diff --git a/boot/1.2/default/Android.bp b/boot/1.2/default/Android.bp
new file mode 100644
index 0000000..c097667
--- /dev/null
+++ b/boot/1.2/default/Android.bp
@@ -0,0 +1,50 @@
+cc_library_shared {
+ name: "android.hardware.boot@1.2-impl",
+ stem: "android.hardware.boot@1.0-impl-1.2",
+ defaults: [
+ "hidl_defaults",
+ "libboot_control_defaults",
+ ],
+ relative_install_path: "hw",
+ vendor: true,
+ recovery_available: true,
+ srcs: ["BootControl.cpp"],
+
+ shared_libs: [
+ "liblog",
+ "libhidlbase",
+ "libhardware",
+ "libutils",
+ "android.hardware.boot@1.0",
+ "android.hardware.boot@1.1",
+ "android.hardware.boot@1.2",
+ ],
+ static_libs: [
+ "libboot_control",
+ "libfstab",
+ ],
+}
+
+cc_binary {
+ name: "android.hardware.boot@1.2-service",
+ defaults: ["hidl_defaults"],
+ relative_install_path: "hw",
+ vendor: true,
+ init_rc: ["android.hardware.boot@1.2-service.rc"],
+ srcs: ["service.cpp"],
+
+ vintf_fragments: [
+ "android.hardware.boot@1.2.xml",
+ ],
+
+ shared_libs: [
+ "liblog",
+ "libhardware",
+ "libhidlbase",
+ "libutils",
+ "android.hardware.boot@1.0",
+ "android.hardware.boot@1.1",
+ "android.hardware.boot@1.2",
+ ],
+
+}
diff --git a/boot/1.2/default/BootControl.cpp b/boot/1.2/default/BootControl.cpp
new file mode 100644
index 0000000..c0bf02f
--- /dev/null
+++ b/boot/1.2/default/BootControl.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "android.hardware.boot@1.2-impl"
+
+#include <memory>
+
+#include <log/log.h>
+
+#include "BootControl.h"
+
+namespace android {
+namespace hardware {
+namespace boot {
+namespace V1_2 {
+namespace implementation {
+
+using ::android::hardware::boot::V1_0::CommandResult;
+
+bool BootControl::Init() {
+ return impl_.Init();
+}
+
+// Methods from ::android::hardware::boot::V1_0::IBootControl.
+Return<uint32_t> BootControl::getNumberSlots() {
+ return impl_.GetNumberSlots();
+}
+
+Return<uint32_t> BootControl::getCurrentSlot() {
+ return impl_.GetCurrentSlot();
+}
+
+Return<void> BootControl::markBootSuccessful(markBootSuccessful_cb _hidl_cb) {
+ struct CommandResult cr;
+ if (impl_.MarkBootSuccessful()) {
+ cr.success = true;
+ cr.errMsg = "Success";
+ } else {
+ cr.success = false;
+ cr.errMsg = "Operation failed";
+ }
+ _hidl_cb(cr);
+ return Void();
+}
+
+Return<void> BootControl::setActiveBootSlot(uint32_t slot, setActiveBootSlot_cb _hidl_cb) {
+ struct CommandResult cr;
+ if (impl_.SetActiveBootSlot(slot)) {
+ cr.success = true;
+ cr.errMsg = "Success";
+ } else {
+ cr.success = false;
+ cr.errMsg = "Operation failed";
+ }
+ _hidl_cb(cr);
+ return Void();
+}
+
+Return<void> BootControl::setSlotAsUnbootable(uint32_t slot, setSlotAsUnbootable_cb _hidl_cb) {
+ struct CommandResult cr;
+ if (impl_.SetSlotAsUnbootable(slot)) {
+ cr.success = true;
+ cr.errMsg = "Success";
+ } else {
+ cr.success = false;
+ cr.errMsg = "Operation failed";
+ }
+ _hidl_cb(cr);
+ return Void();
+}
+
+Return<BoolResult> BootControl::isSlotBootable(uint32_t slot) {
+ if (!impl_.IsValidSlot(slot)) {
+ return BoolResult::INVALID_SLOT;
+ }
+ return impl_.IsSlotBootable(slot) ? BoolResult::TRUE : BoolResult::FALSE;
+}
+
+Return<BoolResult> BootControl::isSlotMarkedSuccessful(uint32_t slot) {
+ if (!impl_.IsValidSlot(slot)) {
+ return BoolResult::INVALID_SLOT;
+ }
+ return impl_.IsSlotMarkedSuccessful(slot) ? BoolResult::TRUE : BoolResult::FALSE;
+}
+
+Return<void> BootControl::getSuffix(uint32_t slot, getSuffix_cb _hidl_cb) {
+ hidl_string ans;
+ const char* suffix = impl_.GetSuffix(slot);
+ if (suffix) {
+ ans = suffix;
+ }
+ _hidl_cb(ans);
+ return Void();
+}
+
+// Methods from ::android::hardware::boot::V1_1::IBootControl.
+Return<bool> BootControl::setSnapshotMergeStatus(MergeStatus status) {
+ return impl_.SetSnapshotMergeStatus(status);
+}
+
+Return<MergeStatus> BootControl::getSnapshotMergeStatus() {
+ return impl_.GetSnapshotMergeStatus();
+}
+
+// Methods from ::android::hardware::boot::V1_2::IBootControl.
+Return<uint32_t> BootControl::getActiveBootSlot() {
+ return impl_.GetActiveBootSlot();
+}
+
+IBootControl* HIDL_FETCH_IBootControl(const char* /* hal */) {
+ auto module = std::make_unique<BootControl>();
+ if (!module->Init()) {
+ ALOGE("Could not initialize BootControl module");
+ return nullptr;
+ }
+ return module.release();
+}
+
+} // namespace implementation
+} // namespace V1_2
+} // namespace boot
+} // namespace hardware
+} // namespace android
diff --git a/boot/1.2/default/BootControl.h b/boot/1.2/default/BootControl.h
new file mode 100644
index 0000000..5791699
--- /dev/null
+++ b/boot/1.2/default/BootControl.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/boot/1.2/IBootControl.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <libboot_control/libboot_control.h>
+
+namespace android {
+namespace hardware {
+namespace boot {
+namespace V1_2 {
+namespace implementation {
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::boot::V1_0::BoolResult;
+using ::android::hardware::boot::V1_1::MergeStatus;
+using ::android::hardware::boot::V1_2::IBootControl;
+
+class BootControl : public IBootControl {
+ public:
+ bool Init();
+
+ // Methods from ::android::hardware::boot::V1_0::IBootControl.
+ Return<uint32_t> getNumberSlots() override;
+ Return<uint32_t> getCurrentSlot() override;
+ Return<void> markBootSuccessful(markBootSuccessful_cb _hidl_cb) override;
+ Return<void> setActiveBootSlot(uint32_t slot, setActiveBootSlot_cb _hidl_cb) override;
+ Return<void> setSlotAsUnbootable(uint32_t slot, setSlotAsUnbootable_cb _hidl_cb) override;
+ Return<BoolResult> isSlotBootable(uint32_t slot) override;
+ Return<BoolResult> isSlotMarkedSuccessful(uint32_t slot) override;
+ Return<void> getSuffix(uint32_t slot, getSuffix_cb _hidl_cb) override;
+
+ // Methods from ::android::hardware::boot::V1_1::IBootControl.
+ Return<bool> setSnapshotMergeStatus(MergeStatus status) override;
+ Return<MergeStatus> getSnapshotMergeStatus() override;
+
+ // Methods from ::android::hardware::boot::V1_2::IBootControl.
+ Return<uint32_t> getActiveBootSlot() override;
+
+ private:
+ android::bootable::BootControl impl_;
+};
+
+extern "C" IBootControl* HIDL_FETCH_IBootControl(const char* name);
+
+} // namespace implementation
+} // namespace V1_2
+} // namespace boot
+} // namespace hardware
+} // namespace android
diff --git a/boot/1.2/default/android.hardware.boot@1.2-service.rc b/boot/1.2/default/android.hardware.boot@1.2-service.rc
new file mode 100644
index 0000000..14926c0
--- /dev/null
+++ b/boot/1.2/default/android.hardware.boot@1.2-service.rc
@@ -0,0 +1,7 @@
+service vendor.boot-hal-1-2 /vendor/bin/hw/android.hardware.boot@1.2-service
+ interface android.hardware.boot@1.0::IBootControl default
+ interface android.hardware.boot@1.1::IBootControl default
+ interface android.hardware.boot@1.2::IBootControl default
+ class early_hal
+ user root
+ group root
diff --git a/boot/1.2/default/android.hardware.boot@1.2.xml b/boot/1.2/default/android.hardware.boot@1.2.xml
new file mode 100644
index 0000000..ba91e8f
--- /dev/null
+++ b/boot/1.2/default/android.hardware.boot@1.2.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.boot</name>
+ <transport>hwbinder</transport>
+ <fqname>@1.2::IBootControl/default</fqname>
+ </hal>
+</manifest>
diff --git a/boot/1.2/default/service.cpp b/boot/1.2/default/service.cpp
new file mode 100644
index 0000000..3053957
--- /dev/null
+++ b/boot/1.2/default/service.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "android.hardware.boot@1.2-service"
+
+#include <android/hardware/boot/1.2/IBootControl.h>
+#include <hidl/LegacySupport.h>
+
+using android::hardware::defaultPassthroughServiceImplementation;
+using IBootControl_V1_0 = android::hardware::boot::V1_0::IBootControl;
+using IBootControl_V1_2 = android::hardware::boot::V1_2::IBootControl;
+
+int main(int /* argc */, char* /* argv */[]) {
+ return defaultPassthroughServiceImplementation<IBootControl_V1_0, IBootControl_V1_2>();
+}
diff --git a/boot/1.2/vts/functional/Android.bp b/boot/1.2/vts/functional/Android.bp
new file mode 100644
index 0000000..a7f5ccb
--- /dev/null
+++ b/boot/1.2/vts/functional/Android.bp
@@ -0,0 +1,31 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+ name: "VtsHalBootV1_2TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: ["VtsHalBootV1_2TargetTest.cpp"],
+ static_libs: [
+ "android.hardware.boot@1.0",
+ "android.hardware.boot@1.1",
+ "android.hardware.boot@1.2",
+ "libgmock",
+ ],
+ test_suites: [
+ "device-tests",
+ "vts",
+ ],
+}
diff --git a/boot/1.2/vts/functional/VtsHalBootV1_2TargetTest.cpp b/boot/1.2/vts/functional/VtsHalBootV1_2TargetTest.cpp
new file mode 100644
index 0000000..9df23c3
--- /dev/null
+++ b/boot/1.2/vts/functional/VtsHalBootV1_2TargetTest.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "boot_hidl_hal_test"
+
+#include <android-base/logging.h>
+#include <android/hardware/boot/1.2/IBootControl.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include <unistd.h>
+
+using ::android::sp;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::boot::V1_0::CommandResult;
+using ::android::hardware::boot::V1_0::Slot;
+using ::android::hardware::boot::V1_2::IBootControl;
+
+class BootHidlTest : public testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ boot = IBootControl::getService(GetParam());
+ ASSERT_NE(boot, nullptr);
+
+ LOG(INFO) << "Test is remote " << boot->isRemote();
+ }
+
+ sp<IBootControl> boot;
+};
+
+auto generate_callback(CommandResult* dest) {
+ return [=](CommandResult cr) { *dest = cr; };
+}
+
+TEST_P(BootHidlTest, GetActiveBootSlot) {
+ Slot curSlot = boot->getCurrentSlot();
+ Slot otherSlot = curSlot ? 0 : 1;
+
+ // Set the active slot, then check if the getter returns the correct slot.
+ CommandResult cr;
+ Return<void> result = boot->setActiveBootSlot(otherSlot, generate_callback(&cr));
+ EXPECT_TRUE(result.isOk());
+ Slot activeSlot = boot->getActiveBootSlot();
+ EXPECT_EQ(otherSlot, activeSlot);
+
+ result = boot->setActiveBootSlot(curSlot, generate_callback(&cr));
+ EXPECT_TRUE(result.isOk());
+ activeSlot = boot->getActiveBootSlot();
+ EXPECT_EQ(curSlot, activeSlot);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BootHidlTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, BootHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IBootControl::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/camera/common/1.0/default/CameraModule.cpp b/camera/common/1.0/default/CameraModule.cpp
index 86f26e4..27e74f1 100644
--- a/camera/common/1.0/default/CameraModule.cpp
+++ b/camera/common/1.0/default/CameraModule.cpp
@@ -529,24 +529,29 @@
}
void CameraModule::removeCamera(int cameraId) {
- std::unordered_set<std::string> physicalIds;
- camera_metadata_t *metadata = const_cast<camera_metadata_t*>(
- mCameraInfoMap.valueFor(cameraId).static_camera_characteristics);
- common::V1_0::helper::CameraMetadata hidlMetadata(metadata);
+ // Skip HAL1 devices which isn't cached in mCameraInfoMap and don't advertise
+ // static_camera_characteristics
+ if (getDeviceVersion(cameraId) >= CAMERA_DEVICE_API_VERSION_3_0) {
+ std::unordered_set<std::string> physicalIds;
+ camera_metadata_t *metadata = const_cast<camera_metadata_t*>(
+ mCameraInfoMap.valueFor(cameraId).static_camera_characteristics);
+ common::V1_0::helper::CameraMetadata hidlMetadata(metadata);
- if (isLogicalMultiCamera(hidlMetadata, &physicalIds)) {
- for (const auto& id : physicalIds) {
- int idInt = std::stoi(id);
- if (mPhysicalCameraInfoMap.indexOfKey(idInt) >= 0) {
- free_camera_metadata(mPhysicalCameraInfoMap[idInt]);
- mPhysicalCameraInfoMap.removeItem(idInt);
- } else {
- ALOGE("%s: Cannot find corresponding static metadata for physical id %s",
- __FUNCTION__, id.c_str());
+ if (isLogicalMultiCamera(hidlMetadata, &physicalIds)) {
+ for (const auto& id : physicalIds) {
+ int idInt = std::stoi(id);
+ if (mPhysicalCameraInfoMap.indexOfKey(idInt) >= 0) {
+ free_camera_metadata(mPhysicalCameraInfoMap[idInt]);
+ mPhysicalCameraInfoMap.removeItem(idInt);
+ } else {
+ ALOGE("%s: Cannot find corresponding static metadata for physical id %s",
+ __FUNCTION__, id.c_str());
+ }
}
}
+ free_camera_metadata(metadata);
}
- free_camera_metadata(metadata);
+
mCameraInfoMap.removeItem(cameraId);
mDeviceVersionMap.removeItem(cameraId);
}
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 74af9e3..72321e2 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -134,7 +134,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.boot</name>
- <version>1.1</version>
+ <version>1.2</version>
<interface>
<name>IBootControl</name>
<instance>default</instance>
diff --git a/current.txt b/current.txt
index 7aa9593..8623fc0 100644
--- a/current.txt
+++ b/current.txt
@@ -772,12 +772,15 @@
2c331a9605f3a08d9c1e0a36169ca57758bc43c11a78ef3f3730509885e52c15 android.hardware.graphics.composer@2.4::IComposerClient
3da3ce039247872d95c6bd48621dbfdfa1c2d2a91a90f257862f87ee2bc46300 android.hardware.health@2.1::types
9679f27a42f75781c8993ef163ed92808a1928de186639834841d0b8e326e63d android.hardware.gatekeeper@1.0::IGatekeeper
+9c4eb603d7b9ad675a14edb6180681c5a78da5c6bdc7755853912c974a21f7e5 android.hardware.gnss@1.0::IAGnssCallback
40456eb90ea88b62d18ad3fbf1da8917981cd55ac04ce69c8e058d49ff5beff4 android.hardware.keymaster@3.0::IKeymasterDevice
6017b4f2481feb0fffceae81c62bc372c898998b2d8fe69fbd39859d3a315e5e android.hardware.keymaster@4.0::IKeymasterDevice
dabe23dde7c9e3ad65c61def7392f186d7efe7f4216f9b6f9cf0863745b1a9f4 android.hardware.keymaster@4.1::IKeymasterDevice
cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardware.neuralnetworks@1.2::IDevice
9625e85f56515ad2cf87b6a1847906db669f746ea4ab02cd3d4ca25abc9b0109 android.hardware.neuralnetworks@1.2::types
9e758e208d14f7256e0885d6d8ad0b61121b21d8c313864f981727ae55bffd16 android.hardware.neuralnetworks@1.3::types
+e8c86c69c438da8d1549856c1bb3e2d1b8da52722f8235ff49a30f2cce91742c android.hardware.soundtrigger@2.1::ISoundTriggerHwCallback
+b9fbb6e2e061ed0960939d48b785e9700210add1f13ed32ecd688d0f1ca20ef7 android.hardware.renderscript@1.0::types
0f53d70e1eadf8d987766db4bf6ae2048004682168f4cab118da576787def3fa android.hardware.radio@1.0::types
38d65fb20c60a5b823298560fc0825457ecdc49603a4b4e94bf81511790737da android.hardware.radio@1.4::types
954c334efd80e8869b66d1ce5fe2755712d96ba4b3c38d415739c330af5fb4cb android.hardware.radio@1.5::types
diff --git a/gnss/1.0/IAGnssCallback.hal b/gnss/1.0/IAGnssCallback.hal
index 81f1689..11a6a5d 100644
--- a/gnss/1.0/IAGnssCallback.hal
+++ b/gnss/1.0/IAGnssCallback.hal
@@ -42,7 +42,6 @@
/**
* Represents the status of AGNSS augmented to support IPv4.
*/
- @export(name="", value_prefix="GPS_")
struct AGnssStatusIpV4 {
AGnssType type;
AGnssStatusValue status;
diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp
index 9c498d5..ef43a34 100644
--- a/gnss/1.1/default/Android.bp
+++ b/gnss/1.1/default/Android.bp
@@ -18,6 +18,7 @@
"android.hardware.gnss@2.0",
"android.hardware.gnss@1.1",
"android.hardware.gnss@1.0",
+ "android.hardware.gnss-ndk_platform",
],
static_libs: [
"android.hardware.gnss@common-default-lib",
diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp
index 37de55d..7da462f 100644
--- a/gnss/2.0/default/Android.bp
+++ b/gnss/2.0/default/Android.bp
@@ -29,7 +29,7 @@
"GnssMeasurement.cpp",
"GnssMeasurementCorrections.cpp",
"GnssVisibilityControl.cpp",
- "service.cpp"
+ "service.cpp",
],
shared_libs: [
"libhidlbase",
@@ -39,8 +39,9 @@
"android.hardware.gnss.visibility_control@1.0",
"android.hardware.gnss@2.1",
"android.hardware.gnss@2.0",
- "android.hardware.gnss@1.0",
"android.hardware.gnss@1.1",
+ "android.hardware.gnss@1.0",
+ "android.hardware.gnss-ndk_platform",
],
static_libs: [
"android.hardware.gnss@common-default-lib",
diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp
index 7739f90..63e5013 100644
--- a/gnss/2.1/default/Android.bp
+++ b/gnss/2.1/default/Android.bp
@@ -34,6 +34,7 @@
"android.hardware.gnss@1.0",
"android.hardware.gnss@1.1",
"android.hardware.gnss@2.0",
+ "android.hardware.gnss-ndk_platform",
],
static_libs: [
"android.hardware.gnss@common-default-lib",
diff --git a/gnss/2.1/vts/functional/gnss_hal_test.h b/gnss/2.1/vts/functional/gnss_hal_test.h
index 7950670..2bcecf4 100644
--- a/gnss/2.1/vts/functional/gnss_hal_test.h
+++ b/gnss/2.1/vts/functional/gnss_hal_test.h
@@ -19,10 +19,9 @@
#include <android/hardware/gnss/2.1/IGnss.h>
#include "v2_1/gnss_hal_test_template.h"
-using android::hardware::gnss::V2_1::IGnss;
-
// The main test class for GNSS HAL.
-class GnssHalTest : public GnssHalTestTemplate<IGnss> {
+class GnssHalTest : public android::hardware::gnss::common::GnssHalTestTemplate<
+ android::hardware::gnss::V2_1::IGnss> {
public:
/**
* IsGnssHalVersion_2_1:
diff --git a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
index 7afd49c..deb80e8 100644
--- a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
@@ -27,6 +27,9 @@
using android::hardware::gnss::common::Utils;
+using android::hardware::gnss::V2_1::IGnssAntennaInfo;
+using android::hardware::gnss::V2_1::IGnssAntennaInfoCallback;
+
using IGnssMeasurement_2_1 = android::hardware::gnss::V2_1::IGnssMeasurement;
using IGnssMeasurement_2_0 = android::hardware::gnss::V2_0::IGnssMeasurement;
using IGnssMeasurement_1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
diff --git a/gnss/3.0/default/Android.bp b/gnss/3.0/default/Android.bp
index 2b33b32..bb3c467 100644
--- a/gnss/3.0/default/Android.bp
+++ b/gnss/3.0/default/Android.bp
@@ -36,6 +36,7 @@
"android.hardware.gnss@3.0",
"android.hardware.gnss.measurement_corrections@1.1",
"android.hardware.gnss.measurement_corrections@1.0",
+ "android.hardware.gnss-ndk_platform",
],
static_libs: [
"android.hardware.gnss@common-default-lib",
diff --git a/gnss/3.0/vts/functional/gnss_hal_test.h b/gnss/3.0/vts/functional/gnss_hal_test.h
index 387214e..be6d38c 100644
--- a/gnss/3.0/vts/functional/gnss_hal_test.h
+++ b/gnss/3.0/vts/functional/gnss_hal_test.h
@@ -19,7 +19,6 @@
#include <android/hardware/gnss/3.0/IGnss.h>
#include "v2_1/gnss_hal_test_template.h"
-using android::hardware::gnss::V3_0::IGnss;
-
// The main test class for GNSS HAL.
-class GnssHalTest : public GnssHalTestTemplate<IGnss> {};
\ No newline at end of file
+class GnssHalTest : public android::hardware::gnss::common::GnssHalTestTemplate<
+ android::hardware::gnss::V3_0::IGnss> {};
\ No newline at end of file
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl
index 354c953..a0e8de4 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl
@@ -21,4 +21,6 @@
int flags;
long timestampNs;
double timeUncertaintyNs;
+ const int HAS_TIMESTAMP_NS = 1;
+ const int HAS_TIME_UNCERTAINTY_NS = 2;
}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl
new file mode 100644
index 0000000..42b940e
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl
@@ -0,0 +1,39 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+parcelable GnssClock {
+ int gnssClockFlags;
+ int leapSecond;
+ long timeNs;
+ double timeUncertaintyNs;
+ long fullBiasNs;
+ double biasNs;
+ double biasUncertaintyNs;
+ double driftNsps;
+ double driftUncertaintyNsps;
+ int hwClockDiscontinuityCount;
+ android.hardware.gnss.GnssSignalType referenceSignalTypeForIsb;
+ const int HAS_LEAP_SECOND = 1;
+ const int HAS_TIME_UNCERTAINTY = 2;
+ const int HAS_FULL_BIAS = 4;
+ const int HAS_BIAS = 8;
+ const int HAS_BIAS_UNCERTAINTY = 16;
+ const int HAS_DRIFT = 32;
+ const int HAS_DRIFT_UNCERTAINTY = 64;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl
new file mode 100644
index 0000000..7ffabd2
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+parcelable GnssData {
+ android.hardware.gnss.GnssMeasurement[] measurements;
+ android.hardware.gnss.GnssClock clock;
+ android.hardware.gnss.ElapsedRealtime elapsedRealtime;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl
new file mode 100644
index 0000000..7d15855
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl
@@ -0,0 +1,79 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+parcelable GnssMeasurement {
+ int flags;
+ int svid;
+ android.hardware.gnss.GnssSignalType signalType;
+ double timeOffsetNs;
+ int state;
+ long receivedSvTimeInNs;
+ long receivedSvTimeUncertaintyInNs;
+ double antennaCN0DbHz;
+ double basebandCN0DbHz;
+ double pseudorangeRateMps;
+ double pseudorangeRateUncertaintyMps;
+ int accumulatedDeltaRangeState;
+ double accumulatedDeltaRangeM;
+ double accumulatedDeltaRangeUncertaintyM;
+ float carrierFrequencyHz;
+ long carrierCycles;
+ double carrierPhase;
+ double carrierPhaseUncertainty;
+ android.hardware.gnss.GnssMultipathIndicator multipathIndicator;
+ double snrDb;
+ double agcLevelDb;
+ double fullInterSignalBiasNs;
+ double fullInterSignalBiasUncertaintyNs;
+ double satelliteInterSignalBiasNs;
+ double satelliteInterSignalBiasUncertaintyNs;
+ const int HAS_SNR = 1;
+ const int HAS_CARRIER_FREQUENCY = 512;
+ const int HAS_CARRIER_CYCLES = 1024;
+ const int HAS_CARRIER_PHASE = 2048;
+ const int HAS_CARRIER_PHASE_UNCERTAINTY = 4096;
+ const int HAS_AUTOMATIC_GAIN_CONTROL = 8192;
+ const int HAS_FULL_ISB = 65536;
+ const int HAS_FULL_ISB_UNCERTAINTY = 131072;
+ const int HAS_SATELLITE_ISB = 262144;
+ const int HAS_SATELLITE_ISB_UNCERTAINTY = 524288;
+ const int STATE_UNKNOWN = 0;
+ const int STATE_CODE_LOCK = 1;
+ const int STATE_BIT_SYNC = 2;
+ const int STATE_SUBFRAME_SYNC = 4;
+ const int STATE_TOW_DECODED = 8;
+ const int STATE_MSEC_AMBIGUOUS = 16;
+ const int STATE_SYMBOL_SYNC = 32;
+ const int STATE_GLO_STRING_SYNC = 64;
+ const int STATE_GLO_TOD_DECODED = 128;
+ const int STATE_BDS_D2_BIT_SYNC = 256;
+ const int STATE_BDS_D2_SUBFRAME_SYNC = 512;
+ const int STATE_GAL_E1BC_CODE_LOCK = 1024;
+ const int STATE_GAL_E1C_2ND_CODE_LOCK = 2048;
+ const int STATE_GAL_E1B_PAGE_SYNC = 4096;
+ const int STATE_SBAS_SYNC = 8192;
+ const int STATE_TOW_KNOWN = 16384;
+ const int STATE_GLO_TOD_KNOWN = 32768;
+ const int STATE_2ND_CODE_LOCK = 65536;
+ const int ADR_STATE_UNKNOWN = 0;
+ const int ADR_STATE_VALID = 1;
+ const int ADR_STATE_RESET = 2;
+ const int ADR_STATE_CYCLE_SLIP = 4;
+ const int ADR_STATE_HALF_CYCLE_RESOLVED = 8;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl
new file mode 100644
index 0000000..75ca3af
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@Backing(type="int") @VintfStability
+enum GnssMultipathIndicator {
+ UNKNOWN = 0,
+ PRESENT = 1,
+ NOT_PRESENT = 2,
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl
new file mode 100644
index 0000000..3e66c4a
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl
@@ -0,0 +1,40 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+parcelable GnssSignalType {
+ android.hardware.gnss.GnssConstellationType constellation;
+ double carrierFrequencyHz;
+ String codeType;
+ const String CODE_TYPE_A = "A";
+ const String CODE_TYPE_B = "B";
+ const String CODE_TYPE_C = "C";
+ const String CODE_TYPE_D = "D";
+ const String CODE_TYPE_I = "I";
+ const String CODE_TYPE_L = "L";
+ const String CODE_TYPE_M = "M";
+ const String CODE_TYPE_N = "N";
+ const String CODE_TYPE_P = "P";
+ const String CODE_TYPE_Q = "Q";
+ const String CODE_TYPE_S = "S";
+ const String CODE_TYPE_W = "W";
+ const String CODE_TYPE_X = "X";
+ const String CODE_TYPE_Y = "Y";
+ const String CODE_TYPE_Z = "Z";
+ const String CODE_TYPE_UNKNOWN = "UNKNOWN";
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
index e1a4b9e..10ac150 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
@@ -22,8 +22,7 @@
void close();
android.hardware.gnss.IGnssPsds getExtensionPsds();
android.hardware.gnss.IGnssConfiguration getExtensionGnssConfiguration();
+ android.hardware.gnss.IGnssMeasurementInterface getExtensionGnssMeasurement();
android.hardware.gnss.IGnssPowerIndication getExtensionGnssPowerIndication();
const int ERROR_INVALID_ARGUMENT = 1;
- const int ELAPSED_REALTIME_HAS_TIMESTAMP_NS = 1;
- const int ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS = 2;
}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl
new file mode 100644
index 0000000..e05e9b9
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+interface IGnssMeasurementCallback {
+ void gnssMeasurementCb(in android.hardware.gnss.GnssData data);
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl
new file mode 100644
index 0000000..9576205
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+interface IGnssMeasurementInterface {
+ void setCallback(in android.hardware.gnss.IGnssMeasurementCallback callback, in boolean enableFullTracking);
+ void close();
+}
diff --git a/gnss/aidl/android/hardware/gnss/ElapsedRealtime.aidl b/gnss/aidl/android/hardware/gnss/ElapsedRealtime.aidl
index fae14f8..67d090e 100644
--- a/gnss/aidl/android/hardware/gnss/ElapsedRealtime.aidl
+++ b/gnss/aidl/android/hardware/gnss/ElapsedRealtime.aidl
@@ -22,10 +22,18 @@
@VintfStability
parcelable ElapsedRealtime {
+ /** Bit mask indicating a valid timestampNs is stored in the ElapsedRealtime parcelable. */
+ const int HAS_TIMESTAMP_NS = 1 << 0;
+
+ /**
+ * Bit mask indicating a valid timeUncertaintyNs is stored in the ElapsedRealtime parcelable.
+ */
+ const int HAS_TIME_UNCERTAINTY_NS = 1 << 1;
+
/**
* A bit field of flags indicating the validity of each field in this data structure.
*
- * The bit masks are defined in IGnss interface and prefixed with ELAPSED_REALTIME_HAS_.
+ * The bit masks are the constants with prefix HAS_.
*
* Fields may have invalid information in them, if not marked as valid by the corresponding bit
* in flags.
diff --git a/gnss/aidl/android/hardware/gnss/GnssClock.aidl b/gnss/aidl/android/hardware/gnss/GnssClock.aidl
new file mode 100644
index 0000000..f416e08
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/GnssClock.aidl
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2020 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 android.hardware.gnss;
+
+import android.hardware.gnss.GnssSignalType;
+
+/**
+ * Represents an estimate of the GNSS clock time.
+ */
+@VintfStability
+parcelable GnssClock {
+ /** Bit mask indicating a valid 'leap second' is stored in the GnssClock. */
+ const int HAS_LEAP_SECOND = 1 << 0;
+ /** Bit mask indicating a valid 'time uncertainty' is stored in the GnssClock. */
+ const int HAS_TIME_UNCERTAINTY = 1 << 1;
+ /** Bit mask indicating a valid 'full bias' is stored in the GnssClock. */
+ const int HAS_FULL_BIAS = 1 << 2;
+ /** Bit mask indicating a valid 'bias' is stored in the GnssClock. */
+ const int HAS_BIAS = 1 << 3;
+ /** Bit mask indicating a valid 'bias uncertainty' is stored in the GnssClock. */
+ const int HAS_BIAS_UNCERTAINTY = 1 << 4;
+ /** Bit mask indicating a valid 'drift' is stored in the GnssClock. */
+ const int HAS_DRIFT = 1 << 5;
+ /** Bit mask indicating a valid 'drift uncertainty' is stored in the GnssClock. */
+ const int HAS_DRIFT_UNCERTAINTY = 1 << 6;
+
+ /**
+ * A bitfield of flags indicating the validity of the fields in this data
+ * structure.
+ *
+ * The bit masks are the constants with perfix HAS_.
+ *
+ * Fields for which there is no corresponding flag must be filled in
+ * with a valid value. For convenience, these are marked as mandatory.
+ *
+ * Others fields may have invalid information in them, if not marked as
+ * valid by the corresponding bit in gnssClockFlags.
+ */
+ int gnssClockFlags;
+
+ /**
+ * Leap second data.
+ * The sign of the value is defined by the following equation:
+ * utcTimeNs = timeNs - (fullBiasNs + biasNs) - leapSecond *
+ * 1,000,000,000
+ *
+ * If this data is available, gnssClockFlags must contain
+ * HAS_LEAP_SECOND.
+ */
+ int leapSecond;
+
+ /**
+ * The GNSS receiver internal clock value. This is the local hardware clock
+ * value.
+ *
+ * For local hardware clock, this value is expected to be monotonically
+ * increasing while the hardware clock remains powered on. (For the case of a
+ * HW clock that is not continuously on, see the
+ * hwClockDiscontinuityCount field). The receiver's estimate of GNSS time
+ * can be derived by subtracting the sum of fullBiasNs and biasNs (when
+ * available) from this value.
+ *
+ * This GNSS time must be the best estimate of current GNSS time
+ * that GNSS receiver can achieve.
+ *
+ * Sub-nanosecond accuracy can be provided by means of the 'biasNs' field.
+ * The value contains the timeUncertaintyNs in it.
+ *
+ * This value is mandatory.
+ */
+ long timeNs;
+
+ /**
+ * 1-Sigma uncertainty associated with the clock's time in nanoseconds.
+ * The uncertainty is represented as an absolute (single sided) value.
+ *
+ * If the data is available, gnssClockFlags must contain
+ * HAS_TIME_UNCERTAINTY. Ths value is ideally zero, as the time
+ * 'latched' by timeNs is defined as the reference clock vs. which all
+ * other times (and corresponding uncertainties) are measured.
+ */
+ double timeUncertaintyNs;
+
+ /**
+ * The difference between hardware clock ('time' field) inside GNSS receiver
+ * and the true GPS time since 0000Z, January 6, 1980, in nanoseconds.
+ *
+ * The sign of the value is defined by the following equation:
+ * local estimate of GPS time = timeNs - (fullBiasNs + biasNs)
+ *
+ * If receiver has computed time for a non-GPS constellation, the time offset of
+ * that constellation versus GPS time must be applied to fill this value.
+ *
+ * The error estimate for the sum of this and the biasNs is the biasUncertaintyNs.
+ *
+ * If the data is available gnssClockFlags must contain HAS_FULL_BIAS.
+ *
+ * This value is mandatory if the receiver has estimated GPS time.
+ */
+ long fullBiasNs;
+
+ /**
+ * Sub-nanosecond bias - used with fullBiasNS, see fullBiasNs for details.
+ *
+ * The error estimate for the sum of this and the fullBiasNs is the
+ * biasUncertaintyNs.
+ *
+ * If the data is available gnssClockFlags must contain HAS_BIAS.
+ *
+ * This value is mandatory if the receiver has estimated GPS time.
+ */
+ double biasNs;
+
+ /**
+ * 1-Sigma uncertainty associated with the local estimate of GNSS time (clock
+ * bias) in nanoseconds. The uncertainty is represented as an absolute
+ * (single sided) value.
+ *
+ * The caller is responsible for using this uncertainty (it can be very
+ * large before the GPS time has been fully resolved.)
+ *
+ * If the data is available gnssClockFlags must contain HAS_BIAS_UNCERTAINTY.
+ *
+ * This value is mandatory if the receiver has estimated GPS time.
+ */
+ double biasUncertaintyNs;
+
+ /**
+ * The clock's drift in nanoseconds (per second).
+ *
+ * A positive value means that the frequency is higher than the nominal
+ * frequency, and that the (fullBiasNs + biasNs) is growing more positive
+ * over time.
+ *
+ * If the data is available gnssClockFlags must contain HAS_DRIFT.
+ *
+ * This value is mandatory if the receiver has estimated GPS time.
+ */
+ double driftNsps;
+
+ /**
+ * 1-Sigma uncertainty associated with the clock's drift in nanoseconds (per
+ * second).
+ * The uncertainty is represented as an absolute (single sided) value.
+ *
+ * If the data is available gnssClockFlags must contain HAS_DRIFT_UNCERTAINTY.
+ *
+ * This value is mandatory if the receiver has estimated GPS time.
+ */
+ double driftUncertaintyNsps;
+
+ /**
+ * This field must be incremented, when there are discontinuities in the
+ * hardware clock.
+ *
+ * A "discontinuity" is meant to cover the case of a switch from one source
+ * of clock to another. A single free-running crystal oscillator (XO)
+ * will generally not have any discontinuities, and this can be set and
+ * left at 0.
+ *
+ * If, however, the timeNs value (HW clock) is derived from a composite of
+ * sources, that is not as smooth as a typical XO, or is otherwise stopped &
+ * restarted, then this value shall be incremented each time a discontinuity
+ * occurs. (E.g. this value can start at zero at device boot-up and
+ * increment each time there is a change in clock continuity. In the
+ * unlikely event that this value reaches full scale, rollover (not
+ * clamping) is required, such that this value continues to change, during
+ * subsequent discontinuity events.)
+ *
+ * While this number stays the same, between GnssClock reports, it can be
+ * safely assumed that the timeNs value has been running continuously, e.g.
+ * derived from a single, high quality clock (XO like, or better, that is
+ * typically used during continuous GNSS signal sampling.)
+ *
+ * It is expected, esp. during periods where there are few GNSS signals
+ * available, that the HW clock be discontinuity-free as long as possible,
+ * as this avoids the need to use (waste) a GNSS measurement to fully
+ * re-solve for the GNSS clock bias and drift, when using the accompanying
+ * measurements, from consecutive GnssData reports.
+ *
+ * This value is mandatory.
+ */
+ int hwClockDiscontinuityCount;
+
+ /**
+ * Reference GNSS signal type for inter-signal bias.
+ */
+ GnssSignalType referenceSignalTypeForIsb;
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/GnssData.aidl b/gnss/aidl/android/hardware/gnss/GnssData.aidl
new file mode 100644
index 0000000..ed30c98
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/GnssData.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 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 android.hardware.gnss;
+
+import android.hardware.gnss.ElapsedRealtime;
+import android.hardware.gnss.GnssClock;
+import android.hardware.gnss.GnssMeasurement;
+
+/**
+ * Represents a reading of GNSS measurements. For devices launched in Android Q or newer, it is
+ * mandatory that these be provided, on request, when the GNSS receiver is searching/tracking
+ * signals.
+ *
+ * - Reporting of GNSS constellation measurements is mandatory.
+ * - Reporting of all tracked constellations are encouraged.
+ */
+@VintfStability
+parcelable GnssData {
+ /** The array of measurements. */
+ GnssMeasurement[] measurements;
+
+ /** The GNSS clock time reading. */
+ GnssClock clock;
+
+ /**
+ * Timing information of the GNSS data synchronized with SystemClock.elapsedRealtimeNanos()
+ * clock.
+ */
+ ElapsedRealtime elapsedRealtime;
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl
new file mode 100644
index 0000000..fae862b
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl
@@ -0,0 +1,634 @@
+/*
+ * Copyright (C) 2020 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 android.hardware.gnss;
+
+import android.hardware.gnss.GnssConstellationType;
+import android.hardware.gnss.GnssSignalType;
+import android.hardware.gnss.GnssMultipathIndicator;
+
+/**
+ * Represents a GNSS Measurement, it contains raw and computed information.
+ *
+ * All signal measurement information (e.g. svTime, pseudorangeRate, multipathIndicator) reported in
+ * this struct must be based on GNSS signal measurements only. You must not synthesize measurements
+ * by calculating or reporting expected measurements based on known or estimated position, velocity,
+ * or time.
+ */
+@VintfStability
+parcelable GnssMeasurement {
+ /** Bit mask indicating a valid 'snr' is stored in the GnssMeasurement. */
+ const int HAS_SNR = 1 << 0;
+ /** Bit mask indicating a valid 'carrier frequency' is stored in the GnssMeasurement. */
+ const int HAS_CARRIER_FREQUENCY = 1 << 9;
+ /** Bit mask indicating a valid 'carrier cycles' is stored in the GnssMeasurement. */
+ const int HAS_CARRIER_CYCLES = 1 << 10;
+ /** Bit mask indicating a valid 'carrier phase' is stored in the GnssMeasurement. */
+ const int HAS_CARRIER_PHASE = 1 << 11;
+ /** Bit mask indicating a valid 'carrier phase uncertainty' is stored in the GnssMeasurement. */
+ const int HAS_CARRIER_PHASE_UNCERTAINTY = 1 << 12;
+ /** Bit mask indicating a valid automatic gain control is stored in the GnssMeasurement. */
+ const int HAS_AUTOMATIC_GAIN_CONTROL = 1 << 13;
+ /** Bit mask indicating a valid full inter-signal bias is stored in the GnssMeasurement. */
+ const int HAS_FULL_ISB = 1 << 16;
+ /**
+ * Bit mask indicating a valid full inter-signal bias uncertainty is stored in the
+ * GnssMeasurement.
+ */
+ const int HAS_FULL_ISB_UNCERTAINTY = 1 << 17;
+ /**
+ * Bit mask indicating a valid satellite inter-signal bias is stored in the GnssMeasurement.
+ */
+ const int HAS_SATELLITE_ISB = 1 << 18;
+ /**
+ * Bit mask indicating a valid satellite inter-signal bias uncertainty is stored in the
+ * GnssMeasurement.
+ */
+ const int HAS_SATELLITE_ISB_UNCERTAINTY = 1 << 19;
+
+ /**
+ * A bitfield of flags indicating the validity of the fields in this GnssMeasurement. The bit
+ * masks are defined in the constants with prefix HAS_*
+ *
+ * Fields for which there is no corresponding flag must be filled in with a valid value. For
+ * convenience, these are marked as mandatory.
+ *
+ * Others fields may have invalid information in them, if not marked as valid by the
+ * corresponding bit in flags.
+ */
+ int flags;
+
+ /**
+ * Satellite vehicle ID number, as defined in GnssSvInfo::svid
+ *
+ * This value is mandatory.
+ */
+ int svid;
+
+ /**
+ * Defines the constellation of the given SV.
+ *
+ * This value is mandatory.
+ */
+ GnssSignalType signalType;
+
+ /**
+ * Time offset at which the measurement was taken in nanoseconds.
+ * The reference receiver's time is specified by GnssData::clock::timeNs.
+ *
+ * The sign of timeOffsetNs is given by the following equation:
+ * measurement time = GnssClock::timeNs + timeOffsetNs
+ *
+ * It provides an individual time-stamp for the measurement, and allows
+ * sub-nanosecond accuracy. It may be zero if all measurements are
+ * aligned to a common time.
+ *
+ * This value is mandatory.
+ */
+ double timeOffsetNs;
+
+ /**
+ * Flags indicating the GNSS measurement state.
+ *
+ * The expected behavior here is for GNSS HAL to set all the flags that apply. For example, if
+ * the state for a satellite is only C/A code locked and bit synchronized, and there is still
+ * millisecond ambiguity, the state must be set as:
+ *
+ * STATE_CODE_LOCK | STATE_BIT_SYNC | STATE_MSEC_AMBIGUOUS
+ *
+ * If GNSS is still searching for a satellite, the corresponding state must be set to
+ * STATE_UNKNOWN(0).
+ *
+ * The received satellite time is relative to the beginning of the system week for all
+ * constellations except for Glonass where it is relative to the beginning of the Glonass system
+ * day.
+ *
+ * The table below indicates the valid range of the received GNSS satellite time. These ranges
+ * depend on the constellation and code being tracked and the state of the tracking algorithms
+ * given by the getState method. If the state flag is set, then the valid measurement range is
+ * zero to the value in the table. The state flag with the widest range indicates the range of
+ * the received GNSS satellite time value.
+ *
+ * +---------------------------+--------------------+-----+-----------+--------------------+------+
+ * | |GPS/QZSS |GLNS |BDS |GAL |SBAS |
+ * +---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * |State Flag |L1 |L5I |L5Q |L1OF |B1I |B1I |E1B |E1C |E5AQ |L1 |
+ * | |C/A | | | |(D1) |(D2)| | | |C/A |
+ * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * |STATE_UNKNOWN |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
+ * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * |STATE_CODE_LOCK |1ms |1 ms |1 ms |1 ms |1 ms |1 ms|- |- |1 ms |1 ms |
+ * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * |STATE_SYMBOL_SYNC |20ms |10 ms |1 ms |10 ms|20 ms |2 ms|4 ms |4 ms |1 ms |2 ms |
+ * | |(opt.)| |(opt.)| |(opt.)| |(opt.)|(opt.)|(opt.)| |
+ * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * |STATE_BIT_SYNC |20 ms |20 ms |1 ms |20 ms|20 ms |- |8 ms |- |1 ms |4 ms |
+ * | | | |(opt.)| | | | | |(opt.)| |
+ * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * |STATE_SUBFRAME_SYNC |6s |6s |- |2 s |6 s |- |- |- |100 ms|- |
+ * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * |STATE_TOW_DECODED |1 week|- |- |1 day|1 week|- |1 week|- |- |1 week|
+ * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * |STATE_TOW_KNOWN |1 week|- |- |1 day|1 week|- |1 week|- |- |1 week|
+ * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * |STATE_GLO_STRING_SYNC |- |- |- |2 s |- |- |- |- |- |- |
+ * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * |STATE_GLO_TOD_DECODED |- |- |- |1 day|- |- |- |- |- |- |
+ * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * |STATE_GLO_TOD_KNOWN |- |- |- |1 day|- |- |- |- |- |- |
+ * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * |STATE_BDS_D2_BIT_SYNC |- |- |- |- |- |2 ms|- |- |- |- |
+ * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * |STATE_BDS_D2_SUBFRAME_SYNC |- |- |- |- |- |600 |- |- |- |- |
+ * | | | | | | |ms | | | | |
+ * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * |STATE_GAL_E1BC_CODE_LOCK |- |- |- |- |- |- |4 ms |4 ms |- |- |
+ * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * |STATE_GAL_E1C_2ND_CODE_LOCK|- |- |- |- |- |- |- |100 ms|- |- |
+ * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * |STATE_2ND_CODE_LOCK |- |10 ms |20 ms |- |- |- |- |100 ms|100 ms|- |
+ * | | |(opt.)| | | | | |(opt.)| | |
+ * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * |STATE_GAL_E1B_PAGE_SYNC |- |- |- |- |- |- |2 s |- |- |- |
+ * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * |STATE_SBAS_SYNC |- |- |- |- |- |- |- |- |- |1s |
+ * +---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ *
+ * Note: TOW Known refers to the case where TOW is possibly not decoded over the air but has
+ * been determined from other sources. If TOW decoded is set then TOW Known must also be set.
+ *
+ * Note well: if there is any ambiguity in integer millisecond, STATE_MSEC_AMBIGUOUS must be
+ * set accordingly, in the 'state' field. This value must be populated if 'state' !=
+ * STATE_UNKNOWN.
+ *
+ * Note on optional flags:
+ * - For L1 C/A and B1I, STATE_SYMBOL_SYNC is optional since the symbol length is the
+ * same as the bit length.
+ * - For L5Q and E5aQ, STATE_BIT_SYNC and STATE_SYMBOL_SYNC are optional since they are
+ * implied by STATE_CODE_LOCK.
+ * - STATE_2ND_CODE_LOCK for L5I is optional since it is implied by STATE_SYMBOL_SYNC.
+ * - STATE_2ND_CODE_LOCK for E1C is optional since it is implied by
+ * STATE_GAL_E1C_2ND_CODE_LOCK.
+ * - For E1B and E1C, STATE_SYMBOL_SYNC is optional, because it is implied by
+ * STATE_GAL_E1BC_CODE_LOCK.
+ */
+ const int STATE_UNKNOWN = 0;
+ const int STATE_CODE_LOCK = 1 << 0;
+ const int STATE_BIT_SYNC = 1 << 1;
+ const int STATE_SUBFRAME_SYNC = 1 << 2;
+ const int STATE_TOW_DECODED = 1 << 3;
+ const int STATE_MSEC_AMBIGUOUS = 1 << 4;
+ const int STATE_SYMBOL_SYNC = 1 << 5;
+ const int STATE_GLO_STRING_SYNC = 1 << 6;
+ const int STATE_GLO_TOD_DECODED = 1 << 7;
+ const int STATE_BDS_D2_BIT_SYNC = 1 << 8;
+ const int STATE_BDS_D2_SUBFRAME_SYNC = 1 << 9;
+ const int STATE_GAL_E1BC_CODE_LOCK = 1 << 10;
+ const int STATE_GAL_E1C_2ND_CODE_LOCK = 1 << 11;
+ const int STATE_GAL_E1B_PAGE_SYNC = 1 << 12;
+ const int STATE_SBAS_SYNC = 1 << 13;
+ const int STATE_TOW_KNOWN = 1 << 14;
+ const int STATE_GLO_TOD_KNOWN = 1 << 15;
+ const int STATE_2ND_CODE_LOCK = 1 << 16;
+
+ /**
+ * A bitfield of flags indicating the GnssMeasurementState per satellite sync state. It
+ * represents the current sync state for the associated satellite.
+ *
+ * Based on the sync state, the 'received GNSS tow' field must be interpreted accordingly.
+ *
+ * The bit masks are defined in the constants with prefix STATE_.
+ *
+ * This value is mandatory.
+ */
+ int state;
+
+ /**
+ * The received GNSS Time-of-Week at the measurement time, in nanoseconds.
+ * For GNSS & QZSS, this is the received GNSS Time-of-Week at the
+ * measurement time, in nanoseconds. The value is relative to the
+ * beginning of the current GNSS week.
+ *
+ * Given the highest sync state that can be achieved, per each satellite,
+ * valid range for this field can be:
+ * Searching : [ 0 ] : STATE_UNKNOWN
+ * C/A code lock : [ 0 1ms ] : STATE_CODE_LOCK set
+ * Bit sync : [ 0 20ms ] : STATE_BIT_SYNC set
+ * Subframe sync : [ 0 6s ] : STATE_SUBFRAME_SYNC set
+ * TOW decoded : [ 0 1week ] : STATE_TOW_DECODED set
+ * TOW Known : [ 0 1week ] : STATE_TOW_KNOWN set
+ *
+ * Note: TOW Known refers to the case where TOW is possibly not decoded
+ * over the air but has been determined from other sources. If TOW
+ * decoded is set then TOW Known must also be set.
+ *
+ * Note: If there is any ambiguity in integer millisecond,
+ * STATE_MSEC_AMBIGUOUS must be set accordingly, in the
+ * 'state' field.
+ *
+ * This value must be populated if 'state' != STATE_UNKNOWN.
+ *
+ * For Glonass, this is the received Glonass time of day, at the
+ * measurement time in nanoseconds.
+ *
+ * Given the highest sync state that can be achieved, per each satellite,
+ * valid range for this field can be:
+ * Searching : [ 0 ] : STATE_UNKNOWN set
+ * C/A code lock : [ 0 1ms ] : STATE_CODE_LOCK set
+ * Symbol sync : [ 0 10ms ] : STATE_SYMBOL_SYNC set
+ * Bit sync : [ 0 20ms ] : STATE_BIT_SYNC set
+ * String sync : [ 0 2s ] : STATE_GLO_STRING_SYNC set
+ * Time of day decoded : [ 0 1day ] : STATE_GLO_TOD_DECODED set
+ * Time of day known : [ 0 1day ] : STATE_GLO_TOD_KNOWN set
+ *
+ * Note: Time of day known refers to the case where it is possibly not
+ * decoded over the air but has been determined from other sources. If
+ * Time of day decoded is set then Time of day known must also be set.
+ *
+ * For Beidou, this is the received Beidou time of week,
+ * at the measurement time in nanoseconds.
+ *
+ * Given the highest sync state that can be achieved, per each satellite,
+ * valid range for this field can be:
+ * Searching : [ 0 ] : STATE_UNKNOWN set.
+ * C/A code lock : [ 0 1ms ] : STATE_CODE_LOCK set.
+ * Bit sync (D2) : [ 0 2ms ] : STATE_BDS_D2_BIT_SYNC set.
+ * Bit sync (D1) : [ 0 20ms ] : STATE_BIT_SYNC set.
+ * Subframe (D2) : [ 0 0.6s ] : STATE_BDS_D2_SUBFRAME_SYNC set.
+ * Subframe (D1) : [ 0 6s ] : STATE_SUBFRAME_SYNC set.
+ * Time of week decoded : [ 0 1week ] : STATE_TOW_DECODED set.
+ * Time of week known : [ 0 1week ] : STATE_TOW_KNOWN set
+ *
+ * Note: TOW Known refers to the case where TOW is possibly not decoded
+ * over the air but has been determined from other sources. If TOW
+ * decoded is set then TOW Known must also be set.
+ *
+ * For Galileo, this is the received Galileo time of week,
+ * at the measurement time in nanoseconds.
+ *
+ * E1BC code lock : [ 0 4ms ] : STATE_GAL_E1BC_CODE_LOCK set.
+ * E1C 2nd code lock : [ 0 100ms] : STATE_GAL_E1C_2ND_CODE_LOCK set.
+ * E1B page : [ 0 2s ] : STATE_GAL_E1B_PAGE_SYNC set.
+ * Time of week decoded : [ 0 1week] : STATE_TOW_DECODED is set.
+ * Time of week known : [ 0 1week] : STATE_TOW_KNOWN set
+ *
+ * Note: TOW Known refers to the case where TOW is possibly not decoded
+ * over the air but has been determined from other sources. If TOW
+ * decoded is set then TOW Known must also be set.
+ *
+ * For SBAS, this is received SBAS time, at the measurement time in
+ * nanoseconds.
+ *
+ * Given the highest sync state that can be achieved, per each satellite,
+ * valid range for this field can be:
+ * Searching : [ 0 ] : STATE_UNKNOWN
+ * C/A code lock: [ 0 1ms ] : STATE_CODE_LOCK is set
+ * Symbol sync : [ 0 2ms ] : STATE_SYMBOL_SYNC is set
+ * Message : [ 0 1s ] : STATE_SBAS_SYNC is set
+ */
+ long receivedSvTimeInNs;
+
+ /**
+ * 1-Sigma uncertainty of the Received GNSS Time-of-Week in nanoseconds.
+ *
+ * This value must be populated if 'state' != STATE_UNKNOWN.
+ */
+ long receivedSvTimeUncertaintyInNs;
+
+ /**
+ * Carrier-to-noise density in dB-Hz, typically in the range [0, 63].
+ * It contains the measured C/N0 value for the signal at the antenna port.
+ *
+ * If a signal has separate components (e.g. Pilot and Data channels) and
+ * the receiver only processes one of the components, then the reported
+ * antennaCN0DbHz reflects only the component that is processed.
+ *
+ * This value is mandatory.
+ */
+ double antennaCN0DbHz;
+
+ /**
+ * Baseband Carrier-to-noise density in dB-Hz, typically in the range [0, 63]. It contains the
+ * measured C/N0 value for the signal measured at the baseband.
+ *
+ * This is typically a few dB weaker than the value estimated for C/N0 at the antenna port,
+ * which is reported in cN0DbHz.
+ *
+ * If a signal has separate components (e.g. Pilot and Data channels) and the receiver only
+ * processes one of the components, then the reported basebandCN0DbHz reflects only the
+ * component that is processed.
+ *
+ * This value is mandatory.
+ */
+ double basebandCN0DbHz;
+
+ /**
+ * Pseudorange rate at the timestamp in m/s. The correction of a given
+ * Pseudorange Rate value includes corrections for receiver and satellite
+ * clock frequency errors. Ensure that this field is independent (see
+ * comment at top of GnssMeasurement struct.)
+ *
+ * It is mandatory to provide the 'uncorrected' 'pseudorange rate', and
+ * provide GnssClock's 'drift' field as well. When providing the
+ * uncorrected pseudorange rate, do not apply the corrections described above.)
+ *
+ * The value includes the 'pseudorange rate uncertainty' in it.
+ * A positive 'uncorrected' value indicates that the SV is moving away from
+ * the receiver.
+ *
+ * The sign of the 'uncorrected' 'pseudorange rate' and its relation to the
+ * sign of 'doppler shift' is given by the equation:
+ * pseudorange rate = -k * doppler shift (where k is a constant)
+ *
+ * This must be the most accurate pseudorange rate available, based on
+ * fresh signal measurements from this channel.
+ *
+ * It is mandatory that this value be provided at typical carrier phase PRR
+ * quality (few cm/sec per second of uncertainty, or better) - when signals
+ * are sufficiently strong & stable, e.g. signals from a GNSS simulator at >=
+ * 35 dB-Hz.
+ */
+ double pseudorangeRateMps;
+
+ /**
+ * 1-Sigma uncertainty of the pseudorangeRateMps.
+ * The uncertainty is represented as an absolute (single sided) value.
+ *
+ * This value is mandatory.
+ */
+ double pseudorangeRateUncertaintyMps;
+
+
+ /**
+ * Flags indicating the Accumulated Delta Range's states.
+ *
+ * See the table below for a detailed interpretation of each state.
+ *
+ * +---------------------+-------------------+-----------------------------+
+ * | ADR_STATE | Time of relevance | Interpretation |
+ * +---------------------+-------------------+-----------------------------+
+ * | UNKNOWN | ADR(t) | No valid carrier phase |
+ * | | | information is available |
+ * | | | at time t. |
+ * +---------------------+-------------------+-----------------------------+
+ * | VALID | ADR(t) | Valid carrier phase |
+ * | | | information is available |
+ * | | | at time t. This indicates |
+ * | | | that this measurement can |
+ * | | | be used as a reference for |
+ * | | | future measurements. |
+ * | | | However, to compare it to |
+ * | | | previous measurements to |
+ * | | | compute delta range, |
+ * | | | other bits should be |
+ * | | | checked. Specifically, it |
+ * | | | can be used for delta range |
+ * | | | computation if it is valid |
+ * | | | and has no reset or cycle |
+ * | | | slip at this epoch i.e. |
+ * | | | if VALID_BIT == 1 && |
+ * | | | CYCLE_SLIP_BIT == 0 && |
+ * | | | RESET_BIT == 0. |
+ * +---------------------+-------------------+-----------------------------+
+ * | RESET | ADR(t) - ADR(t-1) | Carrier phase accumulation |
+ * | | | has been restarted between |
+ * | | | current time t and previous |
+ * | | | time t-1. This indicates |
+ * | | | that this measurement can |
+ * | | | be used as a reference for |
+ * | | | future measurements, but it |
+ * | | | should not be compared to |
+ * | | | previous measurements to |
+ * | | | compute delta range. |
+ * +---------------------+-------------------+-----------------------------+
+ * | CYCLE_SLIP | ADR(t) - ADR(t-1) | Cycle slip(s) have been |
+ * | | | detected between the |
+ * | | | current time t and previous |
+ * | | | time t-1. This indicates |
+ * | | | that this measurement can |
+ * | | | be used as a reference for |
+ * | | | future measurements. |
+ * | | | Clients can use a |
+ * | | | measurement with a cycle |
+ * | | | slip to compute delta range |
+ * | | | against previous |
+ * | | | measurements at their own |
+ * | | | risk. |
+ * +---------------------+-------------------+-----------------------------+
+ * | HALF_CYCLE_RESOLVED | ADR(t) | Half cycle ambiguity is |
+ * | | | resolved at time t. |
+ * +---------------------+-------------------+-----------------------------+
+ */
+ const int ADR_STATE_UNKNOWN = 0;
+ const int ADR_STATE_VALID = 1 << 0;
+ const int ADR_STATE_RESET = 1 << 1;
+ const int ADR_STATE_CYCLE_SLIP = 1 << 2;
+ const int ADR_STATE_HALF_CYCLE_RESOLVED = 1 << 3;
+
+ /**
+ * A bitfield of flags indicating the accumulated delta range's state. It indicates whether ADR
+ * is reset or there is a cycle slip(indicating loss of lock).
+ *
+ * The bit masks are defined in constants with prefix ADR_STATE_.
+ *
+ * This value is mandatory.
+ */
+ int accumulatedDeltaRangeState;
+
+ /**
+ * Accumulated delta range since the last channel reset in meters.
+ * A positive value indicates that the SV is moving away from the receiver.
+ *
+ * The sign of the 'accumulated delta range' and its relation to the sign of
+ * 'carrier phase' is given by the equation:
+ * accumulated delta range = -k * carrier phase (where k is a constant)
+ *
+ * This value must be populated if 'accumulated delta range state' !=
+ * ADR_STATE_UNKNOWN.
+ * However, it is expected that the data is only accurate when:
+ * 'accumulated delta range state' == ADR_STATE_VALID.
+ *
+ * The alignment of the phase measurement will not be adjusted by the receiver so the in-phase
+ * and quadrature phase components will have a quarter cycle offset as they do when transmitted
+ * from the satellites. If the measurement is from a combination of the in-phase and quadrature
+ * phase components, then the alignment of the phase measurement will be aligned to the in-phase
+ * component.
+ */
+ double accumulatedDeltaRangeM;
+
+ /**
+ * 1-Sigma uncertainty of the accumulated delta range in meters.
+ * This value must be populated if 'accumulated delta range state' !=
+ * ADR_STATE_UNKNOWN.
+ */
+ double accumulatedDeltaRangeUncertaintyM;
+
+ /**
+ * Carrier frequency of the signal tracked, for example it can be the
+ * GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz, L5 =
+ * 1176.45 MHz, varying GLO channels, etc. If the field is not set, it
+ * is the primary common use central frequency, e.g. L1 = 1575.45 MHz
+ * for GPS.
+ *
+ * For an L1, L5 receiver tracking a satellite on L1 and L5 at the same
+ * time, two raw measurement structs must be reported for this same
+ * satellite, in one of the measurement structs, all the values related
+ * to L1 must be filled, and in the other all of the values related to
+ * L5 must be filled.
+ *
+ * If the data is available, gnssMeasurementFlags must contain
+ * HAS_CARRIER_FREQUENCY.
+ */
+ float carrierFrequencyHz;
+
+ /**
+ * The number of full carrier cycles between the satellite and the
+ * receiver. The reference frequency is given by the field
+ * 'carrierFrequencyHz'. Indications of possible cycle slips and
+ * resets in the accumulation of this value can be inferred from the
+ * accumulatedDeltaRangeState flags.
+ *
+ * If the data is available, gnssMeasurementFlags must contain
+ * HAS_CARRIER_CYCLES.
+ */
+ long carrierCycles;
+
+ /**
+ * The RF phase detected by the receiver, in the range [0.0, 1.0].
+ * This is usually the fractional part of the complete carrier phase
+ * measurement.
+ *
+ * The reference frequency is given by the field 'carrierFrequencyHz'.
+ * The value contains the 'carrier-phase uncertainty' in it.
+ *
+ * If the data is available, gnssMeasurementFlags must contain
+ * HAS_CARRIER_PHASE.
+ */
+ double carrierPhase;
+
+ /**
+ * 1-Sigma uncertainty of the carrier-phase.
+ * If the data is available, gnssMeasurementFlags must contain
+ * HAS_CARRIER_PHASE_UNCERTAINTY.
+ */
+ double carrierPhaseUncertainty;
+
+ /**
+ * An enumeration that indicates the 'multipath' state of the event.
+ *
+ * The multipath Indicator is intended to report the presence of overlapping
+ * signals that manifest as distorted correlation peaks.
+ *
+ * - if there is a distorted correlation peak shape, report that multipath
+ * is MULTIPATH_INDICATOR_PRESENT.
+ * - if there is no distorted correlation peak shape, report
+ * MULTIPATH_INDICATOR_NOT_PRESENT
+ * - if signals are too weak to discern this information, report
+ * MULTIPATH_INDICATOR_UNKNOWN
+ *
+ * Example: when doing the standardized overlapping Multipath Performance
+ * test (3GPP TS 34.171) the Multipath indicator must report
+ * MULTIPATH_INDICATOR_PRESENT for those signals that are tracked, and
+ * contain multipath, and MULTIPATH_INDICATOR_NOT_PRESENT for those
+ * signals that are tracked and do not contain multipath.
+ */
+ GnssMultipathIndicator multipathIndicator;
+
+ /**
+ * Signal-to-noise ratio at correlator output in dB.
+ * If the data is available, GnssMeasurementFlags must contain HAS_SNR.
+ * This is the power ratio of the "correlation peak height above the
+ * observed noise floor" to "the noise RMS".
+ */
+ double snrDb;
+
+ /**
+ * Automatic gain control (AGC) level. AGC acts as a variable gain
+ * amplifier adjusting the power of the incoming signal. The AGC level
+ * may be used to indicate potential interference. When AGC is at a
+ * nominal level, this value must be set as 0. Higher gain (and/or lower
+ * input power) must be output as a positive number. Hence in cases of
+ * strong jamming, in the band of this signal, this value must go more
+ * negative.
+ *
+ * Note: Different hardware designs (e.g. antenna, pre-amplification, or
+ * other RF HW components) may also affect the typical output of this
+ * value on any given hardware design in an open sky test - the
+ * important aspect of this output is that changes in this value are
+ * indicative of changes on input signal power in the frequency band for
+ * this measurement.
+ */
+ double agcLevelDb;
+
+ /**
+ * The full inter-signal bias (ISB) in nanoseconds.
+ *
+ * This value is the sum of the estimated receiver-side and the space-segment-side inter-system
+ * bias, inter-frequency bias and inter-code bias, including
+ *
+ * - Receiver inter-constellation bias (with respect to the constellation in
+ * GnssClock.referenceSignalTypeForIsb)
+ * - Receiver inter-frequency bias (with respect to the carrier frequency in
+ * GnssClock.referenceSignalTypeForIsb)
+ * - Receiver inter-code bias (with respect to the code type in
+ * GnssClock.referenceSignalTypeForIsb)
+ * - Master clock bias (e.g., GPS-GAL Time Offset (GGTO), GPS-UTC Time Offset (TauGps), BDS-GLO
+ * Time Offset (BGTO)) (with respect to the constellation in
+ * GnssClock.referenceSignalTypeForIsb)
+ * - Group delay (e.g., Total Group Delay (TGD))
+ * - Satellite inter-frequency bias (GLO only) (with respect to the carrier frequency in
+ * GnssClock.referenceSignalTypeForIsb)
+ * - Satellite inter-code bias (e.g., Differential Code Bias (DCB)) (with respect to the code
+ * type in GnssClock.referenceSignalTypeForIsb)
+ *
+ * If a component of the above is already compensated in the provided
+ * GnssMeasurement.receivedSvTimeInNs, then it must not be included in the reported full ISB.
+ *
+ * The value does not include the inter-frequency Ionospheric bias.
+ *
+ * The full ISB of GnssClock.referenceSignalTypeForIsb is defined to be 0.0 nanoseconds.
+ */
+ double fullInterSignalBiasNs;
+
+ /**
+ * 1-sigma uncertainty associated with the full inter-signal bias in nanoseconds.
+ */
+ double fullInterSignalBiasUncertaintyNs;
+
+ /**
+ * The satellite inter-signal bias in nanoseconds.
+ *
+ * This value is the sum of the space-segment-side inter-system bias, inter-frequency bias
+ * and inter-code bias, including
+ *
+ * - Master clock bias (e.g., GPS-GAL Time Offset (GGTO), GPS-UTC Time Offset (TauGps), BDS-GLO
+ * Time Offset (BGTO)) (with respect to the constellation in
+ * GnssClock.referenceSignalTypeForIsb)
+ * - Group delay (e.g., Total Group Delay (TGD))
+ * - Satellite inter-frequency bias (GLO only) (with respect to the carrier frequency in
+ * GnssClock.referenceSignalTypeForIsb)
+ * - Satellite inter-code bias (e.g., Differential Code Bias (DCB)) (with respect to the code
+ * type in GnssClock.referenceSignalTypeForIsb)
+ *
+ * The satellite ISB of GnssClock.referenceSignalTypeForIsb is defined to be 0.0 nanoseconds.
+ */
+ double satelliteInterSignalBiasNs;
+
+ /**
+ * 1-sigma uncertainty associated with the satellite inter-signal bias in nanoseconds.
+ */
+ double satelliteInterSignalBiasUncertaintyNs;
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/GnssMultipathIndicator.aidl b/gnss/aidl/android/hardware/gnss/GnssMultipathIndicator.aidl
new file mode 100644
index 0000000..ec1ce62
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/GnssMultipathIndicator.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 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 android.hardware.gnss;
+
+/**
+ * Enumeration of available values for the GNSS Measurement's multipath
+ * indicator.
+ */
+@VintfStability
+@Backing(type="int")
+enum GnssMultipathIndicator {
+ /** The indicator is not available or unknown. */
+ UNKNOWN = 0,
+ /** The measurement is indicated to be affected by multipath. */
+ PRESENT = 1,
+ /** The measurement is indicated to be not affected by multipath. */
+ NOT_PRESENT = 2,
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/GnssSignalType.aidl b/gnss/aidl/android/hardware/gnss/GnssSignalType.aidl
new file mode 100644
index 0000000..a284fed
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/GnssSignalType.aidl
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2020 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 android.hardware.gnss;
+
+import android.hardware.gnss.GnssConstellationType;
+
+/**
+ * Represents a GNSS signal type.
+ */
+@VintfStability
+parcelable GnssSignalType {
+ /**
+ * Constellation type of the SV that transmits the signal.
+ */
+ GnssConstellationType constellation;
+
+ /**
+ * Carrier frequency of the signal tracked, for example it can be the
+ * GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz, L5 =
+ * 1176.45 MHz, varying GLO channels, etc. If the field is not set, it
+ * is the primary common use central frequency, e.g. L1 = 1575.45 MHz
+ * for GPS.
+ *
+ * For an L1, L5 receiver tracking a satellite on L1 and L5 at the same
+ * time, two raw measurement structs must be reported for this same
+ * satellite, in one of the measurement structs, all the values related
+ * to L1 must be filled, and in the other all of the values related to
+ * L5 must be filled.
+ */
+ double carrierFrequencyHz;
+
+ /**
+ * GNSS signal code type "A" representing GALILEO E1A, GALILEO E6A, IRNSS L5A, IRNSS SA.
+ */
+ const String CODE_TYPE_A = "A";
+
+ /**
+ * GNSS signal code type "B" representing GALILEO E1B, GALILEO E6B, IRNSS L5B, IRNSS SB.
+ */
+ const String CODE_TYPE_B = "B";
+
+ /**
+ * GNSS signal code type "C" representing GPS L1 C/A, GPS L2 C/A, GLONASS G1 C/A,
+ * GLONASS G2 C/A, GALILEO E1C, GALILEO E6C, SBAS L1 C/A, QZSS L1 C/A, IRNSS L5C.
+ */
+ const String CODE_TYPE_C = "C";
+
+ /**
+ * GNSS signal code type "D" representing BDS B1C D.
+ */
+ const String CODE_TYPE_D = "D";
+
+ /**
+ * GNSS signal code type "I" representing GPS L5 I, GLONASS G3 I, GALILEO E5a I, GALILEO E5b I,
+ * GALILEO E5a+b I, SBAS L5 I, QZSS L5 I, BDS B1 I, BDS B2 I, BDS B3 I.
+ */
+ const String CODE_TYPE_I = "I";
+
+ /**
+ * GNSS signal code type "L" representing GPS L1C (P), GPS L2C (L), QZSS L1C (P), QZSS L2C (L),
+ * LEX(6) L.
+ */
+ const String CODE_TYPE_L = "L";
+
+ /**
+ * GNSS signal code type "M" representing GPS L1M, GPS L2M.
+ */
+ const String CODE_TYPE_M = "M";
+
+ /**
+ * GNSS signal code type "N" representing GPS L1 codeless, GPS L2 codeless.
+ */
+ const String CODE_TYPE_N = "N";
+
+ /**
+ * GNSS signal code type "P" representing GPS L1P, GPS L2P, GLONASS G1P, GLONASS G2P, BDS B1C P.
+ */
+ const String CODE_TYPE_P = "P";
+
+ /**
+ * GNSS signal code type "Q" representing GPS L5 Q, GLONASS G3 Q, GALILEO E5a Q, GALILEO E5b Q,
+ * GALILEO E5a+b Q, SBAS L5 Q, QZSS L5 Q, BDS B1 Q, BDS B2 Q, BDS B3 Q.
+ */
+ const String CODE_TYPE_Q = "Q";
+
+ /**
+ * GNSS signal code type "S" represents GPS L1C (D), GPS L2C (M), QZSS L1C (D), QZSS L2C (M),
+ * LEX(6) S.
+ */
+ const String CODE_TYPE_S = "S";
+
+ /**
+ * GNSS signal code type "W" representing GPS L1 Z-tracking, GPS L2 Z-tracking.
+ */
+ const String CODE_TYPE_W = "W";
+
+ /**
+ * GNSS signal code type "X" representing GPS L1C (D+P), GPS L2C (M+L), GPS L5 (I+Q),
+ * GLONASS G3 (I+Q), GALILEO E1 (B+C), GALILEO E5a (I+Q), GALILEO E5b (I+Q), GALILEO E5a+b(I+Q),
+ * GALILEO E6 (B+C), SBAS L5 (I+Q), QZSS L1C (D+P), QZSS L2C (M+L), QZSS L5 (I+Q),
+ * LEX(6) (S+L), BDS B1 (I+Q), BDS B1C (D+P), BDS B2 (I+Q), BDS B3 (I+Q), IRNSS L5 (B+C).
+ */
+ const String CODE_TYPE_X = "X";
+
+ /**
+ * GNSS signal code type "Y" representing GPS L1Y, GPS L2Y.
+ */
+ const String CODE_TYPE_Y = "Y";
+
+ /**
+ * GNSS signal code type "Z" representing GALILEO E1 (A+B+C), GALILEO E6 (A+B+C), QZSS L1-SAIF.
+ */
+ const String CODE_TYPE_Z = "Z";
+
+ /**
+ * GNSS signal code type "UNKNOWN" representing the GNSS Measurement's code type is unknown.
+ */
+ const String CODE_TYPE_UNKNOWN = "UNKNOWN";
+
+ /**
+ * The type of code that is currently being tracked in the GNSS signal.
+ *
+ * For high precision applications the type of code being tracked needs to be considered
+ * in-order to properly apply code specific corrections to the pseudorange measurements.
+ *
+ * The value is one of the constant Strings with prefix CODE_TYPE_ defined in this parcelable.
+ *
+ * This is used to specify the observation descriptor defined in GNSS Observation Data File
+ * Header Section Description in the RINEX standard (Version 3.XX). In RINEX Version 3.03,
+ * in Appendix Table A2 Attributes are listed as uppercase letters (for instance, "A" for
+ * "A channel"). In the future, if for instance a code "G" was added in the official RINEX
+ * standard, "G" could be specified here.
+ */
+ String codeType;
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index 2af57b5..c815e2d 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -17,9 +17,10 @@
package android.hardware.gnss;
import android.hardware.gnss.IGnssCallback;
+import android.hardware.gnss.IGnssConfiguration;
+import android.hardware.gnss.IGnssMeasurementInterface;
import android.hardware.gnss.IGnssPowerIndication;
import android.hardware.gnss.IGnssPsds;
-import android.hardware.gnss.IGnssConfiguration;
/**
* Represents the standard GNSS (Global Navigation Satellite System) interface.
@@ -33,14 +34,6 @@
*/
const int ERROR_INVALID_ARGUMENT = 1;
- /** Bit mask indicating a valid timestampNs is stored in the ElapsedRealtime parcelable. */
- const int ELAPSED_REALTIME_HAS_TIMESTAMP_NS = 1 << 0;
-
- /**
- * Bit mask indicating a valid timeUncertaintyNs is stored in the ElapsedRealtime parcelable.
- */
- const int ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS = 1 << 1;
-
/**
* Opens the interface and provides the callback routines to the implementation of this
* interface.
@@ -74,6 +67,8 @@
/**
* This method returns the IGnssPsds interface.
*
+ * This method must return non-null.
+ *
* @return Handle to the IGnssPsds interface.
*/
IGnssPsds getExtensionPsds();
@@ -81,13 +76,26 @@
/**
* This method returns the IGnssConfiguration interface.
*
+ * This method must return non-null.
+ *
* @return Handle to the IGnssConfiguration interface.
*/
IGnssConfiguration getExtensionGnssConfiguration();
/**
+ * This methods returns the IGnssMeasurementInterface interface.
+ *
+ * This method must return non-null.
+ *
+ * @return Handle to the IGnssMeasurementInterface interface.
+ */
+ IGnssMeasurementInterface getExtensionGnssMeasurement();
+
+ /**
* This method returns the IGnssPowerIndication interface.
*
+ * This method must return non-null.
+ *
* @return Handle to the IGnssPowerIndication interface.
*/
IGnssPowerIndication getExtensionGnssPowerIndication();
diff --git a/gnss/aidl/android/hardware/gnss/IGnssMeasurementCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssMeasurementCallback.aidl
new file mode 100644
index 0000000..328cf2a
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssMeasurementCallback.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 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 android.hardware.gnss;
+
+import android.hardware.gnss.GnssData;
+
+/**
+ * The callback interface to report GNSS Measurement from the HAL.
+ */
+@VintfStability
+interface IGnssMeasurementCallback {
+ /**
+ * Callback for the hal to pass a GnssData structure back to the client.
+ *
+ * @param data Contains a reading of GNSS measurements.
+ */
+ void gnssMeasurementCb(in GnssData data);
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl
new file mode 100644
index 0000000..fdeebde
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2020 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 android.hardware.gnss;
+
+import android.hardware.gnss.IGnssMeasurementCallback;
+
+/**
+ * Extended interface for GNSS Measurement support.
+ */
+@VintfStability
+interface IGnssMeasurementInterface {
+ /**
+ * Initializes the interface and registers the callback routines with the HAL. After a
+ * successful call to 'setCallback' the HAL must begin to provide updates at an average
+ * output rate of 1Hz (occasional intra-measurement time offsets in the range from 0-2000msec
+ * can be tolerated.)
+ *
+ * @param callback Handle to GnssMeasurement callback interface.
+ * @param enableFullTracking If true, GNSS chipset must switch off duty cycling. In such mode
+ * no clock discontinuities are expected and, when supported, carrier phase should be
+ * continuous in good signal conditions. All non-blocklisted, healthy constellations,
+ * satellites and frequency bands that the chipset supports must be reported in this mode.
+ * The GNSS chipset is allowed to consume more power in this mode. If false, API must
+ * optimize power via duty cycling, constellations and frequency limits, etc.
+ *
+ * @return initRet Returns SUCCESS if successful. Returns ERROR_ALREADY_INIT if a callback has
+ * already been registered without a corresponding call to 'close'. Returns ERROR_GENERIC
+ * for any other error. The HAL must not generate any other updates upon returning this
+ * error code.
+ */
+ void setCallback(in IGnssMeasurementCallback callback, in boolean enableFullTracking);
+
+ /**
+ * Stops updates from the HAL, and unregisters the callback routines. After a call to close(),
+ * the previously registered callbacks must be considered invalid by the HAL.
+ *
+ * If close() is invoked without a previous setCallback, this function must perform
+ * no work.
+ */
+ void close();
+}
\ No newline at end of file
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
index 23677ed..6694ce6 100644
--- a/gnss/aidl/default/Android.bp
+++ b/gnss/aidl/default/Android.bp
@@ -50,6 +50,7 @@
"GnssPowerIndication.cpp",
"GnssPsds.cpp",
"GnssConfiguration.cpp",
+ "GnssMeasurementInterface.cpp",
"service.cpp",
],
static_libs: [
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index 669372b..02bad60 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -19,6 +19,7 @@
#include "Gnss.h"
#include <log/log.h>
#include "GnssConfiguration.h"
+#include "GnssMeasurementInterface.h"
#include "GnssPowerIndication.h"
#include "GnssPsds.h"
@@ -74,4 +75,12 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus Gnss::getExtensionGnssMeasurement(
+ std::shared_ptr<IGnssMeasurementInterface>* iGnssMeasurement) {
+ ALOGD("Gnss::getExtensionGnssMeasurement");
+
+ *iGnssMeasurement = SharedRefBase::make<GnssMeasurementInterface>();
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index 9f6ef0e..bccc7f2 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -18,6 +18,7 @@
#include <aidl/android/hardware/gnss/BnGnss.h>
#include <aidl/android/hardware/gnss/BnGnssConfiguration.h>
+#include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h>
#include <aidl/android/hardware/gnss/BnGnssPowerIndication.h>
#include <aidl/android/hardware/gnss/BnGnssPsds.h>
#include "GnssConfiguration.h"
@@ -33,6 +34,8 @@
std::shared_ptr<IGnssConfiguration>* iGnssConfiguration) override;
ndk::ScopedAStatus getExtensionGnssPowerIndication(
std::shared_ptr<IGnssPowerIndication>* iGnssPowerIndication) override;
+ ndk::ScopedAStatus getExtensionGnssMeasurement(
+ std::shared_ptr<IGnssMeasurementInterface>* iGnssMeasurement) override;
std::shared_ptr<GnssConfiguration> mGnssConfiguration;
diff --git a/gnss/aidl/default/GnssConfiguration.h b/gnss/aidl/default/GnssConfiguration.h
index 25fa16e..491733c 100644
--- a/gnss/aidl/default/GnssConfiguration.h
+++ b/gnss/aidl/default/GnssConfiguration.h
@@ -24,8 +24,6 @@
namespace aidl::android::hardware::gnss {
-using android::hardware::gnss::GnssConstellationType;
-
struct BlocklistedSourceHash {
inline int operator()(const BlocklistedSource& source) const {
return int(source.constellation) * 1000 + int(source.svid);
@@ -42,7 +40,8 @@
using std::vector;
using BlocklistedSourceSet =
std::unordered_set<BlocklistedSource, BlocklistedSourceHash, BlocklistedSourceEqual>;
-using BlocklistedConstellationSet = std::unordered_set<GnssConstellationType>;
+using BlocklistedConstellationSet =
+ std::unordered_set<android::hardware::gnss::GnssConstellationType>;
struct GnssConfiguration : public BnGnssConfiguration {
public:
diff --git a/gnss/aidl/default/GnssHidlHal.cpp b/gnss/aidl/default/GnssHidlHal.cpp
index 11fc806..9529ec9 100644
--- a/gnss/aidl/default/GnssHidlHal.cpp
+++ b/gnss/aidl/default/GnssHidlHal.cpp
@@ -17,11 +17,10 @@
#define LOG_TAG "GnssHidlHal"
#include "GnssHidlHal.h"
-//#include <android/hardware/gnss/1.0/IGnssCallback.h>
namespace aidl::android::hardware::gnss {
-namespace V1_0 = ::android::hardware::gnss::V1_0;
+using GnssSvInfo = ::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo;
GnssHidlHal::GnssHidlHal(const std::shared_ptr<Gnss>& gnssAidl) : mGnssAidl(gnssAidl) {
Gnss* iGnss = mGnssAidl.get();
@@ -45,8 +44,8 @@
if (mGnssConfigurationAidl->isBlocklistedV2_1(gnssSvInfoList[i])) {
ALOGD("Blocklisted constellation: %d, svid: %d",
(int)gnssSvInfoList[i].v2_0.constellation, gnssSvInfoList[i].v2_0.v1_0.svid);
- gnssSvInfoList[i].v2_0.v1_0.svFlag &=
- ~static_cast<uint8_t>(V1_0::IGnssCallback::GnssSvFlags::USED_IN_FIX);
+ gnssSvInfoList[i].v2_0.v1_0.svFlag &= ~static_cast<uint8_t>(
+ ::android::hardware::gnss::V1_0::IGnssCallback::GnssSvFlags::USED_IN_FIX);
}
}
return gnssSvInfoList;
diff --git a/gnss/aidl/default/GnssHidlHal.h b/gnss/aidl/default/GnssHidlHal.h
index 50aad3a..93a79a1 100644
--- a/gnss/aidl/default/GnssHidlHal.h
+++ b/gnss/aidl/default/GnssHidlHal.h
@@ -22,16 +22,16 @@
namespace aidl::android::hardware::gnss {
-using ::android::hardware::gnss::common::implementation::GnssTemplate;
-using GnssSvInfo = ::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo;
-
-class GnssHidlHal : public GnssTemplate<::android::hardware::gnss::V2_1::IGnss> {
+class GnssHidlHal : public ::android::hardware::gnss::common::implementation::GnssTemplate<
+ ::android::hardware::gnss::V2_1::IGnss> {
public:
GnssHidlHal(const std::shared_ptr<Gnss>& gnssAidl);
private:
- hidl_vec<GnssSvInfo> filterBlocklistedSatellitesV2_1(
- hidl_vec<GnssSvInfo> gnssSvInfoList) override;
+ hidl_vec<::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo>
+ filterBlocklistedSatellitesV2_1(
+ hidl_vec<::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo> gnssSvInfoList)
+ override;
std::shared_ptr<Gnss> mGnssAidl;
std::shared_ptr<GnssConfiguration> mGnssConfigurationAidl;
diff --git a/gnss/aidl/default/GnssMeasurementInterface.cpp b/gnss/aidl/default/GnssMeasurementInterface.cpp
new file mode 100644
index 0000000..d726d95
--- /dev/null
+++ b/gnss/aidl/default/GnssMeasurementInterface.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssMeasIfaceAidl"
+
+#include "GnssMeasurementInterface.h"
+#include <aidl/android/hardware/gnss/BnGnss.h>
+#include <log/log.h>
+#include "Utils.h"
+
+namespace aidl::android::hardware::gnss {
+
+using Utils = ::android::hardware::gnss::common::Utils;
+
+std::shared_ptr<IGnssMeasurementCallback> GnssMeasurementInterface::sCallback = nullptr;
+
+GnssMeasurementInterface::GnssMeasurementInterface() : mMinIntervalMillis(1000) {}
+
+GnssMeasurementInterface::~GnssMeasurementInterface() {
+ stop();
+}
+
+ndk::ScopedAStatus GnssMeasurementInterface::setCallback(
+ const std::shared_ptr<IGnssMeasurementCallback>& callback, const bool enableFullTracking) {
+ ALOGD("setCallback: enableFullTracking: %d", (int)enableFullTracking);
+ std::unique_lock<std::mutex> lock(mMutex);
+ sCallback = callback;
+
+ if (mIsActive) {
+ ALOGW("GnssMeasurement callback already set. Resetting the callback...");
+ stop();
+ }
+ start();
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssMeasurementInterface::close() {
+ ALOGD("close");
+ stop();
+ std::unique_lock<std::mutex> lock(mMutex);
+ sCallback = nullptr;
+ return ndk::ScopedAStatus::ok();
+}
+
+void GnssMeasurementInterface::start() {
+ ALOGD("start");
+ mIsActive = true;
+ mThread = std::thread([this]() {
+ while (mIsActive == true) {
+ auto measurement = Utils::getMockMeasurement();
+ this->reportMeasurement(measurement);
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
+ }
+ });
+}
+
+void GnssMeasurementInterface::stop() {
+ ALOGD("stop");
+ mIsActive = false;
+ if (mThread.joinable()) {
+ mThread.join();
+ }
+}
+
+void GnssMeasurementInterface::reportMeasurement(const GnssData& data) {
+ ALOGD("reportMeasurement()");
+ std::unique_lock<std::mutex> lock(mMutex);
+ if (sCallback == nullptr) {
+ ALOGE("%s: GnssMeasurement::sCallback is null.", __func__);
+ return;
+ }
+ sCallback->gnssMeasurementCb(data);
+}
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssMeasurementInterface.h b/gnss/aidl/default/GnssMeasurementInterface.h
new file mode 100644
index 0000000..69cd871
--- /dev/null
+++ b/gnss/aidl/default/GnssMeasurementInterface.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/gnss/BnGnssMeasurementCallback.h>
+#include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h>
+#include <atomic>
+#include <mutex>
+#include <thread>
+
+namespace aidl::android::hardware::gnss {
+
+struct GnssMeasurementInterface : public BnGnssMeasurementInterface {
+ public:
+ GnssMeasurementInterface();
+ ~GnssMeasurementInterface();
+ ndk::ScopedAStatus setCallback(const std::shared_ptr<IGnssMeasurementCallback>& callback,
+ const bool enableFullTracking) override;
+ ndk::ScopedAStatus close() override;
+
+ private:
+ void start();
+ void stop();
+ void reportMeasurement(const GnssData&);
+
+ std::atomic<long> mMinIntervalMillis;
+ std::atomic<bool> mIsActive;
+ std::thread mThread;
+
+ // Guarded by mMutex
+ static std::shared_ptr<IGnssMeasurementCallback> sCallback;
+
+ // Synchronization lock for sCallback
+ mutable std::mutex mMutex;
+};
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssPowerIndication.cpp b/gnss/aidl/default/GnssPowerIndication.cpp
index 8ea60f3..429cc8c 100644
--- a/gnss/aidl/default/GnssPowerIndication.cpp
+++ b/gnss/aidl/default/GnssPowerIndication.cpp
@@ -19,6 +19,7 @@
#include "GnssPowerIndication.h"
#include <aidl/android/hardware/gnss/BnGnss.h>
#include <log/log.h>
+#include <utils/SystemClock.h>
namespace aidl::android::hardware::gnss {
@@ -43,10 +44,9 @@
std::unique_lock<std::mutex> lock(mMutex);
ElapsedRealtime elapsedRealtime = {
- .flags = IGnss::ELAPSED_REALTIME_HAS_TIMESTAMP_NS |
- IGnss::ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS,
- .timestampNs = (long)1323542,
- .timeUncertaintyNs = (long)1000,
+ .flags = ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS,
+ .timestampNs = ::android::elapsedRealtimeNano(),
+ .timeUncertaintyNs = 1000,
};
GnssPowerStats gnssPowerStats = {
.elapsedRealtime = elapsedRealtime,
diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp
index d102e7f..c10e809 100644
--- a/gnss/aidl/vts/Android.bp
+++ b/gnss/aidl/vts/Android.bp
@@ -22,6 +22,7 @@
"gnss_hal_test.cpp",
"gnss_hal_test_cases.cpp",
"GnssCallbackAidl.cpp",
+ "GnssMeasurementCallbackAidl.cpp",
"GnssPowerIndicationCallback.cpp",
"VtsHalGnssTargetTest.cpp",
],
diff --git a/gnss/aidl/vts/GnssMeasurementCallbackAidl.cpp b/gnss/aidl/vts/GnssMeasurementCallbackAidl.cpp
new file mode 100644
index 0000000..c4fad7f
--- /dev/null
+++ b/gnss/aidl/vts/GnssMeasurementCallbackAidl.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssMeasurementCallbackAidl"
+
+#include "GnssMeasurementCallbackAidl.h"
+#include <inttypes.h>
+#include <log/log.h>
+
+using android::hardware::gnss::GnssData;
+
+android::binder::Status GnssMeasurementCallbackAidl::gnssMeasurementCb(const GnssData& gnssData) {
+ ALOGI("gnssMeasurementCb");
+ ALOGI("elapsedRealtime: flags = %d, timestampNs: %" PRId64 ", timeUncertaintyNs=%lf",
+ gnssData.elapsedRealtime.flags, gnssData.elapsedRealtime.timestampNs,
+ gnssData.elapsedRealtime.timeUncertaintyNs);
+ for (const auto& measurement : gnssData.measurements) {
+ ALOGI("measurement.receivedSvTimeInNs=%" PRId64, measurement.receivedSvTimeInNs);
+ }
+ gnss_data_cbq_.store(gnssData);
+ return android::binder::Status::ok();
+}
diff --git a/gnss/aidl/vts/GnssMeasurementCallbackAidl.h b/gnss/aidl/vts/GnssMeasurementCallbackAidl.h
new file mode 100644
index 0000000..f6c79cf
--- /dev/null
+++ b/gnss/aidl/vts/GnssMeasurementCallbackAidl.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/BnGnssMeasurementCallback.h>
+#include "GnssCallbackEventQueue.h"
+
+/** Implementation for IGnssMeasurementCallback. */
+class GnssMeasurementCallbackAidl : public android::hardware::gnss::BnGnssMeasurementCallback {
+ public:
+ GnssMeasurementCallbackAidl() : gnss_data_cbq_("gnss_data") {}
+ ~GnssMeasurementCallbackAidl() {}
+
+ android::binder::Status gnssMeasurementCb(
+ const android::hardware::gnss::GnssData& gnssData) override;
+
+ android::hardware::gnss::common::GnssCallbackEventQueue<android::hardware::gnss::GnssData>
+ gnss_data_cbq_;
+};
diff --git a/gnss/aidl/vts/GnssPowerIndicationCallback.h b/gnss/aidl/vts/GnssPowerIndicationCallback.h
index d4c4539..3416f17 100644
--- a/gnss/aidl/vts/GnssPowerIndicationCallback.h
+++ b/gnss/aidl/vts/GnssPowerIndicationCallback.h
@@ -25,7 +25,6 @@
public:
GnssPowerIndicationCallback()
: capabilities_cbq_("capabilities"),
- other_mode_names_cbq_("other_mode_names"),
gnss_power_stats_cbq_("gnss_power_stats") {}
~GnssPowerIndicationCallback() {}
@@ -35,9 +34,6 @@
android::hardware::gnss::common::GnssCallbackEventQueue<int> capabilities_cbq_;
int last_capabilities_;
- android::hardware::gnss::common::GnssCallbackEventQueue<std::vector<std::string>>
- other_mode_names_cbq_;
- std::vector<std::string> last_other_mode_names_;
android::hardware::gnss::common::GnssCallbackEventQueue<android::hardware::gnss::GnssPowerStats>
gnss_power_stats_cbq_;
android::hardware::gnss::GnssPowerStats last_gnss_power_stats_;
diff --git a/gnss/aidl/vts/gnss_hal_test.h b/gnss/aidl/vts/gnss_hal_test.h
index eb5301e..f72f7fe 100644
--- a/gnss/aidl/vts/gnss_hal_test.h
+++ b/gnss/aidl/vts/gnss_hal_test.h
@@ -36,7 +36,7 @@
using android::hardware::gnss::IGnssConfiguration;
// The main test class for GNSS HAL.
-class GnssHalTest : public GnssHalTestTemplate<IGnss_V2_1> {
+class GnssHalTest : public android::hardware::gnss::common::GnssHalTestTemplate<IGnss_V2_1> {
public:
GnssHalTest(){};
~GnssHalTest(){};
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index 4e8d0bd..857c742 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -16,19 +16,30 @@
#define LOG_TAG "GnssHalTestCases"
+#include <android/hardware/gnss/IGnss.h>
+#include <android/hardware/gnss/IGnssMeasurementCallback.h>
+#include <android/hardware/gnss/IGnssMeasurementInterface.h>
#include <android/hardware/gnss/IGnssPowerIndication.h>
#include <android/hardware/gnss/IGnssPsds.h>
+#include "GnssMeasurementCallbackAidl.h"
#include "GnssPowerIndicationCallback.h"
#include "gnss_hal_test.h"
using android::sp;
using android::hardware::gnss::BlocklistedSource;
-using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType;
+using android::hardware::gnss::ElapsedRealtime;
+using android::hardware::gnss::GnssClock;
+using android::hardware::gnss::GnssMeasurement;
+using android::hardware::gnss::IGnss;
using android::hardware::gnss::IGnssConfiguration;
+using android::hardware::gnss::IGnssMeasurementCallback;
+using android::hardware::gnss::IGnssMeasurementInterface;
using android::hardware::gnss::IGnssPowerIndication;
using android::hardware::gnss::IGnssPsds;
using android::hardware::gnss::PsdsType;
+using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType;
+
/*
* SetupTeardownCreateCleanup:
* Requests the gnss HAL then calls cleanup
@@ -53,6 +64,62 @@
}
/*
+ * TestGnssMeasurementExtension:
+ * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension.
+ * 2. Sets a GnssMeasurementCallback, waits for a measurement, and verifies fields are valid.
+ */
+TEST_P(GnssHalTest, TestGnssMeasurementExtension) {
+ const int kFirstGnssMeasurementTimeoutSeconds = 10;
+ sp<IGnssMeasurementInterface> iGnssMeasurement;
+ auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(iGnssMeasurement != nullptr);
+
+ auto callback = sp<GnssMeasurementCallbackAidl>::make();
+ status = iGnssMeasurement->setCallback(callback, /* enableFullTracking= */ true);
+ ASSERT_TRUE(status.isOk());
+
+ android::hardware::gnss::GnssData lastMeasurement;
+ ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastMeasurement,
+ kFirstGnssMeasurementTimeoutSeconds));
+ EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), 1);
+ ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
+
+ // Validity check GnssData fields
+ ASSERT_TRUE(
+ lastMeasurement.elapsedRealtime.flags >= 0 &&
+ lastMeasurement.elapsedRealtime.flags <=
+ (ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS));
+ if (lastMeasurement.elapsedRealtime.flags & ElapsedRealtime::HAS_TIMESTAMP_NS) {
+ ASSERT_TRUE(lastMeasurement.elapsedRealtime.timestampNs > 0);
+ }
+ if (lastMeasurement.elapsedRealtime.flags & ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS) {
+ ASSERT_TRUE(lastMeasurement.elapsedRealtime.timeUncertaintyNs > 0);
+ }
+ ASSERT_TRUE(lastMeasurement.clock.gnssClockFlags >= 0 &&
+ lastMeasurement.clock.gnssClockFlags <=
+ (GnssClock::HAS_LEAP_SECOND | GnssClock::HAS_TIME_UNCERTAINTY |
+ GnssClock::HAS_FULL_BIAS | GnssClock::HAS_BIAS |
+ GnssClock::HAS_BIAS_UNCERTAINTY | GnssClock::HAS_DRIFT |
+ GnssClock::HAS_DRIFT_UNCERTAINTY));
+ for (const auto& measurement : lastMeasurement.measurements) {
+ ASSERT_TRUE(
+ measurement.flags >= 0 &&
+ measurement.flags <=
+ (GnssMeasurement::HAS_SNR | GnssMeasurement::HAS_CARRIER_FREQUENCY |
+ GnssMeasurement::HAS_CARRIER_CYCLES | GnssMeasurement::HAS_CARRIER_PHASE |
+ GnssMeasurement::HAS_CARRIER_PHASE_UNCERTAINTY |
+ GnssMeasurement::HAS_AUTOMATIC_GAIN_CONTROL |
+ GnssMeasurement::HAS_FULL_ISB | GnssMeasurement::HAS_FULL_ISB_UNCERTAINTY |
+ GnssMeasurement::HAS_SATELLITE_ISB |
+ GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY));
+ }
+
+ status = iGnssMeasurement->close();
+ ASSERT_TRUE(status.isOk());
+}
+
+/*
* TestGnssPowerIndication
* 1. Gets the GnssPowerIndicationExtension.
* 2. Sets a GnssPowerIndicationCallback.
diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp
index 730de4b..be1d532 100644
--- a/gnss/common/utils/default/Android.bp
+++ b/gnss/common/utils/default/Android.bp
@@ -42,5 +42,6 @@
"android.hardware.gnss@2.1",
"android.hardware.gnss.measurement_corrections@1.1",
"android.hardware.gnss.measurement_corrections@1.0",
+ "android.hardware.gnss-ndk_platform",
],
}
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index d336f1b..dd932d4 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -17,6 +17,7 @@
#include <Constants.h>
#include <MockLocation.h>
#include <Utils.h>
+#include <aidl/android/hardware/gnss/BnGnss.h>
#include <utils/SystemClock.h>
namespace android {
@@ -24,16 +25,28 @@
namespace gnss {
namespace common {
+using IGnss = aidl::android::hardware::gnss::IGnss;
+using IGnssMeasurementCallback = aidl::android::hardware::gnss::IGnssMeasurementCallback;
+using GnssMeasurement = aidl::android::hardware::gnss::GnssMeasurement;
using GnssSvFlags = V1_0::IGnssCallback::GnssSvFlags;
using GnssMeasurementFlagsV1_0 = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags;
using GnssMeasurementFlagsV2_1 = V2_1::IGnssMeasurementCallback::GnssMeasurementFlags;
using GnssMeasurementStateV2_0 = V2_0::IGnssMeasurementCallback::GnssMeasurementState;
-using ElapsedRealtime = V2_0::ElapsedRealtime;
+using ElapsedRealtime = aidl::android::hardware::gnss::ElapsedRealtime;
using ElapsedRealtimeFlags = V2_0::ElapsedRealtimeFlags;
using GnssConstellationTypeV2_0 = V2_0::GnssConstellationType;
using IGnssMeasurementCallbackV2_0 = V2_0::IGnssMeasurementCallback;
using GnssSignalType = V2_1::GnssSignalType;
+using GnssDataV2_0 = V2_0::IGnssMeasurementCallback::GnssData;
+using GnssDataV2_1 = V2_1::IGnssMeasurementCallback::GnssData;
+using GnssSvInfoV1_0 = V1_0::IGnssCallback::GnssSvInfo;
+using GnssSvInfoV2_0 = V2_0::IGnssCallback::GnssSvInfo;
+using GnssSvInfoV2_1 = V2_1::IGnssCallback::GnssSvInfo;
+using GnssAntennaInfo = ::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo;
+using Row = V2_1::IGnssAntennaInfoCallback::Row;
+using Coord = V2_1::IGnssAntennaInfoCallback::Coord;
+
GnssDataV2_1 Utils::getMockMeasurementV2_1() {
GnssDataV2_0 gnssDataV2_0 = Utils::getMockMeasurementV2_0();
V2_1::IGnssMeasurementCallback::GnssMeasurement gnssMeasurementV2_1 = {
@@ -110,7 +123,7 @@
.driftUncertaintyNsps = 310.64968328491528,
.hwClockDiscontinuityCount = 1};
- ElapsedRealtime timestamp = {
+ V2_0::ElapsedRealtime timestamp = {
.flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
.timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
@@ -124,6 +137,52 @@
return gnssData;
}
+aidl::android::hardware::gnss::GnssData Utils::getMockMeasurement() {
+ aidl::android::hardware::gnss::GnssSignalType signalType = {
+ .constellation = aidl::android::hardware::gnss::GnssConstellationType::GLONASS,
+ .carrierFrequencyHz = 1.59975e+09,
+ .codeType = aidl::android::hardware::gnss::GnssSignalType::CODE_TYPE_C,
+ };
+ aidl::android::hardware::gnss::GnssMeasurement measurement = {
+ .flags = GnssMeasurement::HAS_CARRIER_FREQUENCY,
+ .svid = 6,
+ .signalType = signalType,
+ .timeOffsetNs = 0.0,
+ .receivedSvTimeInNs = 8195997131077,
+ .receivedSvTimeUncertaintyInNs = 15,
+ .antennaCN0DbHz = 30.0,
+ .pseudorangeRateMps = -484.13739013671875,
+ .pseudorangeRateUncertaintyMps = 1.0379999876022339,
+ .accumulatedDeltaRangeState = GnssMeasurement::ADR_STATE_UNKNOWN,
+ .accumulatedDeltaRangeM = 0.0,
+ .accumulatedDeltaRangeUncertaintyM = 0.0,
+ .multipathIndicator = aidl::android::hardware::gnss::GnssMultipathIndicator::UNKNOWN,
+ .state = GnssMeasurement::STATE_CODE_LOCK | GnssMeasurement::STATE_BIT_SYNC |
+ GnssMeasurement::STATE_SUBFRAME_SYNC | GnssMeasurement::STATE_TOW_DECODED |
+ GnssMeasurement::STATE_GLO_STRING_SYNC |
+ GnssMeasurement::STATE_GLO_TOD_DECODED};
+
+ aidl::android::hardware::gnss::GnssClock clock = {.timeNs = 2713545000000,
+ .fullBiasNs = -1226701900521857520,
+ .biasNs = 0.59689998626708984,
+ .biasUncertaintyNs = 47514.989972114563,
+ .driftNsps = -51.757811607455452,
+ .driftUncertaintyNsps = 310.64968328491528,
+ .hwClockDiscontinuityCount = 1};
+
+ ElapsedRealtime timestamp = {
+ .flags = ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS,
+ .timestampNs = ::android::elapsedRealtimeNano(),
+ // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
+ // In an actual implementation provide an estimate of the synchronization uncertainty
+ // or don't set the field.
+ .timeUncertaintyNs = 1000000};
+
+ aidl::android::hardware::gnss::GnssData gnssData = {
+ .measurements = {measurement}, .clock = clock, .elapsedRealtime = timestamp};
+ return gnssData;
+}
+
V2_0::GnssLocation Utils::getMockLocationV2_0() {
const V2_0::ElapsedRealtime timestamp = {
.flags = V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
diff --git a/gnss/common/utils/default/include/NmeaFixInfo.h b/gnss/common/utils/default/include/NmeaFixInfo.h
index fb2c1a4..06eae7e 100644
--- a/gnss/common/utils/default/include/NmeaFixInfo.h
+++ b/gnss/common/utils/default/include/NmeaFixInfo.h
@@ -26,11 +26,6 @@
namespace hardware {
namespace gnss {
namespace common {
-using ::android::sp;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
constexpr char GPGA_RECORD_TAG[] = "$GPGGA";
constexpr char GPRMC_RECORD_TAG[] = "$GPRMC";
diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h
index d9ad5a5..0ca1b00 100644
--- a/gnss/common/utils/default/include/Utils.h
+++ b/gnss/common/utils/default/include/Utils.h
@@ -17,6 +17,7 @@
#ifndef android_hardware_gnss_common_default_Utils_H_
#define android_hardware_gnss_common_default_Utils_H_
+#include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h>
#include <android/hardware/gnss/1.0/IGnss.h>
#include <android/hardware/gnss/2.0/IGnss.h>
#include <android/hardware/gnss/2.1/IGnss.h>
@@ -28,28 +29,22 @@
namespace gnss {
namespace common {
-using GnssDataV2_0 = V2_0::IGnssMeasurementCallback::GnssData;
-using GnssDataV2_1 = V2_1::IGnssMeasurementCallback::GnssData;
-using GnssSvInfoV1_0 = V1_0::IGnssCallback::GnssSvInfo;
-using GnssSvInfoV2_0 = V2_0::IGnssCallback::GnssSvInfo;
-using GnssSvInfoV2_1 = V2_1::IGnssCallback::GnssSvInfo;
-using GnssAntennaInfo = ::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo;
-using Row = ::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::Row;
-using Coord = ::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::Coord;
-
struct Utils {
- static GnssDataV2_0 getMockMeasurementV2_0();
- static GnssDataV2_1 getMockMeasurementV2_1();
+ static aidl::android::hardware::gnss::GnssData getMockMeasurement();
+ static V2_0::IGnssMeasurementCallback::GnssData getMockMeasurementV2_0();
+ static V2_1::IGnssMeasurementCallback::GnssData getMockMeasurementV2_1();
static V2_0::GnssLocation getMockLocationV2_0();
static V1_0::GnssLocation getMockLocationV1_0();
- static hidl_vec<GnssSvInfoV2_1> getMockSvInfoListV2_1();
- static GnssSvInfoV2_1 getMockSvInfoV2_1(GnssSvInfoV2_0 gnssSvInfoV2_0, float basebandCN0DbHz);
- static GnssSvInfoV2_0 getMockSvInfoV2_0(GnssSvInfoV1_0 gnssSvInfoV1_0,
- V2_0::GnssConstellationType type);
- static GnssSvInfoV1_0 getMockSvInfoV1_0(int16_t svid, V1_0::GnssConstellationType type,
- float cN0DbHz, float elevationDegrees,
- float azimuthDegrees);
- static hidl_vec<GnssAntennaInfo> getMockAntennaInfos();
+ static hidl_vec<V2_1::IGnssCallback::GnssSvInfo> getMockSvInfoListV2_1();
+ static V2_1::IGnssCallback::GnssSvInfo getMockSvInfoV2_1(
+ V2_0::IGnssCallback::GnssSvInfo gnssSvInfoV2_0, float basebandCN0DbHz);
+ static V2_0::IGnssCallback::GnssSvInfo getMockSvInfoV2_0(
+ V1_0::IGnssCallback::GnssSvInfo gnssSvInfoV1_0, V2_0::GnssConstellationType type);
+ static V1_0::IGnssCallback::GnssSvInfo getMockSvInfoV1_0(int16_t svid,
+ V1_0::GnssConstellationType type,
+ float cN0DbHz, float elevationDegrees,
+ float azimuthDegrees);
+ static hidl_vec<V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo> getMockAntennaInfos();
};
} // namespace common
diff --git a/gnss/common/utils/default/include/v2_1/GnssAntennaInfo.h b/gnss/common/utils/default/include/v2_1/GnssAntennaInfo.h
index e74ff54..a232499 100644
--- a/gnss/common/utils/default/include/v2_1/GnssAntennaInfo.h
+++ b/gnss/common/utils/default/include/v2_1/GnssAntennaInfo.h
@@ -23,29 +23,25 @@
namespace android::hardware::gnss::V2_1::implementation {
-using ::android::sp;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using IGnssAntennaInfo = ::android::hardware::gnss::V2_1::IGnssAntennaInfo;
-using IGnssAntennaInfoCallback = ::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback;
-
-struct GnssAntennaInfo : public IGnssAntennaInfo {
+struct GnssAntennaInfo : public ::android::hardware::gnss::V2_1::IGnssAntennaInfo {
GnssAntennaInfo();
~GnssAntennaInfo();
// Methods from ::android::hardware::gnss::V2_1::IGnssAntennaInfo follow.
Return<GnssAntennaInfoStatus> setCallback(
- const sp<IGnssAntennaInfoCallback>& callback) override;
+ const sp<::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback>& callback) override;
Return<void> close() override;
private:
void start();
void stop();
void reportAntennaInfo(
- const hidl_vec<IGnssAntennaInfoCallback::GnssAntennaInfo>& antennaInfo) const;
+ const hidl_vec<
+ ::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo>&
+ antennaInfo) const;
// Guarded by mMutex
- static sp<IGnssAntennaInfoCallback> sCallback;
+ static sp<::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback> sCallback;
std::atomic<long> mMinIntervalMillis;
std::atomic<bool> mIsActive;
diff --git a/gnss/common/utils/default/include/v2_1/GnssConfiguration.h b/gnss/common/utils/default/include/v2_1/GnssConfiguration.h
index 8463a5c..2cfb38f 100644
--- a/gnss/common/utils/default/include/v2_1/GnssConfiguration.h
+++ b/gnss/common/utils/default/include/v2_1/GnssConfiguration.h
@@ -25,35 +25,27 @@
namespace android::hardware::gnss::V2_1::implementation {
-using ::android::sp;
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-
-using BlacklistedSourceV2_1 =
- ::android::hardware::gnss::V2_1::IGnssConfiguration::BlacklistedSource;
-using GnssConstellationTypeV2_0 = V2_0::GnssConstellationType;
-using GnssSvInfoV2_1 = V2_1::IGnssCallback::GnssSvInfo;
-
struct BlacklistedSourceHashV2_1 {
- inline int operator()(const BlacklistedSourceV2_1& source) const {
+ inline int operator()(
+ const ::android::hardware::gnss::V2_1::IGnssConfiguration::BlacklistedSource& source)
+ const {
return int(source.constellation) * 1000 + int(source.svid);
}
};
struct BlacklistedSourceEqualV2_1 {
- inline bool operator()(const BlacklistedSourceV2_1& s1, const BlacklistedSourceV2_1& s2) const {
+ inline bool operator()(
+ const ::android::hardware::gnss::V2_1::IGnssConfiguration::BlacklistedSource& s1,
+ const ::android::hardware::gnss::V2_1::IGnssConfiguration::BlacklistedSource& s2)
+ const {
return (s1.constellation == s2.constellation) && (s1.svid == s2.svid);
}
};
using BlacklistedSourceSetV2_1 =
- std::unordered_set<BlacklistedSourceV2_1, BlacklistedSourceHashV2_1,
- BlacklistedSourceEqualV2_1>;
-using BlacklistedConstellationSetV2_1 = std::unordered_set<GnssConstellationTypeV2_0>;
+ std::unordered_set<::android::hardware::gnss::V2_1::IGnssConfiguration::BlacklistedSource,
+ BlacklistedSourceHashV2_1, BlacklistedSourceEqualV2_1>;
+using BlacklistedConstellationSetV2_1 = std::unordered_set<V2_0::GnssConstellationType>;
struct GnssConfiguration : public IGnssConfiguration {
// Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
@@ -78,7 +70,7 @@
Return<bool> setBlacklist_2_1(
const hidl_vec<V2_1::IGnssConfiguration::BlacklistedSource>& blacklist) override;
- Return<bool> isBlacklistedV2_1(const GnssSvInfoV2_1& gnssSvInfo) const;
+ Return<bool> isBlacklistedV2_1(const V2_1::IGnssCallback::GnssSvInfo& gnssSvInfo) const;
private:
mutable std::recursive_mutex mMutex;
diff --git a/gnss/common/utils/default/include/v2_1/GnssDebug.h b/gnss/common/utils/default/include/v2_1/GnssDebug.h
index 8580989..481de59 100644
--- a/gnss/common/utils/default/include/v2_1/GnssDebug.h
+++ b/gnss/common/utils/default/include/v2_1/GnssDebug.h
@@ -21,15 +21,8 @@
namespace android::hardware::gnss::V1_1::implementation {
-using ::android::sp;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using V1_0::IGnssDebug;
-
/* Interface for GNSS Debug support. */
-struct GnssDebug : public IGnssDebug {
+struct GnssDebug : public V1_0::IGnssDebug {
/*
* Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow.
* These declarations were generated from IGnssDebug.hal.
diff --git a/gnss/common/utils/default/include/v2_1/GnssMeasurement.h b/gnss/common/utils/default/include/v2_1/GnssMeasurement.h
index 1d1fc9d..db8407b 100644
--- a/gnss/common/utils/default/include/v2_1/GnssMeasurement.h
+++ b/gnss/common/utils/default/include/v2_1/GnssMeasurement.h
@@ -25,17 +25,6 @@
namespace android::hardware::gnss::V2_1::implementation {
-using GnssDataV2_1 = V2_1::IGnssMeasurementCallback::GnssData;
-using GnssDataV2_0 = V2_0::IGnssMeasurementCallback::GnssData;
-
-using ::android::sp;
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-
struct GnssMeasurement : public IGnssMeasurement {
GnssMeasurement();
~GnssMeasurement();
@@ -59,8 +48,8 @@
private:
void start();
void stop();
- void reportMeasurement(const GnssDataV2_0&);
- void reportMeasurement(const GnssDataV2_1&);
+ void reportMeasurement(const V2_0::IGnssMeasurementCallback::GnssData&);
+ void reportMeasurement(const V2_1::IGnssMeasurementCallback::GnssData&);
// Guarded by mMutex
static sp<V2_1::IGnssMeasurementCallback> sCallback_2_1;
diff --git a/gnss/common/utils/default/include/v2_1/GnssMeasurementCorrections.h b/gnss/common/utils/default/include/v2_1/GnssMeasurementCorrections.h
index eaa7659..54045ad 100644
--- a/gnss/common/utils/default/include/v2_1/GnssMeasurementCorrections.h
+++ b/gnss/common/utils/default/include/v2_1/GnssMeasurementCorrections.h
@@ -22,9 +22,6 @@
namespace android::hardware::gnss::measurement_corrections::V1_1::implementation {
-using ::android::sp;
-using ::android::hardware::Return;
-
struct GnssMeasurementCorrections : public IMeasurementCorrections {
GnssMeasurementCorrections();
~GnssMeasurementCorrections();
diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
index 4d1baa7..4d4ec93 100644
--- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h
+++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
@@ -39,16 +39,6 @@
namespace android::hardware::gnss::common::implementation {
-using GnssSvInfo = V2_1::IGnssCallback::GnssSvInfo;
-
-using common::NmeaFixInfo;
-using common::Utils;
-using measurement_corrections::V1_1::implementation::GnssMeasurementCorrections;
-
-using V2_1::implementation::GnssAntennaInfo;
-using V2_1::implementation::GnssConfiguration;
-using V2_1::implementation::GnssMeasurement;
-
constexpr int INPUT_BUFFER_SIZE = 128;
constexpr char CMD_GET_LOCATION[] = "CMD_GET_LOCATION";
constexpr char GNSS_PATH[] = "/dev/gnss0";
@@ -120,7 +110,7 @@
std::unique_ptr<V2_0::GnssLocation> getLocationFromHW();
void reportLocation(const V2_0::GnssLocation&) const;
void reportLocation(const V1_0::GnssLocation&) const;
- void reportSvStatus(const hidl_vec<GnssSvInfo>&) const;
+ void reportSvStatus(const hidl_vec<V2_1::IGnssCallback::GnssSvInfo>&) const;
Return<void> help(const hidl_handle& fd);
Return<void> setLocation(const hidl_handle& fd, const hidl_vec<hidl_string>& options);
@@ -131,15 +121,15 @@
static sp<V1_0::IGnssCallback> sGnssCallback_1_0;
std::atomic<long> mMinIntervalMs;
- sp<GnssConfiguration> mGnssConfiguration;
+ sp<V2_1::implementation::GnssConfiguration> mGnssConfiguration;
std::atomic<bool> mIsActive;
std::atomic<bool> mHardwareModeChecked;
std::atomic<int> mGnssFd;
std::thread mThread;
mutable std::mutex mMutex;
- virtual hidl_vec<GnssSvInfo> filterBlocklistedSatellitesV2_1(
- hidl_vec<GnssSvInfo> gnssSvInfoList);
+ virtual hidl_vec<V2_1::IGnssCallback::GnssSvInfo> filterBlocklistedSatellitesV2_1(
+ hidl_vec<V2_1::IGnssCallback::GnssSvInfo> gnssSvInfoList);
};
template <class T_IGnss>
@@ -154,7 +144,7 @@
template <class T_IGnss>
GnssTemplate<T_IGnss>::GnssTemplate()
: mMinIntervalMs(1000),
- mGnssConfiguration{new GnssConfiguration()},
+ mGnssConfiguration{new V2_1::implementation::GnssConfiguration()},
mHardwareModeChecked(false),
mGnssFd(-1) {}
@@ -237,8 +227,8 @@
}
template <class T_IGnss>
-hidl_vec<GnssSvInfo> GnssTemplate<T_IGnss>::filterBlocklistedSatellitesV2_1(
- hidl_vec<GnssSvInfo> gnssSvInfoList) {
+hidl_vec<V2_1::IGnssCallback::GnssSvInfo> GnssTemplate<T_IGnss>::filterBlocklistedSatellitesV2_1(
+ hidl_vec<V2_1::IGnssCallback::GnssSvInfo> gnssSvInfoList) {
ALOGD("filterBlocklistedSatellitesV2_1");
for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
if (mGnssConfiguration->isBlacklistedV2_1(gnssSvInfoList[i])) {
@@ -348,7 +338,7 @@
template <class T_IGnss>
Return<sp<V1_0::IGnssMeasurement>> GnssTemplate<T_IGnss>::getExtensionGnssMeasurement() {
ALOGD("Gnss::getExtensionGnssMeasurement");
- return new GnssMeasurement();
+ return new V2_1::implementation::GnssMeasurement();
}
template <class T_IGnss>
@@ -501,14 +491,14 @@
template <class T_IGnss>
Return<sp<V2_0::IGnssMeasurement>> GnssTemplate<T_IGnss>::getExtensionGnssMeasurement_2_0() {
ALOGD("Gnss::getExtensionGnssMeasurement_2_0");
- return new GnssMeasurement();
+ return new V2_1::implementation::GnssMeasurement();
}
template <class T_IGnss>
Return<sp<measurement_corrections::V1_0::IMeasurementCorrections>>
GnssTemplate<T_IGnss>::getExtensionMeasurementCorrections() {
ALOGD("Gnss::getExtensionMeasurementCorrections()");
- return new GnssMeasurementCorrections();
+ return new measurement_corrections::V1_1::implementation::GnssMeasurementCorrections();
}
template <class T_IGnss>
@@ -569,7 +559,7 @@
template <class T_IGnss>
Return<sp<V2_1::IGnssMeasurement>> GnssTemplate<T_IGnss>::getExtensionGnssMeasurement_2_1() {
ALOGD("Gnss::getExtensionGnssMeasurement_2_1");
- return new GnssMeasurement();
+ return new V2_1::implementation::GnssMeasurement();
}
template <class T_IGnss>
@@ -582,17 +572,18 @@
Return<sp<measurement_corrections::V1_1::IMeasurementCorrections>>
GnssTemplate<T_IGnss>::getExtensionMeasurementCorrections_1_1() {
ALOGD("Gnss::getExtensionMeasurementCorrections_1_1()");
- return new GnssMeasurementCorrections();
+ return new measurement_corrections::V1_1::implementation::GnssMeasurementCorrections();
}
template <class T_IGnss>
Return<sp<V2_1::IGnssAntennaInfo>> GnssTemplate<T_IGnss>::getExtensionGnssAntennaInfo() {
ALOGD("Gnss::getExtensionGnssAntennaInfo");
- return new GnssAntennaInfo();
+ return new V2_1::implementation::GnssAntennaInfo();
}
template <class T_IGnss>
-void GnssTemplate<T_IGnss>::reportSvStatus(const hidl_vec<GnssSvInfo>& svInfoList) const {
+void GnssTemplate<T_IGnss>::reportSvStatus(
+ const hidl_vec<V2_1::IGnssCallback::GnssSvInfo>& svInfoList) const {
std::unique_lock<std::mutex> lock(mMutex);
// TODO(skz): update this to call 2_0 callback if non-null
if (sGnssCallback_2_1 == nullptr) {
diff --git a/gnss/common/utils/default/v2_1/GnssConfiguration.cpp b/gnss/common/utils/default/v2_1/GnssConfiguration.cpp
index 8b30701..be974bc 100644
--- a/gnss/common/utils/default/v2_1/GnssConfiguration.cpp
+++ b/gnss/common/utils/default/v2_1/GnssConfiguration.cpp
@@ -21,6 +21,9 @@
namespace android::hardware::gnss::V2_1::implementation {
+using GnssSvInfoV2_1 = V2_1::IGnssCallback::GnssSvInfo;
+using BlacklistedSourceV2_1 = V2_1::IGnssConfiguration::BlacklistedSource;
+
// Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
Return<bool> GnssConfiguration::setSuplEs(bool enable) {
ALOGD("setSuplEs enable: %d", enable);
@@ -69,7 +72,7 @@
// Methods from ::android::hardware::gnss::V2_1::IGnssConfiguration follow.
Return<bool> GnssConfiguration::setBlacklist_2_1(
- const hidl_vec<V2_1::IGnssConfiguration::BlacklistedSource>& sourceList) {
+ const hidl_vec<BlacklistedSourceV2_1>& sourceList) {
std::unique_lock<std::recursive_mutex> lock(mMutex);
mBlacklistedConstellationSet.clear();
mBlacklistedSourceSet.clear();
diff --git a/gnss/common/utils/default/v2_1/GnssMeasurement.cpp b/gnss/common/utils/default/v2_1/GnssMeasurement.cpp
index 7d3a002..887cb5a 100644
--- a/gnss/common/utils/default/v2_1/GnssMeasurement.cpp
+++ b/gnss/common/utils/default/v2_1/GnssMeasurement.cpp
@@ -114,7 +114,7 @@
}
}
-void GnssMeasurement::reportMeasurement(const GnssDataV2_0& data) {
+void GnssMeasurement::reportMeasurement(const V2_0::IGnssMeasurementCallback::GnssData& data) {
ALOGD("reportMeasurement()");
std::unique_lock<std::mutex> lock(mMutex);
if (sCallback_2_0 == nullptr) {
@@ -127,7 +127,7 @@
}
}
-void GnssMeasurement::reportMeasurement(const GnssDataV2_1& data) {
+void GnssMeasurement::reportMeasurement(const V2_1::IGnssMeasurementCallback::GnssData& data) {
ALOGD("reportMeasurement()");
std::unique_lock<std::mutex> lock(mMutex);
if (sCallback_2_1 == nullptr) {
diff --git a/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h b/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h
index 1439158..fec3503 100644
--- a/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h
+++ b/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h
@@ -23,36 +23,10 @@
#include <gtest/gtest.h>
#include <chrono>
-using ::android::hardware::gnss::common::Utils;
-
-using android::hardware::hidl_vec;
-using android::hardware::Return;
-using android::hardware::Void;
-
-using android::hardware::gnss::common::GnssCallback;
-using android::hardware::gnss::common::GnssCallbackEventQueue;
-using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrectionsCallback;
-using android::hardware::gnss::V1_0::GnssLocationFlags;
-using android::hardware::gnss::V2_0::GnssConstellationType;
-using android::hardware::gnss::V2_1::IGnssAntennaInfo;
-using android::hardware::gnss::V2_1::IGnssAntennaInfoCallback;
-
-using GnssLocation_1_0 = android::hardware::gnss::V1_0::GnssLocation;
-using GnssLocation_2_0 = android::hardware::gnss::V2_0::GnssLocation;
-
-using IGnssCallback_1_0 = android::hardware::gnss::V1_0::IGnssCallback;
-using IGnssCallback_2_0 = android::hardware::gnss::V2_0::IGnssCallback;
-using IGnssCallback_2_1 = android::hardware::gnss::V2_1::IGnssCallback;
-
-using IGnssMeasurementCallback_1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
-using IGnssMeasurementCallback_1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback;
-using IGnssMeasurementCallback_2_0 = android::hardware::gnss::V2_0::IGnssMeasurementCallback;
-using IGnssMeasurementCallback_2_1 = android::hardware::gnss::V2_1::IGnssMeasurementCallback;
-
-using android::sp;
-
#define TIMEOUT_SEC 2 // for basic commands/responses
+namespace android::hardware::gnss::common {
+
// The main test class for GNSS HAL.
template <class T_IGnss>
class GnssHalTestTemplate : public testing::TestWithParam<std::string> {
@@ -62,34 +36,37 @@
virtual void TearDown() override;
/* Callback class for GnssMeasurement. */
- class GnssMeasurementCallback : public IGnssMeasurementCallback_2_1 {
+ class GnssMeasurementCallback : public V2_1::IGnssMeasurementCallback {
public:
- GnssCallbackEventQueue<IGnssMeasurementCallback_2_1::GnssData> measurement_cbq_;
+ GnssCallbackEventQueue<V2_1::IGnssMeasurementCallback::GnssData> measurement_cbq_;
GnssMeasurementCallback() : measurement_cbq_("measurement"){};
virtual ~GnssMeasurementCallback() = default;
// Methods from V1_0::IGnssMeasurementCallback follow.
- Return<void> GnssMeasurementCb(const IGnssMeasurementCallback_1_0::GnssData&) override {
+ Return<void> GnssMeasurementCb(const V1_0::IGnssMeasurementCallback::GnssData&) override {
return Void();
}
// Methods from V1_1::IGnssMeasurementCallback follow.
- Return<void> gnssMeasurementCb(const IGnssMeasurementCallback_1_1::GnssData&) override {
+ Return<void> gnssMeasurementCb(const V1_1::IGnssMeasurementCallback::GnssData&) override {
return Void();
}
// Methods from V2_0::IGnssMeasurementCallback follow.
- Return<void> gnssMeasurementCb_2_0(const IGnssMeasurementCallback_2_0::GnssData&) override {
+ Return<void> gnssMeasurementCb_2_0(
+ const V2_0::IGnssMeasurementCallback::GnssData&) override {
return Void();
}
// Methods from V2_1::IGnssMeasurementCallback follow.
- Return<void> gnssMeasurementCb_2_1(const IGnssMeasurementCallback_2_1::GnssData&) override;
+ Return<void> gnssMeasurementCb_2_1(
+ const V2_1::IGnssMeasurementCallback::GnssData&) override;
};
/* Callback class for GnssMeasurementCorrections. */
- class GnssMeasurementCorrectionsCallback : public IMeasurementCorrectionsCallback {
+ class GnssMeasurementCorrectionsCallback
+ : public measurement_corrections::V1_0::IMeasurementCorrectionsCallback {
public:
uint32_t last_capabilities_;
GnssCallbackEventQueue<uint32_t> capabilities_cbq_;
@@ -102,9 +79,9 @@
};
/* Callback class for GnssAntennaInfo. */
- class GnssAntennaInfoCallback : public IGnssAntennaInfoCallback {
+ class GnssAntennaInfoCallback : public V2_1::IGnssAntennaInfoCallback {
public:
- GnssCallbackEventQueue<hidl_vec<IGnssAntennaInfoCallback::GnssAntennaInfo>>
+ GnssCallbackEventQueue<hidl_vec<V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo>>
antenna_info_cbq_;
GnssAntennaInfoCallback() : antenna_info_cbq_("info"){};
@@ -112,7 +89,7 @@
// Methods from V2_1::GnssAntennaInfoCallback follow.
Return<void> gnssAntennaInfoCb(
- const hidl_vec<IGnssAntennaInfoCallback::GnssAntennaInfo>& gnssAntennaInfos);
+ const hidl_vec<V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo>& gnssAntennaInfos);
};
/*
@@ -138,7 +115,7 @@
*
* check_speed: true if speed related fields are also verified.
*/
- void CheckLocation(const GnssLocation_2_0& location, const bool check_speed);
+ void CheckLocation(const V2_0::GnssLocation& location, const bool check_speed);
/*
* StartAndCheckLocations:
@@ -170,7 +147,7 @@
* Note that location is not stopped in this method. The client should call
* StopAndClearLocations() after the call.
*/
- GnssConstellationType startLocationAndGetNonGpsConstellation(
+ V2_0::GnssConstellationType startLocationAndGetNonGpsConstellation(
const int locations_to_await, const int gnss_sv_info_list_timeout);
sp<T_IGnss> gnss_hal_; // GNSS HAL to call into
@@ -283,7 +260,7 @@
}
template <class T_IGnss>
-void GnssHalTestTemplate<T_IGnss>::CheckLocation(const GnssLocation_2_0& location,
+void GnssHalTestTemplate<T_IGnss>::CheckLocation(const V2_0::GnssLocation& location,
bool check_speed) {
const bool check_more_accuracies =
(gnss_cb_->info_cbq_.calledCount() > 0 && gnss_cb_->last_info_.yearOfHw >= 2017);
@@ -315,7 +292,7 @@
}
template <class T_IGnss>
-GnssConstellationType GnssHalTestTemplate<T_IGnss>::startLocationAndGetNonGpsConstellation(
+V2_0::GnssConstellationType GnssHalTestTemplate<T_IGnss>::startLocationAndGetNonGpsConstellation(
const int locations_to_await, const int gnss_sv_info_list_timeout) {
gnss_cb_->location_cbq_.reset();
StartAndCheckLocations(locations_to_await);
@@ -328,29 +305,29 @@
sv_info_list_cbq_size, locations_to_await, location_called_count);
// Find first non-GPS constellation to blacklist
- GnssConstellationType constellation_to_blacklist = GnssConstellationType::UNKNOWN;
+ V2_0::GnssConstellationType constellation_to_blacklist = V2_0::GnssConstellationType::UNKNOWN;
for (int i = 0; i < sv_info_list_cbq_size; ++i) {
- hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ hidl_vec<V2_1::IGnssCallback::GnssSvInfo> sv_info_vec;
gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, gnss_sv_info_list_timeout);
for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
const auto& gnss_sv = sv_info_vec[iSv];
- if ((gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX) &&
- (gnss_sv.v2_0.constellation != GnssConstellationType::UNKNOWN) &&
- (gnss_sv.v2_0.constellation != GnssConstellationType::GPS)) {
+ if ((gnss_sv.v2_0.v1_0.svFlag & V1_0::IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
+ (gnss_sv.v2_0.constellation != V2_0::GnssConstellationType::UNKNOWN) &&
+ (gnss_sv.v2_0.constellation != V2_0::GnssConstellationType::GPS)) {
// found a non-GPS constellation
constellation_to_blacklist = gnss_sv.v2_0.constellation;
break;
}
}
- if (constellation_to_blacklist != GnssConstellationType::UNKNOWN) {
+ if (constellation_to_blacklist != V2_0::GnssConstellationType::UNKNOWN) {
break;
}
}
- if (constellation_to_blacklist == GnssConstellationType::UNKNOWN) {
+ if (constellation_to_blacklist == V2_0::GnssConstellationType::UNKNOWN) {
ALOGI("No non-GPS constellations found, constellation blacklist test less effective.");
// Proceed functionally to blacklist something.
- constellation_to_blacklist = GnssConstellationType::GLONASS;
+ constellation_to_blacklist = V2_0::GnssConstellationType::GLONASS;
}
return constellation_to_blacklist;
@@ -358,7 +335,7 @@
template <class T_IGnss>
Return<void> GnssHalTestTemplate<T_IGnss>::GnssMeasurementCallback::gnssMeasurementCb_2_1(
- const IGnssMeasurementCallback_2_1::GnssData& data) {
+ const V2_1::IGnssMeasurementCallback::GnssData& data) {
ALOGD("GnssMeasurement v2.1 received. Size = %d", (int)data.measurements.size());
measurement_cbq_.store(data);
return Void();
@@ -374,8 +351,10 @@
template <class T_IGnss>
Return<void> GnssHalTestTemplate<T_IGnss>::GnssAntennaInfoCallback::gnssAntennaInfoCb(
- const hidl_vec<IGnssAntennaInfoCallback::GnssAntennaInfo>& gnssAntennaInfos) {
+ const hidl_vec<V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo>& gnssAntennaInfos) {
ALOGD("GnssAntennaInfo v2.1 received. Size = %d", (int)gnssAntennaInfos.size());
antenna_info_cbq_.store(gnssAntennaInfos);
return Void();
}
+
+} // namespace android::hardware::gnss::common
diff --git a/graphics/composer/2.1/vts/functional/Android.bp b/graphics/composer/2.1/vts/functional/Android.bp
index e137afb..9e703d8 100644
--- a/graphics/composer/2.1/vts/functional/Android.bp
+++ b/graphics/composer/2.1/vts/functional/Android.bp
@@ -21,6 +21,7 @@
// TODO(b/64437680): Assume these libs are always available on the device.
shared_libs: [
+ "libbase",
"libfmq",
"libsync",
"android.hardware.graphics.mapper@2.0",
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
index 4fee560..f0250c0 100644
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
+++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "graphics_composer_hidl_hal_test"
#include <android-base/logging.h>
+#include <android-base/properties.h>
#include <composer-vts/2.1/ComposerVts.h>
#include <composer-vts/2.1/GraphicsComposerCallback.h>
#include <composer-vts/2.1/TestCommandReader.h>
@@ -1102,3 +1103,15 @@
} // namespace graphics
} // namespace hardware
} // namespace android
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+
+ using namespace std::chrono_literals;
+ if (!android::base::WaitForProperty("init.svc.surfaceflinger", "stopped", 10s)) {
+ ALOGE("Failed to stop init.svc.surfaceflinger");
+ return -1;
+ }
+
+ return RUN_ALL_TESTS();
+}
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index 16e9138..6aa836c 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -31,6 +31,7 @@
"libEGL",
"libGLESv1_CM",
"libGLESv2",
+ "libbase",
"libfmq",
"libgui",
"libhidlbase",
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
index 4d7df1c..31ec885 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "graphics_composer_hidl_hal_test@2.2"
#include <android-base/logging.h>
+#include <android-base/properties.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <composer-vts/2.1/GraphicsComposerCallback.h>
#include <composer-vts/2.1/TestCommandReader.h>
@@ -700,3 +701,15 @@
} // namespace graphics
} // namespace hardware
} // namespace android
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+
+ using namespace std::chrono_literals;
+ if (!android::base::WaitForProperty("init.svc.surfaceflinger", "stopped", 10s)) {
+ ALOGE("Failed to stop init.svc.surfaceflinger");
+ return -1;
+ }
+
+ return RUN_ALL_TESTS();
+}
\ No newline at end of file
diff --git a/graphics/composer/2.3/vts/functional/Android.bp b/graphics/composer/2.3/vts/functional/Android.bp
index 1ab6b3b..1cbb60e 100644
--- a/graphics/composer/2.3/vts/functional/Android.bp
+++ b/graphics/composer/2.3/vts/functional/Android.bp
@@ -21,6 +21,7 @@
// TODO(b/64437680): Assume these libs are always available on the device.
shared_libs: [
+ "libbase",
"libfmq",
"libhidlbase",
"libsync",
diff --git a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
index a4c1b63..8b42654 100644
--- a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
+++ b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
@@ -19,6 +19,7 @@
#include <algorithm>
#include <android-base/logging.h>
+#include <android-base/properties.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <composer-command-buffer/2.3/ComposerCommandBuffer.h>
#include <composer-vts/2.1/GraphicsComposerCallback.h>
@@ -630,3 +631,15 @@
} // namespace graphics
} // namespace hardware
} // namespace android
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+
+ using namespace std::chrono_literals;
+ if (!android::base::WaitForProperty("init.svc.surfaceflinger", "stopped", 10s)) {
+ ALOGE("Failed to stop init.svc.surfaceflinger");
+ return -1;
+ }
+
+ return RUN_ALL_TESTS();
+}
\ No newline at end of file
diff --git a/graphics/composer/2.4/vts/functional/Android.bp b/graphics/composer/2.4/vts/functional/Android.bp
index d0209b7..cab549c 100644
--- a/graphics/composer/2.4/vts/functional/Android.bp
+++ b/graphics/composer/2.4/vts/functional/Android.bp
@@ -21,6 +21,7 @@
// TODO(b/64437680): Assume these libs are always available on the device.
shared_libs: [
+ "libbase",
"libfmq",
"libsync",
"android.hardware.graphics.mapper@2.0",
diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
index e6ecf93..d8312a2 100644
--- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
+++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
@@ -21,6 +21,7 @@
#include <thread>
#include <android-base/logging.h>
+#include <android-base/properties.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <composer-command-buffer/2.4/ComposerCommandBuffer.h>
#include <composer-vts/2.4/ComposerVts.h>
@@ -57,6 +58,25 @@
using ContentType = IComposerClient::ContentType;
using DisplayCapability = IComposerClient::DisplayCapability;
+class VtsDisplay {
+ public:
+ VtsDisplay(Display display, int32_t displayWidth, int32_t displayHeight)
+ : mDisplay(display), mDisplayWidth(displayWidth), mDisplayHeight(displayHeight) {}
+
+ Display get() const { return mDisplay; }
+
+ IComposerClient::FRect getCrop() const {
+ return {0, 0, static_cast<float>(mDisplayWidth), static_cast<float>(mDisplayHeight)};
+ }
+
+ IComposerClient::Rect getFrameRect() const { return {0, 0, mDisplayWidth, mDisplayHeight}; }
+
+ private:
+ const Display mDisplay;
+ const int32_t mDisplayWidth;
+ const int32_t mDisplayHeight;
+};
+
class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> {
protected:
void SetUp() override {
@@ -67,15 +87,19 @@
mComposerCallback = new GraphicsComposerCallback;
mComposerClient->registerCallback_2_4(mComposerCallback);
- // assume the first display is primary and is never removed
- mPrimaryDisplay = waitForFirstDisplay();
+ // assume the first displays are built-in and are never removed
+ mDisplays = waitForDisplays();
mInvalidDisplayId = GetInvalidDisplayId();
// explicitly disable vsync
- mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
+ for (const auto& display : mDisplays) {
+ mComposerClient->setVsyncEnabled(display.get(), false);
+ }
mComposerCallback->setVsyncAllowed(false);
+ ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>());
+
mWriter = std::make_unique<CommandWriterBase>(1024);
mReader = std::make_unique<TestCommandReader>();
}
@@ -83,6 +107,7 @@
void TearDown() override {
ASSERT_EQ(0, mReader->mErrors.size());
ASSERT_EQ(0, mReader->mCompositionChanges.size());
+
if (mComposerCallback != nullptr) {
EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
@@ -97,10 +122,10 @@
// display. Currently assuming that a device will never have close to
// std::numeric_limit<uint64_t>::max() displays registered while running tests
Display GetInvalidDisplayId() {
- std::vector<Display> validDisplays = mComposerCallback->getDisplays();
uint64_t id = std::numeric_limits<uint64_t>::max();
while (id > 0) {
- if (std::find(validDisplays.begin(), validDisplays.end(), id) == validDisplays.end()) {
+ if (std::none_of(mDisplays.begin(), mDisplays.end(),
+ [&](const VtsDisplay& display) { return id == display.get(); })) {
return id;
}
id--;
@@ -127,6 +152,30 @@
void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
+ const native_handle_t* allocate() {
+ return mGralloc->allocate(
+ /*width*/ 64, /*height*/ 64, /*layerCount*/ 1,
+ static_cast<common::V1_1::PixelFormat>(PixelFormat::RGBA_8888),
+ static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN));
+ }
+
+ struct TestParameters {
+ nsecs_t delayForChange;
+ bool refreshMiss;
+ };
+
+ void Test_setActiveConfigWithConstraints(const TestParameters& params);
+
+ void sendRefreshFrame(const VtsDisplay& display, const VsyncPeriodChangeTimeline*);
+
+ void waitForVsyncPeriodChange(Display display, const VsyncPeriodChangeTimeline& timeline,
+ int64_t desiredTimeNanos, int64_t oldPeriodNanos,
+ int64_t newPeriodNanos);
+
+ std::unique_ptr<ComposerClient> mComposerClient;
+ std::vector<VtsDisplay> mDisplays;
+ Display mInvalidDisplayId;
+
void forEachTwoConfigs(Display display, std::function<void(Config, Config)> func) {
const auto displayConfigs = mComposerClient->getDisplayConfigs(display);
for (const Config config1 : displayConfigs) {
@@ -138,88 +187,44 @@
}
}
- // use the slot count usually set by SF
- static constexpr uint32_t kBufferSlotCount = 64;
-
void Test_setContentType(const ContentType& contentType, const char* contentTypeStr);
void Test_setContentTypeForDisplay(const Display& display,
const std::vector<ContentType>& capabilities,
const ContentType& contentType, const char* contentTypeStr);
- std::unique_ptr<Composer> mComposer;
- std::unique_ptr<ComposerClient> mComposerClient;
- sp<GraphicsComposerCallback> mComposerCallback;
- // the first display and is assumed never to be removed
- Display mPrimaryDisplay;
- Display mInvalidDisplayId;
- std::unique_ptr<CommandWriterBase> mWriter;
- std::unique_ptr<TestCommandReader> mReader;
-
private:
- Display waitForFirstDisplay() {
+ // use the slot count usually set by SF
+ static constexpr uint32_t kBufferSlotCount = 64;
+
+ std::vector<VtsDisplay> waitForDisplays() {
while (true) {
+ // Sleep for a small period of time to allow all built-in displays
+ // to post hotplug events
+ std::this_thread::sleep_for(5ms);
std::vector<Display> displays = mComposerCallback->getDisplays();
if (displays.empty()) {
- usleep(5 * 1000);
continue;
}
- return displays[0];
+ std::vector<VtsDisplay> vtsDisplays;
+ vtsDisplays.reserve(displays.size());
+ for (Display display : displays) {
+ const Config activeConfig = mComposerClient->getActiveConfig(display);
+ const int32_t displayWidth = mComposerClient->getDisplayAttribute_2_4(
+ display, activeConfig, IComposerClient::Attribute::WIDTH);
+ const int32_t displayHeight = mComposerClient->getDisplayAttribute_2_4(
+ display, activeConfig, IComposerClient::Attribute::HEIGHT);
+ vtsDisplays.emplace_back(VtsDisplay{display, displayWidth, displayHeight});
+ }
+
+ return vtsDisplays;
}
}
-};
-// Tests for IComposerClient::Command.
-class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest {
- protected:
- void SetUp() override {
- ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::SetUp());
-
- ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>());
-
- const Config activeConfig = mComposerClient->getActiveConfig(mPrimaryDisplay);
- mDisplayWidth = mComposerClient->getDisplayAttribute_2_4(mPrimaryDisplay, activeConfig,
- IComposerClient::Attribute::WIDTH);
- mDisplayHeight = mComposerClient->getDisplayAttribute_2_4(
- mPrimaryDisplay, activeConfig, IComposerClient::Attribute::HEIGHT);
-
- mWriter = std::make_unique<CommandWriterBase>(1024);
- mReader = std::make_unique<TestCommandReader>();
- }
-
- void TearDown() override {
- ASSERT_EQ(0, mReader->mErrors.size());
- ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown());
- }
-
- const native_handle_t* allocate() {
- return mGralloc->allocate(
- /*width*/ 64, /*height*/ 64, /*layerCount*/ 1,
- static_cast<common::V1_1::PixelFormat>(PixelFormat::RGBA_8888),
- static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN));
- }
-
- void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
-
- struct TestParameters {
- nsecs_t delayForChange;
- bool refreshMiss;
- };
-
- void Test_setActiveConfigWithConstraints(const TestParameters& params);
-
- void sendRefreshFrame(const VsyncPeriodChangeTimeline*);
-
- void waitForVsyncPeriodChange(Display display, const VsyncPeriodChangeTimeline& timeline,
- int64_t desiredTimeNanos, int64_t oldPeriodNanos,
- int64_t newPeriodNanos);
-
+ std::unique_ptr<Composer> mComposer;
std::unique_ptr<CommandWriterBase> mWriter;
std::unique_ptr<TestCommandReader> mReader;
- int32_t mDisplayWidth;
- int32_t mDisplayHeight;
-
- private:
+ sp<GraphicsComposerCallback> mComposerCallback;
std::unique_ptr<Gralloc> mGralloc;
};
@@ -230,9 +235,10 @@
}
TEST_P(GraphicsComposerHidlTest, getDisplayCapabilities) {
- for (Display display : mComposerCallback->getDisplays()) {
+ for (const auto& display : mDisplays) {
std::vector<IComposerClient::DisplayCapability> capabilities;
- EXPECT_EQ(Error::NONE, mComposerClient->getDisplayCapabilities(display, &capabilities));
+ EXPECT_EQ(Error::NONE,
+ mComposerClient->getDisplayCapabilities(display.get(), &capabilities));
}
}
@@ -241,38 +247,40 @@
EXPECT_EQ(Error::BAD_DISPLAY,
mComposerClient->getDisplayConnectionType(mInvalidDisplayId, &type));
- for (Display display : mComposerCallback->getDisplays()) {
- EXPECT_EQ(Error::NONE, mComposerClient->getDisplayConnectionType(display, &type));
+ for (const auto& display : mDisplays) {
+ EXPECT_EQ(Error::NONE, mComposerClient->getDisplayConnectionType(display.get(), &type));
}
}
TEST_P(GraphicsComposerHidlTest, GetDisplayAttribute_2_4) {
- std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
- for (auto config : configs) {
- const std::array<IComposerClient::Attribute, 4> requiredAttributes = {{
- IComposerClient::Attribute::WIDTH,
- IComposerClient::Attribute::HEIGHT,
- IComposerClient::Attribute::VSYNC_PERIOD,
- IComposerClient::Attribute::CONFIG_GROUP,
- }};
- for (auto attribute : requiredAttributes) {
- mComposerClient->getRaw()->getDisplayAttribute_2_4(
- mPrimaryDisplay, config, attribute,
- [&](const auto& tmpError, const auto& value) {
- EXPECT_EQ(Error::NONE, tmpError);
- EXPECT_NE(-1, value);
- });
- }
+ for (const auto& display : mDisplays) {
+ std::vector<Config> configs = mComposerClient->getDisplayConfigs(display.get());
+ for (auto config : configs) {
+ const std::array<IComposerClient::Attribute, 4> requiredAttributes = {{
+ IComposerClient::Attribute::WIDTH,
+ IComposerClient::Attribute::HEIGHT,
+ IComposerClient::Attribute::VSYNC_PERIOD,
+ IComposerClient::Attribute::CONFIG_GROUP,
+ }};
+ for (auto attribute : requiredAttributes) {
+ mComposerClient->getRaw()->getDisplayAttribute_2_4(
+ display.get(), config, attribute,
+ [&](const auto& tmpError, const auto& value) {
+ EXPECT_EQ(Error::NONE, tmpError);
+ EXPECT_NE(-1, value);
+ });
+ }
- const std::array<IComposerClient::Attribute, 2> optionalAttributes = {{
- IComposerClient::Attribute::DPI_X,
- IComposerClient::Attribute::DPI_Y,
- }};
- for (auto attribute : optionalAttributes) {
- mComposerClient->getRaw()->getDisplayAttribute_2_4(
- mPrimaryDisplay, config, attribute, [&](const auto& tmpError, const auto&) {
- EXPECT_TRUE(tmpError == Error::NONE || tmpError == Error::UNSUPPORTED);
- });
+ const std::array<IComposerClient::Attribute, 2> optionalAttributes = {{
+ IComposerClient::Attribute::DPI_X,
+ IComposerClient::Attribute::DPI_Y,
+ }};
+ for (auto attribute : optionalAttributes) {
+ mComposerClient->getRaw()->getDisplayAttribute_2_4(
+ display.get(), config, attribute, [&](const auto& tmpError, const auto&) {
+ EXPECT_TRUE(tmpError == Error::NONE || tmpError == Error::UNSUPPORTED);
+ });
+ }
}
}
}
@@ -283,11 +291,12 @@
mComposerClient->getDisplayVsyncPeriod(mInvalidDisplayId, &vsyncPeriodNanos));
}
-TEST_P(GraphicsComposerHidlCommandTest, getDisplayVsyncPeriod) {
- for (Display display : mComposerCallback->getDisplays()) {
- for (Config config : mComposerClient->getDisplayConfigs(display)) {
+TEST_P(GraphicsComposerHidlTest, getDisplayVsyncPeriod) {
+ for (const auto& display : mDisplays) {
+ for (Config config : mComposerClient->getDisplayConfigs(display.get())) {
VsyncPeriodNanos expectedVsyncPeriodNanos = mComposerClient->getDisplayAttribute_2_4(
- display, config, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
+ display.get(), config,
+ IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
VsyncPeriodChangeTimeline timeline;
IComposerClient::VsyncPeriodChangeConstraints constraints;
@@ -295,12 +304,12 @@
constraints.desiredTimeNanos = systemTime();
constraints.seamlessRequired = false;
EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints(
- display, config, constraints, &timeline));
+ display.get(), config, constraints, &timeline));
if (timeline.refreshRequired) {
- sendRefreshFrame(&timeline);
+ sendRefreshFrame(display, &timeline);
}
- waitForVsyncPeriodChange(display, timeline, constraints.desiredTimeNanos, 0,
+ waitForVsyncPeriodChange(display.get(), timeline, constraints.desiredTimeNanos, 0,
expectedVsyncPeriodNanos);
VsyncPeriodNanos vsyncPeriodNanos;
@@ -309,7 +318,7 @@
std::this_thread::sleep_for(10ms);
vsyncPeriodNanos = 0;
EXPECT_EQ(Error::NONE,
- mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
+ mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos));
--retryCount;
} while (vsyncPeriodNanos != expectedVsyncPeriodNanos && retryCount > 0);
@@ -322,7 +331,7 @@
timeout *= 2;
vsyncPeriodNanos = 0;
EXPECT_EQ(Error::NONE,
- mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
+ mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos));
EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
}
}
@@ -347,31 +356,34 @@
constraints.seamlessRequired = false;
constraints.desiredTimeNanos = systemTime();
- for (Display display : mComposerCallback->getDisplays()) {
- Config invalidConfigId = GetInvalidConfigId(display);
- EXPECT_EQ(Error::BAD_CONFIG, mComposerClient->setActiveConfigWithConstraints(
- display, invalidConfigId, constraints, &timeline));
+ for (const auto& display : mDisplays) {
+ Config invalidConfigId = GetInvalidConfigId(display.get());
+ EXPECT_EQ(Error::BAD_CONFIG,
+ mComposerClient->setActiveConfigWithConstraints(display.get(), invalidConfigId,
+ constraints, &timeline));
}
}
-TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints_SeamlessNotAllowed) {
+TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_SeamlessNotAllowed) {
VsyncPeriodChangeTimeline timeline;
IComposerClient::VsyncPeriodChangeConstraints constraints;
constraints.seamlessRequired = true;
constraints.desiredTimeNanos = systemTime();
- for (Display display : mComposerCallback->getDisplays()) {
- forEachTwoConfigs(display, [&](Config config1, Config config2) {
+ for (const auto& display : mDisplays) {
+ forEachTwoConfigs(display.get(), [&](Config config1, Config config2) {
const auto configGroup1 = mComposerClient->getDisplayAttribute_2_4(
- display, config1, IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
+ display.get(), config1,
+ IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
const auto configGroup2 = mComposerClient->getDisplayAttribute_2_4(
- display, config2, IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
+ display.get(), config2,
+ IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
if (configGroup1 != configGroup2) {
- mComposerClient->setActiveConfig(display, config1);
- sendRefreshFrame(nullptr);
+ mComposerClient->setActiveConfig(display.get(), config1);
+ sendRefreshFrame(display, nullptr);
EXPECT_EQ(Error::SEAMLESS_NOT_ALLOWED,
- mComposerClient->setActiveConfigWithConstraints(display, config2,
+ mComposerClient->setActiveConfigWithConstraints(display.get(), config2,
constraints, &timeline));
}
});
@@ -382,7 +394,8 @@
return std::chrono::time_point<std::chrono::steady_clock>(std::chrono::nanoseconds(time));
}
-void GraphicsComposerHidlCommandTest::sendRefreshFrame(const VsyncPeriodChangeTimeline* timeline) {
+void GraphicsComposerHidlTest::sendRefreshFrame(const VtsDisplay& display,
+ const VsyncPeriodChangeTimeline* timeline) {
if (timeline != nullptr) {
// Refresh time should be before newVsyncAppliedTimeNanos
EXPECT_LT(timeline->refreshTimeNanos, timeline->newVsyncAppliedTimeNanos);
@@ -390,29 +403,25 @@
std::this_thread::sleep_until(toTimePoint(timeline->refreshTimeNanos));
}
- mWriter->selectDisplay(mPrimaryDisplay);
- mComposerClient->setPowerMode(mPrimaryDisplay, V2_1::IComposerClient::PowerMode::ON);
- mComposerClient->setColorMode_2_3(mPrimaryDisplay, ColorMode::NATIVE,
- RenderIntent::COLORIMETRIC);
+ mWriter->selectDisplay(display.get());
+ mComposerClient->setPowerMode(display.get(), V2_1::IComposerClient::PowerMode::ON);
+ mComposerClient->setColorMode_2_3(display.get(), ColorMode::NATIVE, RenderIntent::COLORIMETRIC);
auto handle = allocate();
ASSERT_NE(nullptr, handle);
- IComposerClient::Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight};
-
Layer layer;
- ASSERT_NO_FATAL_FAILURE(
- layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
+ ASSERT_NO_FATAL_FAILURE(layer = mComposerClient->createLayer(display.get(), kBufferSlotCount));
mWriter->selectLayer(layer);
mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE);
- mWriter->setLayerDisplayFrame(displayFrame);
+ mWriter->setLayerDisplayFrame(display.getFrameRect());
mWriter->setLayerPlaneAlpha(1);
- mWriter->setLayerSourceCrop({0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
+ mWriter->setLayerSourceCrop(display.getCrop());
mWriter->setLayerTransform(static_cast<Transform>(0));
- mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, displayFrame));
+ mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, display.getFrameRect()));
mWriter->setLayerZOrder(10);
mWriter->setLayerBlendMode(IComposerClient::BlendMode::NONE);
- mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, displayFrame));
+ mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, display.getFrameRect()));
mWriter->setLayerBuffer(0, handle, -1);
mWriter->setLayerDataspace(Dataspace::UNKNOWN);
@@ -440,9 +449,11 @@
execute();
}
-void GraphicsComposerHidlCommandTest::waitForVsyncPeriodChange(
- Display display, const VsyncPeriodChangeTimeline& timeline, int64_t desiredTimeNanos,
- int64_t oldPeriodNanos, int64_t newPeriodNanos) {
+void GraphicsComposerHidlTest::waitForVsyncPeriodChange(Display display,
+ const VsyncPeriodChangeTimeline& timeline,
+ int64_t desiredTimeNanos,
+ int64_t oldPeriodNanos,
+ int64_t newPeriodNanos) {
const auto CHANGE_DEADLINE = toTimePoint(timeline.newVsyncAppliedTimeNanos) + 100ms;
while (std::chrono::steady_clock::now() <= CHANGE_DEADLINE) {
VsyncPeriodNanos vsyncPeriodNanos;
@@ -456,17 +467,18 @@
}
}
-void GraphicsComposerHidlCommandTest::Test_setActiveConfigWithConstraints(
- const TestParameters& params) {
- for (Display display : mComposerCallback->getDisplays()) {
- forEachTwoConfigs(display, [&](Config config1, Config config2) {
- mComposerClient->setActiveConfig(display, config1);
- sendRefreshFrame(nullptr);
+void GraphicsComposerHidlTest::Test_setActiveConfigWithConstraints(const TestParameters& params) {
+ for (const auto& display : mDisplays) {
+ forEachTwoConfigs(display.get(), [&](Config config1, Config config2) {
+ mComposerClient->setActiveConfig(display.get(), config1);
+ sendRefreshFrame(display, nullptr);
int32_t vsyncPeriod1 = mComposerClient->getDisplayAttribute_2_4(
- display, config1, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
+ display.get(), config1,
+ IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
int32_t vsyncPeriod2 = mComposerClient->getDisplayAttribute_2_4(
- display, config2, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
+ display.get(), config2,
+ IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
if (vsyncPeriod1 == vsyncPeriod2) {
return; // continue
@@ -477,7 +489,7 @@
.desiredTimeNanos = systemTime() + params.delayForChange,
.seamlessRequired = false};
EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints(
- display, config2, constraints, &timeline));
+ display.get(), config2, constraints, &timeline));
EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos >= constraints.desiredTimeNanos);
// Refresh rate should change within a reasonable time
@@ -491,10 +503,10 @@
// callback
std::this_thread::sleep_until(toTimePoint(timeline.refreshTimeNanos) + 100ms);
}
- sendRefreshFrame(&timeline);
+ sendRefreshFrame(display, &timeline);
}
- waitForVsyncPeriodChange(display, timeline, constraints.desiredTimeNanos, vsyncPeriod1,
- vsyncPeriod2);
+ waitForVsyncPeriodChange(display.get(), timeline, constraints.desiredTimeNanos,
+ vsyncPeriod1, vsyncPeriod2);
// At this point the refresh rate should have changed already, however in rare
// cases the implementation might have missed the deadline. In this case a new
@@ -506,30 +518,30 @@
if (newTimeline.has_value()) {
if (newTimeline->refreshRequired) {
- sendRefreshFrame(&newTimeline.value());
+ sendRefreshFrame(display, &newTimeline.value());
}
- waitForVsyncPeriodChange(display, newTimeline.value(), constraints.desiredTimeNanos,
- vsyncPeriod1, vsyncPeriod2);
+ waitForVsyncPeriodChange(display.get(), newTimeline.value(),
+ constraints.desiredTimeNanos, vsyncPeriod1, vsyncPeriod2);
}
VsyncPeriodNanos vsyncPeriodNanos;
EXPECT_EQ(Error::NONE,
- mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
+ mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos));
EXPECT_EQ(vsyncPeriodNanos, vsyncPeriod2);
});
}
}
-TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints) {
+TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints) {
Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = false});
}
-TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints_Delayed) {
+TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_Delayed) {
Test_setActiveConfigWithConstraints({.delayForChange = 300'000'000, // 300ms
.refreshMiss = false});
}
-TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints_MissRefresh) {
+TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_MissRefresh) {
Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = true});
}
@@ -539,9 +551,9 @@
}
TEST_P(GraphicsComposerHidlTest, setAutoLowLatencyMode) {
- for (Display display : mComposerCallback->getDisplays()) {
+ for (const auto& display : mDisplays) {
std::vector<DisplayCapability> capabilities;
- const auto error = mComposerClient->getDisplayCapabilities(display, &capabilities);
+ const auto error = mComposerClient->getDisplayCapabilities(display.get(), &capabilities);
EXPECT_EQ(Error::NONE, error);
const bool allmSupport =
@@ -550,16 +562,16 @@
if (!allmSupport) {
EXPECT_EQ(Error::UNSUPPORTED,
- mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, true));
+ mComposerClient->setAutoLowLatencyMode(display.get(), true));
EXPECT_EQ(Error::UNSUPPORTED,
- mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, false));
+ mComposerClient->setAutoLowLatencyMode(display.get(), false));
GTEST_SUCCEED() << "Auto Low Latency Mode is not supported on display "
- << std::to_string(display) << ", skipping test";
+ << std::to_string(display.get()) << ", skipping test";
return;
}
- EXPECT_EQ(Error::NONE, mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, true));
- EXPECT_EQ(Error::NONE, mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, false));
+ EXPECT_EQ(Error::NONE, mComposerClient->setAutoLowLatencyMode(display.get(), true));
+ EXPECT_EQ(Error::NONE, mComposerClient->setAutoLowLatencyMode(display.get(), false));
}
}
@@ -572,10 +584,10 @@
TEST_P(GraphicsComposerHidlTest, getSupportedContentTypes) {
std::vector<ContentType> supportedContentTypes;
- for (Display display : mComposerCallback->getDisplays()) {
+ for (const auto& display : mDisplays) {
supportedContentTypes.clear();
const auto error =
- mComposerClient->getSupportedContentTypes(display, &supportedContentTypes);
+ mComposerClient->getSupportedContentTypes(display.get(), &supportedContentTypes);
const bool noneSupported =
std::find(supportedContentTypes.begin(), supportedContentTypes.end(),
ContentType::NONE) != supportedContentTypes.end();
@@ -585,8 +597,8 @@
}
TEST_P(GraphicsComposerHidlTest, setContentTypeNoneAlwaysAccepted) {
- for (Display display : mComposerCallback->getDisplays()) {
- const auto error = mComposerClient->setContentType(display, ContentType::NONE);
+ for (const auto& display : mDisplays) {
+ const auto error = mComposerClient->setContentType(display.get(), ContentType::NONE);
EXPECT_NE(Error::UNSUPPORTED, error);
}
}
@@ -618,13 +630,14 @@
void GraphicsComposerHidlTest::Test_setContentType(const ContentType& contentType,
const char* contentTypeStr) {
- for (Display display : mComposerCallback->getDisplays()) {
+ for (const auto& display : mDisplays) {
std::vector<ContentType> supportedContentTypes;
const auto error =
- mComposerClient->getSupportedContentTypes(display, &supportedContentTypes);
+ mComposerClient->getSupportedContentTypes(display.get(), &supportedContentTypes);
EXPECT_EQ(Error::NONE, error);
- Test_setContentTypeForDisplay(display, supportedContentTypes, contentType, contentTypeStr);
+ Test_setContentTypeForDisplay(display.get(), supportedContentTypes, contentType,
+ contentTypeStr);
}
}
@@ -650,13 +663,7 @@
testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
android::hardware::PrintInstanceNameToString);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerHidlCommandTest);
-INSTANTIATE_TEST_SUITE_P(
- PerInstance, GraphicsComposerHidlCommandTest,
- testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
- android::hardware::PrintInstanceNameToString);
-
-TEST_P(GraphicsComposerHidlCommandTest, getLayerGenericMetadataKeys) {
+TEST_P(GraphicsComposerHidlTest, getLayerGenericMetadataKeys) {
std::vector<IComposerClient::LayerGenericMetadataKey> keys;
mComposerClient->getLayerGenericMetadataKeys(&keys);
@@ -685,3 +692,15 @@
} // namespace graphics
} // namespace hardware
} // namespace android
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+
+ using namespace std::chrono_literals;
+ if (!android::base::WaitForProperty("init.svc.surfaceflinger", "stopped", 10s)) {
+ ALOGE("Failed to stop init.svc.surfaceflinger");
+ return -1;
+ }
+
+ return RUN_ALL_TESTS();
+}
\ No newline at end of file
diff --git a/keymaster/3.0/default/KeymasterDevice.cpp b/keymaster/3.0/default/KeymasterDevice.cpp
index 7d3e6f2..8b416c3 100644
--- a/keymaster/3.0/default/KeymasterDevice.cpp
+++ b/keymaster/3.0/default/KeymasterDevice.cpp
@@ -22,7 +22,6 @@
#include <log/log.h>
#include <AndroidKeymaster3Device.h>
-#include <hardware/keymaster0.h>
#include <hardware/keymaster1.h>
#include <hardware/keymaster2.h>
#include <hardware/keymaster_defs.h>
@@ -33,16 +32,6 @@
namespace V3_0 {
namespace implementation {
-static int get_keymaster0_dev(keymaster0_device_t** dev, const hw_module_t* mod) {
- int rc = keymaster0_open(mod, dev);
- if (rc) {
- ALOGE("Error opening keystore keymaster0 device.");
- *dev = nullptr;
- return rc;
- }
- return 0;
-}
-
static int get_keymaster1_dev(keymaster1_device_t** dev, const hw_module_t* mod) {
int rc = keymaster1_open(mod, dev);
if (rc) {
@@ -75,11 +64,7 @@
}
if (mod->module_api_version < KEYMASTER_MODULE_API_VERSION_1_0) {
- keymaster0_device_t* dev = nullptr;
- if (get_keymaster0_dev(&dev, mod)) {
- return nullptr;
- }
- return ::keymaster::ng::CreateKeymasterDevice(dev);
+ return nullptr;
} else if (mod->module_api_version == KEYMASTER_MODULE_API_VERSION_1_0) {
keymaster1_device_t* dev = nullptr;
if (get_keymaster1_dev(&dev, mod)) {
diff --git a/keymint/aidl/aidl_api/android.hardware.keymint/current/android/hardware/keymint/Tag.aidl b/keymint/aidl/aidl_api/android.hardware.keymint/current/android/hardware/keymint/Tag.aidl
index fba58af..33a95fe 100644
--- a/keymint/aidl/aidl_api/android.hardware.keymint/current/android/hardware/keymint/Tag.aidl
+++ b/keymint/aidl/aidl_api/android.hardware.keymint/current/android/hardware/keymint/Tag.aidl
@@ -41,7 +41,7 @@
MIN_SECONDS_BETWEEN_OPS = 805306771,
MAX_USES_PER_BOOT = 805306772,
USER_ID = 805306869,
- USER_SECURE_ID = 1073742326,
+ USER_SECURE_ID = -1610612234,
NO_AUTH_REQUIRED = 1879048695,
USER_AUTH_TYPE = 268435960,
AUTH_TIMEOUT = 805306873,
diff --git a/keymint/aidl/android/hardware/keymint/Tag.aidl b/keymint/aidl/android/hardware/keymint/Tag.aidl
index e85a8f5..46da096 100644
--- a/keymint/aidl/android/hardware/keymint/Tag.aidl
+++ b/keymint/aidl/android/hardware/keymint/Tag.aidl
@@ -355,7 +355,7 @@
*
* Must be hardware-enforced.
*/
- USER_SECURE_ID = (4 << 28) | 502, /* TagType:UINT_REP */
+ USER_SECURE_ID = (10 << 28) | 502, /* TagType:ULONG_REP */
/**
* Tag::NO_AUTH_REQUIRED specifies that no authentication is required to use this key. This tag
diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h
index fb77cb2..d3d933b 100644
--- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h
+++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h
@@ -24,20 +24,28 @@
namespace android::nn {
-GeneralResult<OperandType> convert(const hal::V1_0::OperandType& operandType);
-GeneralResult<OperationType> convert(const hal::V1_0::OperationType& operationType);
-GeneralResult<Operand::LifeTime> convert(const hal::V1_0::OperandLifeTime& lifetime);
-GeneralResult<DeviceStatus> convert(const hal::V1_0::DeviceStatus& deviceStatus);
-GeneralResult<Capabilities::PerformanceInfo> convert(
+GeneralResult<OperandType> unvalidatedConvert(const hal::V1_0::OperandType& operandType);
+GeneralResult<OperationType> unvalidatedConvert(const hal::V1_0::OperationType& operationType);
+GeneralResult<Operand::LifeTime> unvalidatedConvert(const hal::V1_0::OperandLifeTime& lifetime);
+GeneralResult<DeviceStatus> unvalidatedConvert(const hal::V1_0::DeviceStatus& deviceStatus);
+GeneralResult<Capabilities::PerformanceInfo> unvalidatedConvert(
const hal::V1_0::PerformanceInfo& performanceInfo);
+GeneralResult<Capabilities> unvalidatedConvert(const hal::V1_0::Capabilities& capabilities);
+GeneralResult<DataLocation> unvalidatedConvert(const hal::V1_0::DataLocation& location);
+GeneralResult<Operand> unvalidatedConvert(const hal::V1_0::Operand& operand);
+GeneralResult<Operation> unvalidatedConvert(const hal::V1_0::Operation& operation);
+GeneralResult<Model::OperandValues> unvalidatedConvert(
+ const hardware::hidl_vec<uint8_t>& operandValues);
+GeneralResult<Memory> unvalidatedConvert(const hardware::hidl_memory& memory);
+GeneralResult<Model> unvalidatedConvert(const hal::V1_0::Model& model);
+GeneralResult<Request::Argument> unvalidatedConvert(
+ const hal::V1_0::RequestArgument& requestArgument);
+GeneralResult<Request> unvalidatedConvert(const hal::V1_0::Request& request);
+GeneralResult<ErrorStatus> unvalidatedConvert(const hal::V1_0::ErrorStatus& status);
+
+GeneralResult<DeviceStatus> convert(const hal::V1_0::DeviceStatus& deviceStatus);
GeneralResult<Capabilities> convert(const hal::V1_0::Capabilities& capabilities);
-GeneralResult<DataLocation> convert(const hal::V1_0::DataLocation& location);
-GeneralResult<Operand> convert(const hal::V1_0::Operand& operand);
-GeneralResult<Operation> convert(const hal::V1_0::Operation& operation);
-GeneralResult<Model::OperandValues> convert(const hardware::hidl_vec<uint8_t>& operandValues);
-GeneralResult<Memory> convert(const hardware::hidl_memory& memory);
GeneralResult<Model> convert(const hal::V1_0::Model& model);
-GeneralResult<Request::Argument> convert(const hal::V1_0::RequestArgument& requestArgument);
GeneralResult<Request> convert(const hal::V1_0::Request& request);
GeneralResult<ErrorStatus> convert(const hal::V1_0::ErrorStatus& status);
@@ -45,21 +53,28 @@
namespace android::hardware::neuralnetworks::V1_0::utils {
-nn::GeneralResult<OperandType> convert(const nn::OperandType& operandType);
-nn::GeneralResult<OperationType> convert(const nn::OperationType& operationType);
-nn::GeneralResult<OperandLifeTime> convert(const nn::Operand::LifeTime& lifetime);
-nn::GeneralResult<DeviceStatus> convert(const nn::DeviceStatus& deviceStatus);
-nn::GeneralResult<PerformanceInfo> convert(
+nn::GeneralResult<OperandType> unvalidatedConvert(const nn::OperandType& operandType);
+nn::GeneralResult<OperationType> unvalidatedConvert(const nn::OperationType& operationType);
+nn::GeneralResult<OperandLifeTime> unvalidatedConvert(const nn::Operand::LifeTime& lifetime);
+nn::GeneralResult<DeviceStatus> unvalidatedConvert(const nn::DeviceStatus& deviceStatus);
+nn::GeneralResult<PerformanceInfo> unvalidatedConvert(
const nn::Capabilities::PerformanceInfo& performanceInfo);
+nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities);
+nn::GeneralResult<DataLocation> unvalidatedConvert(const nn::DataLocation& location);
+nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand);
+nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation);
+nn::GeneralResult<hidl_vec<uint8_t>> unvalidatedConvert(
+ const nn::Model::OperandValues& operandValues);
+nn::GeneralResult<hidl_memory> unvalidatedConvert(const nn::Memory& memory);
+nn::GeneralResult<Model> unvalidatedConvert(const nn::Model& model);
+nn::GeneralResult<RequestArgument> unvalidatedConvert(const nn::Request::Argument& requestArgument);
+nn::GeneralResult<hidl_memory> unvalidatedConvert(const nn::Request::MemoryPool& memoryPool);
+nn::GeneralResult<Request> unvalidatedConvert(const nn::Request& request);
+nn::GeneralResult<ErrorStatus> unvalidatedConvert(const nn::ErrorStatus& status);
+
+nn::GeneralResult<DeviceStatus> convert(const nn::DeviceStatus& deviceStatus);
nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities);
-nn::GeneralResult<DataLocation> convert(const nn::DataLocation& location);
-nn::GeneralResult<Operand> convert(const nn::Operand& operand);
-nn::GeneralResult<Operation> convert(const nn::Operation& operation);
-nn::GeneralResult<hidl_vec<uint8_t>> convert(const nn::Model::OperandValues& operandValues);
-nn::GeneralResult<hidl_memory> convert(const nn::Memory& memory);
nn::GeneralResult<Model> convert(const nn::Model& model);
-nn::GeneralResult<RequestArgument> convert(const nn::Request::Argument& requestArgument);
-nn::GeneralResult<hidl_memory> convert(const nn::Request::MemoryPool& memoryPool);
nn::GeneralResult<Request> convert(const nn::Request& request);
nn::GeneralResult<ErrorStatus> convert(const nn::ErrorStatus& status);
diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h
index baa2b95..4cec545 100644
--- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h
+++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h
@@ -22,25 +22,16 @@
#include <android-base/logging.h>
#include <android/hardware/neuralnetworks/1.0/types.h>
#include <nnapi/Result.h>
-#include <nnapi/TypeUtils.h>
#include <nnapi/Types.h>
-#include <nnapi/Validation.h>
namespace android::hardware::neuralnetworks::V1_0::utils {
-constexpr auto kVersion = nn::Version::ANDROID_OC_MR1;
-
template <typename Type>
nn::Result<void> validate(const Type& halObject) {
const auto maybeCanonical = nn::convert(halObject);
if (!maybeCanonical.has_value()) {
return nn::error() << maybeCanonical.error().message;
}
- const auto version = NN_TRY(nn::validate(maybeCanonical.value()));
- if (version > utils::kVersion) {
- return NN_ERROR() << "Insufficient version: " << version << " vs required "
- << utils::kVersion;
- }
return {};
}
@@ -53,21 +44,6 @@
return result.has_value();
}
-template <typename Type>
-decltype(nn::convert(std::declval<Type>())) validatedConvertToCanonical(const Type& halObject) {
- auto canonical = NN_TRY(nn::convert(halObject));
- const auto maybeVersion = nn::validate(canonical);
- if (!maybeVersion.has_value()) {
- return nn::error() << maybeVersion.error();
- }
- const auto version = maybeVersion.value();
- if (version > utils::kVersion) {
- return NN_ERROR() << "Insufficient version: " << version << " vs required "
- << utils::kVersion;
- }
- return canonical;
-}
-
} // namespace android::hardware::neuralnetworks::V1_0::utils
#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_H
diff --git a/neuralnetworks/1.0/utils/src/Callbacks.cpp b/neuralnetworks/1.0/utils/src/Callbacks.cpp
index f286bcc..b1259c3 100644
--- a/neuralnetworks/1.0/utils/src/Callbacks.cpp
+++ b/neuralnetworks/1.0/utils/src/Callbacks.cpp
@@ -45,8 +45,7 @@
Return<void> PreparedModelCallback::notify(ErrorStatus status,
const sp<IPreparedModel>& preparedModel) {
if (status != ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status));
} else if (preparedModel == nullptr) {
notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
@@ -73,8 +72,7 @@
Return<void> ExecutionCallback::notify(ErrorStatus status) {
if (status != ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status));
} else {
notifyInternal({});
diff --git a/neuralnetworks/1.0/utils/src/Conversions.cpp b/neuralnetworks/1.0/utils/src/Conversions.cpp
index 6cf9073..fde7346 100644
--- a/neuralnetworks/1.0/utils/src/Conversions.cpp
+++ b/neuralnetworks/1.0/utils/src/Conversions.cpp
@@ -22,7 +22,9 @@
#include <nnapi/OperationTypes.h>
#include <nnapi/Result.h>
#include <nnapi/SharedMemory.h>
+#include <nnapi/TypeUtils.h>
#include <nnapi/Types.h>
+#include <nnapi/Validation.h>
#include <nnapi/hal/CommonUtils.h>
#include <algorithm>
@@ -40,6 +42,8 @@
return static_cast<std::underlying_type_t<Type>>(value);
}
+constexpr auto kVersion = android::nn::Version::ANDROID_OC_MR1;
+
} // namespace
namespace android::nn {
@@ -49,37 +53,53 @@
using hardware::hidl_vec;
template <typename Input>
-using ConvertOutput = std::decay_t<decltype(convert(std::declval<Input>()).value())>;
+using unvalidatedConvertOutput =
+ std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
template <typename Type>
-GeneralResult<std::vector<ConvertOutput<Type>>> convert(const hidl_vec<Type>& arguments) {
- std::vector<ConvertOutput<Type>> canonical;
+GeneralResult<std::vector<unvalidatedConvertOutput<Type>>> unvalidatedConvert(
+ const hidl_vec<Type>& arguments) {
+ std::vector<unvalidatedConvertOutput<Type>> canonical;
canonical.reserve(arguments.size());
for (const auto& argument : arguments) {
- canonical.push_back(NN_TRY(nn::convert(argument)));
+ canonical.push_back(NN_TRY(nn::unvalidatedConvert(argument)));
+ }
+ return canonical;
+}
+
+template <typename Type>
+decltype(nn::unvalidatedConvert(std::declval<Type>())) validatedConvert(const Type& halObject) {
+ auto canonical = NN_TRY(nn::unvalidatedConvert(halObject));
+ const auto maybeVersion = validate(canonical);
+ if (!maybeVersion.has_value()) {
+ return error() << maybeVersion.error();
+ }
+ const auto version = maybeVersion.value();
+ if (version > kVersion) {
+ return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
}
return canonical;
}
} // anonymous namespace
-GeneralResult<OperandType> convert(const hal::V1_0::OperandType& operandType) {
+GeneralResult<OperandType> unvalidatedConvert(const hal::V1_0::OperandType& operandType) {
return static_cast<OperandType>(operandType);
}
-GeneralResult<OperationType> convert(const hal::V1_0::OperationType& operationType) {
+GeneralResult<OperationType> unvalidatedConvert(const hal::V1_0::OperationType& operationType) {
return static_cast<OperationType>(operationType);
}
-GeneralResult<Operand::LifeTime> convert(const hal::V1_0::OperandLifeTime& lifetime) {
+GeneralResult<Operand::LifeTime> unvalidatedConvert(const hal::V1_0::OperandLifeTime& lifetime) {
return static_cast<Operand::LifeTime>(lifetime);
}
-GeneralResult<DeviceStatus> convert(const hal::V1_0::DeviceStatus& deviceStatus) {
+GeneralResult<DeviceStatus> unvalidatedConvert(const hal::V1_0::DeviceStatus& deviceStatus) {
return static_cast<DeviceStatus>(deviceStatus);
}
-GeneralResult<Capabilities::PerformanceInfo> convert(
+GeneralResult<Capabilities::PerformanceInfo> unvalidatedConvert(
const hal::V1_0::PerformanceInfo& performanceInfo) {
return Capabilities::PerformanceInfo{
.execTime = performanceInfo.execTime,
@@ -87,9 +107,10 @@
};
}
-GeneralResult<Capabilities> convert(const hal::V1_0::Capabilities& capabilities) {
- const auto quantized8Performance = NN_TRY(convert(capabilities.quantized8Performance));
- const auto float32Performance = NN_TRY(convert(capabilities.float32Performance));
+GeneralResult<Capabilities> unvalidatedConvert(const hal::V1_0::Capabilities& capabilities) {
+ const auto quantized8Performance =
+ NN_TRY(unvalidatedConvert(capabilities.quantized8Performance));
+ const auto float32Performance = NN_TRY(unvalidatedConvert(capabilities.float32Performance));
auto table = hal::utils::makeQuantized8PerformanceConsistentWithP(float32Performance,
quantized8Performance);
@@ -101,7 +122,7 @@
};
}
-GeneralResult<DataLocation> convert(const hal::V1_0::DataLocation& location) {
+GeneralResult<DataLocation> unvalidatedConvert(const hal::V1_0::DataLocation& location) {
return DataLocation{
.poolIndex = location.poolIndex,
.offset = location.offset,
@@ -109,35 +130,35 @@
};
}
-GeneralResult<Operand> convert(const hal::V1_0::Operand& operand) {
+GeneralResult<Operand> unvalidatedConvert(const hal::V1_0::Operand& operand) {
return Operand{
- .type = NN_TRY(convert(operand.type)),
+ .type = NN_TRY(unvalidatedConvert(operand.type)),
.dimensions = operand.dimensions,
.scale = operand.scale,
.zeroPoint = operand.zeroPoint,
- .lifetime = NN_TRY(convert(operand.lifetime)),
- .location = NN_TRY(convert(operand.location)),
+ .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
+ .location = NN_TRY(unvalidatedConvert(operand.location)),
};
}
-GeneralResult<Operation> convert(const hal::V1_0::Operation& operation) {
+GeneralResult<Operation> unvalidatedConvert(const hal::V1_0::Operation& operation) {
return Operation{
- .type = NN_TRY(convert(operation.type)),
+ .type = NN_TRY(unvalidatedConvert(operation.type)),
.inputs = operation.inputs,
.outputs = operation.outputs,
};
}
-GeneralResult<Model::OperandValues> convert(const hidl_vec<uint8_t>& operandValues) {
+GeneralResult<Model::OperandValues> unvalidatedConvert(const hidl_vec<uint8_t>& operandValues) {
return Model::OperandValues(operandValues.data(), operandValues.size());
}
-GeneralResult<Memory> convert(const hidl_memory& memory) {
+GeneralResult<Memory> unvalidatedConvert(const hidl_memory& memory) {
return createSharedMemoryFromHidlMemory(memory);
}
-GeneralResult<Model> convert(const hal::V1_0::Model& model) {
- auto operations = NN_TRY(convert(model.operations));
+GeneralResult<Model> unvalidatedConvert(const hal::V1_0::Model& model) {
+ auto operations = NN_TRY(unvalidatedConvert(model.operations));
// Verify number of consumers.
const auto numberOfConsumers =
@@ -152,7 +173,7 @@
}
auto main = Model::Subgraph{
- .operands = NN_TRY(convert(model.operands)),
+ .operands = NN_TRY(unvalidatedConvert(model.operands)),
.operations = std::move(operations),
.inputIndexes = model.inputIndexes,
.outputIndexes = model.outputIndexes,
@@ -160,35 +181,35 @@
return Model{
.main = std::move(main),
- .operandValues = NN_TRY(convert(model.operandValues)),
- .pools = NN_TRY(convert(model.pools)),
+ .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
+ .pools = NN_TRY(unvalidatedConvert(model.pools)),
};
}
-GeneralResult<Request::Argument> convert(const hal::V1_0::RequestArgument& argument) {
+GeneralResult<Request::Argument> unvalidatedConvert(const hal::V1_0::RequestArgument& argument) {
const auto lifetime = argument.hasNoValue ? Request::Argument::LifeTime::NO_VALUE
: Request::Argument::LifeTime::POOL;
return Request::Argument{
.lifetime = lifetime,
- .location = NN_TRY(convert(argument.location)),
+ .location = NN_TRY(unvalidatedConvert(argument.location)),
.dimensions = argument.dimensions,
};
}
-GeneralResult<Request> convert(const hal::V1_0::Request& request) {
- auto memories = NN_TRY(convert(request.pools));
+GeneralResult<Request> unvalidatedConvert(const hal::V1_0::Request& request) {
+ auto memories = NN_TRY(unvalidatedConvert(request.pools));
std::vector<Request::MemoryPool> pools;
pools.reserve(memories.size());
std::move(memories.begin(), memories.end(), std::back_inserter(pools));
return Request{
- .inputs = NN_TRY(convert(request.inputs)),
- .outputs = NN_TRY(convert(request.outputs)),
+ .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
+ .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
.pools = std::move(pools),
};
}
-GeneralResult<ErrorStatus> convert(const hal::V1_0::ErrorStatus& status) {
+GeneralResult<ErrorStatus> unvalidatedConvert(const hal::V1_0::ErrorStatus& status) {
switch (status) {
case hal::V1_0::ErrorStatus::NONE:
case hal::V1_0::ErrorStatus::DEVICE_UNAVAILABLE:
@@ -201,46 +222,81 @@
<< "Invalid ErrorStatus " << underlyingType(status);
}
+GeneralResult<DeviceStatus> convert(const hal::V1_0::DeviceStatus& deviceStatus) {
+ return validatedConvert(deviceStatus);
+}
+
+GeneralResult<Capabilities> convert(const hal::V1_0::Capabilities& capabilities) {
+ return validatedConvert(capabilities);
+}
+
+GeneralResult<Model> convert(const hal::V1_0::Model& model) {
+ return validatedConvert(model);
+}
+
+GeneralResult<Request> convert(const hal::V1_0::Request& request) {
+ return validatedConvert(request);
+}
+
+GeneralResult<ErrorStatus> convert(const hal::V1_0::ErrorStatus& status) {
+ return validatedConvert(status);
+}
+
} // namespace android::nn
namespace android::hardware::neuralnetworks::V1_0::utils {
namespace {
template <typename Input>
-using ConvertOutput = std::decay_t<decltype(convert(std::declval<Input>()).value())>;
+using unvalidatedConvertOutput =
+ std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
template <typename Type>
-nn::GeneralResult<hidl_vec<ConvertOutput<Type>>> convert(const std::vector<Type>& arguments) {
- hidl_vec<ConvertOutput<Type>> halObject(arguments.size());
+nn::GeneralResult<hidl_vec<unvalidatedConvertOutput<Type>>> unvalidatedConvert(
+ const std::vector<Type>& arguments) {
+ hidl_vec<unvalidatedConvertOutput<Type>> halObject(arguments.size());
for (size_t i = 0; i < arguments.size(); ++i) {
- halObject[i] = NN_TRY(utils::convert(arguments[i]));
+ halObject[i] = NN_TRY(utils::unvalidatedConvert(arguments[i]));
}
return halObject;
}
+template <typename Type>
+decltype(utils::unvalidatedConvert(std::declval<Type>())) validatedConvert(const Type& canonical) {
+ const auto maybeVersion = nn::validate(canonical);
+ if (!maybeVersion.has_value()) {
+ return nn::error() << maybeVersion.error();
+ }
+ const auto version = maybeVersion.value();
+ if (version > kVersion) {
+ return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
+ }
+ return utils::unvalidatedConvert(canonical);
+}
+
} // anonymous namespace
-nn::GeneralResult<OperandType> convert(const nn::OperandType& operandType) {
+nn::GeneralResult<OperandType> unvalidatedConvert(const nn::OperandType& operandType) {
return static_cast<OperandType>(operandType);
}
-nn::GeneralResult<OperationType> convert(const nn::OperationType& operationType) {
+nn::GeneralResult<OperationType> unvalidatedConvert(const nn::OperationType& operationType) {
return static_cast<OperationType>(operationType);
}
-nn::GeneralResult<OperandLifeTime> convert(const nn::Operand::LifeTime& lifetime) {
+nn::GeneralResult<OperandLifeTime> unvalidatedConvert(const nn::Operand::LifeTime& lifetime) {
if (lifetime == nn::Operand::LifeTime::POINTER) {
return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
- << "Model cannot be converted because it contains pointer-based memory";
+ << "Model cannot be unvalidatedConverted because it contains pointer-based memory";
}
return static_cast<OperandLifeTime>(lifetime);
}
-nn::GeneralResult<DeviceStatus> convert(const nn::DeviceStatus& deviceStatus) {
+nn::GeneralResult<DeviceStatus> unvalidatedConvert(const nn::DeviceStatus& deviceStatus) {
return static_cast<DeviceStatus>(deviceStatus);
}
-nn::GeneralResult<PerformanceInfo> convert(
+nn::GeneralResult<PerformanceInfo> unvalidatedConvert(
const nn::Capabilities::PerformanceInfo& performanceInfo) {
return PerformanceInfo{
.execTime = performanceInfo.execTime,
@@ -248,16 +304,16 @@
};
}
-nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities) {
+nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
return Capabilities{
- .float32Performance = NN_TRY(convert(
+ .float32Performance = NN_TRY(unvalidatedConvert(
capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32))),
- .quantized8Performance = NN_TRY(convert(
+ .quantized8Performance = NN_TRY(unvalidatedConvert(
capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_QUANT8_ASYMM))),
};
}
-nn::GeneralResult<DataLocation> convert(const nn::DataLocation& location) {
+nn::GeneralResult<DataLocation> unvalidatedConvert(const nn::DataLocation& location) {
return DataLocation{
.poolIndex = location.poolIndex,
.offset = location.offset,
@@ -265,42 +321,43 @@
};
}
-nn::GeneralResult<Operand> convert(const nn::Operand& operand) {
+nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand) {
return Operand{
- .type = NN_TRY(convert(operand.type)),
+ .type = NN_TRY(unvalidatedConvert(operand.type)),
.dimensions = operand.dimensions,
.numberOfConsumers = 0,
.scale = operand.scale,
.zeroPoint = operand.zeroPoint,
- .lifetime = NN_TRY(convert(operand.lifetime)),
- .location = NN_TRY(convert(operand.location)),
+ .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
+ .location = NN_TRY(unvalidatedConvert(operand.location)),
};
}
-nn::GeneralResult<Operation> convert(const nn::Operation& operation) {
+nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
return Operation{
- .type = NN_TRY(convert(operation.type)),
+ .type = NN_TRY(unvalidatedConvert(operation.type)),
.inputs = operation.inputs,
.outputs = operation.outputs,
};
}
-nn::GeneralResult<hidl_vec<uint8_t>> convert(const nn::Model::OperandValues& operandValues) {
+nn::GeneralResult<hidl_vec<uint8_t>> unvalidatedConvert(
+ const nn::Model::OperandValues& operandValues) {
return hidl_vec<uint8_t>(operandValues.data(), operandValues.data() + operandValues.size());
}
-nn::GeneralResult<hidl_memory> convert(const nn::Memory& memory) {
+nn::GeneralResult<hidl_memory> unvalidatedConvert(const nn::Memory& memory) {
return hidl_memory(memory.name, NN_TRY(hal::utils::hidlHandleFromSharedHandle(memory.handle)),
memory.size);
}
-nn::GeneralResult<Model> convert(const nn::Model& model) {
+nn::GeneralResult<Model> unvalidatedConvert(const nn::Model& model) {
if (!hal::utils::hasNoPointerData(model)) {
return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
- << "Mdoel cannot be converted because it contains pointer-based memory";
+ << "Mdoel cannot be unvalidatedConverted because it contains pointer-based memory";
}
- auto operands = NN_TRY(convert(model.main.operands));
+ auto operands = NN_TRY(unvalidatedConvert(model.main.operands));
// Update number of consumers.
const auto numberOfConsumers =
@@ -312,45 +369,46 @@
return Model{
.operands = std::move(operands),
- .operations = NN_TRY(convert(model.main.operations)),
+ .operations = NN_TRY(unvalidatedConvert(model.main.operations)),
.inputIndexes = model.main.inputIndexes,
.outputIndexes = model.main.outputIndexes,
- .operandValues = NN_TRY(convert(model.operandValues)),
- .pools = NN_TRY(convert(model.pools)),
+ .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
+ .pools = NN_TRY(unvalidatedConvert(model.pools)),
};
}
-nn::GeneralResult<RequestArgument> convert(const nn::Request::Argument& requestArgument) {
+nn::GeneralResult<RequestArgument> unvalidatedConvert(
+ const nn::Request::Argument& requestArgument) {
if (requestArgument.lifetime == nn::Request::Argument::LifeTime::POINTER) {
return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
- << "Request cannot be converted because it contains pointer-based memory";
+ << "Request cannot be unvalidatedConverted because it contains pointer-based memory";
}
const bool hasNoValue = requestArgument.lifetime == nn::Request::Argument::LifeTime::NO_VALUE;
return RequestArgument{
.hasNoValue = hasNoValue,
- .location = NN_TRY(convert(requestArgument.location)),
+ .location = NN_TRY(unvalidatedConvert(requestArgument.location)),
.dimensions = requestArgument.dimensions,
};
}
-nn::GeneralResult<hidl_memory> convert(const nn::Request::MemoryPool& memoryPool) {
- return convert(std::get<nn::Memory>(memoryPool));
+nn::GeneralResult<hidl_memory> unvalidatedConvert(const nn::Request::MemoryPool& memoryPool) {
+ return unvalidatedConvert(std::get<nn::Memory>(memoryPool));
}
-nn::GeneralResult<Request> convert(const nn::Request& request) {
+nn::GeneralResult<Request> unvalidatedConvert(const nn::Request& request) {
if (!hal::utils::hasNoPointerData(request)) {
return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
- << "Request cannot be converted because it contains pointer-based memory";
+ << "Request cannot be unvalidatedConverted because it contains pointer-based memory";
}
return Request{
- .inputs = NN_TRY(convert(request.inputs)),
- .outputs = NN_TRY(convert(request.outputs)),
- .pools = NN_TRY(convert(request.pools)),
+ .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
+ .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
+ .pools = NN_TRY(unvalidatedConvert(request.pools)),
};
}
-nn::GeneralResult<ErrorStatus> convert(const nn::ErrorStatus& status) {
+nn::GeneralResult<ErrorStatus> unvalidatedConvert(const nn::ErrorStatus& status) {
switch (status) {
case nn::ErrorStatus::NONE:
case nn::ErrorStatus::DEVICE_UNAVAILABLE:
@@ -363,4 +421,24 @@
}
}
+nn::GeneralResult<DeviceStatus> convert(const nn::DeviceStatus& deviceStatus) {
+ return validatedConvert(deviceStatus);
+}
+
+nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities) {
+ return validatedConvert(capabilities);
+}
+
+nn::GeneralResult<Model> convert(const nn::Model& model) {
+ return validatedConvert(model);
+}
+
+nn::GeneralResult<Request> convert(const nn::Request& request) {
+ return validatedConvert(request);
+}
+
+nn::GeneralResult<ErrorStatus> convert(const nn::ErrorStatus& status) {
+ return validatedConvert(status);
+}
+
} // namespace android::hardware::neuralnetworks::V1_0::utils
diff --git a/neuralnetworks/1.0/utils/src/Device.cpp b/neuralnetworks/1.0/utils/src/Device.cpp
index 671416b..285c515 100644
--- a/neuralnetworks/1.0/utils/src/Device.cpp
+++ b/neuralnetworks/1.0/utils/src/Device.cpp
@@ -48,16 +48,15 @@
<< "uninitialized";
const auto cb = [&result](ErrorStatus status, const Capabilities& capabilities) {
if (status != ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
result = NN_ERROR(canonical) << "getCapabilities failed with " << toString(status);
} else {
- result = validatedConvertToCanonical(capabilities);
+ result = nn::convert(capabilities);
}
};
const auto ret = device->getCapabilities(cb);
- NN_TRY(hal::utils::handleTransportError(ret));
+ HANDLE_TRANSPORT_FAILURE(ret);
return result;
}
@@ -120,7 +119,8 @@
nn::GeneralResult<void> Device::wait() const {
const auto ret = kDevice->ping();
- return hal::utils::handleTransportError(ret);
+ HANDLE_TRANSPORT_FAILURE(ret);
+ return {};
}
nn::GeneralResult<std::vector<bool>> Device::getSupportedOperations(const nn::Model& model) const {
@@ -135,8 +135,7 @@
<< "uninitialized";
auto cb = [&result, &model](ErrorStatus status, const hidl_vec<bool>& supportedOperations) {
if (status != ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
result = NN_ERROR(canonical)
<< "getSupportedOperations failed with " << toString(status);
} else if (supportedOperations.size() != model.main.operations.size()) {
@@ -150,7 +149,7 @@
};
const auto ret = kDevice->getSupportedOperations(hidlModel, cb);
- NN_TRY(hal::utils::handleTransportError(ret));
+ HANDLE_TRANSPORT_FAILURE(ret);
return result;
}
@@ -170,10 +169,9 @@
const auto scoped = kDeathHandler.protectCallback(cb.get());
const auto ret = kDevice->prepareModel(hidlModel, cb);
- const auto status = NN_TRY(hal::utils::handleTransportError(ret));
+ const auto status = HANDLE_TRANSPORT_FAILURE(ret);
if (status != ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
return NN_ERROR(canonical) << "prepareModel failed with " << toString(status);
}
diff --git a/neuralnetworks/1.0/utils/src/PreparedModel.cpp b/neuralnetworks/1.0/utils/src/PreparedModel.cpp
index 11ccbe3..46dd3f8 100644
--- a/neuralnetworks/1.0/utils/src/PreparedModel.cpp
+++ b/neuralnetworks/1.0/utils/src/PreparedModel.cpp
@@ -67,11 +67,9 @@
const auto scoped = kDeathHandler.protectCallback(cb.get());
const auto ret = kPreparedModel->execute(hidlRequest, cb);
- const auto status =
- NN_TRY(hal::utils::makeExecutionFailure(hal::utils::handleTransportError(ret)));
+ const auto status = HANDLE_TRANSPORT_FAILURE(ret);
if (status != ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
return NN_ERROR(canonical) << "execute failed with " << toString(status);
}
diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h
index 16ddd53..f646462 100644
--- a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h
+++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h
@@ -24,9 +24,14 @@
namespace android::nn {
-GeneralResult<OperationType> convert(const hal::V1_1::OperationType& operationType);
+GeneralResult<OperationType> unvalidatedConvert(const hal::V1_1::OperationType& operationType);
+GeneralResult<Capabilities> unvalidatedConvert(const hal::V1_1::Capabilities& capabilities);
+GeneralResult<Operation> unvalidatedConvert(const hal::V1_1::Operation& operation);
+GeneralResult<Model> unvalidatedConvert(const hal::V1_1::Model& model);
+GeneralResult<ExecutionPreference> unvalidatedConvert(
+ const hal::V1_1::ExecutionPreference& executionPreference);
+
GeneralResult<Capabilities> convert(const hal::V1_1::Capabilities& capabilities);
-GeneralResult<Operation> convert(const hal::V1_1::Operation& operation);
GeneralResult<Model> convert(const hal::V1_1::Model& model);
GeneralResult<ExecutionPreference> convert(
const hal::V1_1::ExecutionPreference& executionPreference);
@@ -35,9 +40,14 @@
namespace android::hardware::neuralnetworks::V1_1::utils {
-nn::GeneralResult<OperationType> convert(const nn::OperationType& operationType);
+nn::GeneralResult<OperationType> unvalidatedConvert(const nn::OperationType& operationType);
+nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities);
+nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation);
+nn::GeneralResult<Model> unvalidatedConvert(const nn::Model& model);
+nn::GeneralResult<ExecutionPreference> unvalidatedConvert(
+ const nn::ExecutionPreference& executionPreference);
+
nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities);
-nn::GeneralResult<Operation> convert(const nn::Operation& operation);
nn::GeneralResult<Model> convert(const nn::Model& model);
nn::GeneralResult<ExecutionPreference> convert(const nn::ExecutionPreference& executionPreference);
diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h
index 0fee628..052d88e 100644
--- a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h
+++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h
@@ -22,15 +22,12 @@
#include <android-base/logging.h>
#include <android/hardware/neuralnetworks/1.1/types.h>
#include <nnapi/Result.h>
-#include <nnapi/TypeUtils.h>
#include <nnapi/Types.h>
-#include <nnapi/Validation.h>
#include <nnapi/hal/1.0/Conversions.h>
namespace android::hardware::neuralnetworks::V1_1::utils {
constexpr auto kDefaultExecutionPreference = ExecutionPreference::FAST_SINGLE_ANSWER;
-constexpr auto kVersion = nn::Version::ANDROID_P;
template <typename Type>
nn::Result<void> validate(const Type& halObject) {
@@ -38,11 +35,6 @@
if (!maybeCanonical.has_value()) {
return nn::error() << maybeCanonical.error().message;
}
- const auto version = NN_TRY(nn::validate(maybeCanonical.value()));
- if (version > utils::kVersion) {
- return NN_ERROR() << "Insufficient version: " << version << " vs required "
- << utils::kVersion;
- }
return {};
}
@@ -55,21 +47,6 @@
return result.has_value();
}
-template <typename Type>
-decltype(nn::convert(std::declval<Type>())) validatedConvertToCanonical(const Type& halObject) {
- auto canonical = NN_TRY(nn::convert(halObject));
- const auto maybeVersion = nn::validate(canonical);
- if (!maybeVersion.has_value()) {
- return nn::error() << maybeVersion.error();
- }
- const auto version = maybeVersion.value();
- if (version > utils::kVersion) {
- return NN_ERROR() << "Insufficient version: " << version << " vs required "
- << utils::kVersion;
- }
- return canonical;
-}
-
} // namespace android::hardware::neuralnetworks::V1_1::utils
#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_H
diff --git a/neuralnetworks/1.1/utils/src/Conversions.cpp b/neuralnetworks/1.1/utils/src/Conversions.cpp
index ffe0752..359f68a 100644
--- a/neuralnetworks/1.1/utils/src/Conversions.cpp
+++ b/neuralnetworks/1.1/utils/src/Conversions.cpp
@@ -23,7 +23,9 @@
#include <nnapi/OperationTypes.h>
#include <nnapi/Result.h>
#include <nnapi/SharedMemory.h>
+#include <nnapi/TypeUtils.h>
#include <nnapi/Types.h>
+#include <nnapi/Validation.h>
#include <nnapi/hal/1.0/Conversions.h>
#include <nnapi/hal/CommonUtils.h>
@@ -33,35 +35,58 @@
#include <type_traits>
#include <utility>
+namespace {
+
+constexpr auto kVersion = android::nn::Version::ANDROID_P;
+
+} // namespace
+
namespace android::nn {
namespace {
using hardware::hidl_vec;
template <typename Input>
-using convertOutput = std::decay_t<decltype(convert(std::declval<Input>()).value())>;
+using unvalidatedConvertOutput =
+ std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
template <typename Type>
-GeneralResult<std::vector<convertOutput<Type>>> convert(const hidl_vec<Type>& arguments) {
- std::vector<convertOutput<Type>> canonical;
+GeneralResult<std::vector<unvalidatedConvertOutput<Type>>> unvalidatedConvert(
+ const hidl_vec<Type>& arguments) {
+ std::vector<unvalidatedConvertOutput<Type>> canonical;
canonical.reserve(arguments.size());
for (const auto& argument : arguments) {
- canonical.push_back(NN_TRY(nn::convert(argument)));
+ canonical.push_back(NN_TRY(nn::unvalidatedConvert(argument)));
+ }
+ return canonical;
+}
+
+template <typename Type>
+decltype(nn::unvalidatedConvert(std::declval<Type>())) validatedConvert(const Type& halObject) {
+ auto canonical = NN_TRY(nn::unvalidatedConvert(halObject));
+ const auto maybeVersion = validate(canonical);
+ if (!maybeVersion.has_value()) {
+ return error() << maybeVersion.error();
+ }
+ const auto version = maybeVersion.value();
+ if (version > kVersion) {
+ return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
}
return canonical;
}
} // anonymous namespace
-GeneralResult<OperationType> convert(const hal::V1_1::OperationType& operationType) {
+GeneralResult<OperationType> unvalidatedConvert(const hal::V1_1::OperationType& operationType) {
return static_cast<OperationType>(operationType);
}
-GeneralResult<Capabilities> convert(const hal::V1_1::Capabilities& capabilities) {
- const auto quantized8Performance = NN_TRY(convert(capabilities.quantized8Performance));
- const auto float32Performance = NN_TRY(convert(capabilities.float32Performance));
+GeneralResult<Capabilities> unvalidatedConvert(const hal::V1_1::Capabilities& capabilities) {
+ const auto quantized8Performance =
+ NN_TRY(unvalidatedConvert(capabilities.quantized8Performance));
+ const auto float32Performance = NN_TRY(unvalidatedConvert(capabilities.float32Performance));
const auto relaxedFloat32toFloat16Performance =
- NN_TRY(convert(capabilities.relaxedFloat32toFloat16Performance));
+ NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16Performance));
auto table = hal::utils::makeQuantized8PerformanceConsistentWithP(float32Performance,
quantized8Performance);
@@ -73,16 +98,16 @@
};
}
-GeneralResult<Operation> convert(const hal::V1_1::Operation& operation) {
+GeneralResult<Operation> unvalidatedConvert(const hal::V1_1::Operation& operation) {
return Operation{
- .type = NN_TRY(convert(operation.type)),
+ .type = NN_TRY(unvalidatedConvert(operation.type)),
.inputs = operation.inputs,
.outputs = operation.outputs,
};
}
-GeneralResult<Model> convert(const hal::V1_1::Model& model) {
- auto operations = NN_TRY(convert(model.operations));
+GeneralResult<Model> unvalidatedConvert(const hal::V1_1::Model& model) {
+ auto operations = NN_TRY(unvalidatedConvert(model.operations));
// Verify number of consumers.
const auto numberOfConsumers =
@@ -97,7 +122,7 @@
}
auto main = Model::Subgraph{
- .operands = NN_TRY(convert(model.operands)),
+ .operands = NN_TRY(unvalidatedConvert(model.operands)),
.operations = std::move(operations),
.inputIndexes = model.inputIndexes,
.outputIndexes = model.outputIndexes,
@@ -105,85 +130,114 @@
return Model{
.main = std::move(main),
- .operandValues = NN_TRY(convert(model.operandValues)),
- .pools = NN_TRY(convert(model.pools)),
+ .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
+ .pools = NN_TRY(unvalidatedConvert(model.pools)),
.relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
};
}
-GeneralResult<ExecutionPreference> convert(
+GeneralResult<ExecutionPreference> unvalidatedConvert(
const hal::V1_1::ExecutionPreference& executionPreference) {
return static_cast<ExecutionPreference>(executionPreference);
}
+GeneralResult<Capabilities> convert(const hal::V1_1::Capabilities& capabilities) {
+ return validatedConvert(capabilities);
+}
+
+GeneralResult<Model> convert(const hal::V1_1::Model& model) {
+ return validatedConvert(model);
+}
+
+GeneralResult<ExecutionPreference> convert(
+ const hal::V1_1::ExecutionPreference& executionPreference) {
+ return validatedConvert(executionPreference);
+}
+
} // namespace android::nn
namespace android::hardware::neuralnetworks::V1_1::utils {
namespace {
-using utils::convert;
+using utils::unvalidatedConvert;
-nn::GeneralResult<V1_0::PerformanceInfo> convert(
+nn::GeneralResult<V1_0::PerformanceInfo> unvalidatedConvert(
const nn::Capabilities::PerformanceInfo& performanceInfo) {
- return V1_0::utils::convert(performanceInfo);
+ return V1_0::utils::unvalidatedConvert(performanceInfo);
}
-nn::GeneralResult<V1_0::Operand> convert(const nn::Operand& operand) {
- return V1_0::utils::convert(operand);
+nn::GeneralResult<V1_0::Operand> unvalidatedConvert(const nn::Operand& operand) {
+ return V1_0::utils::unvalidatedConvert(operand);
}
-nn::GeneralResult<hidl_vec<uint8_t>> convert(const nn::Model::OperandValues& operandValues) {
- return V1_0::utils::convert(operandValues);
+nn::GeneralResult<hidl_vec<uint8_t>> unvalidatedConvert(
+ const nn::Model::OperandValues& operandValues) {
+ return V1_0::utils::unvalidatedConvert(operandValues);
}
-nn::GeneralResult<hidl_memory> convert(const nn::Memory& memory) {
- return V1_0::utils::convert(memory);
+nn::GeneralResult<hidl_memory> unvalidatedConvert(const nn::Memory& memory) {
+ return V1_0::utils::unvalidatedConvert(memory);
}
template <typename Input>
-using convertOutput = std::decay_t<decltype(convert(std::declval<Input>()).value())>;
+using unvalidatedConvertOutput =
+ std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
template <typename Type>
-nn::GeneralResult<hidl_vec<convertOutput<Type>>> convert(const std::vector<Type>& arguments) {
- hidl_vec<convertOutput<Type>> halObject(arguments.size());
+nn::GeneralResult<hidl_vec<unvalidatedConvertOutput<Type>>> unvalidatedConvert(
+ const std::vector<Type>& arguments) {
+ hidl_vec<unvalidatedConvertOutput<Type>> halObject(arguments.size());
for (size_t i = 0; i < arguments.size(); ++i) {
- halObject[i] = NN_TRY(convert(arguments[i]));
+ halObject[i] = NN_TRY(unvalidatedConvert(arguments[i]));
}
return halObject;
}
+template <typename Type>
+decltype(utils::unvalidatedConvert(std::declval<Type>())) validatedConvert(const Type& canonical) {
+ const auto maybeVersion = nn::validate(canonical);
+ if (!maybeVersion.has_value()) {
+ return nn::error() << maybeVersion.error();
+ }
+ const auto version = maybeVersion.value();
+ if (version > kVersion) {
+ return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
+ }
+ return utils::unvalidatedConvert(canonical);
+}
+
} // anonymous namespace
-nn::GeneralResult<OperationType> convert(const nn::OperationType& operationType) {
+nn::GeneralResult<OperationType> unvalidatedConvert(const nn::OperationType& operationType) {
return static_cast<OperationType>(operationType);
}
-nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities) {
+nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
return Capabilities{
- .float32Performance = NN_TRY(convert(
+ .float32Performance = NN_TRY(unvalidatedConvert(
capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32))),
- .quantized8Performance = NN_TRY(convert(
+ .quantized8Performance = NN_TRY(unvalidatedConvert(
capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_QUANT8_ASYMM))),
- .relaxedFloat32toFloat16Performance =
- NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
+ .relaxedFloat32toFloat16Performance = NN_TRY(
+ unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
};
}
-nn::GeneralResult<Operation> convert(const nn::Operation& operation) {
+nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
return Operation{
- .type = NN_TRY(convert(operation.type)),
+ .type = NN_TRY(unvalidatedConvert(operation.type)),
.inputs = operation.inputs,
.outputs = operation.outputs,
};
}
-nn::GeneralResult<Model> convert(const nn::Model& model) {
+nn::GeneralResult<Model> unvalidatedConvert(const nn::Model& model) {
if (!hal::utils::hasNoPointerData(model)) {
return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
- << "Mdoel cannot be converted because it contains pointer-based memory";
+ << "Mdoel cannot be unvalidatedConverted because it contains pointer-based memory";
}
- auto operands = NN_TRY(convert(model.main.operands));
+ auto operands = NN_TRY(unvalidatedConvert(model.main.operands));
// Update number of consumers.
const auto numberOfConsumers =
@@ -195,17 +249,30 @@
return Model{
.operands = std::move(operands),
- .operations = NN_TRY(convert(model.main.operations)),
+ .operations = NN_TRY(unvalidatedConvert(model.main.operations)),
.inputIndexes = model.main.inputIndexes,
.outputIndexes = model.main.outputIndexes,
- .operandValues = NN_TRY(convert(model.operandValues)),
- .pools = NN_TRY(convert(model.pools)),
+ .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
+ .pools = NN_TRY(unvalidatedConvert(model.pools)),
.relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
};
}
-nn::GeneralResult<ExecutionPreference> convert(const nn::ExecutionPreference& executionPreference) {
+nn::GeneralResult<ExecutionPreference> unvalidatedConvert(
+ const nn::ExecutionPreference& executionPreference) {
return static_cast<ExecutionPreference>(executionPreference);
}
+nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities) {
+ return validatedConvert(capabilities);
+}
+
+nn::GeneralResult<Model> convert(const nn::Model& model) {
+ return validatedConvert(model);
+}
+
+nn::GeneralResult<ExecutionPreference> convert(const nn::ExecutionPreference& executionPreference) {
+ return validatedConvert(executionPreference);
+}
+
} // namespace android::hardware::neuralnetworks::V1_1::utils
diff --git a/neuralnetworks/1.1/utils/src/Device.cpp b/neuralnetworks/1.1/utils/src/Device.cpp
index a0378c9..f73d3f8 100644
--- a/neuralnetworks/1.1/utils/src/Device.cpp
+++ b/neuralnetworks/1.1/utils/src/Device.cpp
@@ -49,16 +49,15 @@
<< "uninitialized";
const auto cb = [&result](V1_0::ErrorStatus status, const Capabilities& capabilities) {
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
result = NN_ERROR(canonical) << "getCapabilities_1_1 failed with " << toString(status);
} else {
- result = validatedConvertToCanonical(capabilities);
+ result = nn::convert(capabilities);
}
};
const auto ret = device->getCapabilities_1_1(cb);
- NN_TRY(hal::utils::handleTransportError(ret));
+ HANDLE_TRANSPORT_FAILURE(ret);
return result;
}
@@ -121,7 +120,8 @@
nn::GeneralResult<void> Device::wait() const {
const auto ret = kDevice->ping();
- return hal::utils::handleTransportError(ret);
+ HANDLE_TRANSPORT_FAILURE(ret);
+ return {};
}
nn::GeneralResult<std::vector<bool>> Device::getSupportedOperations(const nn::Model& model) const {
@@ -137,8 +137,7 @@
auto cb = [&result, &model](V1_0::ErrorStatus status,
const hidl_vec<bool>& supportedOperations) {
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
result = NN_ERROR(canonical)
<< "getSupportedOperations_1_1 failed with " << toString(status);
} else if (supportedOperations.size() != model.main.operations.size()) {
@@ -152,7 +151,7 @@
};
const auto ret = kDevice->getSupportedOperations_1_1(hidlModel, cb);
- NN_TRY(hal::utils::handleTransportError(ret));
+ HANDLE_TRANSPORT_FAILURE(ret);
return result;
}
@@ -173,10 +172,9 @@
const auto scoped = kDeathHandler.protectCallback(cb.get());
const auto ret = kDevice->prepareModel_1_1(hidlModel, hidlPreference, cb);
- const auto status = NN_TRY(hal::utils::handleTransportError(ret));
+ const auto status = HANDLE_TRANSPORT_FAILURE(ret);
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
return NN_ERROR(canonical) << "prepareModel failed with " << toString(status);
}
diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h
index 24911fe..5dcbc0b 100644
--- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h
+++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h
@@ -24,27 +24,34 @@
namespace android::nn {
-GeneralResult<OperandType> convert(const hal::V1_2::OperandType& operandType);
-GeneralResult<OperationType> convert(const hal::V1_2::OperationType& operationType);
+GeneralResult<OperandType> unvalidatedConvert(const hal::V1_2::OperandType& operandType);
+GeneralResult<OperationType> unvalidatedConvert(const hal::V1_2::OperationType& operationType);
+GeneralResult<DeviceType> unvalidatedConvert(const hal::V1_2::DeviceType& deviceType);
+GeneralResult<Capabilities> unvalidatedConvert(const hal::V1_2::Capabilities& capabilities);
+GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
+ const hal::V1_2::Capabilities::OperandPerformance& operandPerformance);
+GeneralResult<Operation> unvalidatedConvert(const hal::V1_2::Operation& operation);
+GeneralResult<Operand::SymmPerChannelQuantParams> unvalidatedConvert(
+ const hal::V1_2::SymmPerChannelQuantParams& symmPerChannelQuantParams);
+GeneralResult<Operand> unvalidatedConvert(const hal::V1_2::Operand& operand);
+GeneralResult<Operand::ExtraParams> unvalidatedConvert(
+ const hal::V1_2::Operand::ExtraParams& extraParams);
+GeneralResult<Model> unvalidatedConvert(const hal::V1_2::Model& model);
+GeneralResult<Model::ExtensionNameAndPrefix> unvalidatedConvert(
+ const hal::V1_2::Model::ExtensionNameAndPrefix& extensionNameAndPrefix);
+GeneralResult<OutputShape> unvalidatedConvert(const hal::V1_2::OutputShape& outputShape);
+GeneralResult<MeasureTiming> unvalidatedConvert(const hal::V1_2::MeasureTiming& measureTiming);
+GeneralResult<Timing> unvalidatedConvert(const hal::V1_2::Timing& timing);
+GeneralResult<Extension> unvalidatedConvert(const hal::V1_2::Extension& extension);
+GeneralResult<Extension::OperandTypeInformation> unvalidatedConvert(
+ const hal::V1_2::Extension::OperandTypeInformation& operandTypeInformation);
+GeneralResult<SharedHandle> unvalidatedConvert(const hardware::hidl_handle& handle);
+
GeneralResult<DeviceType> convert(const hal::V1_2::DeviceType& deviceType);
GeneralResult<Capabilities> convert(const hal::V1_2::Capabilities& capabilities);
-GeneralResult<Capabilities::OperandPerformance> convert(
- const hal::V1_2::Capabilities::OperandPerformance& operandPerformance);
-GeneralResult<Operation> convert(const hal::V1_2::Operation& operation);
-GeneralResult<Operand::SymmPerChannelQuantParams> convert(
- const hal::V1_2::SymmPerChannelQuantParams& symmPerChannelQuantParams);
-GeneralResult<Operand> convert(const hal::V1_2::Operand& operand);
-GeneralResult<Operand::ExtraParams> convert(const hal::V1_2::Operand::ExtraParams& extraParams);
GeneralResult<Model> convert(const hal::V1_2::Model& model);
-GeneralResult<Model::ExtensionNameAndPrefix> convert(
- const hal::V1_2::Model::ExtensionNameAndPrefix& extensionNameAndPrefix);
-GeneralResult<OutputShape> convert(const hal::V1_2::OutputShape& outputShape);
GeneralResult<MeasureTiming> convert(const hal::V1_2::MeasureTiming& measureTiming);
GeneralResult<Timing> convert(const hal::V1_2::Timing& timing);
-GeneralResult<Extension> convert(const hal::V1_2::Extension& extension);
-GeneralResult<Extension::OperandTypeInformation> convert(
- const hal::V1_2::Extension::OperandTypeInformation& operandTypeInformation);
-GeneralResult<SharedHandle> convert(const hardware::hidl_handle& handle);
GeneralResult<std::vector<Extension>> convert(
const hardware::hidl_vec<hal::V1_2::Extension>& extensions);
@@ -57,27 +64,34 @@
namespace android::hardware::neuralnetworks::V1_2::utils {
-nn::GeneralResult<OperandType> convert(const nn::OperandType& operandType);
-nn::GeneralResult<OperationType> convert(const nn::OperationType& operationType);
+nn::GeneralResult<OperandType> unvalidatedConvert(const nn::OperandType& operandType);
+nn::GeneralResult<OperationType> unvalidatedConvert(const nn::OperationType& operationType);
+nn::GeneralResult<DeviceType> unvalidatedConvert(const nn::DeviceType& deviceType);
+nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities);
+nn::GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
+ const nn::Capabilities::OperandPerformance& operandPerformance);
+nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation);
+nn::GeneralResult<SymmPerChannelQuantParams> unvalidatedConvert(
+ const nn::Operand::SymmPerChannelQuantParams& symmPerChannelQuantParams);
+nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand);
+nn::GeneralResult<Operand::ExtraParams> unvalidatedConvert(
+ const nn::Operand::ExtraParams& extraParams);
+nn::GeneralResult<Model> unvalidatedConvert(const nn::Model& model);
+nn::GeneralResult<Model::ExtensionNameAndPrefix> unvalidatedConvert(
+ const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix);
+nn::GeneralResult<OutputShape> unvalidatedConvert(const nn::OutputShape& outputShape);
+nn::GeneralResult<MeasureTiming> unvalidatedConvert(const nn::MeasureTiming& measureTiming);
+nn::GeneralResult<Timing> unvalidatedConvert(const nn::Timing& timing);
+nn::GeneralResult<Extension> unvalidatedConvert(const nn::Extension& extension);
+nn::GeneralResult<Extension::OperandTypeInformation> unvalidatedConvert(
+ const nn::Extension::OperandTypeInformation& operandTypeInformation);
+nn::GeneralResult<hidl_handle> unvalidatedConvert(const nn::SharedHandle& handle);
+
nn::GeneralResult<DeviceType> convert(const nn::DeviceType& deviceType);
nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities);
-nn::GeneralResult<Capabilities::OperandPerformance> convert(
- const nn::Capabilities::OperandPerformance& operandPerformance);
-nn::GeneralResult<Operation> convert(const nn::Operation& operation);
-nn::GeneralResult<SymmPerChannelQuantParams> convert(
- const nn::Operand::SymmPerChannelQuantParams& symmPerChannelQuantParams);
-nn::GeneralResult<Operand> convert(const nn::Operand& operand);
-nn::GeneralResult<Operand::ExtraParams> convert(const nn::Operand::ExtraParams& extraParams);
nn::GeneralResult<Model> convert(const nn::Model& model);
-nn::GeneralResult<Model::ExtensionNameAndPrefix> convert(
- const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix);
-nn::GeneralResult<OutputShape> convert(const nn::OutputShape& outputShape);
nn::GeneralResult<MeasureTiming> convert(const nn::MeasureTiming& measureTiming);
nn::GeneralResult<Timing> convert(const nn::Timing& timing);
-nn::GeneralResult<Extension> convert(const nn::Extension& extension);
-nn::GeneralResult<Extension::OperandTypeInformation> convert(
- const nn::Extension::OperandTypeInformation& operandTypeInformation);
-nn::GeneralResult<hidl_handle> convert(const nn::SharedHandle& handle);
nn::GeneralResult<hidl_vec<Extension>> convert(const std::vector<nn::Extension>& extensions);
nn::GeneralResult<hidl_vec<hidl_handle>> convert(const std::vector<nn::SharedHandle>& handles);
diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h
index bbd5343..a68830d 100644
--- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h
+++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h
@@ -37,7 +37,6 @@
nn::GeneralResult<std::string> initVersionString(V1_2::IDevice* device);
nn::GeneralResult<nn::DeviceType> initDeviceType(V1_2::IDevice* device);
nn::GeneralResult<std::vector<nn::Extension>> initExtensions(V1_2::IDevice* device);
-nn::GeneralResult<nn::Capabilities> initCapabilities(V1_2::IDevice* device);
nn::GeneralResult<std::pair<uint32_t, uint32_t>> initNumberOfCacheFilesNeeded(
V1_2::IDevice* device);
diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h
index a9a6bae..70149a2 100644
--- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h
+++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h
@@ -22,9 +22,7 @@
#include <android-base/logging.h>
#include <android/hardware/neuralnetworks/1.2/types.h>
#include <nnapi/Result.h>
-#include <nnapi/TypeUtils.h>
#include <nnapi/Types.h>
-#include <nnapi/Validation.h>
#include <nnapi/hal/1.0/Conversions.h>
#include <nnapi/hal/1.1/Conversions.h>
@@ -35,7 +33,6 @@
constexpr auto kDefaultMesaureTiming = MeasureTiming::NO;
constexpr auto kNoTiming = Timing{.timeOnDevice = std::numeric_limits<uint64_t>::max(),
.timeInDriver = std::numeric_limits<uint64_t>::max()};
-constexpr auto kVersion = nn::Version::ANDROID_Q;
template <typename Type>
nn::Result<void> validate(const Type& halObject) {
@@ -43,11 +40,6 @@
if (!maybeCanonical.has_value()) {
return nn::error() << maybeCanonical.error().message;
}
- const auto version = NN_TRY(nn::validate(maybeCanonical.value()));
- if (version > utils::kVersion) {
- return NN_ERROR() << "Insufficient version: " << version << " vs required "
- << utils::kVersion;
- }
return {};
}
@@ -60,21 +52,6 @@
return result.has_value();
}
-template <typename Type>
-decltype(nn::convert(std::declval<Type>())) validatedConvertToCanonical(const Type& halObject) {
- auto canonical = NN_TRY(nn::convert(halObject));
- const auto maybeVersion = nn::validate(canonical);
- if (!maybeVersion.has_value()) {
- return nn::error() << maybeVersion.error();
- }
- const auto version = maybeVersion.value();
- if (version > utils::kVersion) {
- return NN_ERROR() << "Insufficient version: " << version << " vs required "
- << utils::kVersion;
- }
- return canonical;
-}
-
} // namespace android::hardware::neuralnetworks::V1_2::utils
#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_H
diff --git a/neuralnetworks/1.2/utils/src/Callbacks.cpp b/neuralnetworks/1.2/utils/src/Callbacks.cpp
index cb739f0..39f88c2 100644
--- a/neuralnetworks/1.2/utils/src/Callbacks.cpp
+++ b/neuralnetworks/1.2/utils/src/Callbacks.cpp
@@ -52,8 +52,7 @@
nn::GeneralResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>>
convertExecutionGeneralResultsHelper(const hidl_vec<OutputShape>& outputShapes,
const Timing& timing) {
- return std::make_pair(NN_TRY(validatedConvertToCanonical(outputShapes)),
- NN_TRY(validatedConvertToCanonical(timing)));
+ return std::make_pair(NN_TRY(nn::convert(outputShapes)), NN_TRY(nn::convert(timing)));
}
nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>>
@@ -67,8 +66,7 @@
Return<void> PreparedModelCallback::notify(V1_0::ErrorStatus status,
const sp<V1_0::IPreparedModel>& preparedModel) {
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status));
} else if (preparedModel == nullptr) {
notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
@@ -82,8 +80,7 @@
Return<void> PreparedModelCallback::notify_1_2(V1_0::ErrorStatus status,
const sp<IPreparedModel>& preparedModel) {
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status));
} else if (preparedModel == nullptr) {
notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
@@ -110,8 +107,7 @@
Return<void> ExecutionCallback::notify(V1_0::ErrorStatus status) {
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status));
} else {
notifyInternal({});
@@ -123,8 +119,7 @@
const hidl_vec<OutputShape>& outputShapes,
const Timing& timing) {
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status));
} else {
notifyInternal(convertExecutionGeneralResults(outputShapes, timing));
diff --git a/neuralnetworks/1.2/utils/src/Conversions.cpp b/neuralnetworks/1.2/utils/src/Conversions.cpp
index 08c94de..f11474f 100644
--- a/neuralnetworks/1.2/utils/src/Conversions.cpp
+++ b/neuralnetworks/1.2/utils/src/Conversions.cpp
@@ -24,6 +24,7 @@
#include <nnapi/SharedMemory.h>
#include <nnapi/TypeUtils.h>
#include <nnapi/Types.h>
+#include <nnapi/Validation.h>
#include <nnapi/hal/1.0/Conversions.h>
#include <nnapi/hal/CommonUtils.h>
#include <nnapi/hal/HandleError.h>
@@ -42,6 +43,8 @@
return static_cast<std::underlying_type_t<Type>>(value);
}
+constexpr auto kVersion = android::nn::Version::ANDROID_Q;
+
} // namespace
namespace android::nn {
@@ -76,42 +79,70 @@
using hardware::hidl_vec;
template <typename Input>
-using ConvertOutput = std::decay_t<decltype(convert(std::declval<Input>()).value())>;
+using unvalidatedConvertOutput =
+ std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
template <typename Type>
-GeneralResult<std::vector<ConvertOutput<Type>>> convertVec(const hidl_vec<Type>& arguments) {
- std::vector<ConvertOutput<Type>> canonical;
+GeneralResult<std::vector<unvalidatedConvertOutput<Type>>> unvalidatedConvertVec(
+ const hidl_vec<Type>& arguments) {
+ std::vector<unvalidatedConvertOutput<Type>> canonical;
canonical.reserve(arguments.size());
for (const auto& argument : arguments) {
- canonical.push_back(NN_TRY(nn::convert(argument)));
+ canonical.push_back(NN_TRY(nn::unvalidatedConvert(argument)));
}
return canonical;
}
template <typename Type>
-GeneralResult<std::vector<ConvertOutput<Type>>> convert(const hidl_vec<Type>& arguments) {
- return convertVec(arguments);
+GeneralResult<std::vector<unvalidatedConvertOutput<Type>>> unvalidatedConvert(
+ const hidl_vec<Type>& arguments) {
+ return unvalidatedConvertVec(arguments);
+}
+
+template <typename Type>
+decltype(nn::unvalidatedConvert(std::declval<Type>())) validatedConvert(const Type& halObject) {
+ auto canonical = NN_TRY(nn::unvalidatedConvert(halObject));
+ const auto maybeVersion = validate(canonical);
+ if (!maybeVersion.has_value()) {
+ return error() << maybeVersion.error();
+ }
+ const auto version = maybeVersion.value();
+ if (version > kVersion) {
+ return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
+ }
+ return canonical;
+}
+
+template <typename Type>
+GeneralResult<std::vector<unvalidatedConvertOutput<Type>>> validatedConvert(
+ const hidl_vec<Type>& arguments) {
+ std::vector<unvalidatedConvertOutput<Type>> canonical;
+ canonical.reserve(arguments.size());
+ for (const auto& argument : arguments) {
+ canonical.push_back(NN_TRY(validatedConvert(argument)));
+ }
+ return canonical;
}
} // anonymous namespace
-GeneralResult<OperandType> convert(const hal::V1_2::OperandType& operandType) {
+GeneralResult<OperandType> unvalidatedConvert(const hal::V1_2::OperandType& operandType) {
return static_cast<OperandType>(operandType);
}
-GeneralResult<OperationType> convert(const hal::V1_2::OperationType& operationType) {
+GeneralResult<OperationType> unvalidatedConvert(const hal::V1_2::OperationType& operationType) {
return static_cast<OperationType>(operationType);
}
-GeneralResult<DeviceType> convert(const hal::V1_2::DeviceType& deviceType) {
+GeneralResult<DeviceType> unvalidatedConvert(const hal::V1_2::DeviceType& deviceType) {
return static_cast<DeviceType>(deviceType);
}
-GeneralResult<Capabilities> convert(const hal::V1_2::Capabilities& capabilities) {
+GeneralResult<Capabilities> unvalidatedConvert(const hal::V1_2::Capabilities& capabilities) {
const bool validOperandTypes = std::all_of(
capabilities.operandPerformance.begin(), capabilities.operandPerformance.end(),
[](const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) {
- const auto maybeType = convert(operandPerformance.type);
+ const auto maybeType = unvalidatedConvert(operandPerformance.type);
return !maybeType.has_value() ? false : validOperandType(maybeType.value());
});
if (!validOperandTypes) {
@@ -120,10 +151,10 @@
}
const auto relaxedFloat32toFloat16PerformanceScalar =
- NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
+ NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
const auto relaxedFloat32toFloat16PerformanceTensor =
- NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
- auto operandPerformance = NN_TRY(convert(capabilities.operandPerformance));
+ NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
+ auto operandPerformance = NN_TRY(unvalidatedConvert(capabilities.operandPerformance));
auto table = NN_TRY(hal::utils::makeGeneralFailure(
Capabilities::OperandPerformanceTable::create(std::move(operandPerformance)),
@@ -136,23 +167,23 @@
};
}
-GeneralResult<Capabilities::OperandPerformance> convert(
+GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) {
return Capabilities::OperandPerformance{
- .type = NN_TRY(convert(operandPerformance.type)),
- .info = NN_TRY(convert(operandPerformance.info)),
+ .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
+ .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
};
}
-GeneralResult<Operation> convert(const hal::V1_2::Operation& operation) {
+GeneralResult<Operation> unvalidatedConvert(const hal::V1_2::Operation& operation) {
return Operation{
- .type = NN_TRY(convert(operation.type)),
+ .type = NN_TRY(unvalidatedConvert(operation.type)),
.inputs = operation.inputs,
.outputs = operation.outputs,
};
}
-GeneralResult<Operand::SymmPerChannelQuantParams> convert(
+GeneralResult<Operand::SymmPerChannelQuantParams> unvalidatedConvert(
const hal::V1_2::SymmPerChannelQuantParams& symmPerChannelQuantParams) {
return Operand::SymmPerChannelQuantParams{
.scales = symmPerChannelQuantParams.scales,
@@ -160,25 +191,26 @@
};
}
-GeneralResult<Operand> convert(const hal::V1_2::Operand& operand) {
+GeneralResult<Operand> unvalidatedConvert(const hal::V1_2::Operand& operand) {
return Operand{
- .type = NN_TRY(convert(operand.type)),
+ .type = NN_TRY(unvalidatedConvert(operand.type)),
.dimensions = operand.dimensions,
.scale = operand.scale,
.zeroPoint = operand.zeroPoint,
- .lifetime = NN_TRY(convert(operand.lifetime)),
- .location = NN_TRY(convert(operand.location)),
- .extraParams = NN_TRY(convert(operand.extraParams)),
+ .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
+ .location = NN_TRY(unvalidatedConvert(operand.location)),
+ .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
};
}
-GeneralResult<Operand::ExtraParams> convert(const hal::V1_2::Operand::ExtraParams& extraParams) {
+GeneralResult<Operand::ExtraParams> unvalidatedConvert(
+ const hal::V1_2::Operand::ExtraParams& extraParams) {
using Discriminator = hal::V1_2::Operand::ExtraParams::hidl_discriminator;
switch (extraParams.getDiscriminator()) {
case Discriminator::none:
return Operand::NoParams{};
case Discriminator::channelQuant:
- return convert(extraParams.channelQuant());
+ return unvalidatedConvert(extraParams.channelQuant());
case Discriminator::extension:
return extraParams.extension();
}
@@ -187,8 +219,8 @@
<< underlyingType(extraParams.getDiscriminator());
}
-GeneralResult<Model> convert(const hal::V1_2::Model& model) {
- auto operations = NN_TRY(convert(model.operations));
+GeneralResult<Model> unvalidatedConvert(const hal::V1_2::Model& model) {
+ auto operations = NN_TRY(unvalidatedConvert(model.operations));
// Verify number of consumers.
const auto numberOfConsumers =
@@ -203,7 +235,7 @@
}
auto main = Model::Subgraph{
- .operands = NN_TRY(convert(model.operands)),
+ .operands = NN_TRY(unvalidatedConvert(model.operands)),
.operations = std::move(operations),
.inputIndexes = model.inputIndexes,
.outputIndexes = model.outputIndexes,
@@ -211,14 +243,14 @@
return Model{
.main = std::move(main),
- .operandValues = NN_TRY(convert(model.operandValues)),
- .pools = NN_TRY(convert(model.pools)),
+ .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
+ .pools = NN_TRY(unvalidatedConvert(model.pools)),
.relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
- .extensionNameToPrefix = NN_TRY(convert(model.extensionNameToPrefix)),
+ .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
};
}
-GeneralResult<Model::ExtensionNameAndPrefix> convert(
+GeneralResult<Model::ExtensionNameAndPrefix> unvalidatedConvert(
const hal::V1_2::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) {
return Model::ExtensionNameAndPrefix{
.name = extensionNameAndPrefix.name,
@@ -226,29 +258,29 @@
};
}
-GeneralResult<OutputShape> convert(const hal::V1_2::OutputShape& outputShape) {
+GeneralResult<OutputShape> unvalidatedConvert(const hal::V1_2::OutputShape& outputShape) {
return OutputShape{
.dimensions = outputShape.dimensions,
.isSufficient = outputShape.isSufficient,
};
}
-GeneralResult<MeasureTiming> convert(const hal::V1_2::MeasureTiming& measureTiming) {
+GeneralResult<MeasureTiming> unvalidatedConvert(const hal::V1_2::MeasureTiming& measureTiming) {
return static_cast<MeasureTiming>(measureTiming);
}
-GeneralResult<Timing> convert(const hal::V1_2::Timing& timing) {
+GeneralResult<Timing> unvalidatedConvert(const hal::V1_2::Timing& timing) {
return Timing{.timeOnDevice = timing.timeOnDevice, .timeInDriver = timing.timeInDriver};
}
-GeneralResult<Extension> convert(const hal::V1_2::Extension& extension) {
+GeneralResult<Extension> unvalidatedConvert(const hal::V1_2::Extension& extension) {
return Extension{
.name = extension.name,
- .operandTypes = NN_TRY(convert(extension.operandTypes)),
+ .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes)),
};
}
-GeneralResult<Extension::OperandTypeInformation> convert(
+GeneralResult<Extension::OperandTypeInformation> unvalidatedConvert(
const hal::V1_2::Extension::OperandTypeInformation& operandTypeInformation) {
return Extension::OperandTypeInformation{
.type = operandTypeInformation.type,
@@ -257,21 +289,41 @@
};
}
-GeneralResult<SharedHandle> convert(const hidl_handle& hidlHandle) {
+GeneralResult<SharedHandle> unvalidatedConvert(const hidl_handle& hidlHandle) {
return hal::utils::sharedHandleFromNativeHandle(hidlHandle.getNativeHandle());
}
+GeneralResult<DeviceType> convert(const hal::V1_2::DeviceType& deviceType) {
+ return validatedConvert(deviceType);
+}
+
+GeneralResult<Capabilities> convert(const hal::V1_2::Capabilities& capabilities) {
+ return validatedConvert(capabilities);
+}
+
+GeneralResult<Model> convert(const hal::V1_2::Model& model) {
+ return validatedConvert(model);
+}
+
+GeneralResult<MeasureTiming> convert(const hal::V1_2::MeasureTiming& measureTiming) {
+ return validatedConvert(measureTiming);
+}
+
+GeneralResult<Timing> convert(const hal::V1_2::Timing& timing) {
+ return validatedConvert(timing);
+}
+
GeneralResult<std::vector<Extension>> convert(const hidl_vec<hal::V1_2::Extension>& extensions) {
- return convertVec(extensions);
+ return validatedConvert(extensions);
}
GeneralResult<std::vector<SharedHandle>> convert(const hidl_vec<hidl_handle>& handles) {
- return convertVec(handles);
+ return validatedConvert(handles);
}
GeneralResult<std::vector<OutputShape>> convert(
const hidl_vec<hal::V1_2::OutputShape>& outputShapes) {
- return convertVec(outputShapes);
+ return validatedConvert(outputShapes);
}
} // namespace android::nn
@@ -279,44 +331,48 @@
namespace android::hardware::neuralnetworks::V1_2::utils {
namespace {
-using utils::convert;
+using utils::unvalidatedConvert;
-nn::GeneralResult<V1_0::OperandLifeTime> convert(const nn::Operand::LifeTime& lifetime) {
- return V1_0::utils::convert(lifetime);
+nn::GeneralResult<V1_0::OperandLifeTime> unvalidatedConvert(const nn::Operand::LifeTime& lifetime) {
+ return V1_0::utils::unvalidatedConvert(lifetime);
}
-nn::GeneralResult<V1_0::PerformanceInfo> convert(
+nn::GeneralResult<V1_0::PerformanceInfo> unvalidatedConvert(
const nn::Capabilities::PerformanceInfo& performanceInfo) {
- return V1_0::utils::convert(performanceInfo);
+ return V1_0::utils::unvalidatedConvert(performanceInfo);
}
-nn::GeneralResult<V1_0::DataLocation> convert(const nn::DataLocation& location) {
- return V1_0::utils::convert(location);
+nn::GeneralResult<V1_0::DataLocation> unvalidatedConvert(const nn::DataLocation& location) {
+ return V1_0::utils::unvalidatedConvert(location);
}
-nn::GeneralResult<hidl_vec<uint8_t>> convert(const nn::Model::OperandValues& operandValues) {
- return V1_0::utils::convert(operandValues);
+nn::GeneralResult<hidl_vec<uint8_t>> unvalidatedConvert(
+ const nn::Model::OperandValues& operandValues) {
+ return V1_0::utils::unvalidatedConvert(operandValues);
}
-nn::GeneralResult<hidl_memory> convert(const nn::Memory& memory) {
- return V1_0::utils::convert(memory);
+nn::GeneralResult<hidl_memory> unvalidatedConvert(const nn::Memory& memory) {
+ return V1_0::utils::unvalidatedConvert(memory);
}
template <typename Input>
-using ConvertOutput = std::decay_t<decltype(convert(std::declval<Input>()).value())>;
+using unvalidatedConvertOutput =
+ std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
template <typename Type>
-nn::GeneralResult<hidl_vec<ConvertOutput<Type>>> convertVec(const std::vector<Type>& arguments) {
- hidl_vec<ConvertOutput<Type>> halObject(arguments.size());
+nn::GeneralResult<hidl_vec<unvalidatedConvertOutput<Type>>> unvalidatedConvertVec(
+ const std::vector<Type>& arguments) {
+ hidl_vec<unvalidatedConvertOutput<Type>> halObject(arguments.size());
for (size_t i = 0; i < arguments.size(); ++i) {
- halObject[i] = NN_TRY(convert(arguments[i]));
+ halObject[i] = NN_TRY(unvalidatedConvert(arguments[i]));
}
return halObject;
}
template <typename Type>
-nn::GeneralResult<hidl_vec<ConvertOutput<Type>>> convert(const std::vector<Type>& arguments) {
- return convertVec(arguments);
+nn::GeneralResult<hidl_vec<unvalidatedConvertOutput<Type>>> unvalidatedConvert(
+ const std::vector<Type>& arguments) {
+ return unvalidatedConvertVec(arguments);
}
nn::GeneralResult<Operand::ExtraParams> makeExtraParams(nn::Operand::NoParams /*noParams*/) {
@@ -326,7 +382,7 @@
nn::GeneralResult<Operand::ExtraParams> makeExtraParams(
const nn::Operand::SymmPerChannelQuantParams& channelQuant) {
Operand::ExtraParams ret;
- ret.channelQuant(NN_TRY(convert(channelQuant)));
+ ret.channelQuant(NN_TRY(unvalidatedConvert(channelQuant)));
return ret;
}
@@ -337,17 +393,40 @@
return ret;
}
+template <typename Type>
+decltype(utils::unvalidatedConvert(std::declval<Type>())) validatedConvert(const Type& canonical) {
+ const auto maybeVersion = nn::validate(canonical);
+ if (!maybeVersion.has_value()) {
+ return nn::error() << maybeVersion.error();
+ }
+ const auto version = maybeVersion.value();
+ if (version > kVersion) {
+ return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
+ }
+ return utils::unvalidatedConvert(canonical);
+}
+
+template <typename Type>
+nn::GeneralResult<hidl_vec<unvalidatedConvertOutput<Type>>> validatedConvert(
+ const std::vector<Type>& arguments) {
+ hidl_vec<unvalidatedConvertOutput<Type>> halObject(arguments.size());
+ for (size_t i = 0; i < arguments.size(); ++i) {
+ halObject[i] = NN_TRY(validatedConvert(arguments[i]));
+ }
+ return halObject;
+}
+
} // anonymous namespace
-nn::GeneralResult<OperandType> convert(const nn::OperandType& operandType) {
+nn::GeneralResult<OperandType> unvalidatedConvert(const nn::OperandType& operandType) {
return static_cast<OperandType>(operandType);
}
-nn::GeneralResult<OperationType> convert(const nn::OperationType& operationType) {
+nn::GeneralResult<OperationType> unvalidatedConvert(const nn::OperationType& operationType) {
return static_cast<OperationType>(operationType);
}
-nn::GeneralResult<DeviceType> convert(const nn::DeviceType& deviceType) {
+nn::GeneralResult<DeviceType> unvalidatedConvert(const nn::DeviceType& deviceType) {
switch (deviceType) {
case nn::DeviceType::UNKNOWN:
return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Invalid DeviceType UNKNOWN";
@@ -361,7 +440,7 @@
<< "Invalid DeviceType " << underlyingType(deviceType);
}
-nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities) {
+nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
std::vector<nn::Capabilities::OperandPerformance> operandPerformance;
operandPerformance.reserve(capabilities.operandPerformance.asVector().size());
std::copy_if(capabilities.operandPerformance.asVector().begin(),
@@ -372,31 +451,31 @@
});
return Capabilities{
- .relaxedFloat32toFloat16PerformanceScalar =
- NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
- .relaxedFloat32toFloat16PerformanceTensor =
- NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
- .operandPerformance = NN_TRY(convert(operandPerformance)),
+ .relaxedFloat32toFloat16PerformanceScalar = NN_TRY(
+ unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
+ .relaxedFloat32toFloat16PerformanceTensor = NN_TRY(
+ unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
+ .operandPerformance = NN_TRY(unvalidatedConvert(operandPerformance)),
};
}
-nn::GeneralResult<Capabilities::OperandPerformance> convert(
+nn::GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
const nn::Capabilities::OperandPerformance& operandPerformance) {
return Capabilities::OperandPerformance{
- .type = NN_TRY(convert(operandPerformance.type)),
- .info = NN_TRY(convert(operandPerformance.info)),
+ .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
+ .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
};
}
-nn::GeneralResult<Operation> convert(const nn::Operation& operation) {
+nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
return Operation{
- .type = NN_TRY(convert(operation.type)),
+ .type = NN_TRY(unvalidatedConvert(operation.type)),
.inputs = operation.inputs,
.outputs = operation.outputs,
};
}
-nn::GeneralResult<SymmPerChannelQuantParams> convert(
+nn::GeneralResult<SymmPerChannelQuantParams> unvalidatedConvert(
const nn::Operand::SymmPerChannelQuantParams& symmPerChannelQuantParams) {
return SymmPerChannelQuantParams{
.scales = symmPerChannelQuantParams.scales,
@@ -404,30 +483,31 @@
};
}
-nn::GeneralResult<Operand> convert(const nn::Operand& operand) {
+nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand) {
return Operand{
- .type = NN_TRY(convert(operand.type)),
+ .type = NN_TRY(unvalidatedConvert(operand.type)),
.dimensions = operand.dimensions,
.numberOfConsumers = 0,
.scale = operand.scale,
.zeroPoint = operand.zeroPoint,
- .lifetime = NN_TRY(convert(operand.lifetime)),
- .location = NN_TRY(convert(operand.location)),
- .extraParams = NN_TRY(convert(operand.extraParams)),
+ .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
+ .location = NN_TRY(unvalidatedConvert(operand.location)),
+ .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
};
}
-nn::GeneralResult<Operand::ExtraParams> convert(const nn::Operand::ExtraParams& extraParams) {
+nn::GeneralResult<Operand::ExtraParams> unvalidatedConvert(
+ const nn::Operand::ExtraParams& extraParams) {
return std::visit([](const auto& x) { return makeExtraParams(x); }, extraParams);
}
-nn::GeneralResult<Model> convert(const nn::Model& model) {
+nn::GeneralResult<Model> unvalidatedConvert(const nn::Model& model) {
if (!hal::utils::hasNoPointerData(model)) {
return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
- << "Model cannot be converted because it contains pointer-based memory";
+ << "Model cannot be unvalidatedConverted because it contains pointer-based memory";
}
- auto operands = NN_TRY(convert(model.main.operands));
+ auto operands = NN_TRY(unvalidatedConvert(model.main.operands));
// Update number of consumers.
const auto numberOfConsumers =
@@ -439,17 +519,17 @@
return Model{
.operands = std::move(operands),
- .operations = NN_TRY(convert(model.main.operations)),
+ .operations = NN_TRY(unvalidatedConvert(model.main.operations)),
.inputIndexes = model.main.inputIndexes,
.outputIndexes = model.main.outputIndexes,
- .operandValues = NN_TRY(convert(model.operandValues)),
- .pools = NN_TRY(convert(model.pools)),
+ .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
+ .pools = NN_TRY(unvalidatedConvert(model.pools)),
.relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
- .extensionNameToPrefix = NN_TRY(convert(model.extensionNameToPrefix)),
+ .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
};
}
-nn::GeneralResult<Model::ExtensionNameAndPrefix> convert(
+nn::GeneralResult<Model::ExtensionNameAndPrefix> unvalidatedConvert(
const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) {
return Model::ExtensionNameAndPrefix{
.name = extensionNameAndPrefix.name,
@@ -457,27 +537,27 @@
};
}
-nn::GeneralResult<OutputShape> convert(const nn::OutputShape& outputShape) {
+nn::GeneralResult<OutputShape> unvalidatedConvert(const nn::OutputShape& outputShape) {
return OutputShape{.dimensions = outputShape.dimensions,
.isSufficient = outputShape.isSufficient};
}
-nn::GeneralResult<MeasureTiming> convert(const nn::MeasureTiming& measureTiming) {
+nn::GeneralResult<MeasureTiming> unvalidatedConvert(const nn::MeasureTiming& measureTiming) {
return static_cast<MeasureTiming>(measureTiming);
}
-nn::GeneralResult<Timing> convert(const nn::Timing& timing) {
+nn::GeneralResult<Timing> unvalidatedConvert(const nn::Timing& timing) {
return Timing{.timeOnDevice = timing.timeOnDevice, .timeInDriver = timing.timeInDriver};
}
-nn::GeneralResult<Extension> convert(const nn::Extension& extension) {
+nn::GeneralResult<Extension> unvalidatedConvert(const nn::Extension& extension) {
return Extension{
.name = extension.name,
- .operandTypes = NN_TRY(convert(extension.operandTypes)),
+ .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes)),
};
}
-nn::GeneralResult<Extension::OperandTypeInformation> convert(
+nn::GeneralResult<Extension::OperandTypeInformation> unvalidatedConvert(
const nn::Extension::OperandTypeInformation& operandTypeInformation) {
return Extension::OperandTypeInformation{
.type = operandTypeInformation.type,
@@ -486,20 +566,40 @@
};
}
-nn::GeneralResult<hidl_handle> convert(const nn::SharedHandle& handle) {
+nn::GeneralResult<hidl_handle> unvalidatedConvert(const nn::SharedHandle& handle) {
return hal::utils::hidlHandleFromSharedHandle(handle);
}
+nn::GeneralResult<DeviceType> convert(const nn::DeviceType& deviceType) {
+ return validatedConvert(deviceType);
+}
+
+nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities) {
+ return validatedConvert(capabilities);
+}
+
+nn::GeneralResult<Model> convert(const nn::Model& model) {
+ return validatedConvert(model);
+}
+
+nn::GeneralResult<MeasureTiming> convert(const nn::MeasureTiming& measureTiming) {
+ return validatedConvert(measureTiming);
+}
+
+nn::GeneralResult<Timing> convert(const nn::Timing& timing) {
+ return validatedConvert(timing);
+}
+
nn::GeneralResult<hidl_vec<Extension>> convert(const std::vector<nn::Extension>& extensions) {
- return convertVec(extensions);
+ return validatedConvert(extensions);
}
nn::GeneralResult<hidl_vec<hidl_handle>> convert(const std::vector<nn::SharedHandle>& handles) {
- return convertVec(handles);
+ return validatedConvert(handles);
}
nn::GeneralResult<hidl_vec<OutputShape>> convert(const std::vector<nn::OutputShape>& outputShapes) {
- return convertVec(outputShapes);
+ return validatedConvert(outputShapes);
}
} // namespace android::hardware::neuralnetworks::V1_2::utils
diff --git a/neuralnetworks/1.2/utils/src/Device.cpp b/neuralnetworks/1.2/utils/src/Device.cpp
index 517d61f..0061065 100644
--- a/neuralnetworks/1.2/utils/src/Device.cpp
+++ b/neuralnetworks/1.2/utils/src/Device.cpp
@@ -42,6 +42,29 @@
#include <vector>
namespace android::hardware::neuralnetworks::V1_2::utils {
+namespace {
+
+nn::GeneralResult<nn::Capabilities> initCapabilities(V1_2::IDevice* device) {
+ CHECK(device != nullptr);
+
+ nn::GeneralResult<nn::Capabilities> result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
+ << "uninitialized";
+ const auto cb = [&result](V1_0::ErrorStatus status, const Capabilities& capabilities) {
+ if (status != V1_0::ErrorStatus::NONE) {
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ result = NN_ERROR(canonical) << "getCapabilities_1_2 failed with " << toString(status);
+ } else {
+ result = nn::convert(capabilities);
+ }
+ };
+
+ const auto ret = device->getCapabilities_1_2(cb);
+ HANDLE_TRANSPORT_FAILURE(ret);
+
+ return result;
+}
+
+} // namespace
nn::GeneralResult<std::string> initVersionString(V1_2::IDevice* device) {
CHECK(device != nullptr);
@@ -50,8 +73,7 @@
<< "uninitialized";
const auto cb = [&result](V1_0::ErrorStatus status, const hidl_string& versionString) {
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
result = NN_ERROR(canonical) << "getVersionString failed with " << toString(status);
} else {
result = versionString;
@@ -59,7 +81,7 @@
};
const auto ret = device->getVersionString(cb);
- NN_TRY(hal::utils::handleTransportError(ret));
+ HANDLE_TRANSPORT_FAILURE(ret);
return result;
}
@@ -71,8 +93,7 @@
<< "uninitialized";
const auto cb = [&result](V1_0::ErrorStatus status, DeviceType deviceType) {
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
result = NN_ERROR(canonical) << "getDeviceType failed with " << toString(status);
} else {
result = nn::convert(deviceType);
@@ -80,7 +101,7 @@
};
const auto ret = device->getType(cb);
- NN_TRY(hal::utils::handleTransportError(ret));
+ HANDLE_TRANSPORT_FAILURE(ret);
return result;
}
@@ -92,8 +113,7 @@
NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "uninitialized";
const auto cb = [&result](V1_0::ErrorStatus status, const hidl_vec<Extension>& extensions) {
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
result = NN_ERROR(canonical) << "getExtensions failed with " << toString(status);
} else {
result = nn::convert(extensions);
@@ -101,28 +121,7 @@
};
const auto ret = device->getSupportedExtensions(cb);
- NN_TRY(hal::utils::handleTransportError(ret));
-
- return result;
-}
-
-nn::GeneralResult<nn::Capabilities> initCapabilities(V1_2::IDevice* device) {
- CHECK(device != nullptr);
-
- nn::GeneralResult<nn::Capabilities> result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
- << "uninitialized";
- const auto cb = [&result](V1_0::ErrorStatus status, const Capabilities& capabilities) {
- if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
- result = NN_ERROR(canonical) << "getCapabilities_1_2 failed with " << toString(status);
- } else {
- result = validatedConvertToCanonical(capabilities);
- }
- };
-
- const auto ret = device->getCapabilities_1_2(cb);
- NN_TRY(hal::utils::handleTransportError(ret));
+ HANDLE_TRANSPORT_FAILURE(ret);
return result;
}
@@ -136,8 +135,7 @@
const auto cb = [&result](V1_0::ErrorStatus status, uint32_t numModelCache,
uint32_t numDataCache) {
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
result = NN_ERROR(canonical)
<< "getNumberOfCacheFilesNeeded failed with " << toString(status);
} else {
@@ -146,7 +144,7 @@
};
const auto ret = device->getNumberOfCacheFilesNeeded(cb);
- NN_TRY(hal::utils::handleTransportError(ret));
+ HANDLE_TRANSPORT_FAILURE(ret);
return result;
}
@@ -219,7 +217,8 @@
nn::GeneralResult<void> Device::wait() const {
const auto ret = kDevice->ping();
- return hal::utils::handleTransportError(ret);
+ HANDLE_TRANSPORT_FAILURE(ret);
+ return {};
}
nn::GeneralResult<std::vector<bool>> Device::getSupportedOperations(const nn::Model& model) const {
@@ -235,8 +234,7 @@
auto cb = [&result, &model](V1_0::ErrorStatus status,
const hidl_vec<bool>& supportedOperations) {
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
result = NN_ERROR(canonical)
<< "getSupportedOperations_1_2 failed with " << toString(status);
} else if (supportedOperations.size() != model.main.operations.size()) {
@@ -250,7 +248,7 @@
};
const auto ret = kDevice->getSupportedOperations_1_2(hidlModel, cb);
- NN_TRY(hal::utils::handleTransportError(ret));
+ HANDLE_TRANSPORT_FAILURE(ret);
return result;
}
@@ -275,10 +273,9 @@
const auto ret = kDevice->prepareModel_1_2(hidlModel, hidlPreference, hidlModelCache,
hidlDataCache, hidlToken, cb);
- const auto status = NN_TRY(hal::utils::handleTransportError(ret));
+ const auto status = HANDLE_TRANSPORT_FAILURE(ret);
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
return NN_ERROR(canonical) << "prepareModel_1_2 failed with " << toString(status);
}
@@ -296,10 +293,9 @@
const auto scoped = kDeathHandler.protectCallback(cb.get());
const auto ret = kDevice->prepareModelFromCache(hidlModelCache, hidlDataCache, hidlToken, cb);
- const auto status = NN_TRY(hal::utils::handleTransportError(ret));
+ const auto status = HANDLE_TRANSPORT_FAILURE(ret);
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
return NN_ERROR(canonical) << "prepareModelFromCache failed with " << toString(status);
}
diff --git a/neuralnetworks/1.2/utils/src/PreparedModel.cpp b/neuralnetworks/1.2/utils/src/PreparedModel.cpp
index ff9db21..dad9a7e 100644
--- a/neuralnetworks/1.2/utils/src/PreparedModel.cpp
+++ b/neuralnetworks/1.2/utils/src/PreparedModel.cpp
@@ -42,8 +42,7 @@
nn::GeneralResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>>
convertExecutionResultsHelper(const hidl_vec<OutputShape>& outputShapes, const Timing& timing) {
- return std::make_pair(NN_TRY(validatedConvertToCanonical(outputShapes)),
- NN_TRY(validatedConvertToCanonical(timing)));
+ return std::make_pair(NN_TRY(nn::convert(outputShapes)), NN_TRY(nn::convert(timing)));
}
nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> convertExecutionResults(
@@ -76,8 +75,7 @@
const auto cb = [&result](V1_0::ErrorStatus status, const hidl_vec<OutputShape>& outputShapes,
const Timing& timing) {
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
result = NN_ERROR(canonical) << "executeSynchronously failed with " << toString(status);
} else {
result = convertExecutionResults(outputShapes, timing);
@@ -85,7 +83,7 @@
};
const auto ret = kPreparedModel->executeSynchronously(request, measure, cb);
- NN_TRY(hal::utils::makeExecutionFailure(hal::utils::handleTransportError(ret)));
+ HANDLE_TRANSPORT_FAILURE(ret);
return result;
}
@@ -96,11 +94,9 @@
const auto scoped = kDeathHandler.protectCallback(cb.get());
const auto ret = kPreparedModel->execute_1_2(request, measure, cb);
- const auto status =
- NN_TRY(hal::utils::makeExecutionFailure(hal::utils::handleTransportError(ret)));
+ const auto status = HANDLE_TRANSPORT_FAILURE(ret);
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
return NN_ERROR(canonical) << "execute failed with " << toString(status);
}
diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h
index 64aa96e..9653a05 100644
--- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h
+++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h
@@ -25,26 +25,41 @@
namespace android::nn {
-GeneralResult<OperandType> convert(const hal::V1_3::OperandType& operandType);
-GeneralResult<OperationType> convert(const hal::V1_3::OperationType& operationType);
+GeneralResult<OperandType> unvalidatedConvert(const hal::V1_3::OperandType& operandType);
+GeneralResult<OperationType> unvalidatedConvert(const hal::V1_3::OperationType& operationType);
+GeneralResult<Priority> unvalidatedConvert(const hal::V1_3::Priority& priority);
+GeneralResult<Capabilities> unvalidatedConvert(const hal::V1_3::Capabilities& capabilities);
+GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
+ const hal::V1_3::Capabilities::OperandPerformance& operandPerformance);
+GeneralResult<Operation> unvalidatedConvert(const hal::V1_3::Operation& operation);
+GeneralResult<Operand::LifeTime> unvalidatedConvert(
+ const hal::V1_3::OperandLifeTime& operandLifeTime);
+GeneralResult<Operand> unvalidatedConvert(const hal::V1_3::Operand& operand);
+GeneralResult<Model> unvalidatedConvert(const hal::V1_3::Model& model);
+GeneralResult<Model::Subgraph> unvalidatedConvert(const hal::V1_3::Subgraph& subgraph);
+GeneralResult<BufferDesc> unvalidatedConvert(const hal::V1_3::BufferDesc& bufferDesc);
+GeneralResult<BufferRole> unvalidatedConvert(const hal::V1_3::BufferRole& bufferRole);
+GeneralResult<Request> unvalidatedConvert(const hal::V1_3::Request& request);
+GeneralResult<Request::MemoryPool> unvalidatedConvert(
+ const hal::V1_3::Request::MemoryPool& memoryPool);
+GeneralResult<OptionalTimePoint> unvalidatedConvert(
+ const hal::V1_3::OptionalTimePoint& optionalTimePoint);
+GeneralResult<OptionalTimeoutDuration> unvalidatedConvert(
+ const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration);
+GeneralResult<ErrorStatus> unvalidatedConvert(const hal::V1_3::ErrorStatus& errorStatus);
+
GeneralResult<Priority> convert(const hal::V1_3::Priority& priority);
GeneralResult<Capabilities> convert(const hal::V1_3::Capabilities& capabilities);
-GeneralResult<Capabilities::OperandPerformance> convert(
- const hal::V1_3::Capabilities::OperandPerformance& operandPerformance);
-GeneralResult<Operation> convert(const hal::V1_3::Operation& operation);
-GeneralResult<Operand::LifeTime> convert(const hal::V1_3::OperandLifeTime& operandLifeTime);
-GeneralResult<Operand> convert(const hal::V1_3::Operand& operand);
GeneralResult<Model> convert(const hal::V1_3::Model& model);
-GeneralResult<Model::Subgraph> convert(const hal::V1_3::Subgraph& subgraph);
GeneralResult<BufferDesc> convert(const hal::V1_3::BufferDesc& bufferDesc);
-GeneralResult<BufferRole> convert(const hal::V1_3::BufferRole& bufferRole);
GeneralResult<Request> convert(const hal::V1_3::Request& request);
-GeneralResult<Request::MemoryPool> convert(const hal::V1_3::Request::MemoryPool& memoryPool);
GeneralResult<OptionalTimePoint> convert(const hal::V1_3::OptionalTimePoint& optionalTimePoint);
GeneralResult<OptionalTimeoutDuration> convert(
const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration);
GeneralResult<ErrorStatus> convert(const hal::V1_3::ErrorStatus& errorStatus);
+GeneralResult<SharedHandle> convert(const hardware::hidl_handle& handle);
+GeneralResult<Memory> convert(const hardware::hidl_memory& memory);
GeneralResult<std::vector<BufferRole>> convert(
const hardware::hidl_vec<hal::V1_3::BufferRole>& bufferRoles);
@@ -52,26 +67,40 @@
namespace android::hardware::neuralnetworks::V1_3::utils {
-nn::GeneralResult<OperandType> convert(const nn::OperandType& operandType);
-nn::GeneralResult<OperationType> convert(const nn::OperationType& operationType);
+nn::GeneralResult<OperandType> unvalidatedConvert(const nn::OperandType& operandType);
+nn::GeneralResult<OperationType> unvalidatedConvert(const nn::OperationType& operationType);
+nn::GeneralResult<Priority> unvalidatedConvert(const nn::Priority& priority);
+nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities);
+nn::GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
+ const nn::Capabilities::OperandPerformance& operandPerformance);
+nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation);
+nn::GeneralResult<OperandLifeTime> unvalidatedConvert(const nn::Operand::LifeTime& operandLifeTime);
+nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand);
+nn::GeneralResult<Model> unvalidatedConvert(const nn::Model& model);
+nn::GeneralResult<Subgraph> unvalidatedConvert(const nn::Model::Subgraph& subgraph);
+nn::GeneralResult<BufferDesc> unvalidatedConvert(const nn::BufferDesc& bufferDesc);
+nn::GeneralResult<BufferRole> unvalidatedConvert(const nn::BufferRole& bufferRole);
+nn::GeneralResult<Request> unvalidatedConvert(const nn::Request& request);
+nn::GeneralResult<Request::MemoryPool> unvalidatedConvert(
+ const nn::Request::MemoryPool& memoryPool);
+nn::GeneralResult<OptionalTimePoint> unvalidatedConvert(
+ const nn::OptionalTimePoint& optionalTimePoint);
+nn::GeneralResult<OptionalTimeoutDuration> unvalidatedConvert(
+ const nn::OptionalTimeoutDuration& optionalTimeoutDuration);
+nn::GeneralResult<ErrorStatus> unvalidatedConvert(const nn::ErrorStatus& errorStatus);
+
nn::GeneralResult<Priority> convert(const nn::Priority& priority);
nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities);
-nn::GeneralResult<Capabilities::OperandPerformance> convert(
- const nn::Capabilities::OperandPerformance& operandPerformance);
-nn::GeneralResult<Operation> convert(const nn::Operation& operation);
-nn::GeneralResult<OperandLifeTime> convert(const nn::Operand::LifeTime& operandLifeTime);
-nn::GeneralResult<Operand> convert(const nn::Operand& operand);
nn::GeneralResult<Model> convert(const nn::Model& model);
-nn::GeneralResult<Subgraph> convert(const nn::Model::Subgraph& subgraph);
nn::GeneralResult<BufferDesc> convert(const nn::BufferDesc& bufferDesc);
-nn::GeneralResult<BufferRole> convert(const nn::BufferRole& bufferRole);
nn::GeneralResult<Request> convert(const nn::Request& request);
-nn::GeneralResult<Request::MemoryPool> convert(const nn::Request::MemoryPool& memoryPool);
nn::GeneralResult<OptionalTimePoint> convert(const nn::OptionalTimePoint& optionalTimePoint);
nn::GeneralResult<OptionalTimeoutDuration> convert(
const nn::OptionalTimeoutDuration& optionalTimeoutDuration);
nn::GeneralResult<ErrorStatus> convert(const nn::ErrorStatus& errorStatus);
+nn::GeneralResult<hidl_handle> convert(const nn::SharedHandle& handle);
+nn::GeneralResult<hidl_memory> convert(const nn::Memory& memory);
nn::GeneralResult<hidl_vec<BufferRole>> convert(const std::vector<nn::BufferRole>& bufferRoles);
} // namespace android::hardware::neuralnetworks::V1_3::utils
diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h
index e61859d..29b0c80 100644
--- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h
+++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h
@@ -22,9 +22,7 @@
#include <android-base/logging.h>
#include <android/hardware/neuralnetworks/1.3/types.h>
#include <nnapi/Result.h>
-#include <nnapi/TypeUtils.h>
#include <nnapi/Types.h>
-#include <nnapi/Validation.h>
#include <nnapi/hal/1.0/Conversions.h>
#include <nnapi/hal/1.1/Conversions.h>
#include <nnapi/hal/1.2/Conversions.h>
@@ -32,7 +30,6 @@
namespace android::hardware::neuralnetworks::V1_3::utils {
constexpr auto kDefaultPriority = Priority::MEDIUM;
-constexpr auto kVersion = nn::Version::ANDROID_R;
template <typename Type>
nn::Result<void> validate(const Type& halObject) {
@@ -40,11 +37,6 @@
if (!maybeCanonical.has_value()) {
return nn::error() << maybeCanonical.error().message;
}
- const auto version = NN_TRY(nn::validate(maybeCanonical.value()));
- if (version > utils::kVersion) {
- return NN_ERROR() << "Insufficient version: " << version << " vs required "
- << utils::kVersion;
- }
return {};
}
@@ -57,21 +49,6 @@
return result.has_value();
}
-template <typename Type>
-decltype(nn::convert(std::declval<Type>())) validatedConvertToCanonical(const Type& halObject) {
- auto canonical = NN_TRY(nn::convert(halObject));
- const auto maybeVersion = nn::validate(canonical);
- if (!maybeVersion.has_value()) {
- return nn::error() << maybeVersion.error();
- }
- const auto version = maybeVersion.value();
- if (version > utils::kVersion) {
- return NN_ERROR() << "Insufficient version: " << version << " vs required "
- << utils::kVersion;
- }
- return canonical;
-}
-
} // namespace android::hardware::neuralnetworks::V1_3::utils
#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_H
diff --git a/neuralnetworks/1.3/utils/src/Buffer.cpp b/neuralnetworks/1.3/utils/src/Buffer.cpp
index f3fe9b5..ffdeccd 100644
--- a/neuralnetworks/1.3/utils/src/Buffer.cpp
+++ b/neuralnetworks/1.3/utils/src/Buffer.cpp
@@ -61,13 +61,12 @@
}
nn::GeneralResult<void> Buffer::copyTo(const nn::Memory& dst) const {
- const auto hidlDst = NN_TRY(V1_0::utils::convert(dst));
+ const auto hidlDst = NN_TRY(convert(dst));
const auto ret = kBuffer->copyTo(hidlDst);
- const auto status = NN_TRY(hal::utils::handleTransportError(ret));
+ const auto status = HANDLE_TRANSPORT_FAILURE(ret);
if (status != ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
return NN_ERROR(canonical) << "IBuffer::copyTo failed with " << toString(status);
}
@@ -76,14 +75,13 @@
nn::GeneralResult<void> Buffer::copyFrom(const nn::Memory& src,
const nn::Dimensions& dimensions) const {
- const auto hidlSrc = NN_TRY(V1_0::utils::convert(src));
+ const auto hidlSrc = NN_TRY(convert(src));
const auto hidlDimensions = hidl_vec<uint32_t>(dimensions);
const auto ret = kBuffer->copyFrom(hidlSrc, hidlDimensions);
- const auto status = NN_TRY(hal::utils::handleTransportError(ret));
+ const auto status = HANDLE_TRANSPORT_FAILURE(ret);
if (status != ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
return NN_ERROR(canonical) << "IBuffer::copyFrom failed with " << toString(status);
}
diff --git a/neuralnetworks/1.3/utils/src/Callbacks.cpp b/neuralnetworks/1.3/utils/src/Callbacks.cpp
index ff81275..e3c6074 100644
--- a/neuralnetworks/1.3/utils/src/Callbacks.cpp
+++ b/neuralnetworks/1.3/utils/src/Callbacks.cpp
@@ -60,8 +60,7 @@
nn::GeneralResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>>
convertExecutionGeneralResultsHelper(const hidl_vec<V1_2::OutputShape>& outputShapes,
const V1_2::Timing& timing) {
- return std::make_pair(NN_TRY(validatedConvertToCanonical(outputShapes)),
- NN_TRY(validatedConvertToCanonical(timing)));
+ return std::make_pair(NN_TRY(nn::convert(outputShapes)), NN_TRY(nn::convert(timing)));
}
nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>>
@@ -76,8 +75,7 @@
Return<void> PreparedModelCallback::notify(V1_0::ErrorStatus status,
const sp<V1_0::IPreparedModel>& preparedModel) {
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status));
} else if (preparedModel == nullptr) {
notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
@@ -91,8 +89,7 @@
Return<void> PreparedModelCallback::notify_1_2(V1_0::ErrorStatus status,
const sp<V1_2::IPreparedModel>& preparedModel) {
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status));
} else if (preparedModel == nullptr) {
notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
@@ -106,8 +103,7 @@
Return<void> PreparedModelCallback::notify_1_3(ErrorStatus status,
const sp<IPreparedModel>& preparedModel) {
if (status != ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status));
} else if (preparedModel == nullptr) {
notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
@@ -134,8 +130,7 @@
Return<void> ExecutionCallback::notify(V1_0::ErrorStatus status) {
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status));
} else {
notifyInternal({});
@@ -147,8 +142,7 @@
const hidl_vec<V1_2::OutputShape>& outputShapes,
const V1_2::Timing& timing) {
if (status != V1_0::ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status));
} else {
notifyInternal(convertExecutionGeneralResults(outputShapes, timing));
@@ -160,8 +154,7 @@
const hidl_vec<V1_2::OutputShape>& outputShapes,
const V1_2::Timing& timing) {
if (status != ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status));
} else {
notifyInternal(convertExecutionGeneralResults(outputShapes, timing));
diff --git a/neuralnetworks/1.3/utils/src/Conversions.cpp b/neuralnetworks/1.3/utils/src/Conversions.cpp
index 0dc0785..949dd0d 100644
--- a/neuralnetworks/1.3/utils/src/Conversions.cpp
+++ b/neuralnetworks/1.3/utils/src/Conversions.cpp
@@ -24,6 +24,7 @@
#include <nnapi/SharedMemory.h>
#include <nnapi/TypeUtils.h>
#include <nnapi/Types.h>
+#include <nnapi/Validation.h>
#include <nnapi/hal/1.0/Conversions.h>
#include <nnapi/hal/1.2/Conversions.h>
#include <nnapi/hal/CommonUtils.h>
@@ -44,6 +45,8 @@
return static_cast<std::underlying_type_t<Type>>(value);
}
+constexpr auto kVersion = android::nn::Version::ANDROID_R;
+
} // namespace
namespace android::nn {
@@ -77,110 +80,140 @@
using hardware::hidl_vec;
template <typename Input>
-using ConvertOutput = std::decay_t<decltype(convert(std::declval<Input>()).value())>;
+using unvalidatedConvertOutput =
+ std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
template <typename Type>
-GeneralResult<std::vector<ConvertOutput<Type>>> convertVec(const hidl_vec<Type>& arguments) {
- std::vector<ConvertOutput<Type>> canonical;
+GeneralResult<std::vector<unvalidatedConvertOutput<Type>>> unvalidatedConvertVec(
+ const hidl_vec<Type>& arguments) {
+ std::vector<unvalidatedConvertOutput<Type>> canonical;
canonical.reserve(arguments.size());
for (const auto& argument : arguments) {
- canonical.push_back(NN_TRY(nn::convert(argument)));
+ canonical.push_back(NN_TRY(nn::unvalidatedConvert(argument)));
}
return canonical;
}
template <typename Type>
-GeneralResult<std::vector<ConvertOutput<Type>>> convert(const hidl_vec<Type>& arguments) {
- return convertVec(arguments);
+GeneralResult<std::vector<unvalidatedConvertOutput<Type>>> unvalidatedConvert(
+ const hidl_vec<Type>& arguments) {
+ return unvalidatedConvertVec(arguments);
+}
+
+template <typename Type>
+decltype(nn::unvalidatedConvert(std::declval<Type>())) validatedConvert(const Type& halObject) {
+ auto canonical = NN_TRY(nn::unvalidatedConvert(halObject));
+ const auto maybeVersion = validate(canonical);
+ if (!maybeVersion.has_value()) {
+ return error() << maybeVersion.error();
+ }
+ const auto version = maybeVersion.value();
+ if (version > kVersion) {
+ return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
+ }
+ return canonical;
+}
+
+template <typename Type>
+GeneralResult<std::vector<unvalidatedConvertOutput<Type>>> validatedConvert(
+ const hidl_vec<Type>& arguments) {
+ std::vector<unvalidatedConvertOutput<Type>> canonical;
+ canonical.reserve(arguments.size());
+ for (const auto& argument : arguments) {
+ canonical.push_back(NN_TRY(validatedConvert(argument)));
+ }
+ return canonical;
}
} // anonymous namespace
-GeneralResult<OperandType> convert(const hal::V1_3::OperandType& operandType) {
+GeneralResult<OperandType> unvalidatedConvert(const hal::V1_3::OperandType& operandType) {
return static_cast<OperandType>(operandType);
}
-GeneralResult<OperationType> convert(const hal::V1_3::OperationType& operationType) {
+GeneralResult<OperationType> unvalidatedConvert(const hal::V1_3::OperationType& operationType) {
return static_cast<OperationType>(operationType);
}
-GeneralResult<Priority> convert(const hal::V1_3::Priority& priority) {
+GeneralResult<Priority> unvalidatedConvert(const hal::V1_3::Priority& priority) {
return static_cast<Priority>(priority);
}
-GeneralResult<Capabilities> convert(const hal::V1_3::Capabilities& capabilities) {
+GeneralResult<Capabilities> unvalidatedConvert(const hal::V1_3::Capabilities& capabilities) {
const bool validOperandTypes = std::all_of(
capabilities.operandPerformance.begin(), capabilities.operandPerformance.end(),
[](const hal::V1_3::Capabilities::OperandPerformance& operandPerformance) {
- const auto maybeType = convert(operandPerformance.type);
+ const auto maybeType = unvalidatedConvert(operandPerformance.type);
return !maybeType.has_value() ? false : validOperandType(maybeType.value());
});
if (!validOperandTypes) {
return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
- << "Invalid OperandType when converting OperandPerformance in Capabilities";
+ << "Invalid OperandType when unvalidatedConverting OperandPerformance in "
+ "Capabilities";
}
- auto operandPerformance = NN_TRY(convert(capabilities.operandPerformance));
+ auto operandPerformance = NN_TRY(unvalidatedConvert(capabilities.operandPerformance));
auto table = NN_TRY(hal::utils::makeGeneralFailure(
Capabilities::OperandPerformanceTable::create(std::move(operandPerformance)),
nn::ErrorStatus::GENERAL_FAILURE));
return Capabilities{
- .relaxedFloat32toFloat16PerformanceScalar =
- NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
- .relaxedFloat32toFloat16PerformanceTensor =
- NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
+ .relaxedFloat32toFloat16PerformanceScalar = NN_TRY(
+ unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
+ .relaxedFloat32toFloat16PerformanceTensor = NN_TRY(
+ unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
.operandPerformance = std::move(table),
- .ifPerformance = NN_TRY(convert(capabilities.ifPerformance)),
- .whilePerformance = NN_TRY(convert(capabilities.whilePerformance)),
+ .ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance)),
+ .whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance)),
};
}
-GeneralResult<Capabilities::OperandPerformance> convert(
+GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
const hal::V1_3::Capabilities::OperandPerformance& operandPerformance) {
return Capabilities::OperandPerformance{
- .type = NN_TRY(convert(operandPerformance.type)),
- .info = NN_TRY(convert(operandPerformance.info)),
+ .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
+ .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
};
}
-GeneralResult<Operation> convert(const hal::V1_3::Operation& operation) {
+GeneralResult<Operation> unvalidatedConvert(const hal::V1_3::Operation& operation) {
return Operation{
- .type = NN_TRY(convert(operation.type)),
+ .type = NN_TRY(unvalidatedConvert(operation.type)),
.inputs = operation.inputs,
.outputs = operation.outputs,
};
}
-GeneralResult<Operand::LifeTime> convert(const hal::V1_3::OperandLifeTime& operandLifeTime) {
+GeneralResult<Operand::LifeTime> unvalidatedConvert(
+ const hal::V1_3::OperandLifeTime& operandLifeTime) {
return static_cast<Operand::LifeTime>(operandLifeTime);
}
-GeneralResult<Operand> convert(const hal::V1_3::Operand& operand) {
+GeneralResult<Operand> unvalidatedConvert(const hal::V1_3::Operand& operand) {
return Operand{
- .type = NN_TRY(convert(operand.type)),
+ .type = NN_TRY(unvalidatedConvert(operand.type)),
.dimensions = operand.dimensions,
.scale = operand.scale,
.zeroPoint = operand.zeroPoint,
- .lifetime = NN_TRY(convert(operand.lifetime)),
- .location = NN_TRY(convert(operand.location)),
- .extraParams = NN_TRY(convert(operand.extraParams)),
+ .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
+ .location = NN_TRY(unvalidatedConvert(operand.location)),
+ .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
};
}
-GeneralResult<Model> convert(const hal::V1_3::Model& model) {
+GeneralResult<Model> unvalidatedConvert(const hal::V1_3::Model& model) {
return Model{
- .main = NN_TRY(convert(model.main)),
- .referenced = NN_TRY(convert(model.referenced)),
- .operandValues = NN_TRY(convert(model.operandValues)),
- .pools = NN_TRY(convert(model.pools)),
+ .main = NN_TRY(unvalidatedConvert(model.main)),
+ .referenced = NN_TRY(unvalidatedConvert(model.referenced)),
+ .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
+ .pools = NN_TRY(unvalidatedConvert(model.pools)),
.relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
- .extensionNameToPrefix = NN_TRY(convert(model.extensionNameToPrefix)),
+ .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
};
}
-GeneralResult<Model::Subgraph> convert(const hal::V1_3::Subgraph& subgraph) {
- auto operations = NN_TRY(convert(subgraph.operations));
+GeneralResult<Model::Subgraph> unvalidatedConvert(const hal::V1_3::Subgraph& subgraph) {
+ auto operations = NN_TRY(unvalidatedConvert(subgraph.operations));
// Verify number of consumers.
const auto numberOfConsumers =
@@ -196,18 +229,18 @@
}
return Model::Subgraph{
- .operands = NN_TRY(convert(subgraph.operands)),
+ .operands = NN_TRY(unvalidatedConvert(subgraph.operands)),
.operations = std::move(operations),
.inputIndexes = subgraph.inputIndexes,
.outputIndexes = subgraph.outputIndexes,
};
}
-GeneralResult<BufferDesc> convert(const hal::V1_3::BufferDesc& bufferDesc) {
+GeneralResult<BufferDesc> unvalidatedConvert(const hal::V1_3::BufferDesc& bufferDesc) {
return BufferDesc{.dimensions = bufferDesc.dimensions};
}
-GeneralResult<BufferRole> convert(const hal::V1_3::BufferRole& bufferRole) {
+GeneralResult<BufferRole> unvalidatedConvert(const hal::V1_3::BufferRole& bufferRole) {
return BufferRole{
.modelIndex = bufferRole.modelIndex,
.ioIndex = bufferRole.ioIndex,
@@ -215,15 +248,16 @@
};
}
-GeneralResult<Request> convert(const hal::V1_3::Request& request) {
+GeneralResult<Request> unvalidatedConvert(const hal::V1_3::Request& request) {
return Request{
- .inputs = NN_TRY(convert(request.inputs)),
- .outputs = NN_TRY(convert(request.outputs)),
- .pools = NN_TRY(convert(request.pools)),
+ .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
+ .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
+ .pools = NN_TRY(unvalidatedConvert(request.pools)),
};
}
-GeneralResult<Request::MemoryPool> convert(const hal::V1_3::Request::MemoryPool& memoryPool) {
+GeneralResult<Request::MemoryPool> unvalidatedConvert(
+ const hal::V1_3::Request::MemoryPool& memoryPool) {
using Discriminator = hal::V1_3::Request::MemoryPool::hidl_discriminator;
switch (memoryPool.getDiscriminator()) {
case Discriminator::hidlMemory:
@@ -236,12 +270,14 @@
<< underlyingType(memoryPool.getDiscriminator());
}
-GeneralResult<OptionalTimePoint> convert(const hal::V1_3::OptionalTimePoint& optionalTimePoint) {
+GeneralResult<OptionalTimePoint> unvalidatedConvert(
+ const hal::V1_3::OptionalTimePoint& optionalTimePoint) {
constexpr auto kTimePointMaxCount = TimePoint::max().time_since_epoch().count();
const auto makeTimePoint = [](uint64_t count) -> GeneralResult<OptionalTimePoint> {
if (count > kTimePointMaxCount) {
return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
- << "Unable to convert OptionalTimePoint because the count exceeds the max";
+ << "Unable to unvalidatedConvert OptionalTimePoint because the count exceeds "
+ "the max";
}
const auto nanoseconds = std::chrono::nanoseconds{count};
return TimePoint{nanoseconds};
@@ -259,13 +295,14 @@
<< underlyingType(optionalTimePoint.getDiscriminator());
}
-GeneralResult<OptionalTimeoutDuration> convert(
+GeneralResult<OptionalTimeoutDuration> unvalidatedConvert(
const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration) {
constexpr auto kTimeoutDurationMaxCount = TimeoutDuration::max().count();
const auto makeTimeoutDuration = [](uint64_t count) -> GeneralResult<OptionalTimeoutDuration> {
if (count > kTimeoutDurationMaxCount) {
return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
- << "Unable to convert OptionalTimeoutDuration because the count exceeds the max";
+ << "Unable to unvalidatedConvert OptionalTimeoutDuration because the count "
+ "exceeds the max";
}
return TimeoutDuration{count};
};
@@ -282,7 +319,7 @@
<< underlyingType(optionalTimeoutDuration.getDiscriminator());
}
-GeneralResult<ErrorStatus> convert(const hal::V1_3::ErrorStatus& status) {
+GeneralResult<ErrorStatus> unvalidatedConvert(const hal::V1_3::ErrorStatus& status) {
switch (status) {
case hal::V1_3::ErrorStatus::NONE:
case hal::V1_3::ErrorStatus::DEVICE_UNAVAILABLE:
@@ -299,9 +336,50 @@
<< "Invalid ErrorStatus " << underlyingType(status);
}
+GeneralResult<Priority> convert(const hal::V1_3::Priority& priority) {
+ return validatedConvert(priority);
+}
+
+GeneralResult<Capabilities> convert(const hal::V1_3::Capabilities& capabilities) {
+ return validatedConvert(capabilities);
+}
+
+GeneralResult<Model> convert(const hal::V1_3::Model& model) {
+ return validatedConvert(model);
+}
+
+GeneralResult<BufferDesc> convert(const hal::V1_3::BufferDesc& bufferDesc) {
+ return validatedConvert(bufferDesc);
+}
+
+GeneralResult<Request> convert(const hal::V1_3::Request& request) {
+ return validatedConvert(request);
+}
+
+GeneralResult<OptionalTimePoint> convert(const hal::V1_3::OptionalTimePoint& optionalTimePoint) {
+ return validatedConvert(optionalTimePoint);
+}
+
+GeneralResult<OptionalTimeoutDuration> convert(
+ const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration) {
+ return validatedConvert(optionalTimeoutDuration);
+}
+
+GeneralResult<ErrorStatus> convert(const hal::V1_3::ErrorStatus& errorStatus) {
+ return validatedConvert(errorStatus);
+}
+
+GeneralResult<SharedHandle> convert(const hardware::hidl_handle& handle) {
+ return validatedConvert(handle);
+}
+
+GeneralResult<Memory> convert(const hardware::hidl_memory& memory) {
+ return validatedConvert(memory);
+}
+
GeneralResult<std::vector<BufferRole>> convert(
const hardware::hidl_vec<hal::V1_3::BufferRole>& bufferRoles) {
- return convertVec(bufferRoles);
+ return validatedConvert(bufferRoles);
}
} // namespace android::nn
@@ -309,58 +387,67 @@
namespace android::hardware::neuralnetworks::V1_3::utils {
namespace {
-using utils::convert;
+using utils::unvalidatedConvert;
-nn::GeneralResult<V1_0::PerformanceInfo> convert(
+nn::GeneralResult<V1_0::PerformanceInfo> unvalidatedConvert(
const nn::Capabilities::PerformanceInfo& performanceInfo) {
- return V1_0::utils::convert(performanceInfo);
+ return V1_0::utils::unvalidatedConvert(performanceInfo);
}
-nn::GeneralResult<V1_0::DataLocation> convert(const nn::DataLocation& dataLocation) {
- return V1_0::utils::convert(dataLocation);
+nn::GeneralResult<V1_0::DataLocation> unvalidatedConvert(const nn::DataLocation& dataLocation) {
+ return V1_0::utils::unvalidatedConvert(dataLocation);
}
-nn::GeneralResult<hidl_vec<uint8_t>> convert(const nn::Model::OperandValues& operandValues) {
- return V1_0::utils::convert(operandValues);
+nn::GeneralResult<hidl_vec<uint8_t>> unvalidatedConvert(
+ const nn::Model::OperandValues& operandValues) {
+ return V1_0::utils::unvalidatedConvert(operandValues);
}
-nn::GeneralResult<hidl_memory> convert(const nn::Memory& memory) {
- return V1_0::utils::convert(memory);
+nn::GeneralResult<hidl_handle> unvalidatedConvert(const nn::SharedHandle& handle) {
+ return V1_2::utils::unvalidatedConvert(handle);
}
-nn::GeneralResult<V1_0::RequestArgument> convert(const nn::Request::Argument& argument) {
- return V1_0::utils::convert(argument);
+nn::GeneralResult<hidl_memory> unvalidatedConvert(const nn::Memory& memory) {
+ return V1_0::utils::unvalidatedConvert(memory);
}
-nn::GeneralResult<V1_2::Operand::ExtraParams> convert(const nn::Operand::ExtraParams& extraParams) {
- return V1_2::utils::convert(extraParams);
+nn::GeneralResult<V1_0::RequestArgument> unvalidatedConvert(const nn::Request::Argument& argument) {
+ return V1_0::utils::unvalidatedConvert(argument);
}
-nn::GeneralResult<V1_2::Model::ExtensionNameAndPrefix> convert(
+nn::GeneralResult<V1_2::Operand::ExtraParams> unvalidatedConvert(
+ const nn::Operand::ExtraParams& extraParams) {
+ return V1_2::utils::unvalidatedConvert(extraParams);
+}
+
+nn::GeneralResult<V1_2::Model::ExtensionNameAndPrefix> unvalidatedConvert(
const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) {
- return V1_2::utils::convert(extensionNameAndPrefix);
+ return V1_2::utils::unvalidatedConvert(extensionNameAndPrefix);
}
template <typename Input>
-using ConvertOutput = std::decay_t<decltype(convert(std::declval<Input>()).value())>;
+using unvalidatedConvertOutput =
+ std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
template <typename Type>
-nn::GeneralResult<hidl_vec<ConvertOutput<Type>>> convertVec(const std::vector<Type>& arguments) {
- hidl_vec<ConvertOutput<Type>> halObject(arguments.size());
+nn::GeneralResult<hidl_vec<unvalidatedConvertOutput<Type>>> unvalidatedConvertVec(
+ const std::vector<Type>& arguments) {
+ hidl_vec<unvalidatedConvertOutput<Type>> halObject(arguments.size());
for (size_t i = 0; i < arguments.size(); ++i) {
- halObject[i] = NN_TRY(convert(arguments[i]));
+ halObject[i] = NN_TRY(unvalidatedConvert(arguments[i]));
}
return halObject;
}
template <typename Type>
-nn::GeneralResult<hidl_vec<ConvertOutput<Type>>> convert(const std::vector<Type>& arguments) {
- return convertVec(arguments);
+nn::GeneralResult<hidl_vec<unvalidatedConvertOutput<Type>>> unvalidatedConvert(
+ const std::vector<Type>& arguments) {
+ return unvalidatedConvertVec(arguments);
}
nn::GeneralResult<Request::MemoryPool> makeMemoryPool(const nn::Memory& memory) {
Request::MemoryPool ret;
- ret.hidlMemory(NN_TRY(convert(memory)));
+ ret.hidlMemory(NN_TRY(unvalidatedConvert(memory)));
return ret;
}
@@ -374,21 +461,46 @@
return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Unable to make memory pool from IBuffer";
}
+using utils::unvalidatedConvert;
+
+template <typename Type>
+decltype(unvalidatedConvert(std::declval<Type>())) validatedConvert(const Type& canonical) {
+ const auto maybeVersion = nn::validate(canonical);
+ if (!maybeVersion.has_value()) {
+ return nn::error() << maybeVersion.error();
+ }
+ const auto version = maybeVersion.value();
+ if (version > kVersion) {
+ return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
+ }
+ return unvalidatedConvert(canonical);
+}
+
+template <typename Type>
+nn::GeneralResult<hidl_vec<unvalidatedConvertOutput<Type>>> validatedConvert(
+ const std::vector<Type>& arguments) {
+ hidl_vec<unvalidatedConvertOutput<Type>> halObject(arguments.size());
+ for (size_t i = 0; i < arguments.size(); ++i) {
+ halObject[i] = NN_TRY(validatedConvert(arguments[i]));
+ }
+ return halObject;
+}
+
} // anonymous namespace
-nn::GeneralResult<OperandType> convert(const nn::OperandType& operandType) {
+nn::GeneralResult<OperandType> unvalidatedConvert(const nn::OperandType& operandType) {
return static_cast<OperandType>(operandType);
}
-nn::GeneralResult<OperationType> convert(const nn::OperationType& operationType) {
+nn::GeneralResult<OperationType> unvalidatedConvert(const nn::OperationType& operationType) {
return static_cast<OperationType>(operationType);
}
-nn::GeneralResult<Priority> convert(const nn::Priority& priority) {
+nn::GeneralResult<Priority> unvalidatedConvert(const nn::Priority& priority) {
return static_cast<Priority>(priority);
}
-nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities) {
+nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
std::vector<nn::Capabilities::OperandPerformance> operandPerformance;
operandPerformance.reserve(capabilities.operandPerformance.asVector().size());
std::copy_if(capabilities.operandPerformance.asVector().begin(),
@@ -399,71 +511,72 @@
});
return Capabilities{
- .relaxedFloat32toFloat16PerformanceScalar =
- NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
- .relaxedFloat32toFloat16PerformanceTensor =
- NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
- .operandPerformance = NN_TRY(convert(operandPerformance)),
- .ifPerformance = NN_TRY(convert(capabilities.ifPerformance)),
- .whilePerformance = NN_TRY(convert(capabilities.whilePerformance)),
+ .relaxedFloat32toFloat16PerformanceScalar = NN_TRY(
+ unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
+ .relaxedFloat32toFloat16PerformanceTensor = NN_TRY(
+ unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
+ .operandPerformance = NN_TRY(unvalidatedConvert(operandPerformance)),
+ .ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance)),
+ .whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance)),
};
}
-nn::GeneralResult<Capabilities::OperandPerformance> convert(
+nn::GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
const nn::Capabilities::OperandPerformance& operandPerformance) {
return Capabilities::OperandPerformance{
- .type = NN_TRY(convert(operandPerformance.type)),
- .info = NN_TRY(convert(operandPerformance.info)),
+ .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
+ .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
};
}
-nn::GeneralResult<Operation> convert(const nn::Operation& operation) {
+nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
return Operation{
- .type = NN_TRY(convert(operation.type)),
+ .type = NN_TRY(unvalidatedConvert(operation.type)),
.inputs = operation.inputs,
.outputs = operation.outputs,
};
}
-nn::GeneralResult<OperandLifeTime> convert(const nn::Operand::LifeTime& operandLifeTime) {
+nn::GeneralResult<OperandLifeTime> unvalidatedConvert(
+ const nn::Operand::LifeTime& operandLifeTime) {
if (operandLifeTime == nn::Operand::LifeTime::POINTER) {
return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
- << "Model cannot be converted because it contains pointer-based memory";
+ << "Model cannot be unvalidatedConverted because it contains pointer-based memory";
}
return static_cast<OperandLifeTime>(operandLifeTime);
}
-nn::GeneralResult<Operand> convert(const nn::Operand& operand) {
+nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand) {
return Operand{
- .type = NN_TRY(convert(operand.type)),
+ .type = NN_TRY(unvalidatedConvert(operand.type)),
.dimensions = operand.dimensions,
.numberOfConsumers = 0,
.scale = operand.scale,
.zeroPoint = operand.zeroPoint,
- .lifetime = NN_TRY(convert(operand.lifetime)),
- .location = NN_TRY(convert(operand.location)),
- .extraParams = NN_TRY(convert(operand.extraParams)),
+ .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
+ .location = NN_TRY(unvalidatedConvert(operand.location)),
+ .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
};
}
-nn::GeneralResult<Model> convert(const nn::Model& model) {
+nn::GeneralResult<Model> unvalidatedConvert(const nn::Model& model) {
if (!hal::utils::hasNoPointerData(model)) {
return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
- << "Model cannot be converted because it contains pointer-based memory";
+ << "Model cannot be unvalidatedConverted because it contains pointer-based memory";
}
return Model{
- .main = NN_TRY(convert(model.main)),
- .referenced = NN_TRY(convert(model.referenced)),
- .operandValues = NN_TRY(convert(model.operandValues)),
- .pools = NN_TRY(convert(model.pools)),
+ .main = NN_TRY(unvalidatedConvert(model.main)),
+ .referenced = NN_TRY(unvalidatedConvert(model.referenced)),
+ .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
+ .pools = NN_TRY(unvalidatedConvert(model.pools)),
.relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
- .extensionNameToPrefix = NN_TRY(convert(model.extensionNameToPrefix)),
+ .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
};
}
-nn::GeneralResult<Subgraph> convert(const nn::Model::Subgraph& subgraph) {
- auto operands = NN_TRY(convert(subgraph.operands));
+nn::GeneralResult<Subgraph> unvalidatedConvert(const nn::Model::Subgraph& subgraph) {
+ auto operands = NN_TRY(unvalidatedConvert(subgraph.operands));
// Update number of consumers.
const auto numberOfConsumers =
@@ -475,17 +588,17 @@
return Subgraph{
.operands = std::move(operands),
- .operations = NN_TRY(convert(subgraph.operations)),
+ .operations = NN_TRY(unvalidatedConvert(subgraph.operations)),
.inputIndexes = subgraph.inputIndexes,
.outputIndexes = subgraph.outputIndexes,
};
}
-nn::GeneralResult<BufferDesc> convert(const nn::BufferDesc& bufferDesc) {
+nn::GeneralResult<BufferDesc> unvalidatedConvert(const nn::BufferDesc& bufferDesc) {
return BufferDesc{.dimensions = bufferDesc.dimensions};
}
-nn::GeneralResult<BufferRole> convert(const nn::BufferRole& bufferRole) {
+nn::GeneralResult<BufferRole> unvalidatedConvert(const nn::BufferRole& bufferRole) {
return BufferRole{
.modelIndex = bufferRole.modelIndex,
.ioIndex = bufferRole.ioIndex,
@@ -493,30 +606,33 @@
};
}
-nn::GeneralResult<Request> convert(const nn::Request& request) {
+nn::GeneralResult<Request> unvalidatedConvert(const nn::Request& request) {
if (!hal::utils::hasNoPointerData(request)) {
return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
- << "Request cannot be converted because it contains pointer-based memory";
+ << "Request cannot be unvalidatedConverted because it contains pointer-based memory";
}
return Request{
- .inputs = NN_TRY(convert(request.inputs)),
- .outputs = NN_TRY(convert(request.outputs)),
- .pools = NN_TRY(convert(request.pools)),
+ .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
+ .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
+ .pools = NN_TRY(unvalidatedConvert(request.pools)),
};
}
-nn::GeneralResult<Request::MemoryPool> convert(const nn::Request::MemoryPool& memoryPool) {
+nn::GeneralResult<Request::MemoryPool> unvalidatedConvert(
+ const nn::Request::MemoryPool& memoryPool) {
return std::visit([](const auto& o) { return makeMemoryPool(o); }, memoryPool);
}
-nn::GeneralResult<OptionalTimePoint> convert(const nn::OptionalTimePoint& optionalTimePoint) {
+nn::GeneralResult<OptionalTimePoint> unvalidatedConvert(
+ const nn::OptionalTimePoint& optionalTimePoint) {
OptionalTimePoint ret;
if (optionalTimePoint.has_value()) {
const auto count = optionalTimePoint.value().time_since_epoch().count();
if (count < 0) {
return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
- << "Unable to convert OptionalTimePoint because time since epoch count is "
+ << "Unable to unvalidatedConvert OptionalTimePoint because time since epoch "
+ "count is "
"negative";
}
ret.nanosecondsSinceEpoch(count);
@@ -524,21 +640,22 @@
return ret;
}
-nn::GeneralResult<OptionalTimeoutDuration> convert(
+nn::GeneralResult<OptionalTimeoutDuration> unvalidatedConvert(
const nn::OptionalTimeoutDuration& optionalTimeoutDuration) {
OptionalTimeoutDuration ret;
if (optionalTimeoutDuration.has_value()) {
const auto count = optionalTimeoutDuration.value().count();
if (count < 0) {
return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
- << "Unable to convert OptionalTimeoutDuration because count is negative";
+ << "Unable to unvalidatedConvert OptionalTimeoutDuration because count is "
+ "negative";
}
ret.nanoseconds(count);
}
return ret;
}
-nn::GeneralResult<ErrorStatus> convert(const nn::ErrorStatus& errorStatus) {
+nn::GeneralResult<ErrorStatus> unvalidatedConvert(const nn::ErrorStatus& errorStatus) {
switch (errorStatus) {
case nn::ErrorStatus::NONE:
case nn::ErrorStatus::DEVICE_UNAVAILABLE:
@@ -555,8 +672,49 @@
}
}
+nn::GeneralResult<Priority> convert(const nn::Priority& priority) {
+ return validatedConvert(priority);
+}
+
+nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities) {
+ return validatedConvert(capabilities);
+}
+
+nn::GeneralResult<Model> convert(const nn::Model& model) {
+ return validatedConvert(model);
+}
+
+nn::GeneralResult<BufferDesc> convert(const nn::BufferDesc& bufferDesc) {
+ return validatedConvert(bufferDesc);
+}
+
+nn::GeneralResult<Request> convert(const nn::Request& request) {
+ return validatedConvert(request);
+}
+
+nn::GeneralResult<OptionalTimePoint> convert(const nn::OptionalTimePoint& optionalTimePoint) {
+ return validatedConvert(optionalTimePoint);
+}
+
+nn::GeneralResult<OptionalTimeoutDuration> convert(
+ const nn::OptionalTimeoutDuration& optionalTimeoutDuration) {
+ return validatedConvert(optionalTimeoutDuration);
+}
+
+nn::GeneralResult<ErrorStatus> convert(const nn::ErrorStatus& errorStatus) {
+ return validatedConvert(errorStatus);
+}
+
+nn::GeneralResult<hidl_handle> convert(const nn::SharedHandle& handle) {
+ return validatedConvert(handle);
+}
+
+nn::GeneralResult<hidl_memory> convert(const nn::Memory& memory) {
+ return validatedConvert(memory);
+}
+
nn::GeneralResult<hidl_vec<BufferRole>> convert(const std::vector<nn::BufferRole>& bufferRoles) {
- return convertVec(bufferRoles);
+ return validatedConvert(bufferRoles);
}
} // namespace android::hardware::neuralnetworks::V1_3::utils
diff --git a/neuralnetworks/1.3/utils/src/Device.cpp b/neuralnetworks/1.3/utils/src/Device.cpp
index 5e3d5c2..82837ba 100644
--- a/neuralnetworks/1.3/utils/src/Device.cpp
+++ b/neuralnetworks/1.3/utils/src/Device.cpp
@@ -71,6 +71,26 @@
return NN_TRY(std::move(result));
}
+nn::GeneralResult<nn::Capabilities> initCapabilities(V1_3::IDevice* device) {
+ CHECK(device != nullptr);
+
+ nn::GeneralResult<nn::Capabilities> result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
+ << "uninitialized";
+ const auto cb = [&result](ErrorStatus status, const Capabilities& capabilities) {
+ if (status != ErrorStatus::NONE) {
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ result = NN_ERROR(canonical) << "getCapabilities_1_3 failed with " << toString(status);
+ } else {
+ result = nn::convert(capabilities);
+ }
+ };
+
+ const auto ret = device->getCapabilities_1_3(cb);
+ HANDLE_TRANSPORT_FAILURE(ret);
+
+ return result;
+}
+
} // namespace
nn::GeneralResult<std::shared_ptr<const Device>> Device::create(std::string name,
@@ -87,7 +107,7 @@
auto versionString = NN_TRY(V1_2::utils::initVersionString(device.get()));
const auto deviceType = NN_TRY(V1_2::utils::initDeviceType(device.get()));
auto extensions = NN_TRY(V1_2::utils::initExtensions(device.get()));
- auto capabilities = NN_TRY(V1_2::utils::initCapabilities(device.get()));
+ auto capabilities = NN_TRY(initCapabilities(device.get()));
const auto numberOfCacheFilesNeeded =
NN_TRY(V1_2::utils::initNumberOfCacheFilesNeeded(device.get()));
@@ -142,7 +162,8 @@
nn::GeneralResult<void> Device::wait() const {
const auto ret = kDevice->ping();
- return hal::utils::handleTransportError(ret);
+ HANDLE_TRANSPORT_FAILURE(ret);
+ return {};
}
nn::GeneralResult<std::vector<bool>> Device::getSupportedOperations(const nn::Model& model) const {
@@ -157,8 +178,7 @@
<< "uninitialized";
auto cb = [&result, &model](ErrorStatus status, const hidl_vec<bool>& supportedOperations) {
if (status != ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
result = NN_ERROR(canonical)
<< "IDevice::getSupportedOperations_1_3 failed with " << toString(status);
} else if (supportedOperations.size() != model.main.operations.size()) {
@@ -172,7 +192,7 @@
};
const auto ret = kDevice->getSupportedOperations_1_3(hidlModel, cb);
- NN_TRY(hal::utils::handleTransportError(ret));
+ HANDLE_TRANSPORT_FAILURE(ret);
return result;
}
@@ -200,10 +220,9 @@
const auto ret =
kDevice->prepareModel_1_3(hidlModel, hidlPreference, hidlPriority, hidlDeadline,
hidlModelCache, hidlDataCache, hidlToken, cb);
- const auto status = NN_TRY(hal::utils::handleTransportError(ret));
+ const auto status = HANDLE_TRANSPORT_FAILURE(ret);
if (status != ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
return NN_ERROR(canonical) << "prepareModel_1_3 failed with " << toString(status);
}
@@ -223,10 +242,9 @@
const auto ret = kDevice->prepareModelFromCache_1_3(hidlDeadline, hidlModelCache, hidlDataCache,
hidlToken, cb);
- const auto status = NN_TRY(hal::utils::handleTransportError(ret));
+ const auto status = HANDLE_TRANSPORT_FAILURE(ret);
if (status != ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
return NN_ERROR(canonical) << "prepareModelFromCache_1_3 failed with " << toString(status);
}
@@ -246,8 +264,7 @@
<< "uninitialized";
auto cb = [&result](ErrorStatus status, const sp<IBuffer>& buffer, uint32_t token) {
if (status != ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
result = NN_ERROR(canonical) << "IDevice::allocate failed with " << toString(status);
} else if (buffer == nullptr) {
result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Returned buffer is nullptr";
@@ -261,7 +278,7 @@
const auto ret =
kDevice->allocate(hidlDesc, hidlPreparedModels, hidlInputRoles, hidlOutputRoles, cb);
- NN_TRY(hal::utils::handleTransportError(ret));
+ HANDLE_TRANSPORT_FAILURE(ret);
return result;
}
diff --git a/neuralnetworks/1.3/utils/src/PreparedModel.cpp b/neuralnetworks/1.3/utils/src/PreparedModel.cpp
index 2781053..49b9b0b 100644
--- a/neuralnetworks/1.3/utils/src/PreparedModel.cpp
+++ b/neuralnetworks/1.3/utils/src/PreparedModel.cpp
@@ -27,6 +27,7 @@
#include <android/hardware/neuralnetworks/1.3/types.h>
#include <nnapi/IPreparedModel.h>
#include <nnapi/Result.h>
+#include <nnapi/TypeUtils.h>
#include <nnapi/Types.h>
#include <nnapi/hal/1.2/Conversions.h>
#include <nnapi/hal/CommonUtils.h>
@@ -44,8 +45,7 @@
nn::GeneralResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>>
convertExecutionResultsHelper(const hidl_vec<V1_2::OutputShape>& outputShapes,
const V1_2::Timing& timing) {
- return std::make_pair(NN_TRY(validatedConvertToCanonical(outputShapes)),
- NN_TRY(validatedConvertToCanonical(timing)));
+ return std::make_pair(NN_TRY(nn::convert(outputShapes)), NN_TRY(nn::convert(timing)));
}
nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> convertExecutionResults(
@@ -55,8 +55,7 @@
nn::GeneralResult<std::pair<nn::Timing, nn::Timing>> convertFencedExecutionCallbackResults(
const V1_2::Timing& timingLaunched, const V1_2::Timing& timingFenced) {
- return std::make_pair(NN_TRY(validatedConvertToCanonical(timingLaunched)),
- NN_TRY(validatedConvertToCanonical(timingFenced)));
+ return std::make_pair(NN_TRY(nn::convert(timingLaunched)), NN_TRY(nn::convert(timingFenced)));
}
nn::GeneralResult<std::pair<nn::SyncFence, nn::ExecuteFencedInfoCallback>>
@@ -64,9 +63,9 @@
const sp<IFencedExecutionCallback>& callback) {
auto resultSyncFence = nn::SyncFence::createAsSignaled();
if (syncFence.getNativeHandle() != nullptr) {
- auto nativeHandle = NN_TRY(validatedConvertToCanonical(syncFence));
+ auto sharedHandle = NN_TRY(nn::convert(syncFence));
resultSyncFence = NN_TRY(hal::utils::makeGeneralFailure(
- nn::SyncFence::create(std::move(nativeHandle)), nn::ErrorStatus::GENERAL_FAILURE));
+ nn::SyncFence::create(std::move(sharedHandle)), nn::ErrorStatus::GENERAL_FAILURE));
}
if (callback == nullptr) {
@@ -81,8 +80,8 @@
auto cb = [&result](ErrorStatus status, const V1_2::Timing& timingLaunched,
const V1_2::Timing& timingFenced) {
if (status != ErrorStatus::NONE) {
- const auto canonical = validatedConvertToCanonical(status).value_or(
- nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical =
+ nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
result = NN_ERROR(canonical) << "getExecutionInfo failed with " << toString(status);
} else {
result = convertFencedExecutionCallbackResults(timingLaunched, timingFenced);
@@ -90,7 +89,7 @@
};
const auto ret = callback->getExecutionInfo(cb);
- NN_TRY(hal::utils::handleTransportError(ret));
+ HANDLE_TRANSPORT_FAILURE(ret);
return result;
};
@@ -125,8 +124,7 @@
const auto cb = [&result](ErrorStatus status, const hidl_vec<V1_2::OutputShape>& outputShapes,
const V1_2::Timing& timing) {
if (status != ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
result = NN_ERROR(canonical) << "executeSynchronously failed with " << toString(status);
} else {
result = convertExecutionResults(outputShapes, timing);
@@ -135,7 +133,7 @@
const auto ret = kPreparedModel->executeSynchronously_1_3(request, measure, deadline,
loopTimeoutDuration, cb);
- NN_TRY(hal::utils::makeExecutionFailure(hal::utils::handleTransportError(ret)));
+ HANDLE_TRANSPORT_FAILURE(ret);
return result;
}
@@ -149,11 +147,9 @@
const auto ret =
kPreparedModel->execute_1_3(request, measure, deadline, loopTimeoutDuration, cb);
- const auto status =
- NN_TRY(hal::utils::makeExecutionFailure(hal::utils::handleTransportError(ret)));
+ const auto status = HANDLE_TRANSPORT_FAILURE(ret);
if (status != ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
return NN_ERROR(canonical) << "executeAsynchronously failed with " << toString(status);
}
@@ -223,8 +219,7 @@
auto cb = [&result](ErrorStatus status, const hidl_handle& syncFence,
const sp<IFencedExecutionCallback>& callback) {
if (status != ErrorStatus::NONE) {
- const auto canonical =
- validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
+ const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
result = NN_ERROR(canonical) << "executeFenced failed with " << toString(status);
} else {
result = convertExecuteFencedResults(syncFence, callback);
@@ -234,7 +229,7 @@
const auto ret = kPreparedModel->executeFenced(hidlRequest, hidlWaitFor, hidlMeasure,
hidlDeadline, hidlLoopTimeoutDuration,
hidlTimeoutDurationAfterFence, cb);
- NN_TRY(hal::utils::handleTransportError(ret));
+ HANDLE_TRANSPORT_FAILURE(ret);
auto [syncFence, callback] = NN_TRY(std::move(result));
// If executeFenced required the request memory to be moved into shared memory, block here until
diff --git a/neuralnetworks/TEST_MAPPING b/neuralnetworks/TEST_MAPPING
index 0cefffa..ca5041d 100644
--- a/neuralnetworks/TEST_MAPPING
+++ b/neuralnetworks/TEST_MAPPING
@@ -21,7 +21,9 @@
"include-filter": "-*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*"
}
]
- },
+ }
+ ],
+ "presubmit-large": [
{
"name": "VtsHalNeuralnetworksV1_2TargetTest",
"options": [
diff --git a/neuralnetworks/utils/README.md b/neuralnetworks/utils/README.md
new file mode 100644
index 0000000..0dee103
--- /dev/null
+++ b/neuralnetworks/utils/README.md
@@ -0,0 +1,50 @@
+# NNAPI Conversions
+
+`convert` fails if either the source type or the destination type is invalid, and it yields a valid
+object if the conversion succeeds. For example, let's say that an enumeration in the current
+version has fewer possible values than the "same" canonical enumeration, such as `OperationType`.
+The new value of `HARD_SWISH` (introduced in Android R / NN HAL 1.3) does not map to any valid
+existing value in `OperationType`, but an older value of `ADD` (introduced in Android OC-MR1 / NN
+HAL 1.0) is valid. This can be seen in the following model conversions:
+
+```cpp
+// Unsuccessful conversion
+const nn::Model canonicalModel = createModelWhichHasV1_3Operations();
+const nn::Result<V1_0::Model> maybeVersionedModel = V1_0::utils::convert(canonicalModel);
+EXPECT_FALSE(maybeVersionedModel.has_value());
+```
+```cpp
+// Successful conversion
+const nn::Model canonicalModel = createModelWhichHasOnlyV1_0Operations();
+const nn::Result<V1_0::Model> maybeVersionedModel = V1_0::utils::convert(canonicalModel);
+ASSERT_TRUE(maybeVersionedModel.has_value());
+const V1_0::Model& versionedModel = maybeVersionedModel.value();
+EXPECT_TRUE(V1_0::utils::valid(versionedModel));
+```
+
+`V1_X::utils::convert` does not guarantee that all information is preserved. For example, In the
+case of `nn::ErrorStatus`, the new value of `MISSED_DEADLINE_TRANSIENT` can be represented by the
+existing value of `V1_0::GENERAL_FAILURE`:
+
+```cpp
+// Lossy Canonical -> HAL -> Canonical conversion
+const nn::ErrorStatus canonicalBefore = nn::ErrorStatus::MISSED_DEADLINE_TRANSIENT;
+const V1_0::ErrorStatus versioned = V1_0::utils::convert(canonicalBefore).value();
+const nn::ErrorStatus canonicalAfter = nn::convert(versioned).value();
+EXPECT_NE(canonicalBefore, canonicalAfter);
+```
+
+However, `nn::convert` is guaranteed to preserve all information:
+
+```cpp
+// Lossless HAL -> Canonical -> HAL conversion
+const V1_0::ErrorStatus versionedBefore = V1_0::ErrorStatus::GENERAL_FAILURE;
+const nn::ErrorStatus canonical = nn::convert(versionedBefore).value();
+const V1_0::ErrorStatus versionedAfter = V1_0::utils::convert(canonical).value();
+EXPECT_EQ(versionedBefore, versionedAfter);
+```
+
+The `convert` functions operate only on types that used in a HIDL method call directly. The
+`unvalidatedConvert` functions operate on types that are either used in a HIDL method call directly
+(i.e., not as a nested class) or used in a subsequent version of the NN HAL. Prefer using `convert`
+over `unvalidatedConvert`.
diff --git a/neuralnetworks/utils/common/include/nnapi/hal/HandleError.h b/neuralnetworks/utils/common/include/nnapi/hal/HandleError.h
index e4046b5..78b2a12 100644
--- a/neuralnetworks/utils/common/include/nnapi/hal/HandleError.h
+++ b/neuralnetworks/utils/common/include/nnapi/hal/HandleError.h
@@ -19,65 +19,46 @@
#include <nnapi/Result.h>
#include <nnapi/Types.h>
+#include <type_traits>
+
namespace android::hardware::neuralnetworks::utils {
template <typename Type>
nn::GeneralResult<Type> handleTransportError(const hardware::Return<Type>& ret) {
if (ret.isDeadObject()) {
- return NN_ERROR(nn::ErrorStatus::DEAD_OBJECT)
+ return nn::error(nn::ErrorStatus::DEAD_OBJECT)
<< "Return<>::isDeadObject returned true: " << ret.description();
}
if (!ret.isOk()) {
- return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
+ return nn::error(nn::ErrorStatus::GENERAL_FAILURE)
<< "Return<>::isOk returned false: " << ret.description();
}
- return ret;
+ if constexpr (!std::is_same_v<Type, void>) {
+ return static_cast<Type>(ret);
+ } else {
+ return {};
+ }
}
-template <>
-inline nn::GeneralResult<void> handleTransportError(const hardware::Return<void>& ret) {
- if (ret.isDeadObject()) {
- return NN_ERROR(nn::ErrorStatus::DEAD_OBJECT)
- << "Return<>::isDeadObject returned true: " << ret.description();
- }
- if (!ret.isOk()) {
- return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
- << "Return<>::isOk returned false: " << ret.description();
- }
- return {};
-}
+#define HANDLE_TRANSPORT_FAILURE(ret) \
+ ({ \
+ auto result = ::android::hardware::neuralnetworks::utils::handleTransportError(ret); \
+ if (!result.has_value()) { \
+ return NN_ERROR(result.error().code) << result.error().message; \
+ } \
+ std::move(result).value(); \
+ })
template <typename Type>
nn::GeneralResult<Type> makeGeneralFailure(nn::Result<Type> result, nn::ErrorStatus status) {
if (!result.has_value()) {
return nn::error(status) << std::move(result).error();
}
- return std::move(result).value();
-}
-
-template <>
-inline nn::GeneralResult<void> makeGeneralFailure(nn::Result<void> result, nn::ErrorStatus status) {
- if (!result.has_value()) {
- return nn::error(status) << std::move(result).error();
+ if constexpr (!std::is_same_v<Type, void>) {
+ return std::move(result).value();
+ } else {
+ return {};
}
- return {};
-}
-
-template <typename Type>
-nn::ExecutionResult<Type> makeExecutionFailure(nn::Result<Type> result, nn::ErrorStatus status) {
- if (!result.has_value()) {
- return nn::error(status) << std::move(result).error();
- }
- return std::move(result).value();
-}
-
-template <>
-inline nn::ExecutionResult<void> makeExecutionFailure(nn::Result<void> result,
- nn::ErrorStatus status) {
- if (!result.has_value()) {
- return nn::error(status) << std::move(result).error();
- }
- return {};
}
template <typename Type>
@@ -86,16 +67,16 @@
const auto [message, status] = std::move(result).error();
return nn::error(status) << message;
}
- return std::move(result).value();
+ if constexpr (!std::is_same_v<Type, void>) {
+ return std::move(result).value();
+ } else {
+ return {};
+ }
}
-template <>
-inline nn::ExecutionResult<void> makeExecutionFailure(nn::GeneralResult<void> result) {
- if (!result.has_value()) {
- const auto [message, status] = std::move(result).error();
- return nn::error(status) << message;
- }
- return {};
+template <typename Type>
+nn::ExecutionResult<Type> makeExecutionFailure(nn::Result<Type> result, nn::ErrorStatus status) {
+ return makeExecutionFailure(makeGeneralFailure(result, status));
}
} // namespace android::hardware::neuralnetworks::utils
\ No newline at end of file
diff --git a/neuralnetworks/utils/common/src/ProtectCallback.cpp b/neuralnetworks/utils/common/src/ProtectCallback.cpp
index 1d9a307..abe4cb6 100644
--- a/neuralnetworks/utils/common/src/ProtectCallback.cpp
+++ b/neuralnetworks/utils/common/src/ProtectCallback.cpp
@@ -58,7 +58,7 @@
auto deathRecipient = sp<DeathRecipient>::make();
const auto ret = object->linkToDeath(deathRecipient, /*cookie=*/0);
- const bool success = NN_TRY(handleTransportError(ret));
+ const bool success = HANDLE_TRANSPORT_FAILURE(ret);
if (!success) {
return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "IBase::linkToDeath returned false";
}
diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal
index c73745a..4566558 100644
--- a/radio/1.6/IRadio.hal
+++ b/radio/1.6/IRadio.hal
@@ -217,6 +217,13 @@
* Each subsequent request to this method is processed only after the
* completion of the previous one.
*
+ * When the SIM is in POWER_DOWN, the modem should send an empty vector of
+ * AppStatus in CardStatus.applications. If a SIM in the POWER_DOWN state
+ * is removed and a new SIM is inserted, the new SIM should be in POWER_UP
+ * mode by default. If the device is turned off or restarted while the SIM
+ * is in POWER_DOWN, then the SIM should turn on normally in POWER_UP mode
+ * when the device turns back on.
+ *
* Response callback is IRadioResponse.setSimCardPowerResponse_1_6().
* Note that this differs from setSimCardPower_1_1 in that the response
* callback should only be sent once the device has finished executing
@@ -320,12 +327,26 @@
* @param serial Serial number of request.
* @param networkTypeBitmap a 32-bit bearer bitmap of RadioAccessFamily
*
- * Response callbask is IRadioResponse.setNetworkTypeBitmapResponse()
+ * Response callback is IRadioResponse.setNetworkTypeBitmapResponse()
*/
oneway setAllowedNetworkTypeBitmap(
uint32_t serial, bitfield<RadioAccessFamily> networkTypeBitmap);
/**
+ * Requests bitmap representing the currently allowed network types.
+ *
+ * Requests the bitmap set by the corresponding method
+ * setAllowedNetworkTypeBitmap, which sets a strict set of RATs for the
+ * radio to use. Differs from getPreferredNetworkType and getPreferredNetworkTypeBitmap
+ * in that those request *preferences*.
+ *
+ * @param serial Serial number of request.
+ *
+ * Response callback is IRadioResponse.getNetworkTypeBitmapResponse()
+ */
+ oneway getAllowedNetworkTypeBitmap(uint32_t serial);
+
+ /**
* Control data throttling at modem.
* - DataThrottlingAction:NO_DATA_THROTTLING should clear any existing
* data throttling within the requested completion window.
@@ -358,4 +379,45 @@
* Response callback is IRadioResponse.getSystemSelectionChannelsResponse()
*/
oneway getSystemSelectionChannels(int32_t serial);
+
+ /**
+ * Request all of the current cell information known to the radio. The radio
+ * must return list of all current cells, including the neighboring cells. If for a particular
+ * cell information isn't known then the appropriate unknown value will be returned.
+ * This does not cause or change the rate of unsolicited cellInfoList().
+ *
+ * This is identitcal to getCellInfoList in V1.0, but it requests updated version of CellInfo.
+ *
+ * @param serial Serial number of request.
+ *
+ * Response callback is IRadioResponse.getCellInfoListResponse()
+ */
+ oneway getCellInfoList_1_6(int32_t serial);
+
+ /**
+ * Request current voice registration state.
+ *
+ * @param serial Serial number of request.
+ *
+ * Response function is IRadioResponse.getVoiceRegistrationStateResponse_1_6()
+ */
+ oneway getVoiceRegistrationState_1_6(int32_t serial);
+
+ /**
+ * Requests current signal strength and associated information. Must succeed if radio is on.
+ *
+ * @param serial Serial number of request.
+ *
+ * Response function is IRadioResponse.getSignalStrengthResponse_1_6()
+ */
+ oneway getSignalStrength_1_6(int32_t serial);
+
+ /**
+ * Request current data registration state.
+ *
+ * @param serial Serial number of request.
+ *
+ * Response function is IRadioResponse.getDataRegistrationStateResponse_1_6()
+ */
+ oneway getDataRegistrationState_1_6(int32_t serial);
};
diff --git a/radio/1.6/IRadioIndication.hal b/radio/1.6/IRadioIndication.hal
index f195c0e..1b56d40 100644
--- a/radio/1.6/IRadioIndication.hal
+++ b/radio/1.6/IRadioIndication.hal
@@ -18,8 +18,11 @@
import @1.0::RadioIndicationType;
import @1.5::IRadioIndication;
-import @1.6::SetupDataCallResult;
+import @1.6::CellInfo;
import @1.6::LinkCapacityEstimate;
+import @1.6::NetworkScanResult;
+import @1.6::SignalStrength;
+import @1.6::SetupDataCallResult;
/**
* Interface declaring unsolicited radio indications.
@@ -67,4 +70,35 @@
* @param lce LinkCapacityEstimate
*/
oneway currentLinkCapacityEstimate_1_6(RadioIndicationType type, LinkCapacityEstimate lce);
+
+
+ /**
+ * Indicates current signal strength of the radio.
+ *
+ * This is identical to currentSignalStrength_1_4 but uses an updated version of
+ * SignalStrength.
+ *
+ * @param type Type of radio indication
+ * @param signalStrength SignalStrength information
+ */
+ oneway currentSignalStrength_1_6(RadioIndicationType type, SignalStrength signalStrength);
+
+ /**
+ * Report all of the current cell information known to the radio.
+ *
+ * This indication is updated from IRadioIndication@1.5 to report the @1.6 version of
+ * CellInfo.
+ *
+ * @param type Type of radio indication
+ * @param records Current cell information
+ */
+ oneway cellInfoList_1_6(RadioIndicationType type, vec<CellInfo> records);
+
+ /**
+ * Incremental network scan results.
+ *
+ * This indication is updated from IRadioIndication@1.5 to report the @1.6 version of
+ * CellInfo.
+ */
+ oneway networkScanResult_1_6(RadioIndicationType type, NetworkScanResult result);
};
diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal
index c545db0..f13ee2b 100644
--- a/radio/1.6/IRadioResponse.hal
+++ b/radio/1.6/IRadioResponse.hal
@@ -17,9 +17,13 @@
package android.hardware.radio@1.6;
import @1.0::SendSmsResult;
-import @1.6::RadioResponseInfo;
+import @1.4::RadioAccessFamily;
import @1.5::IRadioResponse;
+import @1.6::CellInfo;
+import @1.6::RegStateResult;
+import @1.6::RadioResponseInfo;
import @1.6::SetupDataCallResult;
+import @1.6::SignalStrength;
/**
* Interface declaring response functions to solicited radio requests.
@@ -207,7 +211,6 @@
* Valid errors returned:
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_ARGUMENTS
* RadioError:SIM_ERR (indicates a timeout or other issue making the SIM unresponsive)
*
@@ -308,6 +311,23 @@
oneway setAllowedNetworkTypeBitmapResponse(RadioResponseInfo info);
/**
+ * Callback of IRadio.getAllowedNetworkTypeBitmap(int, bitfield<RadioAccessFamily>)
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:OPERATION_NOT_ALLOWED
+ * RadioError:MODE_NOT_SUPPORTED
+ * RadioError:INTERNAL_ERR
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:MODEM_ERR
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:NO_RESOURCES
+ */
+ oneway getAllowedNetworkTypeBitmapResponse(
+ RadioResponseInfo info, bitfield<RadioAccessFamily> networkTypeBitmap);
+
+ /**
* @param info Response info struct containing response type, serial no. and error
*
* Valid errors returned:
@@ -328,4 +348,57 @@
* RadioError:INVALID_ARGUMENTS
*/
oneway getSystemSelectionChannelsResponse(RadioResponseInfo info);
+
+ /**
+ * This is identical to getCellInfoListResponse_1_5 but uses an updated version of CellInfo.
+ *
+ * @param info Response info struct containing response type, serial no. and error
+ * @param cellInfo List of current cell information known to radio
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ */
+ oneway getCellInfoListResponse_1_6(RadioResponseInfo info, vec<CellInfo> cellInfo);
+
+ /**
+ * This is identical to getSignalStrengthResponse_1_4 but uses an updated version of
+ * SignalStrength.
+ *
+ * @param signalStrength Current signal strength
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ */
+ oneway getSignalStrengthResponse_1_6(RadioResponseInfo info, SignalStrength signalStrength);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ * @param voiceRegResponse Current Voice registration response as defined by RegStateResult
+ * in types.hal
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ */
+ oneway getVoiceRegistrationStateResponse_1_6(RadioResponseInfo info,
+ RegStateResult voiceRegResponse);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ * @param dataRegResponse Current Data registration response as defined by RegStateResult in
+ * types.hal
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ * RadioError:NOT_PROVISIONED
+ */
+ oneway getDataRegistrationStateResponse_1_6(RadioResponseInfo info,
+ RegStateResult dataRegResponse);
};
diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal
index 2cba915..20dc612 100644
--- a/radio/1.6/types.hal
+++ b/radio/1.6/types.hal
@@ -16,12 +16,35 @@
package android.hardware.radio@1.6;
+import @1.0::CdmaSignalStrength;
+import @1.0::EvdoSignalStrength;
+import @1.0::GsmSignalStrength;
+import @1.0::LteSignalStrength;
import @1.0::RadioError;
import @1.0::RadioResponseType;
+import @1.0::RegState;
+import @1.1::ScanStatus;
+import @1.2::CellInfoCdma;
+import @1.2::CellConnectionStatus;
+import @1.2::TdscdmaSignalStrength;
+import @1.2::WcdmaSignalStrength;
import @1.4::DataCallFailCause;
import @1.4::DataConnActiveStatus;
+import @1.4::NrSignalStrength;
import @1.4::PdpProtocolType;
+import @1.4::RadioTechnology;
+import @1.5::CellIdentity;
+import @1.5::CellIdentityLte;
+import @1.5::CellIdentityNr;
+import @1.5::CellInfoGsm;
+import @1.5::CellInfoWcdma;
+import @1.5::CellInfoTdscdma;
import @1.5::LinkAddress;
+import @1.5::RegStateResult.AccessTechnologySpecificInfo.Cdma2000RegistrationInfo;
+import @1.5::RegStateResult.AccessTechnologySpecificInfo.EutranRegistrationInfo;
+import @1.5::RegistrationFailCause;
+import @1.5::SetupDataCallResult;
+
import android.hidl.safe_union@1.0::Monostate;
struct QosBandwidth {
@@ -416,3 +439,287 @@
*/
HOLD = 3
};
+
+/**
+ * Defines the values for VoPS indicator of NR as per 3gpp spec 24.501 sec 9.10.3.5
+ */
+enum VopsIndicator : uint8_t {
+ /** IMS voice over PS session not supported */
+ VOPS_NOT_SUPPORTED = 0,
+ /** IMS voice over PS session supported over 3GPP access */
+ VOPS_OVER_3GPP = 1,
+ /** IMS voice over PS session supported over non-3GPP access */
+ VOPS_OVER_NON_3GPP = 2,
+};
+
+/**
+ * Defines the values for emergency service indicator of NR
+ * as per 3gpp spec 24.501 sec 9.10.3.5
+ */
+enum EmcIndicator : uint8_t {
+ /** Emergency services not supported */
+ EMC_NOT_SUPPORTED = 0,
+ /** Emergency services supported in NR connected to 5GCN only */
+ EMC_NR_CONNECTED_TO_5GCN = 1,
+ /** Emergency services supported in E-UTRA connected to 5GCN only */
+ EMC_EUTRA_CONNECTED_TO_5GCN = 2,
+ /** Emergency services supported in NR connected to 5GCN and E-UTRA connected to 5GCN */
+ EMC_BOTH_NR_EUTRA_CONNECTED_TO_5GCN = 3
+};
+
+/**
+ * Defines the values for emergency service fallback indicator of NR
+ * as per 3gpp spec 24.501 sec 9.10.3.5
+ */
+enum EmfIndicator : uint8_t {
+ /** Emergency services fallback not supported */
+ EMF_NOT_SUPPORTED = 0,
+ /** Emergency services fallback supported in NR connected to 5GCN only */
+ EMF_NR_CONNECTED_TO_5GCN = 1,
+ /** Emergency services fallback supported in E-UTRA connected to 5GCN only */
+ EMF_EUTRA_CONNECTED_TO_5GCN = 2,
+ /**
+ * Emergency services fallback supported in NR connected to 5GCN and E-UTRA
+ * connected to 5GCN.
+ */
+ EMF_BOTH_NR_EUTRA_CONNECTED_TO_5GCN = 3
+};
+
+/**
+ * Type to define the NR specific network capabilities for voice over PS including
+ * emergency and normal voice calls.
+ */
+struct NrVopsInfo {
+ /**
+ * This indicates if the camped network supports VoNR services, and what kind of services
+ * it supports. This information is received from NR network during NR NAS registration
+ * procedure through NR REGISTRATION ACCEPT.
+ * Refer 3GPP 24.501 EPS 5GS network feature support -> IMS VoPS
+ */
+ VopsIndicator vopsSupported;
+
+ /**
+ * This indicates if the camped network supports VoNR emergency service. This information
+ * is received from NR network through two sources:
+ * a. During NR NAS registration procedure through NR REGISTRATION ACCEPT.
+ * Refer 3GPP 24.501 EPS 5GS network feature support -> EMC
+ * b. In case the device is not registered on the network.
+ * Refer 3GPP 38.331 SIB1 : ims-EmergencySupport
+ * If device is registered on NR, then this field indicates whether the cell
+ * supports IMS emergency bearer services for UEs in limited service mode.
+ */
+ EmcIndicator emcSupported;
+
+ /**
+ * This indicates if the camped network supports VoNR emergency service fallback. This
+ * information is received from NR network during NR NAS registration procedure through
+ * NR REGISTRATION ACCEPT.
+ * Refer 3GPP 24.501 EPS 5GS network feature support -> EMF
+ */
+ EmfIndicator emfSupported;
+};
+
+struct LteSignalStrength {
+ @1.0::LteSignalStrength base;
+
+ /**
+ * CSI channel quality indicator (CQI) table index. There are multiple CQI tables.
+ * The definition of CQI in each table is different.
+ *
+ * Reference: 3GPP TS 136.213 section 7.2.3.
+ *
+ * Range [1, 6], INT_MAX means invalid/unreported.
+ */
+ uint32_t cqiTableIndex;
+};
+
+struct NrSignalStrength {
+ @1.4::NrSignalStrength base;
+
+ /**
+ * CSI channel quality indicator (CQI) table index. There are multiple CQI tables.
+ * The definition of CQI in each table is different.
+ *
+ * Reference: 3GPP TS 138.214 section 5.2.2.1.
+ *
+ * Range [1, 3], INT_MAX means invalid/unreported.
+ */
+ uint32_t csiCqiTableIndex;
+
+ /**
+ * CSI channel quality indicator (CQI) for all subbands.
+ *
+ * If the CQI report is for the entire wideband, a single CQI index is provided.
+ * If the CQI report is for all subbands, one CQI index is provided for each subband,
+ * in ascending order of subband index.
+ * If CQI is not available, the CQI report is empty.
+ *
+ * Reference: 3GPP TS 138.214 section 5.2.2.1.
+ *
+ * Range [0, 15], INT_MAX means invalid/unreported.
+ */
+ vec<uint32_t> csiCqiReport;
+};
+
+/**
+ * Overwritten from @1.4::SignalStrength in order to update LteSignalStrength and NrSignalStrength.
+ */
+struct SignalStrength {
+ /**
+ * If GSM measurements are provided, this structure must contain valid measurements; otherwise
+ * all fields should be set to INT_MAX to mark them as invalid.
+ */
+ GsmSignalStrength gsm;
+
+ /**
+ * If CDMA measurements are provided, this structure must contain valid measurements; otherwise
+ * all fields should be set to INT_MAX to mark them as invalid.
+ */
+ CdmaSignalStrength cdma;
+
+ /**
+ * If EvDO measurements are provided, this structure must contain valid measurements; otherwise
+ * all fields should be set to INT_MAX to mark them as invalid.
+ */
+ EvdoSignalStrength evdo;
+
+ /**
+ * If LTE measurements are provided, this structure must contain valid measurements; otherwise
+ * all fields should be set to INT_MAX to mark them as invalid.
+ */
+ LteSignalStrength lte;
+
+ /**
+ * If TD-SCDMA measurements are provided, this structure must contain valid measurements;
+ * otherwise all fields should be set to INT_MAX to mark them as invalid.
+ */
+ TdscdmaSignalStrength tdscdma;
+
+ /**
+ * If WCDMA measurements are provided, this structure must contain valid measurements; otherwise
+ * all fields should be set to INT_MAX to mark them as invalid.
+ */
+ WcdmaSignalStrength wcdma;
+
+ /**
+ * If NR 5G measurements are provided, this structure must contain valid measurements; otherwise
+ * all fields should be set to INT_MAX to mark them as invalid.
+ */
+ NrSignalStrength nr;
+};
+
+/** Overwritten from @1.5::CellInfoLte in order to update LteSignalStrength. */
+struct CellInfoLte {
+ CellIdentityLte cellIdentityLte;
+ LteSignalStrength signalStrengthLte;
+};
+
+/** Overwritten from @1.5::CellInfoNr in order to update NrSignalStrength. */
+struct CellInfoNr {
+ CellIdentityNr cellIdentityNr;
+ NrSignalStrength signalStrengthNr;
+};
+
+/** Overwritten from @1.5::CellInfo in order to update LteSignalStrength and NrSignalStrength. */
+struct CellInfo {
+ /**
+ * True if this cell is registered false if not registered.
+ */
+ bool registered;
+ /**
+ * Connection status for the cell.
+ */
+ CellConnectionStatus connectionStatus;
+
+ safe_union CellInfoRatSpecificInfo {
+ /**
+ * 3gpp CellInfo types.
+ */
+ CellInfoGsm gsm;
+ CellInfoWcdma wcdma;
+ CellInfoTdscdma tdscdma;
+ CellInfoLte lte;
+ CellInfoNr nr;
+
+ /**
+ * 3gpp2 CellInfo types;
+ */
+ CellInfoCdma cdma;
+ } ratSpecificInfo;
+};
+
+/** Overwritten from @1.5::NetworkScanResult in order to update the CellInfo to 1.6 version. */
+struct NetworkScanResult {
+ /**
+ * The status of the scan.
+ */
+ ScanStatus status;
+
+ /**
+ * The error code of the incremental result.
+ */
+ RadioError error;
+
+ /**
+ * List of network information as CellInfo.
+ */
+ vec<CellInfo> networkInfos;
+};
+
+/**
+ * Overwritten from @1.5::RegStateResult to 1.6 to support NrRegistrationInfo
+ * version.
+ */
+struct RegStateResult {
+ /**
+ * Registration state
+ *
+ * If the RAT is indicated as a GERAN, UTRAN, or CDMA2000 technology, this value reports
+ * registration in the Circuit-switched domain.
+ * If the RAT is indicated as an EUTRAN, NGRAN, or another technology that does not support
+ * circuit-switched services, this value reports registration in the Packet-switched domain.
+ */
+ RegState regState;
+
+ /**
+ * Indicates the available voice radio technology, valid values as
+ * defined by RadioTechnology.
+ */
+ RadioTechnology rat;
+
+ /**
+ * Cause code reported by the network in case registration fails. This will be a mobility
+ * management cause code defined for MM, GMM, MME or equivalent as appropriate for the RAT.
+ */
+ RegistrationFailCause reasonForDenial;
+
+ /** CellIdentity */
+ CellIdentity cellIdentity;
+
+ /**
+ * The most-recent PLMN-ID upon which the UE registered (or attempted to register if a failure
+ * is reported in the reasonForDenial field). This PLMN shall be in standard format consisting
+ * of a 3 digit MCC concatenated with a 2 or 3 digit MNC.
+ */
+ string registeredPlmn;
+
+ /**
+ * Access-technology-specific registration information, such as for CDMA2000.
+ */
+ safe_union AccessTechnologySpecificInfo {
+ Monostate noinit;
+
+ Cdma2000RegistrationInfo cdmaInfo;
+
+ EutranRegistrationInfo eutranInfo;
+
+ struct NgranRegistrationInfo {
+ /**
+ * Network capabilities for voice over PS services. This info is valid only on NR
+ * network and must be present when the device is camped on NR. VopsInfo must be
+ * empty when the device is not camped on NR.
+ */
+ NrVopsInfo nrVopsInfo;
+ } ngranInfo;
+ } accessTechnologySpecificInfo;
+};
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index 6b1ff27..75772cd 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -321,7 +321,6 @@
res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::THROTTLE_ANCHOR_CARRIER,
60000);
ASSERT_OK(res);
-
EXPECT_EQ(std::cv_status::no_timeout, wait());
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
@@ -351,7 +350,6 @@
res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::NO_DATA_THROTTLING, 60000);
ASSERT_OK(res);
-
EXPECT_EQ(std::cv_status::no_timeout, wait());
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
@@ -361,4 +359,50 @@
::android::hardware::radio::V1_6::RadioError::MODEM_ERR,
::android::hardware::radio::V1_6::RadioError::NONE,
::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS}));
-}
\ No newline at end of file
+}
+
+/*
+ * Test IRadio.setSimCardPower_1_6() for the response returned.
+ */
+TEST_P(RadioHidlTest_v1_6, setSimCardPower_1_6) {
+ /* Test setSimCardPower power down */
+ serial = GetRandomSerialNumber();
+ radio_v1_6->setSimCardPower_1_6(serial, CardPowerState::POWER_DOWN);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
+ {::android::hardware::radio::V1_6::RadioError::NONE,
+ ::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS,
+ ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE}));
+
+ // setSimCardPower_1_6 does not return until the request is handled, and should not trigger
+ // CardState::ABSENT when turning off power
+ if (radioRsp_v1_6->rspInfo.error == ::android::hardware::radio::V1_6::RadioError::NONE) {
+ /* Wait some time for setting sim power down and then verify it */
+ updateSimCardStatus();
+ EXPECT_EQ(CardState::PRESENT, cardStatus.base.base.base.cardState);
+ // applications should be an empty vector of AppStatus
+ EXPECT_EQ(0, cardStatus.applications.size());
+ }
+
+ /* Test setSimCardPower power up */
+ serial = GetRandomSerialNumber();
+ radio_v1_6->setSimCardPower_1_6(serial, CardPowerState::POWER_UP);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
+ {::android::hardware::radio::V1_6::RadioError::NONE,
+ ::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS,
+ ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE}));
+
+ // setSimCardPower_1_6 does not return until the request is handled. Just verify that we still
+ // have CardState::PRESENT after turning the power back on
+ if (radioRsp_v1_6->rspInfo.error == ::android::hardware::radio::V1_6::RadioError::NONE) {
+ updateSimCardStatus();
+ EXPECT_EQ(CardState::PRESENT, cardStatus.base.base.base.cardState);
+ }
+}
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
index 85be903..ab56540 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
+++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
@@ -793,11 +793,34 @@
Return<void> setAllowedNetworkTypeBitmapResponse(
const ::android::hardware::radio::V1_6::RadioResponseInfo& info);
+ Return<void> getAllowedNetworkTypeBitmapResponse(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+ const ::android::hardware::hidl_bitfield<
+ ::android::hardware::radio::V1_4::RadioAccessFamily>
+ networkTypeBitmap);
+
Return<void> setDataThrottlingResponse(
const ::android::hardware::radio::V1_6::RadioResponseInfo& info);
Return<void> getSystemSelectionChannelsResponse(
const ::android::hardware::radio::V1_6::RadioResponseInfo& info);
+
+ Return<void> getSignalStrengthResponse_1_6(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_6::SignalStrength& sig_strength);
+
+ Return<void> getCellInfoListResponse_1_6(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::CellInfo>&
+ cellInfo);
+
+ Return<void> getVoiceRegistrationStateResponse_1_6(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_6::RegStateResult& regResponse);
+
+ Return<void> getDataRegistrationStateResponse_1_6(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_6::RegStateResult& regResponse);
};
/* Callback class for radio indication */
@@ -817,6 +840,19 @@
Return<void> unthrottleApn(RadioIndicationType type,
const ::android::hardware::hidl_string& apn);
+ Return<void> currentSignalStrength_1_6(
+ RadioIndicationType type,
+ const ::android::hardware::radio::V1_6::SignalStrength& signalStrength);
+
+ Return<void> networkScanResult_1_6(
+ RadioIndicationType type,
+ const ::android::hardware::radio::V1_6::NetworkScanResult& result);
+
+ Return<void> cellInfoList_1_6(
+ RadioIndicationType type,
+ const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::CellInfo>&
+ records);
+
/* 1.5 Api */
Return<void> uiccApplicationsEnablementChanged(RadioIndicationType type, bool enabled);
diff --git a/radio/1.6/vts/functional/radio_indication.cpp b/radio/1.6/vts/functional/radio_indication.cpp
index afde291..bfc54c0 100644
--- a/radio/1.6/vts/functional/radio_indication.cpp
+++ b/radio/1.6/vts/functional/radio_indication.cpp
@@ -386,3 +386,22 @@
const ::android::hardware::hidl_string& /*reason*/) {
return Void();
}
+
+Return<void> RadioIndication_v1_6::currentSignalStrength_1_6(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::radio::V1_6::SignalStrength& /*signalStrength*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_6::networkScanResult_1_6(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::radio::V1_6::NetworkScanResult& /*result*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_6::cellInfoList_1_6(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::radio::V1_6::CellInfo>& /*records*/) {
+ return Void();
+}
diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp
index 7da675e..e37efdd 100644
--- a/radio/1.6/vts/functional/radio_response.cpp
+++ b/radio/1.6/vts/functional/radio_response.cpp
@@ -808,12 +808,6 @@
return Void();
}
-Return<void> RadioResponse_v1_6::getSignalStrengthResponse_1_4(
- const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
- const ::android::hardware::radio::V1_4::SignalStrength& /*sig_strength*/) {
- return Void();
-}
-
Return<void> RadioResponse_v1_6::getCellInfoListResponse_1_2(
const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::hidl_vec<
@@ -867,6 +861,12 @@
return Void();
}
+Return<void> RadioResponse_v1_6::getSignalStrengthResponse_1_4(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_4::SignalStrength& /*sig_strength*/) {
+ return Void();
+}
+
Return<void> RadioResponse_v1_6::getCellInfoListResponse_1_4(
const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::hidl_vec<
@@ -1157,6 +1157,14 @@
return Void();
}
+Return<void> RadioResponse_v1_6::getAllowedNetworkTypeBitmapResponse(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_bitfield<
+ ::android::hardware::radio::V1_4::RadioAccessFamily>
+ /*networkTypeBitmap*/) {
+ return Void();
+}
+
Return<void> RadioResponse_v1_6::setDataThrottlingResponse(
const ::android::hardware::radio::V1_6::RadioResponseInfo& info) {
rspInfo = info;
@@ -1164,9 +1172,38 @@
return Void();
}
+Return<void> RadioResponse_v1_6::getSignalStrengthResponse_1_6(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_6::SignalStrength& /*sig_strength*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_6::getCellInfoListResponse_1_6(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::radio::V1_6::CellInfo>& /*cellInfo*/) {
+ return Void();
+}
+
Return<void> RadioResponse_v1_6::getSystemSelectionChannelsResponse(
const ::android::hardware::radio::V1_6::RadioResponseInfo& info) {
rspInfo = info;
parent_v1_6.notify(info.serial);
return Void();
}
+
+Return<void> RadioResponse_v1_6::getVoiceRegistrationStateResponse_1_6(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_6::RegStateResult& /*regResponse*/) {
+ rspInfo = info;
+ parent_v1_6.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_6::getDataRegistrationStateResponse_1_6(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_6::RegStateResult& /*regResponse*/) {
+ rspInfo = info;
+ parent_v1_6.notify(info.serial);
+ return Void();
+}
diff --git a/renderscript/1.0/types.hal b/renderscript/1.0/types.hal
index 7c32188..bb39baa 100644
--- a/renderscript/1.0/types.hal
+++ b/renderscript/1.0/types.hal
@@ -170,7 +170,6 @@
};
// Script to Script
-@export(name="RsScriptCall")
struct ScriptCall {
ForEachStrategy strategy;
uint32_t xStart;
diff --git a/sensors/2.1/default/SensorsV2_1.cpp b/sensors/2.1/default/SensorsV2_1.cpp
index 2e3d315..4c5386a 100644
--- a/sensors/2.1/default/SensorsV2_1.cpp
+++ b/sensors/2.1/default/SensorsV2_1.cpp
@@ -45,7 +45,8 @@
mSensorInfo.fifoReservedEventCount = 0;
mSensorInfo.fifoMaxEventCount = 0;
mSensorInfo.requiredPermission = "";
- mSensorInfo.flags = static_cast<uint32_t>(V1_0::SensorFlagBits::ON_CHANGE_MODE);
+ mSensorInfo.flags = static_cast<uint32_t>(V1_0::SensorFlagBits::ON_CHANGE_MODE |
+ V1_0::SensorFlagBits::WAKE_UP);
}
};
diff --git a/sensors/common/default/2.X/Sensor.cpp b/sensors/common/default/2.X/Sensor.cpp
index 870980f..642fc89 100644
--- a/sensors/common/default/2.X/Sensor.cpp
+++ b/sensors/common/default/2.X/Sensor.cpp
@@ -26,6 +26,7 @@
namespace V2_X {
namespace implementation {
+using ::android::hardware::sensors::V1_0::EventPayload;
using ::android::hardware::sensors::V1_0::MetaDataEventType;
using ::android::hardware::sensors::V1_0::OperationMode;
using ::android::hardware::sensors::V1_0::Result;
@@ -133,20 +134,13 @@
}
std::vector<Event> Sensor::readEvents() {
- // For an accelerometer sensor type, default the z-direction
- // value to -9.8
- float zValue = (mSensorInfo.type == SensorType::ACCELEROMETER)
- ? -9.8 : 0.0;
-
std::vector<Event> events;
Event event;
event.sensorHandle = mSensorInfo.sensorHandle;
event.sensorType = mSensorInfo.type;
event.timestamp = ::android::elapsedRealtimeNano();
- event.u.vec3.x = 0;
- event.u.vec3.y = 0;
- event.u.vec3.z = zValue;
- event.u.vec3.status = SensorStatus::ACCURACY_HIGH;
+ memset(&event.u, 0, sizeof(event.u));
+ readEventPayload(event.u);
events.push_back(event);
return events;
}
@@ -194,7 +188,7 @@
for (auto iter = events.begin(); iter != events.end(); ++iter) {
Event ev = *iter;
- if (ev.u.vec3 != mPreviousEvent.u.vec3 || !mPreviousEventSet) {
+ if (!mPreviousEventSet || memcmp(&mPreviousEvent.u, &ev.u, sizeof(ev.u)) != 0) {
outputEvents.push_back(ev);
mPreviousEvent = ev;
mPreviousEventSet = true;
@@ -213,7 +207,7 @@
mSensorInfo.maxRange = 78.4f; // +/- 8g
mSensorInfo.resolution = 1.52e-5;
mSensorInfo.power = 0.001f; // mA
- mSensorInfo.minDelay = 20 * 1000; // microseconds
+ mSensorInfo.minDelay = 10 * 1000; // microseconds
mSensorInfo.maxDelay = kDefaultMaxDelayUs;
mSensorInfo.fifoReservedEventCount = 0;
mSensorInfo.fifoMaxEventCount = 0;
@@ -221,6 +215,13 @@
mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::DATA_INJECTION);
};
+void AccelSensor::readEventPayload(EventPayload& payload) {
+ payload.vec3.x = 0;
+ payload.vec3.y = 0;
+ payload.vec3.z = -9.8;
+ payload.vec3.status = SensorStatus::ACCURACY_HIGH;
+}
+
PressureSensor::PressureSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
: Sensor(callback) {
mSensorInfo.sensorHandle = sensorHandle;
@@ -240,6 +241,10 @@
mSensorInfo.flags = 0;
};
+void PressureSensor::readEventPayload(EventPayload& payload) {
+ payload.scalar = 1013.25f;
+}
+
MagnetometerSensor::MagnetometerSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
: Sensor(callback) {
mSensorInfo.sensorHandle = sensorHandle;
diff --git a/sensors/common/default/2.X/Sensor.h b/sensors/common/default/2.X/Sensor.h
index a792797..8ef11be 100644
--- a/sensors/common/default/2.X/Sensor.h
+++ b/sensors/common/default/2.X/Sensor.h
@@ -47,6 +47,7 @@
using OperationMode = ::android::hardware::sensors::V1_0::OperationMode;
using Result = ::android::hardware::sensors::V1_0::Result;
using Event = ::android::hardware::sensors::V2_1::Event;
+ using EventPayload = ::android::hardware::sensors::V1_0::EventPayload;
using SensorInfo = ::android::hardware::sensors::V2_1::SensorInfo;
using SensorType = ::android::hardware::sensors::V2_1::SensorType;
@@ -65,6 +66,7 @@
protected:
void run();
virtual std::vector<Event> readEvents();
+ virtual void readEventPayload(EventPayload&) {}
static void startThread(Sensor* sensor);
bool isWakeUpSensor();
@@ -101,6 +103,9 @@
class AccelSensor : public Sensor {
public:
AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
+
+ protected:
+ virtual void readEventPayload(EventPayload& payload) override;
};
class GyroSensor : public Sensor {
@@ -116,6 +121,9 @@
class PressureSensor : public Sensor {
public:
PressureSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
+
+ protected:
+ virtual void readEventPayload(EventPayload& payload) override;
};
class MagnetometerSensor : public Sensor {
diff --git a/soundtrigger/2.1/ISoundTriggerHwCallback.hal b/soundtrigger/2.1/ISoundTriggerHwCallback.hal
index 42e851b..b7720b6 100644
--- a/soundtrigger/2.1/ISoundTriggerHwCallback.hal
+++ b/soundtrigger/2.1/ISoundTriggerHwCallback.hal
@@ -22,7 +22,6 @@
/**
* SoundTrigger HAL Callback interface. Obtained during SoundTrigger setup.
*/
-@hidl_callback
interface ISoundTriggerHwCallback extends @2.0::ISoundTriggerHwCallback {
/**
diff --git a/tv/tuner/1.0/vts/functional/Android.bp b/tv/tuner/1.0/vts/functional/Android.bp
index 1765915..7b130ea 100644
--- a/tv/tuner/1.0/vts/functional/Android.bp
+++ b/tv/tuner/1.0/vts/functional/Android.bp
@@ -41,6 +41,9 @@
shared_libs: [
"libbinder",
],
+ data: [
+ ":tuner_frontend_input_ts",
+ ],
test_suites: [
"general-tests",
"vts",
diff --git a/tv/tuner/1.0/vts/functional/AndroidTest.xml b/tv/tuner/1.0/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..3a2db27
--- /dev/null
+++ b/tv/tuner/1.0/vts/functional/AndroidTest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2020 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.
+-->
+<configuration description="Runs VtsHalTvTunerV1_0TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalTvTunerV1_0TargetTest->/data/local/tmp/VtsHalTvTunerV1_0TargetTest" />
+ <option name="push" value="test.es->/data/local/tmp/test.es" />
+ <option name="push" value="segment000000.ts->/data/local/tmp/segment000000.ts" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalTvTunerV1_0TargetTest" />
+ </test>
+</configuration>
diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp
index 4fa1746..6b2413c 100644
--- a/tv/tuner/1.1/default/Filter.cpp
+++ b/tv/tuner/1.1/default/Filter.cpp
@@ -165,8 +165,9 @@
Return<Result> Filter::releaseAvHandle(const hidl_handle& avMemory, uint64_t avDataId) {
ALOGV("%s", __FUNCTION__);
- if ((avMemory.getNativeHandle()->numFds > 0) &&
+ if (mSharedAvMemHandle != NULL && avMemory != NULL &&
(mSharedAvMemHandle.getNativeHandle()->numFds > 0) &&
+ (avMemory.getNativeHandle()->numFds > 0) &&
(sameFile(avMemory.getNativeHandle()->data[0],
mSharedAvMemHandle.getNativeHandle()->data[0]))) {
freeSharedAvHandle();
diff --git a/tv/tuner/1.1/vts/functional/Android.bp b/tv/tuner/1.1/vts/functional/Android.bp
index 1fc36f1..73cd057 100644
--- a/tv/tuner/1.1/vts/functional/Android.bp
+++ b/tv/tuner/1.1/vts/functional/Android.bp
@@ -40,6 +40,9 @@
shared_libs: [
"libbinder",
],
+ data: [
+ ":tuner_frontend_input_es",
+ ],
test_suites: [
"general-tests",
"vts",
diff --git a/tv/tuner/1.1/vts/functional/AndroidTest.xml b/tv/tuner/1.1/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..28f95db
--- /dev/null
+++ b/tv/tuner/1.1/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2020 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.
+-->
+<configuration description="Runs VtsHalTvTunerV1_1TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalTvTunerV1_1TargetTest->/data/local/tmp/VtsHalTvTunerV1_1TargetTest" />
+ <option name="push" value="test.es->/data/local/tmp/test.es" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalTvTunerV1_1TargetTest" />
+ </test>
+</configuration>
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
index e872762..2dcb9a1 100644
--- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
@@ -179,7 +179,7 @@
configSingleFilterInDemuxTest(filterArray[IP_IP0], frontendArray[DVBT]);
}
-TEST_P(TunerFilterHidlTest, ReonfigFilterToReceiveStartId) {
+TEST_P(TunerFilterHidlTest, ReconfigFilterToReceiveStartId) {
description("Recofigure and restart a filter to test start id.");
// TODO use parameterized tests
reconfigSingleFilterInDemuxTest(filterArray[TS_VIDEO0], filterArray[TS_VIDEO1],
diff --git a/tv/tuner/assets/Android.bp b/tv/tuner/assets/Android.bp
new file mode 100644
index 0000000..b58b645
--- /dev/null
+++ b/tv/tuner/assets/Android.bp
@@ -0,0 +1,17 @@
+genrule {
+ name: "tuner_frontend_input_es",
+ srcs: ["tuner_frontend_input.es"],
+ out: [
+ "test.es",
+ ],
+ cmd: "cp -f $(in) $(genDir)/test.es",
+}
+
+genrule {
+ name: "tuner_frontend_input_ts",
+ srcs: ["tuner_frontend_input.ts"],
+ out: [
+ "segment000000.ts",
+ ],
+ cmd: "cp -f $(in) $(genDir)/segment000000.ts",
+}
diff --git a/tv/tuner/assets/tuner_frontend_input.es b/tv/tuner/assets/tuner_frontend_input.es
new file mode 100644
index 0000000..b53c957
--- /dev/null
+++ b/tv/tuner/assets/tuner_frontend_input.es
Binary files differ
diff --git a/tv/tuner/assets/tuner_frontend_input.ts b/tv/tuner/assets/tuner_frontend_input.ts
new file mode 100644
index 0000000..8992c7b
--- /dev/null
+++ b/tv/tuner/assets/tuner_frontend_input.ts
Binary files differ
diff --git a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
index 0b21248..cd7b603 100644
--- a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
@@ -206,7 +206,10 @@
* device/board configuration files ensuring that no ID is assigned to
* multiple clients. No client should use this API unless explicitly
* assigned an always-on source ID. Clients must develop their own way to
- * get IDs from vendor in a stable way.
+ * get IDs from vendor in a stable way. For instance, a client may expose
+ * a stable API (via HAL, sysprops, or xml overlays) to allow vendor to
+ * associate a hardware ID with a specific usecase. When that usecase is
+ * triggered, a client would use that hardware ID here.
*
* @param id The device-specific always-on source ID to enable.
* @param effect The type of haptic event to trigger.
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index dfd2524..adbb0cf 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -116,7 +116,7 @@
}
TEST_P(VibratorAidl, OnWithCallback) {
- if (!(capabilities & IVibrator::CAP_PERFORM_CALLBACK)) return;
+ if (!(capabilities & IVibrator::CAP_ON_CALLBACK)) return;
std::promise<void> completionPromise;
std::future<void> completionFuture{completionPromise.get_future()};
@@ -130,7 +130,7 @@
}
TEST_P(VibratorAidl, OnCallbackNotSupported) {
- if (!(capabilities & IVibrator::CAP_PERFORM_CALLBACK)) {
+ if (!(capabilities & IVibrator::CAP_ON_CALLBACK)) {
sp<CompletionCallback> callback = new CompletionCallback([] {});
EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, vibrator->on(250, callback).exceptionCode());
}
diff --git a/wifi/1.5/Android.bp b/wifi/1.5/Android.bp
index 5a62a3a..e2c38ce 100644
--- a/wifi/1.5/Android.bp
+++ b/wifi/1.5/Android.bp
@@ -7,6 +7,7 @@
"types.hal",
"IWifi.hal",
"IWifiChip.hal",
+ "IWifiApIface.hal",
"IWifiNanIface.hal",
"IWifiNanIfaceEventCallback.hal",
"IWifiStaIface.hal",
diff --git a/wifi/1.5/IWifiApIface.hal b/wifi/1.5/IWifiApIface.hal
new file mode 100644
index 0000000..9625a6b
--- /dev/null
+++ b/wifi/1.5/IWifiApIface.hal
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2020 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 android.hardware.wifi@1.5;
+
+import @1.4::IWifiApIface;
+import @1.0::MacAddress;
+import @1.0::WifiStatus;
+
+/**
+ * Represents a network interface in AP mode.
+ *
+ * This can be obtained through @1.0::IWifiChip.getApIface() and casting
+ * IWifiApIface up to 1.5.
+ */
+interface IWifiApIface extends @1.4::IWifiApIface {
+ /**
+ * Reset all of the AP interfaces MAC address to the factory MAC address.
+ *
+ * @return status WifiStatus of the operation
+ * Possible status codes:
+ * |WifiStatusCode.SUCCESS|,
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ resetToFactoryMacAddress() generates (WifiStatus status);
+};
diff --git a/wifi/1.5/IWifiChip.hal b/wifi/1.5/IWifiChip.hal
index dcc9279..e9caa3d 100644
--- a/wifi/1.5/IWifiChip.hal
+++ b/wifi/1.5/IWifiChip.hal
@@ -17,6 +17,8 @@
package android.hardware.wifi@1.5;
import @1.0::WifiStatus;
+import @1.0::IfaceType;
+import @1.5::IWifiApIface;
import @1.0::IWifiIface;
import @1.3::IWifiChip;
import @1.4::IWifiChip;
@@ -127,4 +129,85 @@
* |WifiStatusCode.ERROR_INVALID_ARGS|
*/
setMultiStaUseCase(MultiStaUseCase useCase) generates (WifiStatus status);
+
+ /**
+ * Create bridged IWifiApIface.
+ *
+ * Depending on the mode the chip is configured in, the interface creation
+ * may fail (code: |ERROR_NOT_AVAILABLE|) if we've already reached the maximum
+ * allowed (specified in |ChipIfaceCombination|) number of ifaces of the AP
+ * type.
+ *
+ * @return status WifiStatus of the operation.
+ * Possible status codes:
+ * |WifiStatusCode.SUCCESS|,
+ * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_NOT_AVAILABLE|
+ * @return iface HIDL interface object representing the iface if
+ * successful, null otherwise.
+ */
+ createBridgedApIface() generates (WifiStatus status, IWifiApIface iface);
+
+ /**
+ * Removes one of the instance on the AP Iface with the provided ifaceName and
+ * ifaceInstanceName.
+ *
+ * Use the API: removeApIface with brIfaceName in the V1_0::WifiChip.hal to remove bridge Iface.
+ *
+ * @param brIfaceName Name of the bridged AP iface.
+ * @param ifaceInstanceName Name of the instance. The empty instance is
+ * invalid.
+ * @return status WifiStatus of the operation.
+ * Possible status codes:
+ * |WifiStatusCode.SUCCESS|,
+ * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+ * |WifiStatusCode.ERROR_INVALID_ARGS|,
+ * |WifiStatusCode.ERROR_NOT_AVAILABLE|
+ */
+ removeIfaceInstanceFromBridgedApIface(string brIfaceName, string ifaceInstanceName)
+ generates (WifiStatus status);
+
+ /**
+ * Representation of a Wi-Fi channel for Wi-Fi coex channel avoidance.
+ */
+ struct CoexUnsafeChannel {
+ /* The band of the channel */
+ WifiBand band;
+ /* The channel number */
+ uint32_t channel;
+ /** The power cap will be a maximum power value in dbm that is allowed to be transmitted by
+ the chip on this channel. A value of PowerCapConstant.NO_POWER_CAP means no limitation
+ on transmitted power is needed by the chip for this channel.
+ */
+ int32_t powerCapDbm;
+ };
+
+ enum PowerCapConstant : int32_t {
+ NO_POWER_CAP = 0x7FFFFFFF,
+ };
+
+ /**
+ * Invoked to indicate that the provided |CoexUnsafeChannels| should be avoided with the
+ * specified restrictions.
+ *
+ * Channel avoidance is a suggestion and should be done on a best-effort approach. If a provided
+ * channel is used, then the specified power cap should be applied.
+ *
+ * In addition, hard restrictions on the Wifi modes may be indicated by |IfaceType| bits
+ * (STA, AP, P2P, NAN, etc) in the |restrictions| bitfield. If a hard restriction is provided,
+ * then the channels should be completely avoided for the provided Wifi modes instead of by
+ * best-effort.
+ *
+ * @param unsafeChannels List of |CoexUnsafeChannels| to avoid.
+ * @param restrictions Bitset of |IfaceType| values indicating Wifi modes to completely avoid.
+ * @return status WifiStatus of the operation.
+ * Possible status codes:
+ * |WifiStatusCode.SUCCESS|,
+ * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+ * |WifiStatusCode.ERROR_INVALID_ARGS|,
+ */
+ setCoexUnsafeChannels(
+ vec<CoexUnsafeChannel> unsafeChannels, bitfield<IfaceType> restrictions)
+ generates (WifiStatus status);
};
diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp
index 83d06fe..8e2e647 100644
--- a/wifi/1.5/default/hidl_struct_util.cpp
+++ b/wifi/1.5/default/hidl_struct_util.cpp
@@ -2800,6 +2800,47 @@
}
CHECK(false);
}
+
+bool convertHidlCoexUnsafeChannelToLegacy(
+ const IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel,
+ legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel) {
+ if (!legacy_unsafe_channel) {
+ return false;
+ }
+ *legacy_unsafe_channel = {};
+ switch (hidl_unsafe_channel.band) {
+ case WifiBand::BAND_24GHZ:
+ legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_2_4_BAND;
+ break;
+ case WifiBand::BAND_5GHZ:
+ legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_5_0_BAND;
+ break;
+ default:
+ return false;
+ };
+ legacy_unsafe_channel->channel = hidl_unsafe_channel.channel;
+ legacy_unsafe_channel->power_cap_dbm = hidl_unsafe_channel.powerCapDbm;
+ return true;
+}
+
+bool convertHidlVectorOfCoexUnsafeChannelToLegacy(
+ const std::vector<IWifiChip::CoexUnsafeChannel>& hidl_unsafe_channels,
+ std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels) {
+ if (!legacy_unsafe_channels) {
+ return false;
+ }
+ *legacy_unsafe_channels = {};
+ for (const auto& hidl_unsafe_channel : hidl_unsafe_channels) {
+ legacy_hal::wifi_coex_unsafe_channel legacy_unsafe_channel;
+ if (!hidl_struct_util::convertHidlCoexUnsafeChannelToLegacy(
+ hidl_unsafe_channel, &legacy_unsafe_channel)) {
+ return false;
+ }
+ legacy_unsafe_channels->push_back(legacy_unsafe_channel);
+ }
+ return true;
+}
+
} // namespace hidl_struct_util
} // namespace implementation
} // namespace V1_5
diff --git a/wifi/1.5/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h
index 49d8a12..feb47ef 100644
--- a/wifi/1.5/default/hidl_struct_util.h
+++ b/wifi/1.5/default/hidl_struct_util.h
@@ -71,6 +71,12 @@
IfaceType hidl_interface_type);
legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy(
IWifiChip::MultiStaUseCase use_case);
+bool convertHidlCoexUnsafeChannelToLegacy(
+ const IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel,
+ legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel);
+bool convertHidlVectorOfCoexUnsafeChannelToLegacy(
+ const std::vector<IWifiChip::CoexUnsafeChannel>& hidl_unsafe_channels,
+ std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels);
// STA iface conversion methods.
bool convertLegacyFeaturesToHidlStaCapabilities(
diff --git a/wifi/1.5/default/service.cpp b/wifi/1.5/default/service.cpp
index 8539a37..23e2b47 100644
--- a/wifi/1.5/default/service.cpp
+++ b/wifi/1.5/default/service.cpp
@@ -17,6 +17,7 @@
#include <android-base/logging.h>
#include <hidl/HidlLazyUtils.h>
#include <hidl/HidlTransportSupport.h>
+#include <signal.h>
#include <utils/Looper.h>
#include <utils/StrongPointer.h>
@@ -45,6 +46,7 @@
#endif
int main(int /*argc*/, char** argv) {
+ signal(SIGPIPE, SIG_IGN);
android::base::InitLogging(
argv, android::base::LogdLogger(android::base::SYSTEM));
LOG(INFO) << "Wifi Hal is booting up...";
diff --git a/wifi/1.5/default/wifi_ap_iface.cpp b/wifi/1.5/default/wifi_ap_iface.cpp
index 04e382a..d98aa45 100644
--- a/wifi/1.5/default/wifi_ap_iface.cpp
+++ b/wifi/1.5/default/wifi_ap_iface.cpp
@@ -29,10 +29,11 @@
using hidl_return_util::validateAndCall;
WifiApIface::WifiApIface(
- const std::string& ifname,
+ const std::string& ifname, const std::vector<std::string>& instances,
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
: ifname_(ifname),
+ instances_(instances),
legacy_hal_(legacy_hal),
iface_util_(iface_util),
is_valid_(true) {}
@@ -81,6 +82,14 @@
getFactoryMacAddress_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
&WifiApIface::getFactoryMacAddressInternal,
+ hidl_status_cb,
+ instances_.size() > 0 ? instances_[0] : ifname_);
+}
+
+Return<void> WifiApIface::resetToFactoryMacAddress(
+ resetToFactoryMacAddress_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiApIface::resetToFactoryMacAddressInternal,
hidl_status_cb);
}
@@ -94,8 +103,8 @@
WifiStatus WifiApIface::setCountryCodeInternal(
const std::array<int8_t, 2>& code) {
- legacy_hal::wifi_error legacy_status =
- legacy_hal_.lock()->setCountryCode(ifname_, code);
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setCountryCode(
+ instances_.size() > 0 ? instances_[0] : ifname_, code);
return createWifiStatusFromLegacyError(legacy_status);
}
@@ -107,13 +116,30 @@
std::vector<uint32_t> valid_frequencies;
std::tie(legacy_status, valid_frequencies) =
legacy_hal_.lock()->getValidFrequenciesForBand(
- ifname_, hidl_struct_util::convertHidlWifiBandToLegacy(band));
+ instances_.size() > 0 ? instances_[0] : ifname_,
+ hidl_struct_util::convertHidlWifiBandToLegacy(band));
return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies};
}
WifiStatus WifiApIface::setMacAddressInternal(
const std::array<uint8_t, 6>& mac) {
- bool status = iface_util_.lock()->setMacAddress(ifname_, mac);
+ bool status;
+ // Support random MAC up to 2 interfaces
+ if (instances_.size() == 2) {
+ int rbyte = 1;
+ for (auto const& intf : instances_) {
+ std::array<uint8_t, 6> rmac = mac;
+ // reverse the bits to avoid clision
+ rmac[rbyte] = 0xff - rmac[rbyte];
+ status = iface_util_.lock()->setMacAddress(intf, rmac);
+ if (!status) {
+ LOG(INFO) << "Failed to set random mac address on " << intf;
+ }
+ rbyte++;
+ }
+ } else {
+ status = iface_util_.lock()->setMacAddress(ifname_, mac);
+ }
if (!status) {
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
}
@@ -121,15 +147,37 @@
}
std::pair<WifiStatus, std::array<uint8_t, 6>>
-WifiApIface::getFactoryMacAddressInternal() {
+WifiApIface::getFactoryMacAddressInternal(const std::string& ifaceName) {
std::array<uint8_t, 6> mac =
- iface_util_.lock()->getFactoryMacAddress(ifname_);
+ iface_util_.lock()->getFactoryMacAddress(ifaceName);
if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 &&
mac[4] == 0 && mac[5] == 0) {
return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), mac};
}
return {createWifiStatus(WifiStatusCode::SUCCESS), mac};
}
+
+WifiStatus WifiApIface::resetToFactoryMacAddressInternal() {
+ std::pair<WifiStatus, std::array<uint8_t, 6>> getMacResult;
+ if (instances_.size() == 2) {
+ for (auto const& intf : instances_) {
+ getMacResult = getFactoryMacAddressInternal(intf);
+ LOG(DEBUG) << "Reset MAC to factory MAC on " << intf;
+ if (getMacResult.first.code != WifiStatusCode::SUCCESS ||
+ !iface_util_.lock()->setMacAddress(intf, getMacResult.second)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ }
+ } else {
+ getMacResult = getFactoryMacAddressInternal(ifname_);
+ LOG(DEBUG) << "Reset MAC to factory MAC on " << ifname_;
+ if (getMacResult.first.code != WifiStatusCode::SUCCESS ||
+ !iface_util_.lock()->setMacAddress(ifname_, getMacResult.second)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
} // namespace implementation
} // namespace V1_5
} // namespace wifi
diff --git a/wifi/1.5/default/wifi_ap_iface.h b/wifi/1.5/default/wifi_ap_iface.h
index 48b444a..02fb2d8 100644
--- a/wifi/1.5/default/wifi_ap_iface.h
+++ b/wifi/1.5/default/wifi_ap_iface.h
@@ -18,7 +18,7 @@
#define WIFI_AP_IFACE_H_
#include <android-base/macros.h>
-#include <android/hardware/wifi/1.4/IWifiApIface.h>
+#include <android/hardware/wifi/1.5/IWifiApIface.h>
#include "wifi_iface_util.h"
#include "wifi_legacy_hal.h"
@@ -33,9 +33,10 @@
/**
* HIDL interface object used to control a AP Iface instance.
*/
-class WifiApIface : public V1_4::IWifiApIface {
+class WifiApIface : public V1_5::IWifiApIface {
public:
WifiApIface(const std::string& ifname,
+ const std::vector<std::string>& instances,
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
// Refer to |WifiChip::invalidate()|.
@@ -55,6 +56,8 @@
setMacAddress_cb hidl_status_cb) override;
Return<void> getFactoryMacAddress(
getFactoryMacAddress_cb hidl_status_cb) override;
+ Return<void> resetToFactoryMacAddress(
+ resetToFactoryMacAddress_cb hidl_status_cb) override;
private:
// Corresponding worker functions for the HIDL methods.
@@ -64,10 +67,12 @@
std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
getValidFrequenciesForBandInternal(V1_0::WifiBand band);
WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
- std::pair<WifiStatus, std::array<uint8_t, 6>>
- getFactoryMacAddressInternal();
+ std::pair<WifiStatus, std::array<uint8_t, 6>> getFactoryMacAddressInternal(
+ const std::string& ifaceName);
+ WifiStatus resetToFactoryMacAddressInternal();
std::string ifname_;
+ std::vector<std::string> instances_;
std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
bool is_valid_;
diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp
index 1c238c8..1b0353b 100644
--- a/wifi/1.5/default/wifi_chip.cpp
+++ b/wifi/1.5/default/wifi_chip.cpp
@@ -19,6 +19,7 @@
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <cutils/properties.h>
+#include <net/if.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
@@ -44,6 +45,7 @@
constexpr char kActiveWlanIfaceNameProperty[] = "wifi.active.interface";
constexpr char kNoActiveWlanIfaceNamePropertyValue[] = "";
constexpr unsigned kMaxWlanIfaces = 5;
+constexpr char kApBridgeIfacePrefix[] = "ap_br_";
template <typename Iface>
void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) {
@@ -101,24 +103,36 @@
return "wlan" + std::to_string(idx);
}
-// Returns the dedicated iface name if one is defined.
-std::string getApIfaceName() {
+// Returns the dedicated iface name if defined.
+// Returns two ifaces in bridged mode.
+std::vector<std::string> getPredefinedApIfaceNames(bool is_bridged) {
+ std::vector<std::string> ifnames;
std::array<char, PROPERTY_VALUE_MAX> buffer;
+ buffer.fill(0);
if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) ==
0) {
- return {};
+ return ifnames;
}
- return buffer.data();
+ ifnames.push_back(buffer.data());
+ if (is_bridged) {
+ buffer.fill(0);
+ if (property_get("ro.vendor.wifi.sap.concurrent.interface",
+ buffer.data(), nullptr) == 0) {
+ return ifnames;
+ }
+ ifnames.push_back(buffer.data());
+ }
+ return ifnames;
}
-std::string getP2pIfaceName() {
+std::string getPredefinedP2pIfaceName() {
std::array<char, PROPERTY_VALUE_MAX> buffer;
property_get("wifi.direct.interface", buffer.data(), "p2p0");
return buffer.data();
}
// Returns the dedicated iface name if one is defined.
-std::string getNanIfaceName() {
+std::string getPredefinedNanIfaceName() {
std::array<char, PROPERTY_VALUE_MAX> buffer;
if (property_get("wifi.aware.interface", buffer.data(), nullptr) == 0) {
return {};
@@ -434,6 +448,13 @@
&WifiChip::createApIfaceInternal, hidl_status_cb);
}
+Return<void> WifiChip::createBridgedApIface(
+ createBridgedApIface_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::createBridgedApIfaceInternal,
+ hidl_status_cb);
+}
+
Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
&WifiChip::getApIfaceNamesInternal, hidl_status_cb);
@@ -453,6 +474,15 @@
ifname);
}
+Return<void> WifiChip::removeIfaceInstanceFromBridgedApIface(
+ const hidl_string& ifname, const hidl_string& ifInstanceName,
+ removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) {
+ return validateAndCall(
+ this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal,
+ hidl_status_cb, ifname, ifInstanceName);
+}
+
Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
&WifiChip::createNanIfaceInternal, hidl_status_cb);
@@ -692,7 +722,17 @@
hidl_status_cb, use_case);
}
+Return<void> WifiChip::setCoexUnsafeChannels(
+ const hidl_vec<CoexUnsafeChannel>& unsafeChannels,
+ hidl_bitfield<IfaceType> restrictions,
+ setCoexUnsafeChannels_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::setCoexUnsafeChannelsInternal,
+ hidl_status_cb, unsafeChannels, restrictions);
+}
+
void WifiChip::invalidateAndRemoveAllIfaces() {
+ invalidateAndClearBridgedApAll();
invalidateAndClearAll(ap_ifaces_);
invalidateAndClearAll(nan_ifaces_);
invalidateAndClearAll(p2p_ifaces_);
@@ -861,21 +901,28 @@
return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump};
}
-std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() {
- if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) {
- return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
- }
- std::string ifname = allocateApIfaceName();
- legacy_hal::wifi_error legacy_status =
- legacy_hal_.lock()->createVirtualInterface(
- ifname,
- hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP));
+WifiStatus WifiChip::createVirtualApInterface(const std::string& apVirtIf) {
+ legacy_hal::wifi_error legacy_status;
+ legacy_status = legacy_hal_.lock()->createVirtualInterface(
+ apVirtIf,
+ hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP));
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
- LOG(ERROR) << "Failed to add interface: " << ifname << " "
+ LOG(ERROR) << "Failed to add interface: " << apVirtIf << " "
<< legacyErrorToString(legacy_status);
- return {createWifiStatusFromLegacyError(legacy_status), {}};
+ return createWifiStatusFromLegacyError(legacy_status);
}
- sp<WifiApIface> iface = new WifiApIface(ifname, legacy_hal_, iface_util_);
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+sp<WifiApIface> WifiChip::newWifiApIface(std::string& ifname) {
+ std::vector<std::string> ap_instances;
+ for (auto const& it : br_ifaces_ap_instances_) {
+ if (it.first == ifname) {
+ ap_instances = it.second;
+ }
+ }
+ sp<WifiApIface> iface =
+ new WifiApIface(ifname, ap_instances, legacy_hal_, iface_util_);
ap_ifaces_.push_back(iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
@@ -883,6 +930,61 @@
}
}
setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+ return iface;
+}
+
+std::pair<WifiStatus, sp<V1_5::IWifiApIface>>
+WifiChip::createApIfaceInternal() {
+ if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
+ }
+ std::string ifname = allocateApIfaceName();
+ WifiStatus status = createVirtualApInterface(ifname);
+ if (status.code != WifiStatusCode::SUCCESS) {
+ return {status, {}};
+ }
+ sp<WifiApIface> iface = newWifiApIface(ifname);
+ return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
+}
+
+std::pair<WifiStatus, sp<V1_5::IWifiApIface>>
+WifiChip::createBridgedApIfaceInternal() {
+ if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
+ }
+ std::vector<std::string> ap_instances = allocateBridgedApInstanceNames();
+ if (ap_instances.size() < 2) {
+ LOG(ERROR) << "Fail to allocate two instances";
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
+ }
+ std::string br_ifname = kApBridgeIfacePrefix + ap_instances[0];
+ for (int i = 0; i < 2; i++) {
+ WifiStatus status = createVirtualApInterface(ap_instances[i]);
+ if (status.code != WifiStatusCode::SUCCESS) {
+ if (i != 0) { // The failure happened when creating second virtual
+ // iface.
+ legacy_hal_.lock()->deleteVirtualInterface(
+ ap_instances.front()); // Remove the first virtual iface.
+ }
+ return {status, {}};
+ }
+ }
+ br_ifaces_ap_instances_[br_ifname] = ap_instances;
+ if (!iface_util_.lock()->createBridge(br_ifname)) {
+ LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str();
+ invalidateAndClearBridgedAp(br_ifname);
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
+ }
+ for (auto const& instance : ap_instances) {
+ // Bind ap instance interface to AP bridge
+ if (!iface_util_.lock()->addIfaceToBridge(br_ifname, instance)) {
+ LOG(ERROR) << "Failed add if to Bridge - if_name="
+ << instance.c_str();
+ invalidateAndClearBridgedAp(br_ifname);
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
+ }
+ }
+ sp<WifiApIface> iface = newWifiApIface(br_ifname);
return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
}
@@ -894,7 +996,7 @@
return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(ap_ifaces_)};
}
-std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::getApIfaceInternal(
+std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::getApIfaceInternal(
const std::string& ifname) {
const auto iface = findUsingName(ap_ifaces_, ifname);
if (!iface.get()) {
@@ -913,12 +1015,8 @@
// nan/rtt objects over AP iface. But, there is no harm to do it
// here and not make that assumption all over the place.
invalidateAndRemoveDependencies(ifname);
- legacy_hal::wifi_error legacy_status =
- legacy_hal_.lock()->deleteVirtualInterface(ifname);
- if (legacy_status != legacy_hal::WIFI_SUCCESS) {
- LOG(ERROR) << "Failed to remove interface: " << ifname << " "
- << legacyErrorToString(legacy_status);
- }
+ // Clear the bridge interface and the iface instance.
+ invalidateAndClearBridgedAp(ifname);
invalidateAndClear(ap_ifaces_, iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
@@ -929,13 +1027,49 @@
return createWifiStatus(WifiStatusCode::SUCCESS);
}
+WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal(
+ const std::string& ifname, const std::string& ifInstanceName) {
+ legacy_hal::wifi_error legacy_status;
+ const auto iface = findUsingName(ap_ifaces_, ifname);
+ if (!iface.get() || !ifInstanceName.empty()) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ // Requires to remove one of the instance in bridge mode
+ for (auto const& it : br_ifaces_ap_instances_) {
+ if (it.first == ifname) {
+ for (auto const& iface : it.second) {
+ if (iface == ifInstanceName) {
+ if (!iface_util_.lock()->removeIfaceFromBridge(it.first,
+ iface)) {
+ LOG(ERROR) << "Failed to remove interface: " << iface
+ << " from " << ifname << ", error: "
+ << legacyErrorToString(legacy_status);
+ return createWifiStatus(
+ WifiStatusCode::ERROR_NOT_AVAILABLE);
+ }
+ legacy_status =
+ legacy_hal_.lock()->deleteVirtualInterface(iface);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to del interface: " << iface
+ << " " << legacyErrorToString(legacy_status);
+ return createWifiStatusFromLegacyError(legacy_status);
+ }
+ }
+ }
+ break;
+ }
+ }
+ br_ifaces_ap_instances_.erase(ifInstanceName);
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
std::pair<WifiStatus, sp<V1_4::IWifiNanIface>>
WifiChip::createNanIfaceInternal() {
if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::NAN)) {
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
}
bool is_dedicated_iface = true;
- std::string ifname = getNanIfaceName();
+ std::string ifname = getPredefinedNanIfaceName();
if (ifname.empty() || !iface_util_.lock()->ifNameToIndex(ifname)) {
// Use the first shared STA iface (wlan0) if a dedicated aware iface is
// not defined.
@@ -988,7 +1122,7 @@
if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::P2P)) {
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
}
- std::string ifname = getP2pIfaceName();
+ std::string ifname = getPredefinedP2pIfaceName();
sp<WifiP2pIface> iface = new WifiP2pIface(ifname, legacy_hal_);
p2p_ifaces_.push_back(iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
@@ -1322,6 +1456,18 @@
return createWifiStatusFromLegacyError(legacy_status);
}
+WifiStatus WifiChip::setCoexUnsafeChannelsInternal(
+ std::vector<CoexUnsafeChannel> unsafe_channels, uint32_t restrictions) {
+ std::vector<legacy_hal::wifi_coex_unsafe_channel> legacy_unsafe_channels;
+ if (!hidl_struct_util::convertHidlVectorOfCoexUnsafeChannelToLegacy(
+ unsafe_channels, &legacy_unsafe_channels)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ auto legacy_status = legacy_hal_.lock()->setCoexUnsafeChannels(
+ legacy_unsafe_channels, restrictions);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
WifiStatus WifiChip::handleChipConfiguration(
/* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
ChipModeId mode_id) {
@@ -1607,7 +1753,7 @@
// ChipIfaceCombination.
// b) Check if the requested iface type can be added to the current mode.
bool WifiChip::canCurrentModeSupportIfaceOfType(IfaceType requested_type) {
- // Check if we can support atleast 1 iface of type.
+ // Check if we can support at least 1 iface of type.
std::map<IfaceType, size_t> req_iface_combo;
req_iface_combo[requested_type] = 1;
return canCurrentModeSupportIfaceCombo(req_iface_combo);
@@ -1623,17 +1769,17 @@
}
bool WifiChip::isStaApConcurrencyAllowedInCurrentMode() {
- // Check if we can support atleast 1 STA & 1 AP concurrently.
+ // Check if we can support at least 1 STA & 1 AP concurrently.
std::map<IfaceType, size_t> req_iface_combo;
req_iface_combo[IfaceType::AP] = 1;
req_iface_combo[IfaceType::STA] = 1;
return canCurrentModeSupportIfaceCombo(req_iface_combo);
}
-bool WifiChip::isDualApAllowedInCurrentMode() {
- // Check if we can support atleast 1 STA & 1 AP concurrently.
+bool WifiChip::isDualStaConcurrencyAllowedInCurrentMode() {
+ // Check if we can support at least 2 STA concurrently.
std::map<IfaceType, size_t> req_iface_combo;
- req_iface_combo[IfaceType::AP] = 2;
+ req_iface_combo[IfaceType::STA] = 2;
return canCurrentModeSupportIfaceCombo(req_iface_combo);
}
@@ -1653,6 +1799,7 @@
uint32_t start_idx) {
for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) {
const auto ifname = getWlanIfaceNameWithType(type, idx);
+ if (findUsingNameFromBridgedApInstances(ifname)) continue;
if (findUsingName(ap_ifaces_, ifname)) continue;
if (findUsingName(sta_ifaces_, ifname)) continue;
return ifname;
@@ -1662,19 +1809,46 @@
return {};
}
+uint32_t WifiChip::startIdxOfApIface() {
+ if (isDualStaConcurrencyAllowedInCurrentMode()) {
+ // When the HAL support dual STAs, AP should start with idx 2.
+ return 2;
+ } else if (isStaApConcurrencyAllowedInCurrentMode()) {
+ // When the HAL support STA + AP but it doesn't support dual STAs.
+ // AP should start with idx 1.
+ return 1;
+ }
+ // No concurrency support.
+ return 0;
+}
+
// AP iface names start with idx 1 for modes supporting
// concurrent STA and not dual AP, else start with idx 0.
std::string WifiChip::allocateApIfaceName() {
// Check if we have a dedicated iface for AP.
- std::string ifname = getApIfaceName();
- if (!ifname.empty()) {
- return ifname;
+ std::vector<std::string> ifnames = getPredefinedApIfaceNames(false);
+ if (!ifnames.empty()) {
+ return ifnames[0];
}
- return allocateApOrStaIfaceName(IfaceType::AP,
- (isStaApConcurrencyAllowedInCurrentMode() &&
- !isDualApAllowedInCurrentMode())
- ? 1
- : 0);
+ return allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface());
+}
+
+std::vector<std::string> WifiChip::allocateBridgedApInstanceNames() {
+ // Check if we have a dedicated iface for AP.
+ std::vector<std::string> instances = getPredefinedApIfaceNames(true);
+ if (instances.size() == 2) {
+ return instances;
+ } else {
+ int num_ifaces_need_to_allocate = 2 - instances.size();
+ for (int i = 0; i < num_ifaces_need_to_allocate; i++) {
+ std::string instance_name =
+ allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface());
+ if (!instance_name.empty()) {
+ instances.push_back(instance_name);
+ }
+ }
+ }
+ return instances;
}
// STA iface names start with idx 0.
@@ -1727,6 +1901,48 @@
return getWlanIfaceName(idx);
}
+void WifiChip::invalidateAndClearBridgedApAll() {
+ for (auto const& it : br_ifaces_ap_instances_) {
+ for (auto const& iface : it.second) {
+ iface_util_.lock()->removeIfaceFromBridge(it.first, iface);
+ legacy_hal_.lock()->deleteVirtualInterface(iface);
+ }
+ iface_util_.lock()->deleteBridge(it.first);
+ }
+ br_ifaces_ap_instances_.clear();
+}
+
+void WifiChip::invalidateAndClearBridgedAp(const std::string& br_name) {
+ if (br_name.empty()) return;
+ // delete managed interfaces
+ for (auto const& it : br_ifaces_ap_instances_) {
+ if (it.first == br_name) {
+ for (auto const& iface : it.second) {
+ iface_util_.lock()->removeIfaceFromBridge(br_name, iface);
+ legacy_hal_.lock()->deleteVirtualInterface(iface);
+ }
+ iface_util_.lock()->deleteBridge(br_name);
+ br_ifaces_ap_instances_.erase(br_name);
+ break;
+ }
+ }
+ return;
+}
+
+bool WifiChip::findUsingNameFromBridgedApInstances(const std::string& name) {
+ for (auto const& it : br_ifaces_ap_instances_) {
+ if (it.first == name) {
+ return true;
+ }
+ for (auto const& iface : it.second) {
+ if (iface == name) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
} // namespace implementation
} // namespace V1_5
} // namespace wifi
diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h
index 693d480..95c122d 100644
--- a/wifi/1.5/default/wifi_chip.h
+++ b/wifi/1.5/default/wifi_chip.h
@@ -94,11 +94,16 @@
Return<void> requestFirmwareDebugDump(
requestFirmwareDebugDump_cb hidl_status_cb) override;
Return<void> createApIface(createApIface_cb hidl_status_cb) override;
+ Return<void> createBridgedApIface(
+ createBridgedApIface_cb hidl_status_cb) override;
Return<void> getApIfaceNames(getApIfaceNames_cb hidl_status_cb) override;
Return<void> getApIface(const hidl_string& ifname,
getApIface_cb hidl_status_cb) override;
Return<void> removeApIface(const hidl_string& ifname,
removeApIface_cb hidl_status_cb) override;
+ Return<void> removeIfaceInstanceFromBridgedApIface(
+ const hidl_string& brIfaceName, const hidl_string& ifaceInstanceName,
+ removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) override;
Return<void> createNanIface(createNanIface_cb hidl_status_cb) override;
Return<void> getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) override;
Return<void> getNanIface(const hidl_string& ifname,
@@ -169,6 +174,10 @@
Return<void> setMultiStaUseCase(
MultiStaUseCase use_case,
setMultiStaUseCase_cb hidl_status_cb) override;
+ Return<void> setCoexUnsafeChannels(
+ const hidl_vec<CoexUnsafeChannel>& unsafe_channels,
+ hidl_bitfield<IfaceType> restrictions,
+ setCoexUnsafeChannels_cb hidl_status_cb) override;
private:
void invalidateAndRemoveAllIfaces();
@@ -192,11 +201,17 @@
requestDriverDebugDumpInternal();
std::pair<WifiStatus, std::vector<uint8_t>>
requestFirmwareDebugDumpInternal();
- std::pair<WifiStatus, sp<IWifiApIface>> createApIfaceInternal();
+ sp<WifiApIface> newWifiApIface(std::string& ifname);
+ WifiStatus createVirtualApInterface(const std::string& apVirtIf);
+ std::pair<WifiStatus, sp<V1_5::IWifiApIface>> createApIfaceInternal();
+ std::pair<WifiStatus, sp<V1_5::IWifiApIface>>
+ createBridgedApIfaceInternal();
std::pair<WifiStatus, std::vector<hidl_string>> getApIfaceNamesInternal();
- std::pair<WifiStatus, sp<IWifiApIface>> getApIfaceInternal(
+ std::pair<WifiStatus, sp<V1_5::IWifiApIface>> getApIfaceInternal(
const std::string& ifname);
WifiStatus removeApIfaceInternal(const std::string& ifname);
+ WifiStatus removeIfaceInstanceFromBridgedApIfaceInternal(
+ const std::string& brIfaceName, const std::string& ifInstanceName);
std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> createNanIfaceInternal();
std::pair<WifiStatus, std::vector<hidl_string>> getNanIfaceNamesInternal();
std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> getNanIfaceInternal(
@@ -241,6 +256,8 @@
const sp<V1_4::IWifiChipEventCallback>& event_callback);
WifiStatus setMultiStaPrimaryConnectionInternal(const std::string& ifname);
WifiStatus setMultiStaUseCaseInternal(MultiStaUseCase use_case);
+ WifiStatus setCoexUnsafeChannelsInternal(
+ std::vector<CoexUnsafeChannel> unsafe_channels, uint32_t restrictions);
WifiStatus handleChipConfiguration(
std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id);
@@ -265,13 +282,18 @@
bool canCurrentModeSupportIfaceOfType(IfaceType requested_type);
bool isValidModeId(ChipModeId mode_id);
bool isStaApConcurrencyAllowedInCurrentMode();
- bool isDualApAllowedInCurrentMode();
+ bool isDualStaConcurrencyAllowedInCurrentMode();
+ uint32_t startIdxOfApIface();
std::string getFirstActiveWlanIfaceName();
std::string allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx);
std::string allocateApIfaceName();
+ std::vector<std::string> allocateBridgedApInstanceNames();
std::string allocateStaIfaceName();
bool writeRingbufferFilesInternal();
std::string getWlanIfaceNameWithType(IfaceType type, unsigned idx);
+ void invalidateAndClearBridgedApAll();
+ void invalidateAndClearBridgedAp(const std::string& br_name);
+ bool findUsingNameFromBridgedApInstances(const std::string& name);
ChipId chip_id_;
std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
@@ -296,7 +318,7 @@
event_cb_handler_;
const std::function<void(const std::string&)> subsystemCallbackHandler_;
-
+ std::map<std::string, std::vector<std::string>> br_ifaces_ap_instances_;
DISALLOW_COPY_AND_ASSIGN(WifiChip);
};
diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp
index 76e718b..773dd9b 100644
--- a/wifi/1.5/default/wifi_legacy_hal.cpp
+++ b/wifi/1.5/default/wifi_legacy_hal.cpp
@@ -1521,6 +1521,14 @@
use_case);
}
+wifi_error WifiLegacyHal::setCoexUnsafeChannels(
+ std::vector<wifi_coex_unsafe_channel> unsafe_channels,
+ uint32_t restrictions) {
+ return global_func_table_.wifi_set_coex_unsafe_channels(
+ global_handle_, unsafe_channels.size(), unsafe_channels.data(),
+ restrictions);
+}
+
void WifiLegacyHal::invalidate() {
global_handle_ = nullptr;
iface_name_to_handle_.clear();
diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h
index 555c540..6266cf6 100644
--- a/wifi/1.5/default/wifi_legacy_hal.h
+++ b/wifi/1.5/default/wifi_legacy_hal.h
@@ -386,6 +386,11 @@
virtual wifi_error multiStaSetPrimaryConnection(const std::string& ifname);
virtual wifi_error multiStaSetUseCase(wifi_multi_sta_use_case use_case);
+ // Coex functions.
+ virtual wifi_error setCoexUnsafeChannels(
+ std::vector<wifi_coex_unsafe_channel> unsafe_channels,
+ uint32_t restrictions);
+
private:
// Retrieve interface handles for all the available interfaces.
wifi_error retrieveIfaceHandles();
diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp
index 71d2ddf..b6c908b 100644
--- a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp
+++ b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp
@@ -149,6 +149,7 @@
populateStubFor(&hal_fn->wifi_get_chip_feature_set);
populateStubFor(&hal_fn->wifi_multi_sta_set_primary_connection);
populateStubFor(&hal_fn->wifi_multi_sta_set_use_case);
+ populateStubFor(&hal_fn->wifi_set_coex_unsafe_channels);
return true;
}
diff --git a/wifi/1.5/default/wifi_sta_iface.cpp b/wifi/1.5/default/wifi_sta_iface.cpp
index f3dcfc5..82bfcf1 100644
--- a/wifi/1.5/default/wifi_sta_iface.cpp
+++ b/wifi/1.5/default/wifi_sta_iface.cpp
@@ -648,6 +648,10 @@
WifiStaIface::getFactoryMacAddressInternal() {
std::array<uint8_t, 6> mac =
iface_util_.lock()->getFactoryMacAddress(ifname_);
+ if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 &&
+ mac[4] == 0 && mac[5] == 0) {
+ return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), mac};
+ }
return {createWifiStatus(WifiStatusCode::SUCCESS), mac};
}
diff --git a/wifi/1.5/vts/functional/Android.bp b/wifi/1.5/vts/functional/Android.bp
index eb595c9..2d8b412 100644
--- a/wifi/1.5/vts/functional/Android.bp
+++ b/wifi/1.5/vts/functional/Android.bp
@@ -60,3 +60,26 @@
"vts",
],
}
+
+// SoftAP-specific tests, similar to VtsHalWifiApV1_0TargetTest.
+cc_test {
+ name: "VtsHalWifiApV1_5TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "wifi_chip_hidl_ap_test.cpp",
+ ],
+ static_libs: [
+ "VtsHalWifiV1_0TargetTestUtil",
+ "android.hardware.wifi@1.0",
+ "android.hardware.wifi@1.1",
+ "android.hardware.wifi@1.2",
+ "android.hardware.wifi@1.3",
+ "android.hardware.wifi@1.4",
+ "android.hardware.wifi@1.5",
+ "libwifi-system-iface",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp b/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp
new file mode 100644
index 0000000..395d317
--- /dev/null
+++ b/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2020 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 <VtsHalHidlTargetCallbackBase.h>
+#include <android-base/logging.h>
+
+#undef NAN // NAN is defined in bionic/libc/include/math.h:38
+
+#include <android/hardware/wifi/1.4/IWifiChipEventCallback.h>
+#include <android/hardware/wifi/1.5/IWifi.h>
+#include <android/hardware/wifi/1.5/IWifiApIface.h>
+#include <android/hardware/wifi/1.5/IWifiChip.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include "wifi_hidl_call_util.h"
+#include "wifi_hidl_test_utils.h"
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::wifi::V1_0::ChipModeId;
+using ::android::hardware::wifi::V1_0::IfaceType;
+using ::android::hardware::wifi::V1_0::IWifiIface;
+using ::android::hardware::wifi::V1_0::WifiDebugRingBufferStatus;
+using ::android::hardware::wifi::V1_0::WifiStatus;
+using ::android::hardware::wifi::V1_0::WifiStatusCode;
+using ::android::hardware::wifi::V1_4::IWifiChipEventCallback;
+using ::android::hardware::wifi::V1_5::IWifiApIface;
+using ::android::hardware::wifi::V1_5::IWifiChip;
+
+/**
+ * Fixture for IWifiChip tests that are conditioned on SoftAP support.
+ */
+class WifiChipHidlTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ // Make sure to start with a clean state
+ stopWifi(GetInstanceName());
+
+ wifi_chip_ = IWifiChip::castFrom(getWifiChip(GetInstanceName()));
+ ASSERT_NE(nullptr, wifi_chip_.get());
+ }
+
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
+
+ protected:
+ // Helper function to configure the Chip in one of the supported modes.
+ // Most of the non-mode-configuration-related methods require chip
+ // to be first configured.
+ ChipModeId configureChipForIfaceType(IfaceType type, bool expectSuccess) {
+ ChipModeId mode_id;
+ EXPECT_EQ(expectSuccess,
+ configureChipToSupportIfaceType(wifi_chip_, type, &mode_id));
+ return mode_id;
+ }
+
+ WifiStatusCode createApIface(sp<IWifiApIface>* ap_iface) {
+ configureChipForIfaceType(IfaceType::AP, true);
+ const auto& status_and_iface = HIDL_INVOKE(wifi_chip_, createApIface);
+ *ap_iface = IWifiApIface::castFrom(status_and_iface.second);
+ return status_and_iface.first.code;
+ }
+
+ WifiStatusCode createBridgedApIface(sp<IWifiApIface>* ap_iface) {
+ configureChipForIfaceType(IfaceType::AP, true);
+ const auto& status_and_iface =
+ HIDL_INVOKE(wifi_chip_, createBridgedApIface);
+ *ap_iface = status_and_iface.second;
+ return status_and_iface.first.code;
+ }
+
+ sp<IWifiChip> wifi_chip_;
+
+ private:
+ std::string GetInstanceName() { return GetParam(); }
+};
+
+// TODO: b/173999527. Add test for bridged API.
+
+/*
+ * resetToFactoryMacAddress
+ */
+TEST_P(WifiChipHidlTest, resetToFactoryMacAddressTest) {
+ sp<IWifiApIface> wifi_ap_iface;
+ const auto& status_code = createApIface(&wifi_ap_iface);
+ if (status_code != WifiStatusCode::SUCCESS) {
+ EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status_code);
+ }
+ const auto& status = HIDL_INVOKE(wifi_ap_iface, resetToFactoryMacAddress);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status.code);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiChipHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::wifi::V1_5::IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/wifi/supplicant/1.4/ISupplicantStaIface.hal b/wifi/supplicant/1.4/ISupplicantStaIface.hal
index f9e4c9b..7441ba5 100644
--- a/wifi/supplicant/1.4/ISupplicantStaIface.hal
+++ b/wifi/supplicant/1.4/ISupplicantStaIface.hal
@@ -71,8 +71,7 @@
* |SupplicantStatusCode.FAILURE_UNKNOWN|,
* |SupplicantStatusCode.FAILURE_IFACE_INVALID|
*/
- initiateVenueUrlAnqpQuery(MacAddress macAddress)
- generates (SupplicantStatus status);
+ initiateVenueUrlAnqpQuery(MacAddress macAddress) generates (SupplicantStatus status);
/**
* Get wpa driver capabilities.
@@ -84,4 +83,55 @@
*/
getWpaDriverCapabilities_1_4() generates (SupplicantStatus status,
bitfield<WpaDriverCapabilitiesMask> driverCapabilitiesMask);
+
+ /**
+ * Generates DPP bootstrap information: Bootstrap ID, DPP URI and listen
+ * channel for responder mode.
+ *
+ * @param MacAddress MAC address of the interface for the DPP operation.
+ * @param deviceInfo Device specific information.
+ * As per DPP Specification V1.0 section 5.2,
+ * allowed Range of ASCII characters in deviceInfo - %x20-7E
+ * semicolon is not allowed.
+ * @param DppCurve Elliptic curve cryptography type used to generate DPP
+ * public/private key pair.
+ * @return status of operation and bootstrap info.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ * |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+ */
+ generateDppBootstrapInfoForResponder(MacAddress macAddress, string deviceInfo, DppCurve curve)
+ generates (SupplicantStatus status, DppResponderBootstrapInfo bootstrapInfo);
+
+ /**
+ * Start DPP in Enrollee-Responder mode.
+ * Framework must first call |generateDppBootstrapInfoForResponder| to generate
+ * the bootstrapping information: Bootstrap ID, DPP URI and the listen channel.
+ * Then call this API with derived listen channel to start listening for
+ * authentication request from Peer initiator.
+ *
+ * @param listenChannel DPP listen channel.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+ * |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+ */
+ startDppEnrolleeResponder(uint32_t listenChannel) generates (SupplicantStatus status);
+
+ /**
+ * Stop DPP Responder operation - Remove the bootstrap code and stop listening.
+ *
+ * @param ownBootstrapId Local device's URI ID obtained through
+ * |generateDppBootstrapInfoForResponder| call.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+ * |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+ */
+ stopDppResponder(uint32_t ownBootstrapId) generates (SupplicantStatus status);
};
diff --git a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal
index 852696d..efcebda 100644
--- a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal
+++ b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal
@@ -40,8 +40,12 @@
/**
* Baseline information as defined in HAL 1.0.
*/
- @1.0::ISupplicantStaIfaceCallback.AnqpData V1_0; /* Container for v1.0 of this struct */
- vec<uint8_t> venueUrl; /* Venue URL ANQP-element */
+ @1.0::ISupplicantStaIfaceCallback.AnqpData V1_0;
+
+ /*
+ * Container for v1.0 of this struct
+ */
+ vec<uint8_t> venueUrl;
};
/**
diff --git a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
index 80beedf..6bed5ab 100644
--- a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
+++ b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
@@ -17,7 +17,7 @@
package android.hardware.wifi.supplicant@1.4;
import @1.3::ISupplicantStaNetwork;
-import @1.4::ISupplicantStaNetworkCallback;
+import ISupplicantStaNetworkCallback;
/**
* Interface exposed by the supplicant for each station mode network
diff --git a/wifi/supplicant/1.4/types.hal b/wifi/supplicant/1.4/types.hal
index 18af8fe..aec61c4 100644
--- a/wifi/supplicant/1.4/types.hal
+++ b/wifi/supplicant/1.4/types.hal
@@ -18,6 +18,7 @@
import @1.0::SupplicantStatusCode;
import @1.3::ConnectionCapabilities;
+import @1.3::DppFailureCode;
import @1.3::WpaDriverCapabilitiesMask;
/**
@@ -40,6 +41,29 @@
};
/**
+ * DppFailureCode: Error codes for DPP (Easy Connect)
+ */
+enum DppFailureCode : @1.3::DppFailureCode {
+ /**
+ * Failure to generate a DPP URI.
+ */
+ URI_GENERATION,
+};
+
+/**
+ * DppCurve: Elliptic curve cryptography type used to generate DPP
+ * public/private key pair.
+ */
+enum DppCurve : uint32_t {
+ PRIME256V1,
+ SECP384R1,
+ SECP521R1,
+ BRAINPOOLP256R1,
+ BRAINPOOLP384R1,
+ BRAINPOOLP512R1,
+};
+
+/**
* Connection Capabilities supported by current network and device
*/
struct ConnectionCapabilities {
@@ -47,6 +71,7 @@
* Baseline information as defined in HAL 1.3.
*/
@1.3::ConnectionCapabilities V1_3;
+
/**
* detailed network mode for legacy network
*/
@@ -64,13 +89,14 @@
* Generic structure to return the status of any supplicant operation.
*/
struct SupplicantStatus {
- SupplicantStatusCode code;
- /**
- * A vendor specific error message to provide more information beyond the
- * status code.
- * This will be used for debbuging purposes only.
- */
- string debugMessage;
+ SupplicantStatusCode code;
+
+ /**
+ * A vendor specific error message to provide more information beyond the
+ * status code.
+ * This will be used for debbuging purposes only.
+ */
+ string debugMessage;
};
/**
@@ -78,7 +104,27 @@
*/
enum WpaDriverCapabilitiesMask : @1.3::WpaDriverCapabilitiesMask {
/**
- *
*/
SAE_PK = 1 << 2,
};
+
+/**
+ * DPP bootstrap info generated for responder mode operation
+ */
+struct DppResponderBootstrapInfo {
+ /**
+ * Generated bootstrap identifier
+ */
+ uint32_t bootstrapId;
+
+ /**
+ * The Wi-Fi channel that the DPP responder is listening on.
+ */
+ uint32_t listenChannel;
+
+ /**
+ * Bootstrapping URI per DPP specification, "section 5.2 Bootstrapping
+ * information", may contain listen channel, MAC address, public key, or other information.
+ */
+ string uri;
+};
diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp
index c0b5a70..ccd469d 100644
--- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -19,6 +19,7 @@
#include <android/hardware/wifi/supplicant/1.1/ISupplicant.h>
#include <android/hardware/wifi/supplicant/1.2/types.h>
#include <android/hardware/wifi/supplicant/1.3/ISupplicant.h>
+#include <android/hardware/wifi/supplicant/1.3/ISupplicantStaNetwork.h>
#include <android/hardware/wifi/supplicant/1.3/types.h>
#include <android/hardware/wifi/supplicant/1.4/ISupplicant.h>
#include <android/hardware/wifi/supplicant/1.4/ISupplicantStaIface.h>
@@ -45,7 +46,10 @@
using ::android::hardware::wifi::supplicant::V1_2::DppNetRole;
using ::android::hardware::wifi::supplicant::V1_2::DppProgressCode;
using ::android::hardware::wifi::supplicant::V1_3::DppSuccessCode;
+using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaNetwork;
using ::android::hardware::wifi::supplicant::V1_4::ConnectionCapabilities;
+using ::android::hardware::wifi::supplicant::V1_4::DppCurve;
+using ::android::hardware::wifi::supplicant::V1_4::DppResponderBootstrapInfo;
using ::android::hardware::wifi::supplicant::V1_4::ISupplicant;
using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface;
using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIfaceCallback;
@@ -74,6 +78,24 @@
sp<ISupplicantStaIface> sta_iface_;
// MAC address to use for various tests.
std::array<uint8_t, 6> mac_addr_;
+
+ bool isDppSupported() {
+ uint32_t keyMgmtMask = 0;
+
+ // We need to first get the key management capabilities from the device.
+ // If DPP is not supported, we just pass the test.
+ sta_iface_->getKeyMgmtCapabilities_1_3(
+ [&](const SupplicantStatus& status, uint32_t keyMgmtMaskInternal) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ keyMgmtMask = keyMgmtMaskInternal;
+ });
+
+ if (!(keyMgmtMask & ISupplicantStaNetwork::KeyMgmtMask::DPP)) {
+ // DPP not supported
+ return false;
+ }
+ return true;
+ }
};
class IfaceCallback : public ISupplicantStaIfaceCallback {
@@ -255,6 +277,48 @@
});
}
+/*
+ * StartDppEnrolleeResponder
+ */
+TEST_P(SupplicantStaIfaceHidlTest, StartDppEnrolleeResponder) {
+ // We need to first get the key management capabilities from the device.
+ // If DPP is not supported, we just pass the test.
+ if (!isDppSupported()) {
+ // DPP not supported
+ return;
+ }
+
+ hidl_string deviceInfo = "DPP_Responder_Mode_VTS_Test";
+ uint32_t bootstrap_id = 0;
+ uint32_t listen_channel = 0;
+ uint8_t mac_address[6] = {0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
+
+ // Generate DPP bootstrap information
+ sta_iface_->generateDppBootstrapInfoForResponder(
+ mac_address, deviceInfo, DppCurve::PRIME256V1,
+ [&](const SupplicantStatusV1_4& status,
+ DppResponderBootstrapInfo bootstrapInfo) {
+ EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code);
+ EXPECT_NE(-1, bootstrapInfo.bootstrapId);
+ EXPECT_NE(0, bootstrapInfo.bootstrapId);
+ bootstrap_id = bootstrapInfo.bootstrapId;
+ listen_channel = bootstrapInfo.listenChannel;
+ EXPECT_NE(0, bootstrapInfo.listenChannel);
+ });
+
+ // Start DPP as Enrollee-Responder.
+ sta_iface_->startDppEnrolleeResponder(
+ listen_channel, [&](const SupplicantStatusV1_4& status) {
+ EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code);
+ });
+
+ // Stop DPP Enrollee-Responder mode, ie remove the URI and stop listen.
+ sta_iface_->stopDppResponder(
+ bootstrap_id, [&](const SupplicantStatusV1_4& status) {
+ EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code);
+ });
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceHidlTest);
INSTANTIATE_TEST_CASE_P(
PerInstance, SupplicantStaIfaceHidlTest,