Merge "Add missing copyright to QuantizedLSTM"
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 213c93a..7c67965 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -3,3 +3,8 @@
 
 [Builtin Hooks]
 clang_format = true
+cpplint = true
+bpfmt = true
+
+[Builtin Hooks Options]
+cpplint = --filter=-,+build/include_what_you_use ${PREUPLOAD_FILES}
diff --git a/nn/common/CpuExecutor.cpp b/nn/common/CpuExecutor.cpp
index 02ccf9a..c7e7a83 100644
--- a/nn/common/CpuExecutor.cpp
+++ b/nn/common/CpuExecutor.cpp
@@ -37,6 +37,8 @@
 
 namespace {
 
+using namespace hal;
+
 class OperationExecutionContext : public IOperationExecutionContext {
     DISALLOW_IMPLICIT_CONSTRUCTORS(OperationExecutionContext);
 
diff --git a/nn/common/ExecutionBurstController.cpp b/nn/common/ExecutionBurstController.cpp
index 55ef9ad..7e9de83 100644
--- a/nn/common/ExecutionBurstController.cpp
+++ b/nn/common/ExecutionBurstController.cpp
@@ -27,14 +27,16 @@
 namespace android::nn {
 namespace {
 
-using ::android::hardware::MQDescriptorSync;
+using namespace hal;
+
+using hardware::MQDescriptorSync;
 using FmqRequestDescriptor = MQDescriptorSync<FmqRequestDatum>;
 using FmqResultDescriptor = MQDescriptorSync<FmqResultDatum>;
 
 constexpr Timing kNoTiming = {std::numeric_limits<uint64_t>::max(),
                               std::numeric_limits<uint64_t>::max()};
 
-class BurstContextDeathHandler : public hardware::hidl_death_recipient {
+class BurstContextDeathHandler : public hidl_death_recipient {
    public:
     using Callback = std::function<void()>;
 
@@ -516,7 +518,7 @@
         const std::shared_ptr<RequestChannelSender>& requestChannelSender,
         const std::shared_ptr<ResultChannelReceiver>& resultChannelReceiver,
         const sp<IBurstContext>& burstContext, const sp<ExecutionBurstCallback>& callback,
-        const sp<hardware::hidl_death_recipient>& deathHandler)
+        const sp<hidl_death_recipient>& deathHandler)
     : mRequestChannelSender(requestChannelSender),
       mResultChannelReceiver(resultChannelReceiver),
       mBurstContext(burstContext),
diff --git a/nn/common/ExecutionBurstServer.cpp b/nn/common/ExecutionBurstServer.cpp
index 28f73e2..74bc340 100644
--- a/nn/common/ExecutionBurstServer.cpp
+++ b/nn/common/ExecutionBurstServer.cpp
@@ -29,6 +29,8 @@
 namespace android::nn {
 namespace {
 
+using namespace hal;
+
 constexpr Timing kNoTiming = {std::numeric_limits<uint64_t>::max(),
                               std::numeric_limits<uint64_t>::max()};
 
diff --git a/nn/common/GraphDump.cpp b/nn/common/GraphDump.cpp
index c5798b3..9fe6bf3 100644
--- a/nn/common/GraphDump.cpp
+++ b/nn/common/GraphDump.cpp
@@ -28,6 +28,8 @@
 namespace android {
 namespace nn {
 
+using namespace hal;
+
 // class Dumper is a wrapper around an std::ostream (if instantiated
 // with a pointer to a stream) or around LOG(INFO) (otherwise).
 //
diff --git a/nn/common/OperationResolver.cpp b/nn/common/OperationResolver.cpp
index b2c03b9..bd1ad03 100644
--- a/nn/common/OperationResolver.cpp
+++ b/nn/common/OperationResolver.cpp
@@ -23,6 +23,8 @@
 namespace android {
 namespace nn {
 
+using namespace hal;
+
 // TODO(b/119608412): Find a way to not reference every operation here.
 const OperationRegistration* register_ABS();
 const OperationRegistration* register_ADD();
diff --git a/nn/common/OperationsUtils.cpp b/nn/common/OperationsUtils.cpp
index e128afb..9219ddd 100644
--- a/nn/common/OperationsUtils.cpp
+++ b/nn/common/OperationsUtils.cpp
@@ -27,6 +27,8 @@
 
 namespace {
 
+using namespace hal;
+
 bool validateOperandTypes(const std::vector<OperandType>& expectedTypes, const char* tag,
                           uint32_t operandCount,
                           std::function<OperandType(uint32_t)> getOperandType) {
diff --git a/nn/common/Utils.cpp b/nn/common/Utils.cpp
index 18eedd7..fc54932 100644
--- a/nn/common/Utils.cpp
+++ b/nn/common/Utils.cpp
@@ -33,6 +33,8 @@
 namespace android {
 namespace nn {
 
+using namespace hal;
+
 const char kVLogPropKey[] = "debug.nn.vlog";
 int vLogMask = ~0;
 
@@ -1781,7 +1783,7 @@
     using OpPerf = Capabilities::OperandPerformance;
 
     // Note: range presents enumerators in declaration order, not in numerical order.
-    static constexpr ::android::hardware::hidl_enum_range<OperandType> kOperandTypeRange;
+    static constexpr hidl_enum_range<OperandType> kOperandTypeRange;
 
     hidl_vec<OpPerf> ret(kOperandTypeRange.end() - kOperandTypeRange.begin());
 
diff --git a/nn/common/ValidateHal.cpp b/nn/common/ValidateHal.cpp
index 421730a..da440d8 100644
--- a/nn/common/ValidateHal.cpp
+++ b/nn/common/ValidateHal.cpp
@@ -27,6 +27,8 @@
 namespace android {
 namespace nn {
 
+using namespace hal;
+
 template <class T_Model>
 struct ModelToHalVersion;
 template <>
diff --git a/nn/common/include/CpuExecutor.h b/nn/common/include/CpuExecutor.h
index 2aa8984..842082a 100644
--- a/nn/common/include/CpuExecutor.h
+++ b/nn/common/include/CpuExecutor.h
@@ -35,7 +35,7 @@
 // may change during execution.
 struct RunTimeOperandInfo {
     // TODO Storing the type here is redundant, as it won't change during execution.
-    OperandType type;
+    hal::OperandType type;
     // The type and dimensions of the operand.  The dimensions can
     // change at runtime.  We include the type because it's useful
     // to pass together with the dimension to the functions implementing
@@ -62,14 +62,14 @@
     // The length of the buffer.
     uint32_t length;
     // Whether this is a temporary variable, a model input, a constant, etc.
-    OperandLifeTime lifetime;
+    hal::OperandLifeTime lifetime;
     // Keeps track of how many operations have yet to make use
     // of this temporary variable.  When the count is decremented to 0,
     // we free the buffer.  For non-temporary variables, this count is
     // always 0.
     uint32_t numberOfUsesLeft;
 
-    Operand::ExtraParams extraParams;
+    hal::Operand::ExtraParams extraParams;
 
     Shape shape() const {
         return {
@@ -103,12 +103,12 @@
 // RunTimePoolInfo objects.
 class RunTimePoolInfo {
    public:
-    static std::optional<RunTimePoolInfo> createFromHidlMemory(const hidl_memory& hidlMemory);
+    static std::optional<RunTimePoolInfo> createFromHidlMemory(const hal::hidl_memory& hidlMemory);
     static RunTimePoolInfo createFromExistingBuffer(uint8_t* buffer);
 
     uint8_t* getBuffer() const;
     bool update() const;
-    hidl_memory getHidlMemory() const;
+    hal::hidl_memory getHidlMemory() const;
 
    private:
     class RunTimePoolInfoImpl;
@@ -118,7 +118,7 @@
 };
 
 bool setRunTimePoolInfosFromHidlMemories(std::vector<RunTimePoolInfo>* poolInfos,
-                                         const hidl_vec<hidl_memory>& pools);
+                                         const hal::hidl_vec<hal::hidl_memory>& pools);
 
 // This class is used to execute a model on the CPU.
 class CpuExecutor {
@@ -140,11 +140,11 @@
     // specified in the constructor.
     // The model must outlive the executor.  We prevent it from being modified
     // while this is executing.
-    int run(const Model& model, const Request& request,
+    int run(const hal::Model& model, const hal::Request& request,
             const std::vector<RunTimePoolInfo>& modelPoolInfos,
             const std::vector<RunTimePoolInfo>& requestPoolInfos);
 
-    const std::vector<OutputShape>& getOutputShapes() const {
+    const std::vector<hal::OutputShape>& getOutputShapes() const {
         CHECK(mFinished) << "getOutputShapes() called by an unfinished CpuExecutor.";
         return mOutputShapes;
     }
@@ -154,7 +154,7 @@
                                const std::vector<RunTimePoolInfo>& modelPoolInfos,
                                const std::vector<RunTimePoolInfo>& requestPoolInfos);
     // Runs one operation of the graph.
-    int executeOperation(const Operation& entry);
+    int executeOperation(const hal::Operation& entry);
     // Decrement the usage count for the operands listed.  Frees the memory
     // allocated for any temporary variable with a count of zero.
     void freeNoLongerUsedOperands(const std::vector<uint32_t>& inputs);
@@ -165,8 +165,8 @@
 
     // The model and the request that we'll execute. Only valid while run()
     // is being executed.
-    const Model* mModel = nullptr;
-    const Request* mRequest = nullptr;
+    const hal::Model* mModel = nullptr;
+    const hal::Request* mRequest = nullptr;
 
     // We're copying the list of all the dimensions from the model, as
     // these may be modified when we run the operations.  Since we're
@@ -177,7 +177,7 @@
     std::vector<RunTimeOperandInfo> mOperands;
 
     // The output operand shapes returning to the runtime.
-    std::vector<OutputShape> mOutputShapes;
+    std::vector<hal::OutputShape> mOutputShapes;
 
     // Whether execution is finished and mOutputShapes is ready
     bool mFinished = false;
@@ -235,20 +235,18 @@
 }
 
 inline bool IsNullInput(const RunTimeOperandInfo *input) {
-    return input->lifetime == OperandLifeTime::NO_VALUE;
+    return input->lifetime == hal::OperandLifeTime::NO_VALUE;
 }
 
-inline int NumInputsWithValues(const Operation &operation,
-                               std::vector<RunTimeOperandInfo> &operands) {
-  const std::vector<uint32_t> &inputs = operation.inputs;
-  return std::count_if(inputs.begin(), inputs.end(),
-                       [&operands](uint32_t i) {
-                         return !IsNullInput(&operands[i]);
-                       });
+inline int NumInputsWithValues(const hal::Operation& operation,
+                               std::vector<RunTimeOperandInfo>& operands) {
+    const std::vector<uint32_t>& inputs = operation.inputs;
+    return std::count_if(inputs.begin(), inputs.end(),
+                         [&operands](uint32_t i) { return !IsNullInput(&operands[i]); });
 }
 
-inline int NumOutputs(const Operation &operation) {
-  return operation.outputs.size();
+inline int NumOutputs(const hal::Operation& operation) {
+    return operation.outputs.size();
 }
 
 inline size_t NumDimensions(const RunTimeOperandInfo *operand) {
@@ -259,16 +257,14 @@
   return operand->shape().dimensions[i];
 }
 
-inline RunTimeOperandInfo *GetInput(const Operation &operation,
-                                    std::vector<RunTimeOperandInfo> &operands,
-                                    int index) {
-  return &operands[operation.inputs[index]];
+inline RunTimeOperandInfo* GetInput(const hal::Operation& operation,
+                                    std::vector<RunTimeOperandInfo>& operands, int index) {
+    return &operands[operation.inputs[index]];
 }
 
-inline RunTimeOperandInfo *GetOutput(const Operation &operation,
-                                     std::vector<RunTimeOperandInfo> &operands,
-                                     int index) {
-  return &operands[operation.outputs[index]];
+inline RunTimeOperandInfo* GetOutput(const hal::Operation& operation,
+                                     std::vector<RunTimeOperandInfo>& operands, int index) {
+    return &operands[operation.outputs[index]];
 }
 
 }  // anonymous namespace
diff --git a/nn/common/include/ExecutionBurstController.h b/nn/common/include/ExecutionBurstController.h
index 5e32726..8330aa2 100644
--- a/nn/common/include/ExecutionBurstController.h
+++ b/nn/common/include/ExecutionBurstController.h
@@ -48,8 +48,8 @@
  *     request.
  * @return Serialized FMQ request data.
  */
-std::vector<FmqRequestDatum> serialize(const Request& request, MeasureTiming measure,
-                                       const std::vector<int32_t>& slots);
+std::vector<hal::FmqRequestDatum> serialize(const hal::Request& request, hal::MeasureTiming measure,
+                                            const std::vector<int32_t>& slots);
 
 /**
  * Deserialize the FMQ result data.
@@ -60,8 +60,8 @@
  * @param data Serialized FMQ result data.
  * @return Result object if successfully deserialized, std::nullopt otherwise.
  */
-std::optional<std::tuple<ErrorStatus, std::vector<OutputShape>, Timing>> deserialize(
-        const std::vector<FmqResultDatum>& data);
+std::optional<std::tuple<hal::ErrorStatus, std::vector<hal::OutputShape>, hal::Timing>> deserialize(
+        const std::vector<hal::FmqResultDatum>& data);
 
 /**
  * ResultChannelReceiver is responsible for waiting on the channel until the
@@ -73,9 +73,9 @@
  * invalidating, unblocking the receiver.
  */
 class ResultChannelReceiver {
-    using FmqResultDescriptor = ::android::hardware::MQDescriptorSync<FmqResultDatum>;
+    using FmqResultDescriptor = ::android::hardware::MQDescriptorSync<hal::FmqResultDatum>;
     using FmqResultChannel =
-            hardware::MessageQueue<FmqResultDatum, hardware::kSynchronizedReadWrite>;
+            hardware::MessageQueue<hal::FmqResultDatum, hardware::kSynchronizedReadWrite>;
 
    public:
     /**
@@ -102,7 +102,8 @@
      * @return Result object if successfully received, std::nullopt if error or
      *     if the receiver object was invalidated.
      */
-    std::optional<std::tuple<ErrorStatus, std::vector<OutputShape>, Timing>> getBlocking();
+    std::optional<std::tuple<hal::ErrorStatus, std::vector<hal::OutputShape>, hal::Timing>>
+    getBlocking();
 
     /**
      * Method to mark the channel as invalid, unblocking any current or future
@@ -111,7 +112,7 @@
     void invalidate();
 
     // prefer calling ResultChannelReceiver::getBlocking
-    std::optional<std::vector<FmqResultDatum>> getPacketBlocking();
+    std::optional<std::vector<hal::FmqResultDatum>> getPacketBlocking();
 
     ResultChannelReceiver(std::unique_ptr<FmqResultChannel> fmqResultChannel, bool blocking);
 
@@ -127,9 +128,9 @@
  * available.
  */
 class RequestChannelSender {
-    using FmqRequestDescriptor = ::android::hardware::MQDescriptorSync<FmqRequestDatum>;
+    using FmqRequestDescriptor = ::android::hardware::MQDescriptorSync<hal::FmqRequestDatum>;
     using FmqRequestChannel =
-            hardware::MessageQueue<FmqRequestDatum, hardware::kSynchronizedReadWrite>;
+            hardware::MessageQueue<hal::FmqRequestDatum, hardware::kSynchronizedReadWrite>;
 
    public:
     /**
@@ -155,7 +156,8 @@
      *     the request.
      * @return 'true' on successful send, 'false' otherwise.
      */
-    bool send(const Request& request, MeasureTiming measure, const std::vector<int32_t>& slots);
+    bool send(const hal::Request& request, hal::MeasureTiming measure,
+              const std::vector<int32_t>& slots);
 
     /**
      * Method to mark the channel as invalid, causing all future calls to
@@ -165,7 +167,7 @@
     void invalidate();
 
     // prefer calling RequestChannelSender::send
-    bool sendPacket(const std::vector<FmqRequestDatum>& packet);
+    bool sendPacket(const std::vector<hal::FmqRequestDatum>& packet);
 
     RequestChannelSender(std::unique_ptr<FmqRequestChannel> fmqRequestChannel, bool blocking);
 
@@ -200,13 +202,14 @@
      * efficiency, if two hidl_memory objects represent the same underlying
      * buffer, they must use the same key.
      */
-    class ExecutionBurstCallback : public IBurstCallback {
+    class ExecutionBurstCallback : public hal::IBurstCallback {
         DISALLOW_COPY_AND_ASSIGN(ExecutionBurstCallback);
 
        public:
         ExecutionBurstCallback() = default;
 
-        Return<void> getMemories(const hidl_vec<int32_t>& slots, getMemories_cb cb) override;
+        hal::Return<void> getMemories(const hal::hidl_vec<int32_t>& slots,
+                                      getMemories_cb cb) override;
 
         /**
          * This function performs one of two different actions:
@@ -224,7 +227,7 @@
          * @return Unique slot identifiers where each returned slot element
          *     corresponds to a memory resource element in "memories".
          */
-        std::vector<int32_t> getSlots(const hidl_vec<hidl_memory>& memories,
+        std::vector<int32_t> getSlots(const hal::hidl_vec<hal::hidl_memory>& memories,
                                       const std::vector<intptr_t>& keys);
 
         /*
@@ -242,13 +245,13 @@
         std::pair<bool, int32_t> freeMemory(intptr_t key);
 
        private:
-        int32_t getSlotLocked(const hidl_memory& memory, intptr_t key);
+        int32_t getSlotLocked(const hal::hidl_memory& memory, intptr_t key);
         int32_t allocateSlotLocked();
 
         std::mutex mMutex;
         std::stack<int32_t, std::vector<int32_t>> mFreeSlots;
         std::map<intptr_t, int32_t> mMemoryIdToSlot;
-        std::vector<hidl_memory> mMemoryCache;
+        std::vector<hal::hidl_memory> mMemoryCache;
     };
 
     /**
@@ -264,15 +267,15 @@
      *     efficient manner.
      * @return ExecutionBurstController Execution burst controller object.
      */
-    static std::unique_ptr<ExecutionBurstController> create(const sp<IPreparedModel>& preparedModel,
-                                                            bool blocking);
+    static std::unique_ptr<ExecutionBurstController> create(
+            const sp<hal::IPreparedModel>& preparedModel, bool blocking);
 
     // prefer calling ExecutionBurstController::create
     ExecutionBurstController(const std::shared_ptr<RequestChannelSender>& requestChannelSender,
                              const std::shared_ptr<ResultChannelReceiver>& resultChannelReceiver,
-                             const sp<IBurstContext>& burstContext,
+                             const sp<hal::IBurstContext>& burstContext,
                              const sp<ExecutionBurstCallback>& callback,
-                             const sp<hardware::hidl_death_recipient>& deathHandler = nullptr);
+                             const sp<hal::hidl_death_recipient>& deathHandler = nullptr);
 
     // explicit destructor to unregister the death recipient
     ~ExecutionBurstController();
@@ -289,8 +292,9 @@
      *     - dynamic output shapes from the execution
      *     - any execution time measurements of the execution
      */
-    std::tuple<ErrorStatus, std::vector<OutputShape>, Timing> compute(
-            const Request& request, MeasureTiming measure, const std::vector<intptr_t>& memoryIds);
+    std::tuple<hal::ErrorStatus, std::vector<hal::OutputShape>, hal::Timing> compute(
+            const hal::Request& request, hal::MeasureTiming measure,
+            const std::vector<intptr_t>& memoryIds);
 
     // TODO: combine "compute" and "tryCompute" back into a single function.
     // "tryCompute" was created later to return the "fallback" boolean. This
@@ -311,8 +315,9 @@
      *     - whether or not a failed burst execution should be re-run using a
      *       different path (e.g., IPreparedModel::executeSynchronously)
      */
-    std::tuple<ErrorStatus, std::vector<OutputShape>, Timing, bool> tryCompute(
-            const Request& request, MeasureTiming measure, const std::vector<intptr_t>& memoryIds);
+    std::tuple<hal::ErrorStatus, std::vector<hal::OutputShape>, hal::Timing, bool> tryCompute(
+            const hal::Request& request, hal::MeasureTiming measure,
+            const std::vector<intptr_t>& memoryIds);
 
     /**
      * Propagate a user's freeing of memory to the service.
@@ -325,9 +330,9 @@
     std::mutex mMutex;
     const std::shared_ptr<RequestChannelSender> mRequestChannelSender;
     const std::shared_ptr<ResultChannelReceiver> mResultChannelReceiver;
-    const sp<IBurstContext> mBurstContext;
+    const sp<hal::IBurstContext> mBurstContext;
     const sp<ExecutionBurstCallback> mMemoryCache;
-    const sp<hardware::hidl_death_recipient> mDeathHandler;
+    const sp<hal::hidl_death_recipient> mDeathHandler;
 };
 
 }  // namespace android::nn
diff --git a/nn/common/include/ExecutionBurstServer.h b/nn/common/include/ExecutionBurstServer.h
index aeab862..f838012 100644
--- a/nn/common/include/ExecutionBurstServer.h
+++ b/nn/common/include/ExecutionBurstServer.h
@@ -31,9 +31,9 @@
 
 namespace android::nn {
 
-using ::android::hardware::MQDescriptorSync;
-using FmqRequestDescriptor = MQDescriptorSync<FmqRequestDatum>;
-using FmqResultDescriptor = MQDescriptorSync<FmqResultDatum>;
+using hardware::MQDescriptorSync;
+using FmqRequestDescriptor = MQDescriptorSync<hal::FmqRequestDatum>;
+using FmqResultDescriptor = MQDescriptorSync<hal::FmqResultDatum>;
 
 /**
  * Function to serialize results.
@@ -45,8 +45,9 @@
  * @param timing Timing information of the execution.
  * @return Serialized FMQ result data.
  */
-std::vector<FmqResultDatum> serialize(ErrorStatus errorStatus,
-                                      const std::vector<OutputShape>& outputShapes, Timing timing);
+std::vector<hal::FmqResultDatum> serialize(hal::ErrorStatus errorStatus,
+                                           const std::vector<hal::OutputShape>& outputShapes,
+                                           hal::Timing timing);
 
 /**
  * Deserialize the FMQ request data.
@@ -58,8 +59,8 @@
  * @param data Serialized FMQ request data.
  * @return Request object if successfully deserialized, std::nullopt otherwise.
  */
-std::optional<std::tuple<Request, std::vector<int32_t>, MeasureTiming>> deserialize(
-        const std::vector<FmqRequestDatum>& data);
+std::optional<std::tuple<hal::Request, std::vector<int32_t>, hal::MeasureTiming>> deserialize(
+        const std::vector<hal::FmqRequestDatum>& data);
 
 /**
  * RequestChannelReceiver is responsible for waiting on the channel until the
@@ -72,7 +73,7 @@
  */
 class RequestChannelReceiver {
     using FmqRequestChannel =
-            hardware::MessageQueue<FmqRequestDatum, hardware::kSynchronizedReadWrite>;
+            hardware::MessageQueue<hal::FmqRequestDatum, hardware::kSynchronizedReadWrite>;
 
    public:
     /**
@@ -96,7 +97,7 @@
      * @return Request object if successfully received, std::nullopt if error or
      *     if the receiver object was invalidated.
      */
-    std::optional<std::tuple<Request, std::vector<int32_t>, MeasureTiming>> getBlocking();
+    std::optional<std::tuple<hal::Request, std::vector<int32_t>, hal::MeasureTiming>> getBlocking();
 
     /**
      * Method to mark the channel as invalid, unblocking any current or future
@@ -107,7 +108,7 @@
     RequestChannelReceiver(std::unique_ptr<FmqRequestChannel> fmqRequestChannel, bool blocking);
 
    private:
-    std::optional<std::vector<FmqRequestDatum>> getPacketBlocking();
+    std::optional<std::vector<hal::FmqRequestDatum>> getPacketBlocking();
 
     const std::unique_ptr<FmqRequestChannel> mFmqRequestChannel;
     std::atomic<bool> mTeardown{false};
@@ -121,7 +122,7 @@
  */
 class ResultChannelSender {
     using FmqResultChannel =
-            hardware::MessageQueue<FmqResultDatum, hardware::kSynchronizedReadWrite>;
+            hardware::MessageQueue<hal::FmqResultDatum, hardware::kSynchronizedReadWrite>;
 
    public:
     /**
@@ -142,10 +143,11 @@
      * @param timing Timing information of the execution.
      * @return 'true' on successful send, 'false' otherwise.
      */
-    bool send(ErrorStatus errorStatus, const std::vector<OutputShape>& outputShapes, Timing timing);
+    bool send(hal::ErrorStatus errorStatus, const std::vector<hal::OutputShape>& outputShapes,
+              hal::Timing timing);
 
     // prefer calling ResultChannelSender::send
-    bool sendPacket(const std::vector<FmqResultDatum>& packet);
+    bool sendPacket(const std::vector<hal::FmqResultDatum>& packet);
 
     ResultChannelSender(std::unique_ptr<FmqResultChannel> fmqResultChannel, bool blocking);
 
@@ -159,7 +161,7 @@
  * deserializing a request object from a FMQ, performing the inference, and
  * serializing the result back across another FMQ.
  */
-class ExecutionBurstServer : public IBurstContext {
+class ExecutionBurstServer : public hal::IBurstContext {
     DISALLOW_IMPLICIT_CONSTRUCTORS(ExecutionBurstServer);
 
    public:
@@ -199,7 +201,7 @@
          * @param memory Memory resource to be cached.
          * @param slot Slot identifier corresponding to the memory resource.
          */
-        virtual void addCacheEntry(const hidl_memory& memory, int32_t slot) = 0;
+        virtual void addCacheEntry(const hal::hidl_memory& memory, int32_t slot) = 0;
 
         /**
          * Removes an entry specified by a slot from the cache.
@@ -224,9 +226,9 @@
          * @return Result of the execution, including the status of the
          *     execution, dynamic output shapes, and any timing information.
          */
-        virtual std::tuple<ErrorStatus, hidl_vec<OutputShape>, Timing> execute(
-                const Request& request, const std::vector<int32_t>& slots,
-                MeasureTiming measure) = 0;
+        virtual std::tuple<hal::ErrorStatus, hal::hidl_vec<hal::OutputShape>, hal::Timing> execute(
+                const hal::Request& request, const std::vector<int32_t>& slots,
+                hal::MeasureTiming measure) = 0;
     };
 
     /**
@@ -248,7 +250,7 @@
      * @result IBurstContext Handle to the burst context.
      */
     static sp<ExecutionBurstServer> create(
-            const sp<IBurstCallback>& callback, const FmqRequestDescriptor& requestChannel,
+            const sp<hal::IBurstCallback>& callback, const FmqRequestDescriptor& requestChannel,
             const FmqResultDescriptor& resultChannel,
             std::shared_ptr<IBurstExecutorWithCache> executorWithCache);
 
@@ -271,19 +273,19 @@
      *     execution.
      * @result IBurstContext Handle to the burst context.
      */
-    static sp<ExecutionBurstServer> create(const sp<IBurstCallback>& callback,
+    static sp<ExecutionBurstServer> create(const sp<hal::IBurstCallback>& callback,
                                            const FmqRequestDescriptor& requestChannel,
                                            const FmqResultDescriptor& resultChannel,
-                                           IPreparedModel* preparedModel);
+                                           hal::IPreparedModel* preparedModel);
 
-    ExecutionBurstServer(const sp<IBurstCallback>& callback,
+    ExecutionBurstServer(const sp<hal::IBurstCallback>& callback,
                          std::unique_ptr<RequestChannelReceiver> requestChannel,
                          std::unique_ptr<ResultChannelSender> resultChannel,
                          std::shared_ptr<IBurstExecutorWithCache> cachedExecutor);
     ~ExecutionBurstServer();
 
     // Used by the NN runtime to preemptively remove any stored memory.
-    Return<void> freeMemory(int32_t slot) override;
+    hal::Return<void> freeMemory(int32_t slot) override;
 
    private:
     // Ensures all cache entries contained in mExecutorWithCache are present in
@@ -300,7 +302,7 @@
     std::thread mWorker;
     std::mutex mMutex;
     std::atomic<bool> mTeardown{false};
-    const sp<IBurstCallback> mCallback;
+    const sp<hal::IBurstCallback> mCallback;
     const std::unique_ptr<RequestChannelReceiver> mRequestChannelReceiver;
     const std::unique_ptr<ResultChannelSender> mResultChannelSender;
     const std::shared_ptr<IBurstExecutorWithCache> mExecutorWithCache;
diff --git a/nn/common/include/HalInterfaces.h b/nn/common/include/HalInterfaces.h
index 9040cc4..4421ae3 100644
--- a/nn/common/include/HalInterfaces.h
+++ b/nn/common/include/HalInterfaces.h
@@ -33,57 +33,64 @@
 #include <android/hidl/memory/1.0/IMemory.h>
 #include <hidlmemory/mapping.h>
 
-using ::android::sp;
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_handle;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::neuralnetworks::V1_0::DataLocation;
-using ::android::hardware::neuralnetworks::V1_0::DeviceStatus;
+namespace android::nn::hal {
+
+using android::sp;
+using hardware::hidl_array;
+using hardware::hidl_death_recipient;
+using hardware::hidl_enum_range;
+using hardware::hidl_handle;
+using hardware::hidl_memory;
+using hardware::hidl_string;
+using hardware::hidl_vec;
+using hardware::Return;
+using hardware::Void;
+using hardware::neuralnetworks::V1_0::DataLocation;
+using hardware::neuralnetworks::V1_0::DeviceStatus;
+using hardware::neuralnetworks::V1_0::ErrorStatus;
+using hardware::neuralnetworks::V1_0::FusedActivationFunc;
+using hardware::neuralnetworks::V1_0::OperandLifeTime;
+using hardware::neuralnetworks::V1_0::PerformanceInfo;
+using hardware::neuralnetworks::V1_0::Request;
+using hardware::neuralnetworks::V1_0::RequestArgument;
+using hardware::neuralnetworks::V1_1::ExecutionPreference;
+using hardware::neuralnetworks::V1_2::Capabilities;
+using hardware::neuralnetworks::V1_2::Constant;
+using hardware::neuralnetworks::V1_2::DeviceType;
+using hardware::neuralnetworks::V1_2::Extension;
+using hardware::neuralnetworks::V1_2::FmqRequestDatum;
+using hardware::neuralnetworks::V1_2::FmqResultDatum;
+using hardware::neuralnetworks::V1_2::IBurstCallback;
+using hardware::neuralnetworks::V1_2::IBurstContext;
+using hardware::neuralnetworks::V1_2::IDevice;
+using hardware::neuralnetworks::V1_2::IExecutionCallback;
+using hardware::neuralnetworks::V1_2::IPreparedModel;
+using hardware::neuralnetworks::V1_2::IPreparedModelCallback;
+using hardware::neuralnetworks::V1_2::MeasureTiming;
+using hardware::neuralnetworks::V1_2::Model;
+using hardware::neuralnetworks::V1_2::Operand;
+using hardware::neuralnetworks::V1_2::OperandType;
+using hardware::neuralnetworks::V1_2::OperandTypeRange;
+using hardware::neuralnetworks::V1_2::Operation;
+using hardware::neuralnetworks::V1_2::OperationType;
+using hardware::neuralnetworks::V1_2::OperationTypeRange;
+using hardware::neuralnetworks::V1_2::OutputShape;
+using hardware::neuralnetworks::V1_2::SymmPerChannelQuantParams;
+using hardware::neuralnetworks::V1_2::Timing;
+using hidl::allocator::V1_0::IAllocator;
+using hidl::memory::V1_0::IMemory;
+
+namespace V1_0 = hardware::neuralnetworks::V1_0;
+namespace V1_1 = hardware::neuralnetworks::V1_1;
+namespace V1_2 = hardware::neuralnetworks::V1_2;
+
+}  // namespace android::nn::hal
+
+// TODO: remove after b/137663811 is addressed
+namespace android::nn {
+using namespace hal;
+}
 using ::android::hardware::neuralnetworks::V1_0::ErrorStatus;
-using ::android::hardware::neuralnetworks::V1_0::FusedActivationFunc;
-using ::android::hardware::neuralnetworks::V1_0::OperandLifeTime;
-using ::android::hardware::neuralnetworks::V1_0::PerformanceInfo;
-using ::android::hardware::neuralnetworks::V1_0::Request;
-using ::android::hardware::neuralnetworks::V1_0::RequestArgument;
 using ::android::hardware::neuralnetworks::V1_1::ExecutionPreference;
-using ::android::hardware::neuralnetworks::V1_2::Capabilities;
-using ::android::hardware::neuralnetworks::V1_2::Constant;
-using ::android::hardware::neuralnetworks::V1_2::DeviceType;
-using ::android::hardware::neuralnetworks::V1_2::Extension;
-using ::android::hardware::neuralnetworks::V1_2::FmqRequestDatum;
-using ::android::hardware::neuralnetworks::V1_2::FmqResultDatum;
-using ::android::hardware::neuralnetworks::V1_2::IBurstCallback;
-using ::android::hardware::neuralnetworks::V1_2::IBurstContext;
-using ::android::hardware::neuralnetworks::V1_2::IDevice;
-using ::android::hardware::neuralnetworks::V1_2::IExecutionCallback;
-using ::android::hardware::neuralnetworks::V1_2::IPreparedModel;
-using ::android::hardware::neuralnetworks::V1_2::IPreparedModelCallback;
-using ::android::hardware::neuralnetworks::V1_2::MeasureTiming;
-using ::android::hardware::neuralnetworks::V1_2::Model;
-using ::android::hardware::neuralnetworks::V1_2::Operand;
-using ::android::hardware::neuralnetworks::V1_2::OperandType;
-using ::android::hardware::neuralnetworks::V1_2::OperandTypeRange;
-using ::android::hardware::neuralnetworks::V1_2::Operation;
-using ::android::hardware::neuralnetworks::V1_2::OperationType;
-using ::android::hardware::neuralnetworks::V1_2::OperationTypeRange;
-using ::android::hardware::neuralnetworks::V1_2::OutputShape;
-using ::android::hardware::neuralnetworks::V1_2::SymmPerChannelQuantParams;
-using ::android::hardware::neuralnetworks::V1_2::Timing;
-using ::android::hidl::allocator::V1_0::IAllocator;
-using ::android::hidl::memory::V1_0::IMemory;
-
-namespace V1_0 = ::android::hardware::neuralnetworks::V1_0;
-namespace V1_1 = ::android::hardware::neuralnetworks::V1_1;
-namespace V1_2 = ::android::hardware::neuralnetworks::V1_2;
-
-namespace android {
-namespace nn {
-
-} // namespace nn
-} // namespace android
 
 #endif  // FRAMEWORKS_ML_COMMON_HAL_INTERFACES_H
diff --git a/nn/common/include/OperationResolver.h b/nn/common/include/OperationResolver.h
index c10427f..c569ca5 100644
--- a/nn/common/include/OperationResolver.h
+++ b/nn/common/include/OperationResolver.h
@@ -25,7 +25,7 @@
 
 // Encapsulates an operation implementation.
 struct OperationRegistration {
-    OperationType type;
+    hal::OperationType type;
     const char* name;
 
     // Validates operand types, shapes, and any values known during graph creation.
@@ -47,7 +47,7 @@
         bool allowZeroSizedInput = false;
     } flags;
 
-    OperationRegistration(OperationType type, const char* name,
+    OperationRegistration(hal::OperationType type, const char* name,
                           std::function<bool(const IOperationValidationContext*)> validate,
                           std::function<bool(IOperationExecutionContext*)> prepare,
                           std::function<bool(IOperationExecutionContext*)> execute, Flag flags)
@@ -62,7 +62,7 @@
 // A registry of operation implementations.
 class IOperationResolver {
    public:
-    virtual const OperationRegistration* findOperation(OperationType operationType) const = 0;
+    virtual const OperationRegistration* findOperation(hal::OperationType operationType) const = 0;
     virtual ~IOperationResolver() {}
 };
 
@@ -86,7 +86,7 @@
         return &instance;
     }
 
-    const OperationRegistration* findOperation(OperationType operationType) const override;
+    const OperationRegistration* findOperation(hal::OperationType operationType) const override;
 
    private:
     BuiltinOperationResolver();
@@ -116,11 +116,11 @@
 //                         .allowZeroSizedInput = true);
 //
 #ifdef NN_INCLUDE_CPU_IMPLEMENTATION
-#define NN_REGISTER_OPERATION(identifier, operationName, validate, prepare, execute, ...)     \
-    const OperationRegistration* register_##identifier() {                                    \
-        static OperationRegistration registration(OperationType::identifier, operationName,   \
-                                                  validate, prepare, execute, {__VA_ARGS__}); \
-        return &registration;                                                                 \
+#define NN_REGISTER_OPERATION(identifier, operationName, validate, prepare, execute, ...)        \
+    const OperationRegistration* register_##identifier() {                                       \
+        static OperationRegistration registration(hal::OperationType::identifier, operationName, \
+                                                  validate, prepare, execute, {__VA_ARGS__});    \
+        return &registration;                                                                    \
     }
 #else
 // This version ignores CPU execution logic (prepare and execute).
@@ -129,7 +129,7 @@
 #define NN_REGISTER_OPERATION(identifier, operationName, validate, unused_prepare, unused_execute, \
                               ...)                                                                 \
     const OperationRegistration* register_##identifier() {                                         \
-        static OperationRegistration registration(OperationType::identifier, operationName,        \
+        static OperationRegistration registration(hal::OperationType::identifier, operationName,   \
                                                   validate, nullptr, nullptr, {__VA_ARGS__});      \
         return &registration;                                                                      \
     }
diff --git a/nn/common/include/OperationsUtils.h b/nn/common/include/OperationsUtils.h
index 4111a2c..fb787ef 100644
--- a/nn/common/include/OperationsUtils.h
+++ b/nn/common/include/OperationsUtils.h
@@ -17,6 +17,7 @@
 #ifndef FRAMEWORKS_ML_COMMON_OPERATIONS_UTILS_H
 #define FRAMEWORKS_ML_COMMON_OPERATIONS_UTILS_H
 
+#include "HalInterfaces.h"
 #include "Utils.h"
 
 #include <cstdint>
@@ -43,11 +44,11 @@
 
 // Stores operand type information. "Shape" is a historical name.
 struct Shape {
-    OperandType type;
+    hal::OperandType type;
     std::vector<uint32_t> dimensions;
     float scale;
     int32_t offset;
-    Operand::ExtraParams extraParams;
+    hal::Operand::ExtraParams extraParams;
 };
 
 // Provides information available during graph creation to validate an operation.
@@ -72,12 +73,12 @@
     virtual HalVersion getHalVersion() const = 0;
 
     virtual uint32_t getNumInputs() const = 0;
-    virtual OperandType getInputType(uint32_t index) const = 0;
+    virtual hal::OperandType getInputType(uint32_t index) const = 0;
     virtual Shape getInputShape(uint32_t index) const = 0;
-    virtual const Operand::ExtraParams getInputExtraParams(uint32_t index) const = 0;
+    virtual const hal::Operand::ExtraParams getInputExtraParams(uint32_t index) const = 0;
 
     virtual uint32_t getNumOutputs() const = 0;
-    virtual OperandType getOutputType(uint32_t index) const = 0;
+    virtual hal::OperandType getOutputType(uint32_t index) const = 0;
     virtual Shape getOutputShape(uint32_t index) const = 0;
 };
 
@@ -87,13 +88,13 @@
     virtual ~IOperationExecutionContext() {}
 
     virtual uint32_t getNumInputs() const = 0;
-    virtual OperandType getInputType(uint32_t index) const = 0;
+    virtual hal::OperandType getInputType(uint32_t index) const = 0;
     virtual Shape getInputShape(uint32_t index) const = 0;
     virtual const void* getInputBuffer(uint32_t index) const = 0;
-    virtual const Operand::ExtraParams getInputExtraParams(uint32_t index) const = 0;
+    virtual const hal::Operand::ExtraParams getInputExtraParams(uint32_t index) const = 0;
 
     virtual uint32_t getNumOutputs() const = 0;
-    virtual OperandType getOutputType(uint32_t index) const = 0;
+    virtual hal::OperandType getOutputType(uint32_t index) const = 0;
     virtual Shape getOutputShape(uint32_t index) const = 0;
     virtual void* getOutputBuffer(uint32_t index) = 0;
 
@@ -121,11 +122,11 @@
 
 // Verifies that the number and types of operation inputs are as expected.
 bool validateInputTypes(const IOperationValidationContext* context,
-                        const std::vector<OperandType>& expectedTypes);
+                        const std::vector<hal::OperandType>& expectedTypes);
 
 // Verifies that the number and types of operation outputs are as expected.
 bool validateOutputTypes(const IOperationValidationContext* context,
-                         const std::vector<OperandType>& expectedTypes);
+                         const std::vector<hal::OperandType>& expectedTypes);
 
 // Verifies that the HAL version specified in the context is greater or equal
 // than the minimal supported HAL version.
diff --git a/nn/common/include/Utils.h b/nn/common/include/Utils.h
index 80ea884..63f6162 100644
--- a/nn/common/include/Utils.h
+++ b/nn/common/include/Utils.h
@@ -160,25 +160,27 @@
 
 // Return a vector with one entry for each non extension OperandType, set to the
 // specified PerformanceInfo value.  The vector will be sorted by OperandType.
-hidl_vec<Capabilities::OperandPerformance> nonExtensionOperandPerformance(PerformanceInfo perf);
+hal::hidl_vec<hal::Capabilities::OperandPerformance> nonExtensionOperandPerformance(
+        hal::PerformanceInfo perf);
 
 // Update the vector entry corresponding to the specified OperandType with the
 // specified PerformanceInfo value.  The vector must already have an entry for
 // that OperandType, and must be sorted by OperandType.
-void update(hidl_vec<Capabilities::OperandPerformance>* operandPerformance, OperandType type,
-            PerformanceInfo perf);
+void update(hal::hidl_vec<hal::Capabilities::OperandPerformance>* operandPerformance,
+            hal::OperandType type, hal::PerformanceInfo perf);
 
 // Look for a vector entry corresponding to the specified OperandType.  If
 // found, return the associated PerformanceInfo.  If not, return a pessimistic
 // PerformanceInfo (FLT_MAX).  The vector must be sorted by OperandType.
-PerformanceInfo lookup(const hidl_vec<Capabilities::OperandPerformance>& operandPerformance,
-                       OperandType type);
+hal::PerformanceInfo lookup(
+        const hal::hidl_vec<hal::Capabilities::OperandPerformance>& operandPerformance,
+        hal::OperandType type);
 
 // Returns true if an operand type is an extension type.
-bool isExtensionOperandType(OperandType type);
+bool isExtensionOperandType(hal::OperandType type);
 
 // Returns true if an operation type is an extension type.
-bool isExtensionOperationType(OperationType type);
+bool isExtensionOperationType(hal::OperationType type);
 
 // Returns the amount of space needed to store a value of the specified
 // dimensions and type. For a tensor with unspecified rank or at least one
@@ -187,7 +189,8 @@
 // Aborts if the specified type is an extension type.
 //
 // See also TypeManager::getSizeOfData(OperandType, const std::vector<uint32_t>&).
-uint32_t nonExtensionOperandSizeOfData(OperandType type, const std::vector<uint32_t>& dimensions);
+uint32_t nonExtensionOperandSizeOfData(hal::OperandType type,
+                                       const std::vector<uint32_t>& dimensions);
 
 // Returns the amount of space needed to store a value of the dimensions and
 // type of this operand. For a tensor with unspecified rank or at least one
@@ -196,7 +199,7 @@
 // Aborts if the specified type is an extension type.
 //
 // See also TypeManager::getSizeOfData(const Operand&).
-inline uint32_t nonExtensionOperandSizeOfData(const Operand& operand) {
+inline uint32_t nonExtensionOperandSizeOfData(const hal::Operand& operand) {
     return nonExtensionOperandSizeOfData(operand.type, operand.dimensions);
 }
 
@@ -208,16 +211,16 @@
 bool nonExtensionOperandTypeIsScalar(int type);
 
 // Returns the name of the operation type in ASCII.
-std::string getOperationName(OperationType opCode);
+std::string getOperationName(hal::OperationType opCode);
 
 // Returns the name of the operand type in ASCII.
-std::string getOperandTypeName(OperandType type);
+std::string getOperandTypeName(hal::OperandType type);
 
 // Whether an operand of tensor type has unspecified dimensions.
 //
 // Undefined behavior if the operand type is a scalar type.
 bool tensorHasUnspecifiedDimensions(int type, const uint32_t* dim, uint32_t dimCount);
-bool tensorHasUnspecifiedDimensions(const Operand& operand);
+bool tensorHasUnspecifiedDimensions(const hal::Operand& operand);
 bool tensorHasUnspecifiedDimensions(const ANeuralNetworksOperandType* type);
 
 // Returns the number of padding bytes needed to align data of the
@@ -230,9 +233,9 @@
 uint32_t alignBytesNeeded(uint32_t index, size_t length);
 
 // Does a detailed LOG(INFO) of the model
-void logModelToInfo(const V1_0::Model& model);
-void logModelToInfo(const V1_1::Model& model);
-void logModelToInfo(const V1_2::Model& model);
+void logModelToInfo(const hal::V1_0::Model& model);
+void logModelToInfo(const hal::V1_1::Model& model);
+void logModelToInfo(const hal::V1_2::Model& model);
 
 inline std::string toString(uint32_t obj) {
     return std::to_string(obj);
@@ -265,17 +268,18 @@
 }
 
 bool validateOperandSymmPerChannelQuantParams(
-        const Operand& halOperand, const ANeuralNetworksSymmPerChannelQuantParams& channelQuant,
-        const char* tag);
+        const hal::Operand& halOperand,
+        const ANeuralNetworksSymmPerChannelQuantParams& channelQuant, const char* tag);
 
 // Validates an operand type.
 //
 // extensionOperandTypeInfo must be nullptr iff the type is not an extension type.
 //
 // If allowPartial is true, the dimensions may be underspecified.
-int validateOperandType(const ANeuralNetworksOperandType& type,
-                        const Extension::OperandTypeInformation* const extensionOperandTypeInfo,
-                        const char* tag, bool allowPartial);
+int validateOperandType(
+        const ANeuralNetworksOperandType& type,
+        const hal::Extension::OperandTypeInformation* const extensionOperandTypeInfo,
+        const char* tag, bool allowPartial);
 int validateOperandList(uint32_t count, const uint32_t* list, uint32_t operandCount,
                         const char* tag);
 
@@ -283,7 +287,7 @@
 // provided operand types in the given HAL version, otherwise returns ANEURALNETWORKS_BAD_DATA.
 int validateOperation(ANeuralNetworksOperationType opType, uint32_t inputCount,
                       const uint32_t* inputIndexes, uint32_t outputCount,
-                      const uint32_t* outputIndexes, const std::vector<Operand>& operands,
+                      const uint32_t* outputIndexes, const std::vector<hal::Operand>& operands,
                       HalVersion halVersion);
 
 inline size_t getSizeFromInts(int lower, int higher) {
@@ -292,25 +296,25 @@
 
 // Convert ANEURALNETWORKS_* result code to ErrorStatus.
 // Not guaranteed to be a 1-to-1 mapping.
-ErrorStatus convertResultCodeToErrorStatus(int resultCode);
+hal::ErrorStatus convertResultCodeToErrorStatus(int resultCode);
 
 // Convert ErrorStatus to ANEURALNETWORKS_* result code.
 // Not guaranteed to be a 1-to-1 mapping.
-int convertErrorStatusToResultCode(ErrorStatus status);
+int convertErrorStatusToResultCode(hal::ErrorStatus status);
 
 // Versioning
 
-bool compliantWithV1_0(const V1_0::Capabilities& capabilities);
-bool compliantWithV1_0(const V1_1::Capabilities& capabilities);
-bool compliantWithV1_0(const V1_2::Capabilities& capabilities);
-bool compliantWithV1_1(const V1_0::Capabilities& capabilities);
-bool compliantWithV1_1(const V1_1::Capabilities& capabilities);
-bool compliantWithV1_1(const V1_2::Capabilities& capabilities);
-bool compliantWithV1_2(const V1_0::Capabilities& capabilities);
-bool compliantWithV1_2(const V1_1::Capabilities& capabilities);
-bool compliantWithV1_2(const V1_2::Capabilities& capabilities);
+bool compliantWithV1_0(const hal::V1_0::Capabilities& capabilities);
+bool compliantWithV1_0(const hal::V1_1::Capabilities& capabilities);
+bool compliantWithV1_0(const hal::V1_2::Capabilities& capabilities);
+bool compliantWithV1_1(const hal::V1_0::Capabilities& capabilities);
+bool compliantWithV1_1(const hal::V1_1::Capabilities& capabilities);
+bool compliantWithV1_1(const hal::V1_2::Capabilities& capabilities);
+bool compliantWithV1_2(const hal::V1_0::Capabilities& capabilities);
+bool compliantWithV1_2(const hal::V1_1::Capabilities& capabilities);
+bool compliantWithV1_2(const hal::V1_2::Capabilities& capabilities);
 
-bool compliantWithV1_0(const V1_2::Operand& operand);
+bool compliantWithV1_0(const hal::V1_2::Operand& operand);
 
 // If noncompliantOperations != nullptr, then
 //     precondition: noncompliantOperations->empty()
@@ -318,34 +322,34 @@
 //                    operations; if the compliance check fails for some reason
 //                    other than a noncompliant operation,
 //                    *noncompliantOperations consists of the indices of all operations
-bool compliantWithV1_0(const V1_0::Model& model);
-bool compliantWithV1_0(const V1_1::Model& model);
-bool compliantWithV1_0(const V1_2::Model& model,
+bool compliantWithV1_0(const hal::V1_0::Model& model);
+bool compliantWithV1_0(const hal::V1_1::Model& model);
+bool compliantWithV1_0(const hal::V1_2::Model& model,
                        std::set<uint32_t>* noncompliantOperations = nullptr);
-bool compliantWithV1_1(const V1_0::Model& model);
-bool compliantWithV1_1(const V1_1::Model& model);
-bool compliantWithV1_1(const V1_2::Model& model,
+bool compliantWithV1_1(const hal::V1_0::Model& model);
+bool compliantWithV1_1(const hal::V1_1::Model& model);
+bool compliantWithV1_1(const hal::V1_2::Model& model,
                        std::set<uint32_t>* noncompliantOperations = nullptr);
 
-V1_0::Capabilities convertToV1_0(const V1_0::Capabilities& capabilities);
-V1_0::Capabilities convertToV1_0(const V1_1::Capabilities& capabilities);
-V1_0::Capabilities convertToV1_0(const V1_2::Capabilities& capabilities);
-V1_1::Capabilities convertToV1_1(const V1_0::Capabilities& capabilities);
-V1_1::Capabilities convertToV1_1(const V1_1::Capabilities& capabilities);
-V1_1::Capabilities convertToV1_1(const V1_2::Capabilities& capabilities);
-V1_2::Capabilities convertToV1_2(const V1_0::Capabilities& capabilities);
-V1_2::Capabilities convertToV1_2(const V1_1::Capabilities& capabilities);
-V1_2::Capabilities convertToV1_2(const V1_2::Capabilities& capabilities);
+hal::V1_0::Capabilities convertToV1_0(const hal::V1_0::Capabilities& capabilities);
+hal::V1_0::Capabilities convertToV1_0(const hal::V1_1::Capabilities& capabilities);
+hal::V1_0::Capabilities convertToV1_0(const hal::V1_2::Capabilities& capabilities);
+hal::V1_1::Capabilities convertToV1_1(const hal::V1_0::Capabilities& capabilities);
+hal::V1_1::Capabilities convertToV1_1(const hal::V1_1::Capabilities& capabilities);
+hal::V1_1::Capabilities convertToV1_1(const hal::V1_2::Capabilities& capabilities);
+hal::V1_2::Capabilities convertToV1_2(const hal::V1_0::Capabilities& capabilities);
+hal::V1_2::Capabilities convertToV1_2(const hal::V1_1::Capabilities& capabilities);
+hal::V1_2::Capabilities convertToV1_2(const hal::V1_2::Capabilities& capabilities);
 
-V1_0::Model convertToV1_0(const V1_0::Model& model);
-V1_0::Model convertToV1_0(const V1_1::Model& model);
-V1_0::Model convertToV1_0(const V1_2::Model& model);
-V1_1::Model convertToV1_1(const V1_0::Model& model);
-V1_1::Model convertToV1_1(const V1_1::Model& model);
-V1_1::Model convertToV1_1(const V1_2::Model& model);
-V1_2::Model convertToV1_2(const V1_0::Model& model);
-V1_2::Model convertToV1_2(const V1_1::Model& model);
-V1_2::Model convertToV1_2(const V1_2::Model& model);
+hal::V1_0::Model convertToV1_0(const hal::V1_0::Model& model);
+hal::V1_0::Model convertToV1_0(const hal::V1_1::Model& model);
+hal::V1_0::Model convertToV1_0(const hal::V1_2::Model& model);
+hal::V1_1::Model convertToV1_1(const hal::V1_0::Model& model);
+hal::V1_1::Model convertToV1_1(const hal::V1_1::Model& model);
+hal::V1_1::Model convertToV1_1(const hal::V1_2::Model& model);
+hal::V1_2::Model convertToV1_2(const hal::V1_0::Model& model);
+hal::V1_2::Model convertToV1_2(const hal::V1_1::Model& model);
+hal::V1_2::Model convertToV1_2(const hal::V1_2::Model& model);
 
 // The IModelSlicer abstract class provides methods to create from an original
 // model a "slice" of that model consisting of the subset of operations that is
@@ -381,24 +385,24 @@
 //
 class IModelSlicer {
    public:
-    virtual std::optional<std::pair<V1_0::Model, std::function<uint32_t(uint32_t)>>>
+    virtual std::optional<std::pair<hal::V1_0::Model, std::function<uint32_t(uint32_t)>>>
     getSliceV1_0() = 0;
-    virtual std::optional<std::pair<V1_1::Model, std::function<uint32_t(uint32_t)>>>
+    virtual std::optional<std::pair<hal::V1_1::Model, std::function<uint32_t(uint32_t)>>>
     getSliceV1_1() = 0;
 
     virtual ~IModelSlicer() = default;
 };
 
-V1_0::OperationType uncheckedConvertToV1_0(V1_2::OperationType type);
-V1_1::OperationType uncheckedConvertToV1_1(V1_2::OperationType type);
+hal::V1_0::OperationType uncheckedConvertToV1_0(hal::V1_2::OperationType type);
+hal::V1_1::OperationType uncheckedConvertToV1_1(hal::V1_2::OperationType type);
 
-V1_0::Operand convertToV1_0(const V1_2::Operand& operand);
+hal::V1_0::Operand convertToV1_0(const hal::V1_2::Operand& operand);
 
-V1_2::Operand convertToV1_2(const V1_0::Operand& operand);
-V1_2::Operand convertToV1_2(const V1_2::Operand& operand);
+hal::V1_2::Operand convertToV1_2(const hal::V1_0::Operand& operand);
+hal::V1_2::Operand convertToV1_2(const hal::V1_2::Operand& operand);
 
-hidl_vec<V1_2::Operand> convertToV1_2(const hidl_vec<V1_0::Operand>& operands);
-hidl_vec<V1_2::Operand> convertToV1_2(const hidl_vec<V1_2::Operand>& operands);
+hal::hidl_vec<hal::V1_2::Operand> convertToV1_2(const hal::hidl_vec<hal::V1_0::Operand>& operands);
+hal::hidl_vec<hal::V1_2::Operand> convertToV1_2(const hal::hidl_vec<hal::V1_2::Operand>& operands);
 
 #ifdef NN_DEBUGGABLE
 uint32_t getProp(const char* str, uint32_t defaultValue = 0);
diff --git a/nn/common/include/ValidateHal.h b/nn/common/include/ValidateHal.h
index 3bb641c..30e79ac 100644
--- a/nn/common/include/ValidateHal.h
+++ b/nn/common/include/ValidateHal.h
@@ -44,20 +44,20 @@
 // are correctly defined, as these are specific to each implementation.
 // Each driver should do their own validation of OEM types.
 template <class T_Model>
-bool validateRequest(const Request& request, const T_Model& model);
+bool validateRequest(const hal::Request& request, const T_Model& model);
 
 // Verfies that the execution preference is valid.
-bool validateExecutionPreference(ExecutionPreference preference);
+bool validateExecutionPreference(hal::ExecutionPreference preference);
 
-bool validOperationType(V1_0::OperationType operation);
-bool validOperationType(V1_1::OperationType operation);
-bool validOperationType(V1_2::OperationType operation);
+bool validOperationType(hal::V1_0::OperationType operation);
+bool validOperationType(hal::V1_1::OperationType operation);
+bool validOperationType(hal::V1_2::OperationType operation);
 
-bool validOperandType(V1_0::OperandType operand);
-bool validOperandType(V1_2::OperandType operand);
+bool validOperandType(hal::V1_0::OperandType operand);
+bool validOperandType(hal::V1_2::OperandType operand);
 
 // Verfies that the memory pool is valid in the specified HAL version.
-bool validatePool(const hidl_memory& pool, HalVersion ver = HalVersion::LATEST);
+bool validatePool(const hal::hidl_memory& pool, HalVersion ver = HalVersion::LATEST);
 
 }  // namespace nn
 }  // namespace android
diff --git a/nn/common/operations/Activation.cpp b/nn/common/operations/Activation.cpp
index 31ce03c..f320d99 100644
--- a/nn/common/operations/Activation.cpp
+++ b/nn/common/operations/Activation.cpp
@@ -18,6 +18,7 @@
 
 #include "ActivationFunctor.h"
 #include "CpuOperationUtils.h"
+#include "HalInterfaces.h"
 #include "OperationResolver.h"
 
 #include <tensorflow/lite/kernels/internal/optimized/legacy_optimized_ops.h>
@@ -28,6 +29,8 @@
 namespace android {
 namespace nn {
 
+using namespace hal;
+
 namespace activation {
 
 constexpr uint32_t kNumInputs = 1;
diff --git a/nn/common/operations/ArgMinMax.cpp b/nn/common/operations/ArgMinMax.cpp
index b323d51..64d4606 100644
--- a/nn/common/operations/ArgMinMax.cpp
+++ b/nn/common/operations/ArgMinMax.cpp
@@ -18,14 +18,17 @@
 
 #define LOG_TAG "Operations"
 
-#include "Operations.h"
 #include "CpuOperationUtils.h"
+#include "HalInterfaces.h"
+#include "Operations.h"
 
 #include "Tracing.h"
 
 namespace android {
 namespace nn {
 
+using namespace hal;
+
 template <typename In, typename Out>
 static void argMinMaxImpl(const In* inputData, const Shape& inputShape,
                           int32_t axis, bool isArgMin,
diff --git a/nn/common/operations/BidirectionalSequenceLSTM.cpp b/nn/common/operations/BidirectionalSequenceLSTM.cpp
index c7391da..a186b72 100644
--- a/nn/common/operations/BidirectionalSequenceLSTM.cpp
+++ b/nn/common/operations/BidirectionalSequenceLSTM.cpp
@@ -30,6 +30,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T>
 inline T* GetBuffer(RunTimeOperandInfo* operand) {
     return reinterpret_cast<T*>(operand->buffer);
diff --git a/nn/common/operations/BidirectionalSequenceLSTM.h b/nn/common/operations/BidirectionalSequenceLSTM.h
index 06c9b03..df0a5be 100644
--- a/nn/common/operations/BidirectionalSequenceLSTM.h
+++ b/nn/common/operations/BidirectionalSequenceLSTM.h
@@ -33,11 +33,12 @@
 
 class BidirectionalSequenceLSTM {
    public:
-    BidirectionalSequenceLSTM(const Operation& operation,
+    BidirectionalSequenceLSTM(const hardware::neuralnetworks::V1_2::Operation& operation,
                               std::vector<RunTimeOperandInfo>& operands);
 
-    bool Prepare(const Operation& operation, std::vector<RunTimeOperandInfo>& operands,
-                 Shape* fwOutputShape, Shape* bwOutputShape);
+    bool Prepare(const hardware::neuralnetworks::V1_2::Operation& operation,
+                 std::vector<RunTimeOperandInfo>& operands, Shape* fwOutputShape,
+                 Shape* bwOutputShape);
     bool Eval();
 
     // Input Tensors of size {max_time, n_batch, n_input}
diff --git a/nn/common/operations/BidirectionalSequenceRNN.cpp b/nn/common/operations/BidirectionalSequenceRNN.cpp
index 32ab00f..1e37f16 100644
--- a/nn/common/operations/BidirectionalSequenceRNN.cpp
+++ b/nn/common/operations/BidirectionalSequenceRNN.cpp
@@ -16,6 +16,7 @@
 
 #define LOG_TAG "Operations"
 
+#include "HalInterfaces.h"
 #include "OperationResolver.h"
 #include "RNN.h"
 
@@ -49,6 +50,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T>
 void transposeFirstTwoDims(const T* input, const Shape& inputShape, T* output) {
     const uint32_t firstDimSize = getSizeOfDimension(inputShape, 0);
diff --git a/nn/common/operations/Broadcast.cpp b/nn/common/operations/Broadcast.cpp
index 9ff6ae8..1323254 100644
--- a/nn/common/operations/Broadcast.cpp
+++ b/nn/common/operations/Broadcast.cpp
@@ -19,6 +19,7 @@
 #define LOG_TAG "Operations"
 
 #include "CpuOperationUtils.h"
+#include "HalInterfaces.h"
 #include "OperationResolver.h"
 
 #include <tensorflow/lite/kernels/internal/optimized/legacy_optimized_ops.h>
@@ -30,6 +31,9 @@
 
 namespace android {
 namespace nn {
+
+using namespace hal;
+
 namespace broadcast {
 
 constexpr uint32_t kNumInputs = 3;
diff --git a/nn/common/operations/Cast.cpp b/nn/common/operations/Cast.cpp
index f569767..b14c8b0 100644
--- a/nn/common/operations/Cast.cpp
+++ b/nn/common/operations/Cast.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "Operations"
 
 #include "Cast.h"
+#include "HalInterfaces.h"
 #include "Tracing.h"
 
 namespace android {
@@ -25,6 +26,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename FromT, typename ToT>
 void copyCast(const FromT* in, ToT* out, int numElements) {
     std::transform(in, in + numElements, out, [](FromT a) -> ToT {
diff --git a/nn/common/operations/ChannelShuffle.cpp b/nn/common/operations/ChannelShuffle.cpp
index 997b033..65f45ed 100644
--- a/nn/common/operations/ChannelShuffle.cpp
+++ b/nn/common/operations/ChannelShuffle.cpp
@@ -25,6 +25,8 @@
 namespace nn {
 namespace channel_shuffle {
 
+using namespace hal;
+
 constexpr char kOperationName[] = "CHANNEL_SHUFFLE";
 
 constexpr uint32_t kNumInputs = 3;
diff --git a/nn/common/operations/Comparisons.cpp b/nn/common/operations/Comparisons.cpp
index 1820dde..0ccecaf 100644
--- a/nn/common/operations/Comparisons.cpp
+++ b/nn/common/operations/Comparisons.cpp
@@ -34,6 +34,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename DataType, typename ComparisonType>
 bool compute(const std::function<bool(ComparisonType, ComparisonType)>& func, const DataType* aData,
              const Shape& aShape, const DataType* bData, const Shape& bShape, bool8* outputData,
diff --git a/nn/common/operations/Concatenation.cpp b/nn/common/operations/Concatenation.cpp
index 04bb2e2..e8b332b 100644
--- a/nn/common/operations/Concatenation.cpp
+++ b/nn/common/operations/Concatenation.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "Operations"
 
 #include "CpuOperationUtils.h"
+#include "HalInterfaces.h"
 #include "OperationResolver.h"
 
 #include <tensorflow/lite/kernels/internal/optimized/legacy_optimized_ops.h>
@@ -35,6 +36,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T>
 bool concatenation(const std::vector<const T*>& inputDataPtrs,
                    const std::vector<Shape>& inputShapes, int32_t axis, T* outputData,
diff --git a/nn/common/operations/Conv2D.cpp b/nn/common/operations/Conv2D.cpp
index 0debed2..678e2d6 100644
--- a/nn/common/operations/Conv2D.cpp
+++ b/nn/common/operations/Conv2D.cpp
@@ -17,10 +17,11 @@
 #define LOG_TAG "Operations"
 
 #include "CpuOperationUtils.h"
+#include "HalInterfaces.h"
 #include "OperationResolver.h"
 #include "Operations.h"
-#include "Utils.h"
 #include "Tracing.h"
+#include "Utils.h"
 
 #include <tensorflow/lite/kernels/internal/optimized/legacy_optimized_ops.h>
 
@@ -39,6 +40,8 @@
 
 namespace {
 
+using namespace hal;
+
 // If possible we will use this static buffer for the tensor.
 constexpr size_t kStaticBufferSize = 1605632;
 char static_scratch_buffer[kStaticBufferSize];
diff --git a/nn/common/operations/Dequantize.cpp b/nn/common/operations/Dequantize.cpp
index 51403d2..85c071d 100644
--- a/nn/common/operations/Dequantize.cpp
+++ b/nn/common/operations/Dequantize.cpp
@@ -33,6 +33,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename InputType, typename OutputType>
 bool compute(const InputType* inputData, const Shape& inputShape, OutputType* outputData) {
     const int numElements = getNumberOfElements(inputShape);
diff --git a/nn/common/operations/Elementwise.cpp b/nn/common/operations/Elementwise.cpp
index 114007d..3610cc0 100644
--- a/nn/common/operations/Elementwise.cpp
+++ b/nn/common/operations/Elementwise.cpp
@@ -35,6 +35,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T>
 inline bool compute(float func(float), const T* input, const Shape& shape, T* output) {
     const auto size = getNumberOfElements(shape);
diff --git a/nn/common/operations/EmbeddingLookup.cpp b/nn/common/operations/EmbeddingLookup.cpp
index d705d95..f3b2911 100644
--- a/nn/common/operations/EmbeddingLookup.cpp
+++ b/nn/common/operations/EmbeddingLookup.cpp
@@ -19,6 +19,7 @@
 #include "EmbeddingLookup.h"
 
 #include "CpuExecutor.h"
+#include "HalInterfaces.h"
 #include "Operations.h"
 
 #include "Tracing.h"
@@ -26,6 +27,8 @@
 namespace android {
 namespace nn {
 
+using namespace hal;
+
 EmbeddingLookup::EmbeddingLookup(const Operation& operation,
                                  std::vector<RunTimeOperandInfo>& operands) {
   value_ = GetInput(operation, operands, kValueTensor);
diff --git a/nn/common/operations/EmbeddingLookup.h b/nn/common/operations/EmbeddingLookup.h
index cc7cecc..ab3c38c 100644
--- a/nn/common/operations/EmbeddingLookup.h
+++ b/nn/common/operations/EmbeddingLookup.h
@@ -28,9 +28,8 @@
 
 class EmbeddingLookup {
  public:
-  EmbeddingLookup(
-      const Operation &operation,
-      std::vector<RunTimeOperandInfo> &operands);
+  EmbeddingLookup(const hardware::neuralnetworks::V1_2::Operation& operation,
+                  std::vector<RunTimeOperandInfo>& operands);
 
   bool Eval();
 
diff --git a/nn/common/operations/FullyConnected.cpp b/nn/common/operations/FullyConnected.cpp
index 509a70e..3dc7478 100644
--- a/nn/common/operations/FullyConnected.cpp
+++ b/nn/common/operations/FullyConnected.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "Operations"
 
 #include "CpuOperationUtils.h"
+#include "HalInterfaces.h"
 #include "OperationResolver.h"
 
 #include <tensorflow/lite/kernels/internal/optimized/legacy_optimized_ops.h>
@@ -41,6 +42,8 @@
 
 namespace {
 
+using namespace hal;
+
 // executionMutex is used to protect concurrent access of non-threadsafe resources
 // like gemmlowp::GemmContext.
 // std::mutex is safe for pthreads on Android.
diff --git a/nn/common/operations/Gather.cpp b/nn/common/operations/Gather.cpp
index e41947c..53d0671 100644
--- a/nn/common/operations/Gather.cpp
+++ b/nn/common/operations/Gather.cpp
@@ -37,6 +37,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T>
 inline bool eval(const T* inputData, const Shape& inputShape, int32_t axis,
                  const int32_t* indicesData, const Shape& indicesShape, T* outputData) {
diff --git a/nn/common/operations/GenerateProposals.cpp b/nn/common/operations/GenerateProposals.cpp
index fd28a74..67d614f 100644
--- a/nn/common/operations/GenerateProposals.cpp
+++ b/nn/common/operations/GenerateProposals.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "Operations"
 
 #include "CpuOperationUtils.h"
+#include "HalInterfaces.h"
 #include "OperationResolver.h"
 #include "OperationsUtils.h"
 
@@ -32,6 +33,8 @@
 
 namespace {
 
+using namespace hal;
+
 struct BoxEncodingCorner {
     float x1, y1, x2, y2;
 };
diff --git a/nn/common/operations/HalOperation.h b/nn/common/operations/HalOperation.h
index f74fce6..d4011e3 100644
--- a/nn/common/operations/HalOperation.h
+++ b/nn/common/operations/HalOperation.h
@@ -17,21 +17,13 @@
 #ifndef FRAMEWORKS_ML_COMMON_OPERATIONS_HAL_OPERATION_H
 #define FRAMEWORKS_ML_COMMON_OPERATIONS_HAL_OPERATION_H
 
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_2 {
+namespace android::hardware::neuralnetworks::V1_2 {
 
 // Individual operation implementations should not depend on the HAL interface,
 // but we have some that do. We use a forward declaration instead of an explicit
 // blueprint dependency to hide this fact.
 struct Operation;
 
-}  // namespace V1_2
-}  // namespace neuralnetworks
-}  // namespace hardware
-}  // namespace android
-
-using ::android::hardware::neuralnetworks::V1_2::Operation;
+}  // namespace android::hardware::neuralnetworks::V1_2
 
 #endif  // FRAMEWORKS_ML_COMMON_OPERATIONS_HAL_OPERATION_H
diff --git a/nn/common/operations/HashtableLookup.cpp b/nn/common/operations/HashtableLookup.cpp
index d718e8c..67cdffd 100644
--- a/nn/common/operations/HashtableLookup.cpp
+++ b/nn/common/operations/HashtableLookup.cpp
@@ -19,6 +19,7 @@
 #include "HashtableLookup.h"
 
 #include "CpuExecutor.h"
+#include "HalInterfaces.h"
 #include "Operations.h"
 
 #include "Tracing.h"
@@ -28,6 +29,8 @@
 
 namespace {
 
+using namespace hal;
+
 int greater(const void* a, const void* b) {
   return *static_cast<const int*>(a) - *static_cast<const int*>(b);
 }
diff --git a/nn/common/operations/HashtableLookup.h b/nn/common/operations/HashtableLookup.h
index 3f84905..8e12929 100644
--- a/nn/common/operations/HashtableLookup.h
+++ b/nn/common/operations/HashtableLookup.h
@@ -28,9 +28,8 @@
 
 class HashtableLookup {
  public:
-  HashtableLookup(
-      const Operation &operation,
-      std::vector<RunTimeOperandInfo> &operands);
+  HashtableLookup(const hardware::neuralnetworks::V1_2::Operation& operation,
+                  std::vector<RunTimeOperandInfo>& operands);
 
   bool Eval();
 
diff --git a/nn/common/operations/HeatmapMaxKeypoint.cpp b/nn/common/operations/HeatmapMaxKeypoint.cpp
index 65a4afa..14fda45 100644
--- a/nn/common/operations/HeatmapMaxKeypoint.cpp
+++ b/nn/common/operations/HeatmapMaxKeypoint.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "Operations"
 
 #include "CpuOperationUtils.h"
+#include "HalInterfaces.h"
 #include "OperationResolver.h"
 #include "OperationsUtils.h"
 
@@ -42,6 +43,8 @@
 
 namespace {
 
+using namespace hal;
+
 // This function uses Taylor expansion up to the quatratic term to approximate bicubic
 // upscaling result.
 // 2nd order Taylor expansion: D(x) = D - b'x + 1/2 * x'Ax
diff --git a/nn/common/operations/InstanceNormalization.cpp b/nn/common/operations/InstanceNormalization.cpp
index c61da09..19d1c5f 100644
--- a/nn/common/operations/InstanceNormalization.cpp
+++ b/nn/common/operations/InstanceNormalization.cpp
@@ -42,6 +42,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T>
 inline bool instanceNormNhwc(const T* inputData, const Shape& inputShape, T gamma, T beta,
                              T epsilon, T* outputData, const Shape& outputShape) {
diff --git a/nn/common/operations/L2Normalization.cpp b/nn/common/operations/L2Normalization.cpp
index 566dace..92cabc7 100644
--- a/nn/common/operations/L2Normalization.cpp
+++ b/nn/common/operations/L2Normalization.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "Operations"
 
 #include "CpuOperationUtils.h"
+#include "HalInterfaces.h"
 #include "OperationResolver.h"
 
 #include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
@@ -38,6 +39,8 @@
 
 namespace {
 
+using namespace hal;
+
 inline bool l2normFloat32Impl(const float* inputData, const Shape& inputShape, int32_t axis,
                               float* outputData, const Shape& outputShape) {
     NNTRACE_TRANS("l2normFloat32");
diff --git a/nn/common/operations/LSHProjection.cpp b/nn/common/operations/LSHProjection.cpp
index 742e887..3735717 100644
--- a/nn/common/operations/LSHProjection.cpp
+++ b/nn/common/operations/LSHProjection.cpp
@@ -19,6 +19,7 @@
 #include "LSHProjection.h"
 
 #include "CpuExecutor.h"
+#include "HalInterfaces.h"
 #include "Tracing.h"
 #include "Utils.h"
 
@@ -27,6 +28,8 @@
 namespace android {
 namespace nn {
 
+using namespace hal;
+
 LSHProjection::LSHProjection(const Operation& operation,
                              std::vector<RunTimeOperandInfo>& operands) {
     input_ = GetInput(operation, operands, kInputTensor);
diff --git a/nn/common/operations/LSHProjection.h b/nn/common/operations/LSHProjection.h
index 2ebf916..9155aaa 100644
--- a/nn/common/operations/LSHProjection.h
+++ b/nn/common/operations/LSHProjection.h
@@ -36,10 +36,11 @@
 
 class LSHProjection {
    public:
-    LSHProjection(const Operation& operation, std::vector<RunTimeOperandInfo>& operands);
+    LSHProjection(const hardware::neuralnetworks::V1_2::Operation& operation,
+                  std::vector<RunTimeOperandInfo>& operands);
 
-    static bool Prepare(const Operation& operation, std::vector<RunTimeOperandInfo>& operands,
-                        Shape* outputShape);
+    static bool Prepare(const hardware::neuralnetworks::V1_2::Operation& operation,
+                        std::vector<RunTimeOperandInfo>& operands, Shape* outputShape);
     template <typename T>
     bool Eval();
 
diff --git a/nn/common/operations/LSTM.cpp b/nn/common/operations/LSTM.cpp
index a772274..3dba298 100644
--- a/nn/common/operations/LSTM.cpp
+++ b/nn/common/operations/LSTM.cpp
@@ -31,6 +31,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T>
 inline T* GetBuffer(RunTimeOperandInfo* operand) {
     return reinterpret_cast<T*>(operand->buffer);
diff --git a/nn/common/operations/LSTM.h b/nn/common/operations/LSTM.h
index 606038f..9672d00 100644
--- a/nn/common/operations/LSTM.h
+++ b/nn/common/operations/LSTM.h
@@ -45,11 +45,12 @@
 
 class LSTMCell {
    public:
-    LSTMCell(const Operation& operation, std::vector<RunTimeOperandInfo>& operands);
+    LSTMCell(const hardware::neuralnetworks::V1_2::Operation& operation,
+             std::vector<RunTimeOperandInfo>& operands);
 
-    bool Prepare(const Operation& operation, std::vector<RunTimeOperandInfo>& operands,
-                 Shape* scratchShape, Shape* outputStateShape, Shape* cellStateShape,
-                 Shape* outputShape);
+    bool Prepare(const hardware::neuralnetworks::V1_2::Operation& operation,
+                 std::vector<RunTimeOperandInfo>& operands, Shape* scratchShape,
+                 Shape* outputStateShape, Shape* cellStateShape, Shape* outputShape);
     bool Eval();
 
     // Input Tensors of size {n_batch, n_input}
diff --git a/nn/common/operations/LogSoftmax.cpp b/nn/common/operations/LogSoftmax.cpp
index d0a5cb9..4132ef9 100644
--- a/nn/common/operations/LogSoftmax.cpp
+++ b/nn/common/operations/LogSoftmax.cpp
@@ -27,6 +27,8 @@
 namespace nn {
 namespace log_softmax {
 
+using namespace hal;
+
 constexpr char kOperationName[] = "LOG_SOFTMAX";
 
 constexpr uint32_t kNumInputs = 3;
diff --git a/nn/common/operations/LogicalAndOr.cpp b/nn/common/operations/LogicalAndOr.cpp
index 9d4968d..6ada724 100644
--- a/nn/common/operations/LogicalAndOr.cpp
+++ b/nn/common/operations/LogicalAndOr.cpp
@@ -34,6 +34,8 @@
 
 namespace {
 
+using namespace hal;
+
 bool compute(const std::function<bool(bool, bool)>& func, const bool8* aData, const Shape& aShape,
              const bool8* bData, const Shape& bShape, bool8* outputData, const Shape& outputShape) {
     IndexedShapeWrapper aShapeIndexed(aShape);
diff --git a/nn/common/operations/LogicalNot.cpp b/nn/common/operations/LogicalNot.cpp
index c715388..8b41813 100644
--- a/nn/common/operations/LogicalNot.cpp
+++ b/nn/common/operations/LogicalNot.cpp
@@ -16,6 +16,7 @@
 
 #define LOG_TAG "Operations"
 
+#include "HalInterfaces.h"
 #include "OperationResolver.h"
 #include "OperationsUtils.h"
 
@@ -31,6 +32,8 @@
 
 namespace {
 
+using namespace hal;
+
 bool compute(const bool8* input, const Shape& shape, bool8* output) {
     const auto size = getNumberOfElements(shape);
     for (uint32_t i = 0; i < size; ++i) {
diff --git a/nn/common/operations/MaximumMinimum.cpp b/nn/common/operations/MaximumMinimum.cpp
index d56e311..bd2c11d 100644
--- a/nn/common/operations/MaximumMinimum.cpp
+++ b/nn/common/operations/MaximumMinimum.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "Operations"
 
 #include "MaximumMinimum.h"
+#include "HalInterfaces.h"
 #include "IndexedShapeWrapper.h"
 #include "OperationsUtils.h"
 #include "Tracing.h"
@@ -27,6 +28,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T>
 bool evalGeneric(const T* aData, const Shape& aShape, const T* bData, const Shape& bShape,
                  bool isMinimum, T* outputData, const Shape& outputShape) {
diff --git a/nn/common/operations/Multinomial.cpp b/nn/common/operations/Multinomial.cpp
index 797063d..9ccb389 100644
--- a/nn/common/operations/Multinomial.cpp
+++ b/nn/common/operations/Multinomial.cpp
@@ -34,6 +34,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T>
 inline T* GetBuffer(RunTimeOperandInfo* operand) {
     return reinterpret_cast<T*>(operand->buffer);
diff --git a/nn/common/operations/Multinomial.h b/nn/common/operations/Multinomial.h
index c12f5b3..1cb7382 100644
--- a/nn/common/operations/Multinomial.h
+++ b/nn/common/operations/Multinomial.h
@@ -32,7 +32,7 @@
 
 class Multinomial {
    public:
-    Multinomial(const android::hardware::neuralnetworks::V1_2::Operation& operation,
+    Multinomial(const hardware::neuralnetworks::V1_2::Operation& operation,
                 std::vector<RunTimeOperandInfo>& operands);
 
     static bool Prepare(const hardware::neuralnetworks::V1_2::Operation& operation,
diff --git a/nn/common/operations/Neg.cpp b/nn/common/operations/Neg.cpp
index 7c61028..48d962c 100644
--- a/nn/common/operations/Neg.cpp
+++ b/nn/common/operations/Neg.cpp
@@ -37,6 +37,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T>
 inline bool compute(const T* input, const Shape& shape, T* output) {
     const auto size = getNumberOfElements(shape);
diff --git a/nn/common/operations/PRelu.cpp b/nn/common/operations/PRelu.cpp
index cd7f081..98491f6 100644
--- a/nn/common/operations/PRelu.cpp
+++ b/nn/common/operations/PRelu.cpp
@@ -28,6 +28,8 @@
 namespace nn {
 namespace prelu {
 
+using namespace hal;
+
 constexpr char kOperationName[] = "PRELU";
 
 constexpr uint32_t kNumInputs = 2;
diff --git a/nn/common/operations/Pooling.cpp b/nn/common/operations/Pooling.cpp
index 3e3b781..a32be7c 100644
--- a/nn/common/operations/Pooling.cpp
+++ b/nn/common/operations/Pooling.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "Operations"
 
 #include "CpuOperationUtils.h"
+#include "HalInterfaces.h"
 #include "OperationResolver.h"
 
 #include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
@@ -25,6 +26,9 @@
 
 namespace android {
 namespace nn {
+
+using namespace hal;
+
 namespace pooling {
 
 constexpr uint32_t kInputTensor = 0;
diff --git a/nn/common/operations/Pow.cpp b/nn/common/operations/Pow.cpp
index 99e1099..40c4adf 100644
--- a/nn/common/operations/Pow.cpp
+++ b/nn/common/operations/Pow.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "Operations"
 
 #include "Pow.h"
+#include "HalInterfaces.h"
 #include "IndexedShapeWrapper.h"
 #include "OperationsUtils.h"
 
@@ -28,6 +29,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T>
 bool evalGeneric(const T* baseData, const Shape& baseShape, const T* exponentData,
                  const Shape& exponentShape, T* outputData, const Shape& outputShape) {
diff --git a/nn/common/operations/Quantize.cpp b/nn/common/operations/Quantize.cpp
index b2ec9e3..368492a 100644
--- a/nn/common/operations/Quantize.cpp
+++ b/nn/common/operations/Quantize.cpp
@@ -36,6 +36,8 @@
 
 namespace {
 
+using namespace hal;
+
 bool quantizeFloat32ToQuant8(const float* inputData, uint8_t* outputData,
                              const Shape& outputShape) {
     NNTRACE_COMP("quantizeFloat32ToQuant8");
diff --git a/nn/common/operations/QuantizedLSTM.cpp b/nn/common/operations/QuantizedLSTM.cpp
index 62060f9..7b9be03 100644
--- a/nn/common/operations/QuantizedLSTM.cpp
+++ b/nn/common/operations/QuantizedLSTM.cpp
@@ -20,6 +20,7 @@
 
 #include "CpuExecutor.h"
 #include "CpuOperationUtils.h"
+#include "HalInterfaces.h"
 
 #include "Tracing.h"
 
@@ -31,6 +32,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T>
 inline T* GetBuffer(RunTimeOperandInfo* operand) {
     return reinterpret_cast<T*>(operand->buffer);
diff --git a/nn/common/operations/QuantizedLSTM.h b/nn/common/operations/QuantizedLSTM.h
index 0d1070a..9a856be 100644
--- a/nn/common/operations/QuantizedLSTM.h
+++ b/nn/common/operations/QuantizedLSTM.h
@@ -29,10 +29,10 @@
 
 class QuantizedLSTMCell {
    public:
-    QuantizedLSTMCell(const android::hardware::neuralnetworks::V1_2::Operation& operation,
+    QuantizedLSTMCell(const hardware::neuralnetworks::V1_2::Operation& operation,
                       std::vector<RunTimeOperandInfo>& operands);
 
-    static bool prepare(const android::hardware::neuralnetworks::V1_2::Operation& operation,
+    static bool prepare(const hardware::neuralnetworks::V1_2::Operation& operation,
                         std::vector<RunTimeOperandInfo>& operands, Shape* cellStateShape,
                         Shape* outputShape);
     bool eval();
diff --git a/nn/common/operations/RNN.cpp b/nn/common/operations/RNN.cpp
index 2394961..dcb5928 100644
--- a/nn/common/operations/RNN.cpp
+++ b/nn/common/operations/RNN.cpp
@@ -27,6 +27,8 @@
 namespace android {
 namespace nn {
 
+using namespace hal;
+
 RNN::RNN(const Operation& operation,
          std::vector<RunTimeOperandInfo>& operands) {
   NNTRACE_TRANS("RNN::RNN");
diff --git a/nn/common/operations/RNN.h b/nn/common/operations/RNN.h
index b09f185..c0dbcc5 100644
--- a/nn/common/operations/RNN.h
+++ b/nn/common/operations/RNN.h
@@ -28,10 +28,12 @@
 
 class RNN {
    public:
-    RNN(const Operation& operation, std::vector<RunTimeOperandInfo>& operands);
+    RNN(const hardware::neuralnetworks::V1_2::Operation& operation,
+        std::vector<RunTimeOperandInfo>& operands);
 
-    static bool Prepare(const Operation& operation, std::vector<RunTimeOperandInfo>& operands,
-                        Shape* hiddenStateShape, Shape* outputShape);
+    static bool Prepare(const hardware::neuralnetworks::V1_2::Operation& operation,
+                        std::vector<RunTimeOperandInfo>& operands, Shape* hiddenStateShape,
+                        Shape* outputShape);
     bool Eval();
 
     static constexpr int kInputTensor = 0;
diff --git a/nn/common/operations/Reduce.cpp b/nn/common/operations/Reduce.cpp
index faa205e..3aa530c 100644
--- a/nn/common/operations/Reduce.cpp
+++ b/nn/common/operations/Reduce.cpp
@@ -42,6 +42,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T>
 inline bool compute(IOperationExecutionContext* context, T init, T func(T, T)) {
     const Shape inputShape = context->getInputShape(kInputTensor);
diff --git a/nn/common/operations/ResizeImageOps.cpp b/nn/common/operations/ResizeImageOps.cpp
index 453bf84..34ad208 100644
--- a/nn/common/operations/ResizeImageOps.cpp
+++ b/nn/common/operations/ResizeImageOps.cpp
@@ -29,6 +29,8 @@
 namespace android {
 namespace nn {
 
+using namespace hal;
+
 namespace resize_image {
 
 constexpr uint32_t kNumInputs = 4;
diff --git a/nn/common/operations/RoiAlign.cpp b/nn/common/operations/RoiAlign.cpp
index ddf7b8e..231f357 100644
--- a/nn/common/operations/RoiAlign.cpp
+++ b/nn/common/operations/RoiAlign.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "Operations"
 
 #include "CpuOperationUtils.h"
+#include "HalInterfaces.h"
 #include "OperationResolver.h"
 #include "OperationsUtils.h"
 #include "Tracing.h"
@@ -48,6 +49,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T_Input, typename T_Roi>
 inline bool roiAlignNhwc(const T_Input* inputData, const Shape& inputShape, const T_Roi* roiData,
                          const Shape& roiShape, const int32_t* batchSplitData,
diff --git a/nn/common/operations/RoiPooling.cpp b/nn/common/operations/RoiPooling.cpp
index bfcf78b..3c87b91 100644
--- a/nn/common/operations/RoiPooling.cpp
+++ b/nn/common/operations/RoiPooling.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "Operations"
 
 #include "CpuOperationUtils.h"
+#include "HalInterfaces.h"
 #include "OperationResolver.h"
 #include "OperationsUtils.h"
 
@@ -46,6 +47,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T_Input, typename T_Roi>
 inline bool roiPoolingNhwc(const T_Input* inputData, const Shape& inputShape, const T_Roi* roiData,
                            const Shape& roiShape, const int32_t* batchSplitData,
diff --git a/nn/common/operations/SVDF.cpp b/nn/common/operations/SVDF.cpp
index 669e92e..844361d 100644
--- a/nn/common/operations/SVDF.cpp
+++ b/nn/common/operations/SVDF.cpp
@@ -27,6 +27,8 @@
 namespace android {
 namespace nn {
 
+using namespace hal;
+
 SVDF::SVDF(const Operation& operation,
            std::vector<RunTimeOperandInfo>& operands) {
     NNTRACE_TRANS("SVDF::SVDF");
diff --git a/nn/common/operations/SVDF.h b/nn/common/operations/SVDF.h
index e7f8d47..257fd11 100644
--- a/nn/common/operations/SVDF.h
+++ b/nn/common/operations/SVDF.h
@@ -36,10 +36,12 @@
 
 class SVDF {
    public:
-    SVDF(const Operation& operation, std::vector<RunTimeOperandInfo>& operands);
+    SVDF(const hardware::neuralnetworks::V1_2::Operation& operation,
+         std::vector<RunTimeOperandInfo>& operands);
 
-    static bool Prepare(const Operation& operation, std::vector<RunTimeOperandInfo>& operands,
-                        Shape* stateShape, Shape* outputShape);
+    static bool Prepare(const hardware::neuralnetworks::V1_2::Operation& operation,
+                        std::vector<RunTimeOperandInfo>& operands, Shape* stateShape,
+                        Shape* outputShape);
     bool Eval();
 
     static constexpr int kInputTensor = 0;
diff --git a/nn/common/operations/Select.cpp b/nn/common/operations/Select.cpp
index 2a26c1e..e9b6645 100644
--- a/nn/common/operations/Select.cpp
+++ b/nn/common/operations/Select.cpp
@@ -35,6 +35,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T>
 bool compute(const bool8* conditionData, const Shape& conditionShape, const T* aData,
              const Shape& aShape, const T* bData, const Shape& bShape, T* outputData,
diff --git a/nn/common/operations/Slice.cpp b/nn/common/operations/Slice.cpp
index 4ecfcb5..fc28f7d 100644
--- a/nn/common/operations/Slice.cpp
+++ b/nn/common/operations/Slice.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "Operations"
 
 #include "CpuOperationUtils.h"
+#include "HalInterfaces.h"
 #include "IndexedShapeWrapper.h"
 #include "OperationResolver.h"
 
@@ -36,6 +37,8 @@
 constexpr uint32_t kNumOutputs = 1;
 constexpr uint32_t kOutputTensor = 0;
 
+using namespace hal;
+
 namespace {
 
 template <typename T>
diff --git a/nn/common/operations/Softmax.cpp b/nn/common/operations/Softmax.cpp
index 209f60e..a93fc86 100644
--- a/nn/common/operations/Softmax.cpp
+++ b/nn/common/operations/Softmax.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "Operations"
 
 #include "CpuOperationUtils.h"
+#include "HalInterfaces.h"
 #include "OperationResolver.h"
 
 #include <tensorflow/lite/kernels/internal/optimized/legacy_optimized_ops.h>
@@ -41,6 +42,8 @@
 
 namespace {
 
+using namespace hal;
+
 inline bool softmaxSlowFloat32(const float* inputData, const Shape& inputShape, const float beta,
                                int32_t axis, float* outputData, const Shape& outputShape) {
     NNTRACE_TRANS("softmaxFloatSlow32");
diff --git a/nn/common/operations/StridedSlice.cpp b/nn/common/operations/StridedSlice.cpp
index c8fba2d..0310567 100644
--- a/nn/common/operations/StridedSlice.cpp
+++ b/nn/common/operations/StridedSlice.cpp
@@ -19,6 +19,7 @@
 #define LOG_TAG "Operations"
 
 #include "CpuOperationUtils.h"
+#include "HalInterfaces.h"
 #include "Operations.h"
 
 #include <tensorflow/lite/kernels/internal/reference/legacy_reference_ops.h>
@@ -28,6 +29,8 @@
 namespace android {
 namespace nn {
 
+using namespace hal;
+
 bool stridedSliceGeneric(const uint8_t* inputData, const Shape& inputShape,
                          const int32_t* beginData, const int32_t* endData,
                          const int32_t* stridesData, int32_t beginMask, int32_t endMask,
diff --git a/nn/common/operations/Tile.cpp b/nn/common/operations/Tile.cpp
index e5f4a61..380f5ac 100644
--- a/nn/common/operations/Tile.cpp
+++ b/nn/common/operations/Tile.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "Operations"
 
 #include "Tile.h"
+#include "HalInterfaces.h"
 #include "Tracing.h"
 
 namespace android {
@@ -25,6 +26,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T>
 void CopyMultipleTimes(const T* in_data, int32_t in_size, int32_t multiplier, T* out_data) {
     for (int i = 0; i < multiplier; ++i) {
diff --git a/nn/common/operations/TopK_V2.cpp b/nn/common/operations/TopK_V2.cpp
index 5d377c0..010d380 100644
--- a/nn/common/operations/TopK_V2.cpp
+++ b/nn/common/operations/TopK_V2.cpp
@@ -18,6 +18,7 @@
 
 #include "TopK_V2.h"
 
+#include "HalInterfaces.h"
 #include "OperationsUtils.h"
 
 #include <algorithm>
@@ -28,6 +29,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T>
 bool evalGeneric(const T* inputData, const Shape& inputShape, const int32_t k, T* valuesData,
                  const Shape& /*valuesShape*/, int32_t* indicesData,
diff --git a/nn/common/operations/Transpose.cpp b/nn/common/operations/Transpose.cpp
index e72eb10..8ae0ccd 100644
--- a/nn/common/operations/Transpose.cpp
+++ b/nn/common/operations/Transpose.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "Operations"
 
 #include "CpuOperationUtils.h"
+#include "HalInterfaces.h"
 #include "OperationResolver.h"
 
 #include <tensorflow/lite/kernels/internal/optimized/legacy_optimized_ops.h>
@@ -39,6 +40,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T>
 bool transposeGeneric(const T* inputData, const Shape& inputShape, const int32_t* perm,
                       const Shape& permShape, T* outputData, const Shape& outputShape) {
diff --git a/nn/common/operations/TransposeConv2D.cpp b/nn/common/operations/TransposeConv2D.cpp
index e6ec1a6..42d6cf4 100644
--- a/nn/common/operations/TransposeConv2D.cpp
+++ b/nn/common/operations/TransposeConv2D.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "Operations"
 
 #include "CpuOperationUtils.h"
+#include "HalInterfaces.h"
 #include "OperationResolver.h"
 #include "Tracing.h"
 
@@ -39,6 +40,8 @@
 
 namespace {
 
+using namespace hal;
+
 // If possible we will use this static buffer for the tensor.
 constexpr size_t kStaticBufferSize = 1605632;
 char static_scratch_buffer[kStaticBufferSize];
diff --git a/nn/common/operations/UnidirectionalSequenceLSTM.cpp b/nn/common/operations/UnidirectionalSequenceLSTM.cpp
index f321169..abed464 100644
--- a/nn/common/operations/UnidirectionalSequenceLSTM.cpp
+++ b/nn/common/operations/UnidirectionalSequenceLSTM.cpp
@@ -83,6 +83,8 @@
 
 namespace {
 
+using namespace hal;
+
 inline bool hasTensor(IOperationExecutionContext* context, const uint32_t tensor) {
     return context->getInputBuffer(tensor) != nullptr;
 }
diff --git a/nn/common/operations/UnidirectionalSequenceRNN.cpp b/nn/common/operations/UnidirectionalSequenceRNN.cpp
index cf5c620..5747907 100644
--- a/nn/common/operations/UnidirectionalSequenceRNN.cpp
+++ b/nn/common/operations/UnidirectionalSequenceRNN.cpp
@@ -16,6 +16,7 @@
 
 #define LOG_TAG "Operations"
 
+#include "HalInterfaces.h"
 #include "OperationResolver.h"
 #include "RNN.h"
 
@@ -37,6 +38,8 @@
 
 namespace {
 
+using namespace hal;
+
 template <typename T>
 void transposeFirstTwoDims(const T* input, const Shape& inputShape, T* output) {
     const uint32_t firstDimSize = getSizeOfDimension(inputShape, 0);
diff --git a/nn/driver/sample/SampleDriver.cpp b/nn/driver/sample/SampleDriver.cpp
index 1b6960a..ab2c9db 100644
--- a/nn/driver/sample/SampleDriver.cpp
+++ b/nn/driver/sample/SampleDriver.cpp
@@ -36,6 +36,8 @@
 
 namespace {
 
+using namespace hal;
+
 using time_point = std::chrono::steady_clock::time_point;
 
 auto now() {
diff --git a/nn/driver/sample/SampleDriver.h b/nn/driver/sample/SampleDriver.h
index 47572e8..f0a14d5 100644
--- a/nn/driver/sample/SampleDriver.h
+++ b/nn/driver/sample/SampleDriver.h
@@ -27,15 +27,15 @@
 namespace nn {
 namespace sample_driver {
 
-using ::android::hardware::MQDescriptorSync;
-using HidlToken = hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
+using hardware::MQDescriptorSync;
+using HidlToken = hal::hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
 
 // Base class used to create sample drivers for the NN HAL.  This class
 // provides some implementation of the more common functions.
 //
 // Since these drivers simulate hardware, they must run the computations
 // on the CPU.  An actual driver would not do that.
-class SampleDriver : public IDevice {
+class SampleDriver : public hal::IDevice {
    public:
     SampleDriver(const char* name,
                  const IOperationResolver* operationResolver = BuiltinOperationResolver::get())
@@ -43,29 +43,32 @@
         android::nn::initVLogMask();
     }
     ~SampleDriver() override {}
-    Return<void> getCapabilities(getCapabilities_cb cb) override;
-    Return<void> getCapabilities_1_1(getCapabilities_1_1_cb cb) override;
-    Return<void> getVersionString(getVersionString_cb cb) override;
-    Return<void> getType(getType_cb cb) override;
-    Return<void> getSupportedExtensions(getSupportedExtensions_cb) override;
-    Return<void> getSupportedOperations(const V1_0::Model& model,
-                                        getSupportedOperations_cb cb) override;
-    Return<void> getSupportedOperations_1_1(const V1_1::Model& model,
-                                            getSupportedOperations_1_1_cb cb) override;
-    Return<void> getNumberOfCacheFilesNeeded(getNumberOfCacheFilesNeeded_cb cb) override;
-    Return<ErrorStatus> prepareModel(const V1_0::Model& model,
-                                     const sp<V1_0::IPreparedModelCallback>& callback) override;
-    Return<ErrorStatus> prepareModel_1_1(const V1_1::Model& model, ExecutionPreference preference,
-                                         const sp<V1_0::IPreparedModelCallback>& callback) override;
-    Return<ErrorStatus> prepareModel_1_2(const V1_2::Model& model, ExecutionPreference preference,
-                                         const hidl_vec<hidl_handle>& modelCache,
-                                         const hidl_vec<hidl_handle>& dataCache,
-                                         const HidlToken& token,
-                                         const sp<V1_2::IPreparedModelCallback>& callback) override;
-    Return<ErrorStatus> prepareModelFromCache(
-            const hidl_vec<hidl_handle>& modelCache, const hidl_vec<hidl_handle>& dataCache,
-            const HidlToken& token, const sp<V1_2::IPreparedModelCallback>& callback) override;
-    Return<DeviceStatus> getStatus() override;
+    hal::Return<void> getCapabilities(getCapabilities_cb cb) override;
+    hal::Return<void> getCapabilities_1_1(getCapabilities_1_1_cb cb) override;
+    hal::Return<void> getVersionString(getVersionString_cb cb) override;
+    hal::Return<void> getType(getType_cb cb) override;
+    hal::Return<void> getSupportedExtensions(getSupportedExtensions_cb) override;
+    hal::Return<void> getSupportedOperations(const hal::V1_0::Model& model,
+                                             getSupportedOperations_cb cb) override;
+    hal::Return<void> getSupportedOperations_1_1(const hal::V1_1::Model& model,
+                                                 getSupportedOperations_1_1_cb cb) override;
+    hal::Return<void> getNumberOfCacheFilesNeeded(getNumberOfCacheFilesNeeded_cb cb) override;
+    hal::Return<hal::ErrorStatus> prepareModel(
+            const hal::V1_0::Model& model,
+            const sp<hal::V1_0::IPreparedModelCallback>& callback) override;
+    hal::Return<hal::ErrorStatus> prepareModel_1_1(
+            const hal::V1_1::Model& model, hal::ExecutionPreference preference,
+            const sp<hal::V1_0::IPreparedModelCallback>& callback) override;
+    hal::Return<hal::ErrorStatus> prepareModel_1_2(
+            const hal::V1_2::Model& model, hal::ExecutionPreference preference,
+            const hal::hidl_vec<hal::hidl_handle>& modelCache,
+            const hal::hidl_vec<hal::hidl_handle>& dataCache, const HidlToken& token,
+            const sp<hal::V1_2::IPreparedModelCallback>& callback) override;
+    hal::Return<hal::ErrorStatus> prepareModelFromCache(
+            const hal::hidl_vec<hal::hidl_handle>& modelCache,
+            const hal::hidl_vec<hal::hidl_handle>& dataCache, const HidlToken& token,
+            const sp<hal::V1_2::IPreparedModelCallback>& callback) override;
+    hal::Return<hal::DeviceStatus> getStatus() override;
 
     // Starts and runs the driver service.  Typically called from main().
     // This will return only once the service shuts down.
@@ -78,26 +81,28 @@
     const IOperationResolver* mOperationResolver;
 };
 
-class SamplePreparedModel : public IPreparedModel {
+class SamplePreparedModel : public hal::IPreparedModel {
    public:
-    SamplePreparedModel(const Model& model, const SampleDriver* driver)
+    SamplePreparedModel(const hal::Model& model, const SampleDriver* driver)
         : mModel(model), mDriver(driver) {}
     ~SamplePreparedModel() override {}
     bool initialize();
-    Return<ErrorStatus> execute(const Request& request,
-                                const sp<V1_0::IExecutionCallback>& callback) override;
-    Return<ErrorStatus> execute_1_2(const Request& request, MeasureTiming measure,
-                                    const sp<V1_2::IExecutionCallback>& callback) override;
-    Return<void> executeSynchronously(const Request& request, MeasureTiming measure,
-                                      executeSynchronously_cb cb) override;
-    Return<void> configureExecutionBurst(
-            const sp<V1_2::IBurstCallback>& callback,
-            const MQDescriptorSync<V1_2::FmqRequestDatum>& requestChannel,
-            const MQDescriptorSync<V1_2::FmqResultDatum>& resultChannel,
+    hal::Return<hal::ErrorStatus> execute(
+            const hal::Request& request,
+            const sp<hal::V1_0::IExecutionCallback>& callback) override;
+    hal::Return<hal::ErrorStatus> execute_1_2(
+            const hal::Request& request, hal::MeasureTiming measure,
+            const sp<hal::V1_2::IExecutionCallback>& callback) override;
+    hal::Return<void> executeSynchronously(const hal::Request& request, hal::MeasureTiming measure,
+                                           executeSynchronously_cb cb) override;
+    hal::Return<void> configureExecutionBurst(
+            const sp<hal::V1_2::IBurstCallback>& callback,
+            const MQDescriptorSync<hal::V1_2::FmqRequestDatum>& requestChannel,
+            const MQDescriptorSync<hal::V1_2::FmqResultDatum>& resultChannel,
             configureExecutionBurst_cb cb) override;
 
    private:
-    Model mModel;
+    hal::Model mModel;
     const SampleDriver* mDriver;
     std::vector<RunTimePoolInfo> mPoolInfos;
 };
diff --git a/nn/driver/sample/SampleDriverFloatFast.cpp b/nn/driver/sample/SampleDriverFloatFast.cpp
index 3908ee5..329408f 100644
--- a/nn/driver/sample/SampleDriverFloatFast.cpp
+++ b/nn/driver/sample/SampleDriverFloatFast.cpp
@@ -30,6 +30,8 @@
 namespace nn {
 namespace sample_driver {
 
+using namespace hal;
+
 class SampleDriverFloatFast : public SampleDriver {
 public:
     SampleDriverFloatFast() : SampleDriver("sample-float-fast") {}
diff --git a/nn/driver/sample/SampleDriverFloatSlow.cpp b/nn/driver/sample/SampleDriverFloatSlow.cpp
index 09d44f3..c5571eb 100644
--- a/nn/driver/sample/SampleDriverFloatSlow.cpp
+++ b/nn/driver/sample/SampleDriverFloatSlow.cpp
@@ -30,6 +30,8 @@
 namespace nn {
 namespace sample_driver {
 
+using namespace hal;
+
 class SampleDriverFloatSlow : public SampleDriver {
 public:
     SampleDriverFloatSlow() : SampleDriver("sample-float-slow") {}
diff --git a/nn/driver/sample/SampleDriverFull.cpp b/nn/driver/sample/SampleDriverFull.cpp
index fb7a613..eb7fa8d 100644
--- a/nn/driver/sample/SampleDriverFull.cpp
+++ b/nn/driver/sample/SampleDriverFull.cpp
@@ -18,7 +18,6 @@
 
 #include "SampleDriverFull.h"
 
-#include "HalInterfaces.h"
 #include "Utils.h"
 #include "ValidateHal.h"
 
@@ -26,6 +25,8 @@
 namespace nn {
 namespace sample_driver {
 
+using namespace hal;
+
 Return<void> SampleDriverFull::getCapabilities_1_2(getCapabilities_1_2_cb cb) {
     android::nn::initVLogMask();
     VLOG(DRIVER) << "getCapabilities_1_2()";
diff --git a/nn/driver/sample/SampleDriverFull.h b/nn/driver/sample/SampleDriverFull.h
index fd71285..f3bdbc6 100644
--- a/nn/driver/sample/SampleDriverFull.h
+++ b/nn/driver/sample/SampleDriverFull.h
@@ -17,6 +17,7 @@
 #ifndef FRAMEWORKS_ML_DRIVER_SAMPLE_SAMPLE_DRIVER_FULL_H
 #define FRAMEWORKS_ML_DRIVER_SAMPLE_SAMPLE_DRIVER_FULL_H
 
+#include "HalInterfaces.h"
 #include "SampleDriver.h"
 
 namespace android {
@@ -25,13 +26,14 @@
 
 class SampleDriverFull : public SampleDriver {
    public:
-    SampleDriverFull(const char* name, PerformanceInfo perf) : SampleDriver(name), mPerf(perf) {}
-    Return<void> getCapabilities_1_2(getCapabilities_1_2_cb cb) override;
-    Return<void> getSupportedOperations_1_2(const V1_2::Model& model,
-                                            getSupportedOperations_1_2_cb cb) override;
+    SampleDriverFull(const char* name, hal::PerformanceInfo perf)
+        : SampleDriver(name), mPerf(perf) {}
+    hal::Return<void> getCapabilities_1_2(getCapabilities_1_2_cb cb) override;
+    hal::Return<void> getSupportedOperations_1_2(const hal::V1_2::Model& model,
+                                                 getSupportedOperations_1_2_cb cb) override;
 
    private:
-    PerformanceInfo mPerf;
+    hal::PerformanceInfo mPerf;
 };
 
 }  // namespace sample_driver
diff --git a/nn/driver/sample/SampleDriverMinimal.cpp b/nn/driver/sample/SampleDriverMinimal.cpp
index b4dc743..6ff5964 100644
--- a/nn/driver/sample/SampleDriverMinimal.cpp
+++ b/nn/driver/sample/SampleDriverMinimal.cpp
@@ -31,6 +31,8 @@
 namespace nn {
 namespace sample_driver {
 
+using namespace hal;
+
 class SampleDriverMinimal : public SampleDriver {
 public:
     SampleDriverMinimal() : SampleDriver("sample-minimal") {}
diff --git a/nn/driver/sample/SampleDriverQuant.cpp b/nn/driver/sample/SampleDriverQuant.cpp
index 0590d5d..8e4c185 100644
--- a/nn/driver/sample/SampleDriverQuant.cpp
+++ b/nn/driver/sample/SampleDriverQuant.cpp
@@ -30,6 +30,8 @@
 namespace nn {
 namespace sample_driver {
 
+using namespace hal;
+
 class SampleDriverQuant : public SampleDriver {
 public:
     SampleDriverQuant() : SampleDriver("sample-quant") {}
diff --git a/nn/runtime/Callbacks.cpp b/nn/runtime/Callbacks.cpp
index 4fd4f0b..44c97fa 100644
--- a/nn/runtime/Callbacks.cpp
+++ b/nn/runtime/Callbacks.cpp
@@ -19,10 +19,11 @@
 #include "Callbacks.h"
 
 #include <android-base/logging.h>
-
 #include <limits>
 
-namespace android::hardware::neuralnetworks::V1_2::implementation {
+namespace android::nn {
+
+using namespace hal;
 
 constexpr Timing kNoTiming = {.timeOnDevice = std::numeric_limits<uint64_t>::max(),
                               .timeInDriver = std::numeric_limits<uint64_t>::max()};
@@ -206,4 +207,4 @@
     mCondition.notify_all();
 }
 
-}  // namespace android::hardware::neuralnetworks::V1_2::implementation
+}  // namespace android::nn
diff --git a/nn/runtime/Callbacks.h b/nn/runtime/Callbacks.h
index 9ed8e65..7e7c23f 100644
--- a/nn/runtime/Callbacks.h
+++ b/nn/runtime/Callbacks.h
@@ -17,13 +17,9 @@
 #ifndef FRAMEWORKS_ML_RUNTIME_CALLBACKS_H
 #define FRAMEWORKS_ML_RUNTIME_CALLBACKS_H
 
+#include "HalInterfaces.h"
+
 #include <android-base/thread_annotations.h>
-#include <android/hardware/neuralnetworks/1.0/IExecutionCallback.h>
-#include <android/hardware/neuralnetworks/1.0/IPreparedModelCallback.h>
-#include <android/hardware/neuralnetworks/1.2/IExecutionCallback.h>
-#include <android/hardware/neuralnetworks/1.2/IPreparedModelCallback.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
 #include <condition_variable>
 #include <functional>
 #include <mutex>
@@ -47,9 +43,7 @@
  * instead.
  */
 
-namespace android::hardware::neuralnetworks::V1_2::implementation {
-
-using V1_0::ErrorStatus;
+namespace android::nn {
 
 /**
  * The PreparedModelCallback class is used to receive the error status of
@@ -65,7 +59,7 @@
  *
  * This callback object is passed as an argument to IDevice::prepareModel*.
  */
-class PreparedModelCallback : public IPreparedModelCallback {
+class PreparedModelCallback : public hal::IPreparedModelCallback {
    public:
     /**
      * IPreparedModelCallback::notify marks the callback object with the return
@@ -90,7 +84,8 @@
      * @param preparedModel Returned model that has been prepared for execution,
      *     nullptr if the model was unable to be prepared.
      */
-    Return<void> notify(ErrorStatus status, const sp<V1_0::IPreparedModel>& preparedModel) override;
+    hal::Return<void> notify(hal::ErrorStatus status,
+                             const sp<hal::V1_0::IPreparedModel>& preparedModel) override;
 
     /**
      * IPreparedModelCallback::notify_1_2 marks the callback object with the
@@ -115,8 +110,8 @@
      * @param preparedModel Returned model that has been prepared for execution,
      *     nullptr if the model was unable to be prepared.
      */
-    Return<void> notify_1_2(ErrorStatus status,
-                            const sp<V1_2::IPreparedModel>& preparedModel) override;
+    hal::Return<void> notify_1_2(hal::ErrorStatus status,
+                                 const sp<hal::V1_2::IPreparedModel>& preparedModel) override;
 
     /**
      * PreparedModelCallback::wait blocks until notify* has been called on the
@@ -137,7 +132,7 @@
      *     - GENERAL_FAILURE if there is an unspecified error
      *     - INVALID_ARGUMENT if the input model is invalid
      */
-    ErrorStatus getStatus() const;
+    hal::ErrorStatus getStatus() const;
 
     /**
      * Retrieves the model that has been prepared for execution from the
@@ -149,14 +144,14 @@
      * @return preparedModel Returned model that has been prepared for
      *     execution, nullptr if the model was unable to be prepared.
      */
-    sp<V1_0::IPreparedModel> getPreparedModel() const;
+    sp<hal::V1_0::IPreparedModel> getPreparedModel() const;
 
    private:
     mutable std::mutex mMutex;
     mutable std::condition_variable mCondition;
     bool mNotified GUARDED_BY(mMutex) = false;
-    ErrorStatus mErrorStatus = ErrorStatus::GENERAL_FAILURE;
-    sp<V1_0::IPreparedModel> mPreparedModel;
+    hal::ErrorStatus mErrorStatus = hal::ErrorStatus::GENERAL_FAILURE;
+    sp<hal::V1_0::IPreparedModel> mPreparedModel;
 };
 
 /**
@@ -173,9 +168,9 @@
  *
  * This callback object is passed as an argument to IPreparedModel::execute*.
  */
-class ExecutionCallback : public IExecutionCallback {
+class ExecutionCallback : public hal::IExecutionCallback {
     using ExecutionFinish =
-            std::function<ErrorStatus(ErrorStatus, const std::vector<OutputShape>&)>;
+            std::function<hal::ErrorStatus(hal::ErrorStatus, const std::vector<hal::OutputShape>&)>;
 
    public:
     /**
@@ -201,7 +196,7 @@
      *         enough to store the resultant values
      *     - INVALID_ARGUMENT if the input request is invalid
      */
-    Return<void> notify(ErrorStatus status) override;
+    hal::Return<void> notify(hal::ErrorStatus status) override;
 
     /**
      * IExecutionCallback::notify_1_2 marks the callback object with the results
@@ -236,12 +231,14 @@
      *     reported as UINT64_MAX. A driver may choose to report any time as
      *     UINT64_MAX, indicating that particular measurement is not available.
      */
-    Return<void> notify_1_2(ErrorStatus status, const hidl_vec<OutputShape>& outputShapes,
-                            const Timing& timing) override;
+    hal::Return<void> notify_1_2(hal::ErrorStatus status,
+                                 const hal::hidl_vec<hal::OutputShape>& outputShapes,
+                                 const hal::Timing& timing) override;
 
     // An overload of the latest notify interface to hide the version from ExecutionBuilder.
-    Return<void> notify(ErrorStatus status, const hidl_vec<OutputShape>& outputShapes,
-                        const Timing& timing) {
+    hal::Return<void> notify(hal::ErrorStatus status,
+                             const hal::hidl_vec<hal::OutputShape>& outputShapes,
+                             const hal::Timing& timing) {
         return notify_1_2(status, outputShapes, timing);
     }
 
@@ -270,7 +267,7 @@
      *     - INVALID_ARGUMENT if one of the input arguments to prepareModel is
      *         invalid
      */
-    ErrorStatus getStatus() const;
+    hal::ErrorStatus getStatus() const;
 
     /**
      * Retrieves the output shapes returned from the asynchronous task launched
@@ -292,7 +289,7 @@
      *     OUTPUT_INSUFFICIENT_SIZE, or if the status is NONE and the model has
      *     at least one output operand that is not fully-specified.
      */
-    const std::vector<OutputShape>& getOutputShapes() const;
+    const std::vector<hal::OutputShape>& getOutputShapes() const;
 
     /**
      * Retrieves the duration of execution of the asynchronous task launched by
@@ -306,7 +303,7 @@
      * @return timing Duration of the execution. Every time must be UINT64_MAX
      *     unless the status is NONE.
      */
-    Timing getTiming() const;
+    hal::Timing getTiming() const;
 
     /**
      * ExecutionCallback::bindThread binds a thread to the ExecutionCallback
@@ -360,8 +357,9 @@
      * before any call to wait or get* return. It then enables all prior and
      * future wait calls on the ExecutionCallback object to proceed.
      */
-    void notifyInternal(ErrorStatus errorStatus, const hidl_vec<OutputShape>& outputShapes,
-                        const Timing& timing);
+    void notifyInternal(hal::ErrorStatus errorStatus,
+                        const hal::hidl_vec<hal::OutputShape>& outputShapes,
+                        const hal::Timing& timing);
 
     // members
     mutable std::mutex mMutex;
@@ -369,18 +367,11 @@
     mutable std::thread mThread GUARDED_BY(mMutex);
     ExecutionFinish mOnFinish GUARDED_BY(mMutex);
     bool mNotified GUARDED_BY(mMutex) = false;
-    ErrorStatus mErrorStatus = ErrorStatus::GENERAL_FAILURE;
-    std::vector<OutputShape> mOutputShapes = {};
-    Timing mTiming = {};
+    hal::ErrorStatus mErrorStatus = hal::ErrorStatus::GENERAL_FAILURE;
+    std::vector<hal::OutputShape> mOutputShapes;
+    hal::Timing mTiming = {};
 };
 
-}  // namespace android::hardware::neuralnetworks::V1_2::implementation
-
-namespace android::nn {
-
-using ::android::hardware::neuralnetworks::V1_2::implementation::ExecutionCallback;
-using ::android::hardware::neuralnetworks::V1_2::implementation::PreparedModelCallback;
-
 }  // namespace android::nn
 
 #endif  // FRAMEWORKS_ML_RUNTIME_CALLBACKS_H
diff --git a/nn/runtime/ExecutionBuilder.cpp b/nn/runtime/ExecutionBuilder.cpp
index 06ee244..57d8716 100644
--- a/nn/runtime/ExecutionBuilder.cpp
+++ b/nn/runtime/ExecutionBuilder.cpp
@@ -36,6 +36,8 @@
 namespace android {
 namespace nn {
 
+using namespace hal;
+
 using HidlToken = hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
 
 const Timing kNoTiming = {.timeOnDevice = UINT64_MAX, .timeInDriver = UINT64_MAX};
diff --git a/nn/runtime/ExecutionBuilder.h b/nn/runtime/ExecutionBuilder.h
index 5aa9397..f2985c8 100644
--- a/nn/runtime/ExecutionBuilder.h
+++ b/nn/runtime/ExecutionBuilder.h
@@ -28,9 +28,6 @@
 #include <unordered_map>
 #include <vector>
 
-using ::android::hardware::neuralnetworks::V1_2::implementation::ExecutionCallback;
-using ::android::hardware::neuralnetworks::V1_2::implementation::PreparedModelCallback;
-
 namespace android {
 namespace nn {
 
@@ -56,18 +53,18 @@
     //   locationAndLength.{poolIndex, offset, length} is valid.
     //   dimensions is valid.
     enum { POINTER, MEMORY, HAS_NO_VALUE, UNSPECIFIED } state = UNSPECIFIED;
-    DataLocation locationAndLength;
+    hal::DataLocation locationAndLength;
     std::vector<uint32_t> dimensions;
     void* buffer;
     bool isSufficient = true;
 
-    int setFromPointer(const Operand& operand, const ANeuralNetworksOperandType* type, void* buffer,
-                       uint32_t length);
-    int setFromMemory(const Operand& operand, const ANeuralNetworksOperandType* type,
+    int setFromPointer(const hal::Operand& operand, const ANeuralNetworksOperandType* type,
+                       void* buffer, uint32_t length);
+    int setFromMemory(const hal::Operand& operand, const ANeuralNetworksOperandType* type,
                       uint32_t poolIndex, uint32_t offset, uint32_t length);
-    int setFromTemporaryMemory(const Operand& operand, uint32_t poolIndex, uint32_t offset,
+    int setFromTemporaryMemory(const hal::Operand& operand, uint32_t poolIndex, uint32_t offset,
                                uint32_t length);
-    int updateDimensionInfo(const Operand& operand, const ANeuralNetworksOperandType* newType);
+    int updateDimensionInfo(const hal::Operand& operand, const ANeuralNetworksOperandType* newType);
 };
 
 class ExecutionBuilder {
@@ -96,19 +93,20 @@
     int burstCompute(BurstBuilder* burst) { return compute(nullptr, burst); }
 
     // Initialize output dimensional information from ModelArgumentInfo.
-    void initializeOutputShapes(std::vector<OutputShape>* outputShapes) const;
+    void initializeOutputShapes(std::vector<hal::OutputShape>* outputShapes) const;
 
     int getOutputOperandDimensions(uint32_t index, uint32_t* dimensions);
     int getOutputOperandRank(uint32_t index, uint32_t* rank);
 
     // Handshake with lower-level execution support
     bool measureTiming() const { return mMeasureTiming; }
-    void reportTiming(Timing timing) { mTiming = timing; }
+    void reportTiming(hal::Timing timing) { mTiming = timing; }
 
     const CompilationBuilder* getCompilation() const { return mCompilation; }
     const ModelBuilder* getModel() const { return mModel; }
 
-    ErrorStatus finish(ErrorStatus error, const std::vector<OutputShape>& outputShapes);
+    hal::ErrorStatus finish(hal::ErrorStatus error,
+                            const std::vector<hal::OutputShape>& outputShapes);
 
    private:
     // If a callback is provided, then this is asynchronous. If a callback is
@@ -124,7 +122,7 @@
     const CompilationBuilder* mCompilation;
 
     // Update output dimensional information from OutputShape to ModelArgumentInfo.
-    bool updateOutputShapes(const std::vector<OutputShape>& outputShapes);
+    bool updateOutputShapes(const std::vector<hal::OutputShape>& outputShapes);
 
     const ModelBuilder* mModel;
     const ExecutionPlan* mPlan;
@@ -151,7 +149,7 @@
     bool mMeasureTiming = false;
 
     // Timing reported from the driver
-    Timing mTiming = {};
+    hal::Timing mTiming = {};
 
     // Properties cannot be set once the execution has started.
     std::atomic_bool mStarted = false;
@@ -186,7 +184,8 @@
     void mapInputsAndOutputsTrivially();
 
     // Update output shapes returned from ExecutionCallback to ExecutionBuilder.
-    bool updateOutputShapes(const std::vector<OutputShape>& from, std::vector<OutputShape>* to);
+    bool updateOutputShapes(const std::vector<hal::OutputShape>& from,
+                            std::vector<hal::OutputShape>* to);
 
     // Map inputs and outputs from ExecutionBuilder to StepExecutor,
     // one at a time.  Note that these are input/output indexes, not
@@ -238,7 +237,7 @@
     void mapInputOrOutput(const ModelArgumentInfo& builderInputOrOutput,
                           ModelArgumentInfo* executorInputOrOutput);
 
-    int setInputOrOutputFromTemporaryMemory(const Operand& inputOrOutputOperand,
+    int setInputOrOutputFromTemporaryMemory(const hal::Operand& inputOrOutputOperand,
                                             const Memory* memory, uint32_t offset,
                                             ModelArgumentInfo* inputOrOutputInfo);
 
diff --git a/nn/runtime/ExecutionPlan.cpp b/nn/runtime/ExecutionPlan.cpp
index 9dde782..fd0f8a0 100644
--- a/nn/runtime/ExecutionPlan.cpp
+++ b/nn/runtime/ExecutionPlan.cpp
@@ -47,13 +47,15 @@
 #include <utility>
 #include <vector>
 
-using HidlToken = hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
-
 namespace android {
 namespace nn {
 
 namespace {
 
+using namespace hal;
+
+using HidlToken = hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
+
 // Opens cache file by filename and sets the handle to the opened fd. Returns false on fail. The
 // handle is expected to come in as empty, and is only set to a fd when the function returns true.
 // The file descriptor is always opened with both read and write permission.
diff --git a/nn/runtime/Manager.cpp b/nn/runtime/Manager.cpp
index d98ddcf..a5ecc89 100644
--- a/nn/runtime/Manager.cpp
+++ b/nn/runtime/Manager.cpp
@@ -30,12 +30,13 @@
 #include <algorithm>
 #include <functional>
 
-using ::android::hardware::neuralnetworks::V1_2::implementation::ExecutionCallback;
-using HidlToken = hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
-
 namespace android {
 namespace nn {
 
+using namespace hal;
+
+using HidlToken = hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
+
 bool Device::isCachingSupported() const {
     auto pair = getNumberOfCacheFilesNeeded();
     // Caching is supported if either of numModelCache or numDataCache is greater than 0.
diff --git a/nn/runtime/Manager.h b/nn/runtime/Manager.h
index dc84ef5..729b296 100644
--- a/nn/runtime/Manager.h
+++ b/nn/runtime/Manager.h
@@ -42,7 +42,7 @@
     virtual const char* getVersionString() const = 0;
     virtual int64_t getFeatureLevel() = 0;
     virtual int32_t getType() const = 0;
-    virtual hidl_vec<Extension> getSupportedExtensions() const = 0;
+    virtual hal::hidl_vec<hal::Extension> getSupportedExtensions() const = 0;
 
     // If hidlModel is not compliant with the HAL version of the driver device,
     // then the behavior depends on whether or not a non-nullptr slicer is
@@ -54,26 +54,29 @@
     // operations may be supported.
     //
     // See the IModelSlicer class in Utils.h for more details.
-    virtual void getSupportedOperations(const Model& hidlModel, IModelSlicer* slicer,
-                                        hidl_vec<bool>* supportedOperations) = 0;
-    void getSupportedOperations(const Model& hidlModel, hidl_vec<bool>* supportedOperations) {
+    virtual void getSupportedOperations(const hal::Model& hidlModel, IModelSlicer* slicer,
+                                        hal::hidl_vec<bool>* supportedOperations) = 0;
+    void getSupportedOperations(const hal::Model& hidlModel,
+                                hal::hidl_vec<bool>* supportedOperations) {
         return getSupportedOperations(hidlModel, nullptr, supportedOperations);
     }
 
-    virtual PerformanceInfo getPerformance(OperandType type) const = 0;
-    virtual PerformanceInfo getRelaxedFloat32toFloat16PerformanceScalar() const = 0;
-    virtual PerformanceInfo getRelaxedFloat32toFloat16PerformanceTensor() const = 0;
+    virtual hal::PerformanceInfo getPerformance(hal::OperandType type) const = 0;
+    virtual hal::PerformanceInfo getRelaxedFloat32toFloat16PerformanceScalar() const = 0;
+    virtual hal::PerformanceInfo getRelaxedFloat32toFloat16PerformanceTensor() const = 0;
     virtual std::pair<uint32_t, uint32_t> getNumberOfCacheFilesNeeded() const = 0;
     bool isCachingSupported() const;
 
     virtual int prepareModel(
-            const Model& hidlModel, ExecutionPreference executionPreference,
-            const hidl_vec<hidl_handle>& modelCache, const hidl_vec<hidl_handle>& dataCache,
-            const hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>& token,
+            const hal::Model& hidlModel, hal::ExecutionPreference executionPreference,
+            const hal::hidl_vec<hal::hidl_handle>& modelCache,
+            const hal::hidl_vec<hal::hidl_handle>& dataCache,
+            const hal::hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>& token,
             std::shared_ptr<VersionedIPreparedModel>* preparedModel) = 0;
     virtual int prepareModelFromCache(
-            const hidl_vec<hidl_handle>& modelCache, const hidl_vec<hidl_handle>& dataCache,
-            const hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>& token,
+            const hal::hidl_vec<hal::hidl_handle>& modelCache,
+            const hal::hidl_vec<hal::hidl_handle>& dataCache,
+            const hal::hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>& token,
             std::shared_ptr<VersionedIPreparedModel>* preparedModel) = 0;
 };
 
@@ -134,7 +137,7 @@
     }
 
     // Register a test device.
-    void forTest_registerDevice(const char* name, const sp<V1_0::IDevice>& device) {
+    void forTest_registerDevice(const char* name, const sp<hal::V1_0::IDevice>& device) {
         registerDevice(name, device);
     }
 
@@ -147,7 +150,7 @@
 
     // Make a test device
     static std::shared_ptr<Device> forTest_makeDriverDevice(const std::string& name,
-                                                            const sp<V1_0::IDevice>& device);
+                                                            const sp<hal::V1_0::IDevice>& device);
 
     bool forTest_isCpuDevice(const ANeuralNetworksDevice* device) const {
         return reinterpret_cast<const Device*>(device) == getCpuDevice().get();
@@ -158,7 +161,7 @@
     DeviceManager();
 
     // Adds a device for the manager to use.
-    void registerDevice(const char* name, const sp<V1_0::IDevice>& device);
+    void registerDevice(const char* name, const sp<hal::V1_0::IDevice>& device);
 
     void findAvailableDevices();
 
diff --git a/nn/runtime/Memory.cpp b/nn/runtime/Memory.cpp
index 2748850..a2e3de5 100644
--- a/nn/runtime/Memory.cpp
+++ b/nn/runtime/Memory.cpp
@@ -19,13 +19,14 @@
 #include "Memory.h"
 
 #include "ExecutionBurstController.h"
-#include "HalInterfaces.h"
 #include "MemoryUtils.h"
 #include "Utils.h"
 
 namespace android {
 namespace nn {
 
+using namespace hal;
+
 Memory::~Memory() {
     for (const auto [ptr, weakBurst] : mUsedBy) {
         if (const std::shared_ptr<ExecutionBurstController> burst = weakBurst.lock()) {
diff --git a/nn/runtime/Memory.h b/nn/runtime/Memory.h
index bacfce1..ef459a5 100644
--- a/nn/runtime/Memory.h
+++ b/nn/runtime/Memory.h
@@ -17,6 +17,7 @@
 #ifndef FRAMEWORKS_ML_RUNTIME_MEMORY_H
 #define FRAMEWORKS_ML_RUNTIME_MEMORY_H
 
+#include "HalInterfaces.h"
 #include "NeuralNetworks.h"
 #include "Utils.h"
 
@@ -47,7 +48,7 @@
     // Creates a shared memory object of the size specified in bytes.
     int create(uint32_t size);
 
-    hardware::hidl_memory getHidlMemory() const { return mHidlMemory; }
+    hal::hidl_memory getHidlMemory() const { return mHidlMemory; }
 
     // Returns a pointer to the underlying memory of this memory object.
     // The function will fail if the memory is not CPU accessible and nullptr
@@ -73,8 +74,8 @@
    protected:
     // The hidl_memory handle for this shared memory.  We will pass this value when
     // communicating with the drivers.
-    hardware::hidl_memory mHidlMemory;
-    sp<IMemory> mMemory;
+    hal::hidl_memory mHidlMemory;
+    sp<hal::IMemory> mMemory;
 
     mutable std::mutex mMutex;
     // mUsedBy is essentially a set of burst objects which use this Memory
@@ -129,10 +130,10 @@
         const native_handle_t* handle = AHardwareBuffer_getNativeHandle(ahwb);
         mHardwareBuffer = ahwb;
         if (mBufferDesc.format == AHARDWAREBUFFER_FORMAT_BLOB) {
-            mHidlMemory = hidl_memory("hardware_buffer_blob", handle, mBufferDesc.width);
+            mHidlMemory = hal::hidl_memory("hardware_buffer_blob", handle, mBufferDesc.width);
         } else {
             // memory size is not used.
-            mHidlMemory = hidl_memory("hardware_buffer", handle, 0);
+            mHidlMemory = hal::hidl_memory("hardware_buffer", handle, 0);
         }
         return ANEURALNETWORKS_NO_ERROR;
     };
diff --git a/nn/runtime/ModelBuilder.cpp b/nn/runtime/ModelBuilder.cpp
index b57937d..60d96c3 100644
--- a/nn/runtime/ModelBuilder.cpp
+++ b/nn/runtime/ModelBuilder.cpp
@@ -31,6 +31,8 @@
 namespace android {
 namespace nn {
 
+using namespace hal;
+
 // The maximum number of operands and operations that a model may have.
 const uint32_t MAX_NUMBER_OF_OPERANDS = 0xFFFFFFFE;
 const uint32_t MAX_NUMBER_OF_OPERATIONS = 0xFFFFFFFE;
diff --git a/nn/runtime/ModelBuilder.h b/nn/runtime/ModelBuilder.h
index 6a2dc62..5e5a12d 100644
--- a/nn/runtime/ModelBuilder.h
+++ b/nn/runtime/ModelBuilder.h
@@ -68,7 +68,7 @@
                           const std::vector<std::shared_ptr<Device>>& devices,
                           bool explicitDeviceList = false);
 
-    Model makeHidlModel() const;
+    hal::Model makeHidlModel() const;
 
     uint32_t operandCount() const {
         // We don't allow more than uint32_t worth of operands
@@ -82,16 +82,18 @@
     uint32_t outputCount() const { return static_cast<uint32_t>(mOutputIndexes.size()); }
     uint32_t getInputOperandIndex(uint32_t i) const { return mInputIndexes[i]; }
     const std::vector<uint32_t>& getInputOperandIndexes() const { return mInputIndexes; }
-    const Operand& getInputOperand(uint32_t i) const { return mOperands[getInputOperandIndex(i)]; }
+    const hal::Operand& getInputOperand(uint32_t i) const {
+        return mOperands[getInputOperandIndex(i)];
+    }
     uint32_t getOutputOperandIndex(uint32_t i) const { return mOutputIndexes[i]; }
     const std::vector<uint32_t>& getOutputOperandIndexes() const { return mOutputIndexes; }
-    const Operand& getOutputOperand(uint32_t i) const {
+    const hal::Operand& getOutputOperand(uint32_t i) const {
         return mOperands[getOutputOperandIndex(i)];
     }
-    const Operand& getOperand(uint32_t index) const { return mOperands[index]; }
-    const Operation& getOperation(uint32_t index) const { return mOperations[index]; }
+    const hal::Operand& getOperand(uint32_t index) const { return mOperands[index]; }
+    const hal::Operation& getOperation(uint32_t index) const { return mOperations[index]; }
     const MemoryTracker& getMemories() const { return mMemories; }
-    const std::vector<Operation>& getOperations() const { return mOperations; }
+    const std::vector<hal::Operation>& getOperations() const { return mOperations; }
     const std::vector<uint32_t>& getSortedOperationMapping() const {
         return mSortedOperationIndexMap;
     }
@@ -109,8 +111,8 @@
     int findBestDeviceForEachOperation(uint32_t preference,
                                        const std::vector<std::shared_ptr<Device>>& devices,
                                        std::vector<int>* bestDeviceForOperation) const;
-    PerformanceInfo getPerformanceInfo(const std::shared_ptr<Device> device,
-                                       uint32_t operationIndex) const;
+    hal::PerformanceInfo getPerformanceInfo(const std::shared_ptr<Device> device,
+                                            uint32_t operationIndex) const;
 
     // Return true if either mCompleteModel or mInvalidModel is true.
     bool badState(const char* name);
@@ -126,10 +128,10 @@
     // of operand and operation type values used in the model.
     //
     // Devices rely on this mapping to interpret extension types.
-    std::vector<Model::ExtensionNameAndPrefix> getExtensionNameToPrefixMap() const;
+    std::vector<hal::Model::ExtensionNameAndPrefix> getExtensionNameToPrefixMap() const;
 
     // The operations of the graph.
-    std::vector<Operation> mOperations;
+    std::vector<hal::Operation> mOperations;
     // The mapping from sorted index to the original index of operations in mOperations.
     // mSortedOperationIndexMap is empty before sortIntoRunOrder() is called.
     std::vector<uint32_t> mSortedOperationIndexMap;
@@ -138,7 +140,7 @@
     // Is at least one of those operations an extension operation?
     bool mHasExtensionOperation = false;
     // The description of the operands of the graph.
-    std::vector<Operand> mOperands;
+    std::vector<hal::Operand> mOperands;
     // Specifies where to find the list of indexes identifying
     // the inputs and outputs of the model.  The offset is into
     // the mOperandIndexes table.
diff --git a/nn/runtime/NeuralNetworks.cpp b/nn/runtime/NeuralNetworks.cpp
index fa33233..dd0ec5c 100644
--- a/nn/runtime/NeuralNetworks.cpp
+++ b/nn/runtime/NeuralNetworks.cpp
@@ -26,6 +26,7 @@
 #include "Callbacks.h"
 #include "CompilationBuilder.h"
 #include "ExecutionBuilder.h"
+#include "HalInterfaces.h"
 #include "Manager.h"
 #include "Memory.h"
 #include "ModelBuilder.h"
@@ -40,6 +41,8 @@
 #include <memory>
 #include <vector>
 
+using namespace android::nn::hal;
+
 // Make sure the constants defined in the header files have not changed values.
 // IMPORTANT: When adding new values, update kNumberOfDataTypes or kNumberOfDataTypesOEM
 // in Utils.h.
@@ -547,7 +550,6 @@
                       ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN,
               "Constant::BYTE_SIZE_OF_CACHE_TOKEN != ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN");
 
-using android::sp;
 using namespace android::nn;
 
 int ANeuralNetworks_getDeviceCount(uint32_t* numDevices) {
diff --git a/nn/runtime/TypeManager.cpp b/nn/runtime/TypeManager.cpp
index fcca745..6468a0f 100644
--- a/nn/runtime/TypeManager.cpp
+++ b/nn/runtime/TypeManager.cpp
@@ -42,6 +42,8 @@
 
 namespace {
 
+using namespace hal;
+
 const uint8_t kLowBitsType = static_cast<uint8_t>(Model::ExtensionTypeEncoding::LOW_BITS_TYPE);
 const uint32_t kMaxPrefix =
         (1 << static_cast<uint8_t>(Model::ExtensionTypeEncoding::HIGH_BITS_PREFIX)) - 1;
diff --git a/nn/runtime/TypeManager.h b/nn/runtime/TypeManager.h
index 5b9e477..af980dc 100644
--- a/nn/runtime/TypeManager.h
+++ b/nn/runtime/TypeManager.h
@@ -47,25 +47,25 @@
     // Looks up information about the extension corresponding to the given prefix
     //
     // Returns false if no extension corresponds to the given prefix.
-    bool getExtensionInfo(uint16_t prefix, const Extension** extension) const;
+    bool getExtensionInfo(uint16_t prefix, const hal::Extension** extension) const;
 
     // Looks up information about an extension operand type
     //
     // Returns false if the extension or type is unknown.
-    bool getExtensionOperandTypeInfo(OperandType type,
-                                     const Extension::OperandTypeInformation** info) const;
+    bool getExtensionOperandTypeInfo(hal::OperandType type,
+                                     const hal::Extension::OperandTypeInformation** info) const;
 
     // Returns true if an operand type is a tensor type.
     //
     // Aborts if the type is an unknown extension type.
-    bool isTensorType(OperandType type) const;
+    bool isTensorType(hal::OperandType type) const;
 
     // Returns the amount of space needed to store a value of the dimensions and
     // type of this operand. For a tensor with unspecified rank or at least one
     // unspecified dimension, returns zero.
     //
     // Aborts if the type is an unknown extension type.
-    uint32_t getSizeOfData(const Operand& operand) const {
+    uint32_t getSizeOfData(const hal::Operand& operand) const {
         return getSizeOfData(operand.type, operand.dimensions);
     }
 
@@ -74,7 +74,7 @@
     // unspecified dimension, returns zero.
     //
     // Aborts if the type is an unknown extension type.
-    uint32_t getSizeOfData(OperandType type, const std::vector<uint32_t>& dimensions) const;
+    uint32_t getSizeOfData(hal::OperandType type, const std::vector<uint32_t>& dimensions) const;
 
     // Returns true if extensions usage is allowed in current process.
     bool areExtensionsAllowed() const { return mExtensionsAllowed; }
@@ -84,7 +84,7 @@
     // Registers an extension.
     //
     // Returns true if the registration was successful.
-    bool forTest_registerExtension(const Extension& extension) {
+    bool forTest_registerExtension(const hal::Extension& extension) {
         return registerExtension(extension, "INTERNAL TEST");
     }
 
@@ -126,7 +126,7 @@
    private:
     TypeManager();
     void findAvailableExtensions();
-    bool registerExtension(Extension extension, const std::string& deviceName);
+    bool registerExtension(hal::Extension extension, const std::string& deviceName);
 
     // Returns the numeric "prefix" value corresponding to an extension.
     //
@@ -136,7 +136,7 @@
     const DeviceManager* mDeviceManager = DeviceManager::get();
 
     // Contains all registered extensions.
-    std::map<std::string, Extension> mExtensionNameToExtension;
+    std::map<std::string, hal::Extension> mExtensionNameToExtension;
 
     // Contains the name of the first discovered device that supports an
     // extension. Used for error reporting.
@@ -151,7 +151,7 @@
     std::map<std::string, uint16_t> mExtensionNameToPrefix;
     // Entries of mPrefixToExtension point into mExtensionNameToExtension.
     // prefix=0 corresponds to no extension and should never be looked up.
-    std::vector<Extension*> mPrefixToExtension = {nullptr};
+    std::vector<hal::Extension*> mPrefixToExtension = {nullptr};
 
     // True if Extensions can be used in current process.
     bool mExtensionsAllowed = false;
diff --git a/nn/runtime/VersionedInterfaces.cpp b/nn/runtime/VersionedInterfaces.cpp
index a07d0b1..cfa5908 100644
--- a/nn/runtime/VersionedInterfaces.cpp
+++ b/nn/runtime/VersionedInterfaces.cpp
@@ -35,6 +35,8 @@
 // anonymous namespace
 namespace {
 
+using namespace hal;
+
 using HidlToken = hidl_array<uint8_t, static_cast<uint32_t>(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>;
 
 const Timing kBadTiming = {.timeOnDevice = UINT64_MAX, .timeInDriver = UINT64_MAX};
@@ -57,7 +59,7 @@
 
 // This class is thread safe
 template <typename ICallback>
-class DeathHandler : public hardware::hidl_death_recipient {
+class DeathHandler : public hidl_death_recipient {
    public:
     void serviceDied(uint64_t /*cookie*/, const wp<hidl::base::V1_0::IBase>& /*who*/) override {
         LOG(ERROR) << "DeathHandler::serviceDied -- service unexpectedly died!";
diff --git a/nn/runtime/VersionedInterfaces.h b/nn/runtime/VersionedInterfaces.h
index ec95b2b..462f04e 100644
--- a/nn/runtime/VersionedInterfaces.h
+++ b/nn/runtime/VersionedInterfaces.h
@@ -74,7 +74,7 @@
      * @return A valid VersionedIDevice object, otherwise nullptr.
      */
     static std::shared_ptr<VersionedIDevice> create(std::string serviceName,
-                                                    sp<V1_0::IDevice> device);
+                                                    sp<hal::V1_0::IDevice> device);
 
     /**
      * Constructor for the VersionedIDevice object.
@@ -98,7 +98,7 @@
      *                - GENERAL_FAILURE if there is an unspecified error
      * @return capabilities Capabilities of the driver.
      */
-    std::pair<ErrorStatus, Capabilities> getCapabilities();
+    std::pair<hal::ErrorStatus, hal::Capabilities> getCapabilities();
 
     /**
      * Gets information about extensions supported by the driver implementation.
@@ -115,7 +115,7 @@
      *     - GENERAL_FAILURE if there is an unspecified error
      * @return extensions A list of supported extensions.
      */
-    std::pair<ErrorStatus, hidl_vec<Extension>> getSupportedExtensions();
+    std::pair<hal::ErrorStatus, hal::hidl_vec<hal::Extension>> getSupportedExtensions();
 
     /**
      * Gets the supported operations in a model.
@@ -143,8 +143,8 @@
      *                             corresponds with the index of the operation
      *                             it is describing.
      */
-    std::pair<ErrorStatus, hidl_vec<bool>> getSupportedOperations(const Model& model,
-                                                                  IModelSlicer* slicer = nullptr);
+    std::pair<hal::ErrorStatus, hal::hidl_vec<bool>> getSupportedOperations(
+            const hal::Model& model, IModelSlicer* slicer = nullptr);
 
     /**
      * Synchronously creates a prepared model for execution and optionally saves it
@@ -236,10 +236,12 @@
      *     - preparedModel A VersionedIPreparedModel object representing a model
      *         that has been prepared for execution, else nullptr.
      */
-    std::pair<ErrorStatus, std::shared_ptr<VersionedIPreparedModel>> prepareModel(
-            const Model& model, ExecutionPreference preference,
-            const hidl_vec<hidl_handle>& modelCache, const hidl_vec<hidl_handle>& dataCache,
-            const hidl_array<uint8_t, static_cast<uint32_t>(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>&
+    std::pair<hal::ErrorStatus, std::shared_ptr<VersionedIPreparedModel>> prepareModel(
+            const hal::Model& model, hal::ExecutionPreference preference,
+            const hal::hidl_vec<hal::hidl_handle>& modelCache,
+            const hal::hidl_vec<hal::hidl_handle>& dataCache,
+            const hal::hidl_array<uint8_t,
+                                  static_cast<uint32_t>(hal::Constant::BYTE_SIZE_OF_CACHE_TOKEN)>&
                     token);
 
     /**
@@ -308,9 +310,11 @@
      *     - preparedModel A VersionedIPreparedModel object representing a model
      *        that has been prepared for execution, else nullptr.
      */
-    std::pair<ErrorStatus, std::shared_ptr<VersionedIPreparedModel>> prepareModelFromCache(
-            const hidl_vec<hidl_handle>& modelCache, const hidl_vec<hidl_handle>& dataCache,
-            const hidl_array<uint8_t, static_cast<uint32_t>(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>&
+    std::pair<hal::ErrorStatus, std::shared_ptr<VersionedIPreparedModel>> prepareModelFromCache(
+            const hal::hidl_vec<hal::hidl_handle>& modelCache,
+            const hal::hidl_vec<hal::hidl_handle>& dataCache,
+            const hal::hidl_array<uint8_t,
+                                  static_cast<uint32_t>(hal::Constant::BYTE_SIZE_OF_CACHE_TOKEN)>&
                     token);
 
     /**
@@ -322,7 +326,7 @@
      *                - DeviceStatus::OFFLINE
      *                - DeviceStatus::UNKNOWN
      */
-    DeviceStatus getStatus();
+    hal::DeviceStatus getStatus();
 
     /**
      * Returns the feature level of a driver.
@@ -377,7 +381,7 @@
      * @return version The version string of the device implementation.
      *     Must have nonzero length if the query is successful, and must be an empty string if not.
      */
-    std::pair<ErrorStatus, hidl_string> getVersionString();
+    std::pair<hal::ErrorStatus, hal::hidl_string> getVersionString();
 
     /**
      * Gets the caching requirements of the driver implementation.
@@ -417,7 +421,7 @@
      *                      the driver needs to cache a single prepared model. It must
      *                      be less than or equal to Constant::MAX_NUMBER_OF_CACHE_FILES.
      */
-    std::tuple<ErrorStatus, uint32_t, uint32_t> getNumberOfCacheFilesNeeded();
+    std::tuple<hal::ErrorStatus, uint32_t, uint32_t> getNumberOfCacheFilesNeeded();
 
     /**
      * Returns the name of the service that implements the driver
@@ -472,7 +476,7 @@
          *                     the case when the service containing the IDevice
          *                     object crashes.
          */
-        Core(sp<V1_0::IDevice> device, sp<IDeviceDeathHandler> deathHandler);
+        Core(sp<hal::V1_0::IDevice> device, sp<IDeviceDeathHandler> deathHandler);
 
         /**
          * Destructor for the Core object.
@@ -502,7 +506,7 @@
          *               interface.
          * @return A valid Core object, otherwise nullopt.
          */
-        static std::optional<Core> create(sp<V1_0::IDevice> device);
+        static std::optional<Core> create(sp<hal::V1_0::IDevice> device);
 
         /**
          * Returns sp<*::IDevice> that is a downcast of the sp<V1_0::IDevice>
@@ -512,15 +516,15 @@
         template <typename T_IDevice>
         sp<T_IDevice> getDevice() const;
         template <>
-        sp<V1_0::IDevice> getDevice() const {
+        sp<hal::V1_0::IDevice> getDevice() const {
             return mDeviceV1_0;
         }
         template <>
-        sp<V1_1::IDevice> getDevice() const {
+        sp<hal::V1_1::IDevice> getDevice() const {
             return mDeviceV1_1;
         }
         template <>
-        sp<V1_2::IDevice> getDevice() const {
+        sp<hal::V1_2::IDevice> getDevice() const {
             return mDeviceV1_2;
         }
 
@@ -553,9 +557,9 @@
          * Idiomatic usage: if mDeviceV1_1 is non-null, do V1_1 dispatch; otherwise,
          * do V1_0 dispatch.
          */
-        sp<V1_0::IDevice> mDeviceV1_0;
-        sp<V1_1::IDevice> mDeviceV1_1;
-        sp<V1_2::IDevice> mDeviceV1_2;
+        sp<hal::V1_0::IDevice> mDeviceV1_0;
+        sp<hal::V1_1::IDevice> mDeviceV1_1;
+        sp<hal::V1_2::IDevice> mDeviceV1_2;
 
         /**
          * HIDL callback to be invoked if the service for mDeviceV1_0 crashes.
@@ -589,9 +593,10 @@
     // If a callback is provided, this method protects it against driver death
     // and waits for it (callback->wait()).
     template <typename T_Return, typename T_IDevice, typename T_Callback = std::nullptr_t>
-    Return<T_Return> recoverable(const char* context,
-                                 const std::function<Return<T_Return>(const sp<T_IDevice>&)>& fn,
-                                 const T_Callback& callback = nullptr) const EXCLUDES(mMutex);
+    hal::Return<T_Return> recoverable(
+            const char* context,
+            const std::function<hal::Return<T_Return>(const sp<T_IDevice>&)>& fn,
+            const T_Callback& callback = nullptr) const EXCLUDES(mMutex);
 
     // The name of the service that implements the driver.
     const std::string mServiceName;
@@ -628,7 +633,7 @@
      *                     the case when the service containing the IDevice
      *                     object crashes.
      */
-    VersionedIPreparedModel(sp<V1_0::IPreparedModel> preparedModel,
+    VersionedIPreparedModel(sp<hal::V1_0::IPreparedModel> preparedModel,
                             sp<IPreparedModelDeathHandler> deathHandler);
 
     /**
@@ -685,8 +690,8 @@
      *                - INVALID_ARGUMENT if one of the input arguments is
      *                  invalid
      */
-    ErrorStatus execute(const Request& request, MeasureTiming timing,
-                        const sp<ExecutionCallback>& callback);
+    hal::ErrorStatus execute(const hal::Request& request, hal::MeasureTiming timing,
+                             const sp<ExecutionCallback>& callback);
 
     /**
      * Performs a synchronous execution on a prepared model.
@@ -737,8 +742,8 @@
      *                choose to report any time as UINT64_MAX, indicating that
      *                measurement is not available.
      */
-    std::tuple<ErrorStatus, hidl_vec<OutputShape>, Timing> executeSynchronously(
-            const Request& request, MeasureTiming measure);
+    std::tuple<hal::ErrorStatus, hal::hidl_vec<hal::OutputShape>, hal::Timing> executeSynchronously(
+            const hal::Request& request, hal::MeasureTiming measure);
 
     /**
      * Creates a burst controller on a prepared model.
@@ -786,8 +791,8 @@
      * Idiomatic usage: if mPreparedModelV1_2 is non-null, do V1_2 dispatch; otherwise,
      * do V1_0 dispatch.
      */
-    sp<V1_0::IPreparedModel> mPreparedModelV1_0;
-    sp<V1_2::IPreparedModel> mPreparedModelV1_2;
+    sp<hal::V1_0::IPreparedModel> mPreparedModelV1_0;
+    sp<hal::V1_2::IPreparedModel> mPreparedModelV1_2;
 
     /**
      * HIDL callback to be invoked if the service for mPreparedModelV1_0 crashes.
diff --git a/nn/runtime/test/TestCompilationCaching.cpp b/nn/runtime/test/TestCompilationCaching.cpp
index 5705417..e180b28 100644
--- a/nn/runtime/test/TestCompilationCaching.cpp
+++ b/nn/runtime/test/TestCompilationCaching.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include "HalInterfaces.h"
 #include "Manager.h"
 #include "SampleDriver.h"
 #include "TestNeuralNetworksWrapper.h"
@@ -24,6 +25,7 @@
 #include <numeric>
 
 using namespace android::nn;
+using namespace hal;
 using Result = test_wrapper::Result;
 using Type = test_wrapper::Type;
 using HidlToken = hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
@@ -389,4 +391,4 @@
                         testing::Combine(kErrorStatusGetNumCacheFilesChoices, kNumCacheChoices,
                                          kNumCacheChoices, kErrorStatusPrepareFromCacheChoices));
 
-}  // end namespace
+}  // namespace
diff --git a/nn/runtime/test/TestCompliance.cpp b/nn/runtime/test/TestCompliance.cpp
index 63a2a31..0a8c887 100644
--- a/nn/runtime/test/TestCompliance.cpp
+++ b/nn/runtime/test/TestCompliance.cpp
@@ -18,13 +18,15 @@
 
 #include <gtest/gtest.h>
 
+#include "HalInterfaces.h"
 #include "ModelBuilder.h"
 #include "TestNeuralNetworksWrapper.h"
 #include "Utils.h"
 
 namespace compliance_test {
 
-using namespace ::android::nn;
+using namespace android::nn;
+using namespace hal;
 using HidlModel = V1_2::Model;
 using WrapperModel = test_wrapper::Model;
 using WrapperOperandType = test_wrapper::OperandType;
diff --git a/nn/runtime/test/TestExecution.cpp b/nn/runtime/test/TestExecution.cpp
index a56a7e7..412c6b2 100644
--- a/nn/runtime/test/TestExecution.cpp
+++ b/nn/runtime/test/TestExecution.cpp
@@ -18,6 +18,7 @@
 
 #include "Callbacks.h"
 #include "CompilationBuilder.h"
+#include "HalInterfaces.h"
 #include "Manager.h"
 #include "ModelBuilder.h"
 #include "NeuralNetworks.h"
@@ -33,12 +34,13 @@
 
 namespace android {
 
+using namespace nn::hal;
 using CompilationBuilder = nn::CompilationBuilder;
 using Device = nn::Device;
 using DeviceManager = nn::DeviceManager;
-using HidlModel = hardware::neuralnetworks::V1_2::Model;
-using HidlToken = hardware::hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
-using PreparedModelCallback = hardware::neuralnetworks::V1_2::implementation::PreparedModelCallback;
+using HidlModel = V1_2::Model;
+using HidlToken = hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
+using PreparedModelCallback = nn::PreparedModelCallback;
 using Result = nn::test_wrapper::Result;
 using SampleDriver = nn::sample_driver::SampleDriver;
 using WrapperCompilation = nn::test_wrapper::Compilation;
@@ -49,7 +51,7 @@
 using WrapperType = nn::test_wrapper::Type;
 
 template <typename T>
-using MQDescriptorSync = ::android::hardware::MQDescriptorSync<T>;
+using MQDescriptorSync = hardware::MQDescriptorSync<T>;
 
 namespace {
 
diff --git a/nn/runtime/test/TestExtensions.cpp b/nn/runtime/test/TestExtensions.cpp
index 4aa7cd1..6fe5927 100644
--- a/nn/runtime/test/TestExtensions.cpp
+++ b/nn/runtime/test/TestExtensions.cpp
@@ -29,6 +29,8 @@
 using SampleDriver = ::android::nn::sample_driver::SampleDriver;
 using TypeManager = ::android::nn::TypeManager;
 
+using namespace android::nn::hal;
+
 const char* kTestDriverName = "extensions-test-driver";
 const char* kTestExtension1 = "vendor.test.one";
 const char* kTestExtension2 = "vendor.test.two";
diff --git a/nn/runtime/test/TestGenerated.cpp b/nn/runtime/test/TestGenerated.cpp
index d259bb6..5f663e3 100644
--- a/nn/runtime/test/TestGenerated.cpp
+++ b/nn/runtime/test/TestGenerated.cpp
@@ -83,21 +83,29 @@
 }
 }  // namespace
 
-Compilation GeneratedTests::compileModel(const Model* model) {
+std::optional<Compilation> GeneratedTests::compileModel(const Model* model) {
     NNTRACE_APP(NNTRACE_PHASE_COMPILATION, "compileModel");
     if (mTestCompilationCaching) {
         // Compile the model twice with the same token, so that compilation caching will be
         // exercised if supported by the driver.
+        // No invalid model will be passed to this branch.
+        EXPECT_FALSE(mExpectFailure);
         Compilation compilation1(model);
-        compilation1.setCaching(mCacheDir, mToken);
-        compilation1.finish();
+        EXPECT_EQ(compilation1.setCaching(mCacheDir, mToken), Result::NO_ERROR);
+        EXPECT_EQ(compilation1.finish(), Result::NO_ERROR);
         Compilation compilation2(model);
-        compilation2.setCaching(mCacheDir, mToken);
-        compilation2.finish();
+        EXPECT_EQ(compilation2.setCaching(mCacheDir, mToken), Result::NO_ERROR);
+        EXPECT_EQ(compilation2.finish(), Result::NO_ERROR);
         return compilation2;
     } else {
         Compilation compilation(model);
-        compilation.finish();
+        Result result = compilation.finish();
+
+        // For valid model, we check the compilation result == NO_ERROR.
+        // For invalid model, the driver may fail at compilation or execution, so any result code is
+        // permitted at this point.
+        if (mExpectFailure && result != Result::NO_ERROR) return std::nullopt;
+        EXPECT_EQ(result, Result::NO_ERROR);
         return compilation;
     }
 }
@@ -151,8 +159,14 @@
             });
         }
 
-        Result r = execution.compute();
-        ASSERT_EQ(Result::NO_ERROR, r);
+        Result result = execution.compute();
+        if (mExpectFailure) {
+            ASSERT_NE(result, Result::NO_ERROR);
+            continue;
+        } else {
+            ASSERT_EQ(result, Result::NO_ERROR);
+        }
+
         {
             NNTRACE_APP(NNTRACE_PHASE_RESULTS, "executeWithCompilation example");
 
@@ -188,8 +202,10 @@
 void GeneratedTests::executeOnce(const Model* model, std::function<bool(int)> isIgnored,
                                  std::vector<MixedTypedExample>& examples, std::string dumpFile) {
     NNTRACE_APP(NNTRACE_PHASE_OVERALL, "executeOnce");
-    Compilation compilation = compileModel(model);
-    executeWithCompilation(model, &compilation, isIgnored, examples, dumpFile);
+    std::optional<Compilation> compilation = compileModel(model);
+    // Early return if compilation fails. The compilation result code is checked in compileModel.
+    if (!compilation) return;
+    executeWithCompilation(model, &compilation.value(), isIgnored, examples, dumpFile);
 }
 
 void GeneratedTests::executeMultithreadedOwnCompilation(const Model* model,
@@ -209,11 +225,14 @@
         std::vector<MixedTypedExample>& examples) {
     NNTRACE_APP(NNTRACE_PHASE_OVERALL, "executeMultithreadedSharedCompilation");
     SCOPED_TRACE("MultithreadedSharedCompilation");
-    Compilation compilation = compileModel(model);
+    std::optional<Compilation> compilation = compileModel(model);
+    // Early return if compilation fails. The ompilation result code is checked in compileModel.
+    if (!compilation) return;
     std::vector<std::thread> threads;
     for (int i = 0; i < 10; i++) {
-        threads.push_back(std::thread(
-                [&]() { executeWithCompilation(model, &compilation, isIgnored, examples, ""); }));
+        threads.push_back(std::thread([&]() {
+            executeWithCompilation(model, &compilation.value(), isIgnored, examples, "");
+        }));
     }
     std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); });
 }
@@ -239,8 +258,10 @@
     };
     mTestCompilationCaching = false;
     executeInternal(dumpFile);
-    mTestCompilationCaching = true;
-    executeInternal("");
+    if (!mExpectFailure) {
+        mTestCompilationCaching = true;
+        executeInternal("");
+    }
 }
 
 void GeneratedTests::SetUp() {
diff --git a/nn/runtime/test/TestGenerated.h b/nn/runtime/test/TestGenerated.h
index aef9041..a677923 100644
--- a/nn/runtime/test/TestGenerated.h
+++ b/nn/runtime/test/TestGenerated.h
@@ -19,6 +19,8 @@
 
 #include <gtest/gtest.h>
 
+#include <optional>
+
 #include "TestCompliance.h"
 #include "TestHarness.h"
 #include "TestNeuralNetworksWrapper.h"
@@ -59,10 +61,12 @@
 
 class GeneratedTests : public GENERATED_TESTS_BASE {
    protected:
+    GeneratedTests(bool expectFailure = false) : mExpectFailure(expectFailure) {}
+
     virtual void SetUp() override;
     virtual void TearDown() override;
 
-    Compilation compileModel(const Model* model);
+    std::optional<Compilation> compileModel(const Model* model);
     void executeWithCompilation(const Model* model, Compilation* compilation,
                                 std::function<bool(int)> isIgnored,
                                 std::vector<MixedTypedExample>& examples, std::string dumpFile);
@@ -79,7 +83,8 @@
 
     std::string mCacheDir;
     std::vector<uint8_t> mToken;
-    bool mTestCompilationCaching;
+    bool mTestCompilationCaching = false;
+    bool mExpectFailure = false;
 #ifdef NNTEST_COMPUTE_MODE
     // SetUp() uses Execution::setComputeMode() to establish a new ComputeMode,
     // and saves off the previous ComputeMode here; TearDown() restores that
@@ -92,6 +97,12 @@
 // Tag for the dynamic output shape tests
 class DynamicOutputShapeTest : public GeneratedTests {};
 
+// Tag for the generated validation tests
+class GeneratedValidationTests : public GeneratedTests {
+   protected:
+    GeneratedValidationTests() : GeneratedTests(/*expectFailure=*/true) {}
+};
+
 }  // namespace generated_tests
 
 using namespace generated_tests;
diff --git a/nn/runtime/test/TestIntrospectionControl.cpp b/nn/runtime/test/TestIntrospectionControl.cpp
index 0b7ad48..3377d62 100644
--- a/nn/runtime/test/TestIntrospectionControl.cpp
+++ b/nn/runtime/test/TestIntrospectionControl.cpp
@@ -35,15 +35,16 @@
 namespace {
 
 using namespace ::android;
+using namespace nn::hal;
 
 using CompilationBuilder = nn::CompilationBuilder;
 using Device = nn::Device;
 using DeviceManager = nn::DeviceManager;
 using ExecutePreference = nn::test_wrapper::ExecutePreference;
 using ExecutionBurstServer = nn::ExecutionBurstServer;
-using HidlModel = hardware::neuralnetworks::V1_2::Model;
-using HidlToken = hardware::hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
-using PreparedModelCallback = hardware::neuralnetworks::V1_2::implementation::PreparedModelCallback;
+using HidlModel = V1_2::Model;
+using HidlToken = hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
+using PreparedModelCallback = nn::PreparedModelCallback;
 using Result = nn::test_wrapper::Result;
 using SampleDriver = nn::sample_driver::SampleDriver;
 using SamplePreparedModel = nn::sample_driver::SamplePreparedModel;
diff --git a/nn/runtime/test/TestPartitioning.cpp b/nn/runtime/test/TestPartitioning.cpp
index 56ba108..d2bea0e 100644
--- a/nn/runtime/test/TestPartitioning.cpp
+++ b/nn/runtime/test/TestPartitioning.cpp
@@ -130,8 +130,7 @@
 
 namespace {
 
-const Timing kBadTiming = {.timeOnDevice = UINT64_MAX, .timeInDriver = UINT64_MAX};
-
+using namespace android::nn::hal;
 using CompilationBuilder = ::android::nn::CompilationBuilder;
 using Device = ::android::nn::Device;
 using DeviceManager = ::android::nn::DeviceManager;
@@ -139,22 +138,22 @@
 using ExecutionPlan = ::android::nn::ExecutionPlan;
 using ExecutionStep = ::android::nn::ExecutionStep;
 using HalVersion = ::android::nn::HalVersion;
-using HidlModel = ::android::hardware::neuralnetworks::V1_2::Model;
-using HidlToken =
-        ::android::hardware::hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
+using HidlModel = V1_2::Model;
+using HidlToken = hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
 using ModelBuilder = ::android::nn::ModelBuilder;
 using Result = ::android::nn::test_wrapper::Result;
 using SampleDriver = ::android::nn::sample_driver::SampleDriver;
-using WrapperSymmPerChannelQuantParams = ::android::nn::test_wrapper::SymmPerChannelQuantParams;
 using WrapperCompilation = ::android::nn::test_wrapper::Compilation;
 using WrapperModel = ::android::nn::test_wrapper::Model;
 using WrapperOperandType = ::android::nn::test_wrapper::OperandType;
+using WrapperSymmPerChannelQuantParams = ::android::nn::test_wrapper::SymmPerChannelQuantParams;
 using WrapperType = ::android::nn::test_wrapper::Type;
 
-template <typename T> using sp = ::android::sp<T>;
 template <typename T>
 using MQDescriptorSync = ::android::hardware::MQDescriptorSync<T>;
 
+const Timing kBadTiming = {.timeOnDevice = UINT64_MAX, .timeInDriver = UINT64_MAX};
+
 Capabilities makeCapabilities(float perf) {
     PerformanceInfo perfInfo = {.execTime = perf, .powerUsage = perf};
     return {.relaxedFloat32toFloat16PerformanceScalar = perfInfo,
diff --git a/nn/runtime/test/TestPartitioningRandom.cpp b/nn/runtime/test/TestPartitioningRandom.cpp
index fdc54a1..d62a6ad 100644
--- a/nn/runtime/test/TestPartitioningRandom.cpp
+++ b/nn/runtime/test/TestPartitioningRandom.cpp
@@ -17,6 +17,7 @@
 #undef NDEBUG
 
 #include "CompilationBuilder.h"
+#include "HalInterfaces.h"
 #include "Manager.h"
 #include "ModelBuilder.h"
 #include "NeuralNetworks.h"
@@ -89,14 +90,14 @@
 
 namespace android {
 
+using namespace nn::hal;
 using CompilationBuilder = nn::CompilationBuilder;
 using Device = nn::Device;
 using DeviceManager = nn::DeviceManager;
 using ExecutionPlan = nn::ExecutionPlan;
 using HalVersion = nn::HalVersion;
-using HidlModel = hardware::neuralnetworks::V1_2::Model;
-using HidlToken =
-        ::android::hardware::hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
+using HidlModel = V1_2::Model;
+using HidlToken = hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
 using MemoryBuilder = nn::Memory;
 using ModelBuilder = nn::ModelBuilder;
 using Result = nn::test_wrapper::Result;
diff --git a/nn/runtime/test/fibonacci_extension/FibonacciDriver.cpp b/nn/runtime/test/fibonacci_extension/FibonacciDriver.cpp
index 7c1b2af..85a708b 100644
--- a/nn/runtime/test/fibonacci_extension/FibonacciDriver.cpp
+++ b/nn/runtime/test/fibonacci_extension/FibonacciDriver.cpp
@@ -32,6 +32,8 @@
 namespace sample_driver {
 namespace {
 
+using namespace hal;
+
 const uint8_t kLowBitsType = static_cast<uint8_t>(Model::ExtensionTypeEncoding::LOW_BITS_TYPE);
 const uint32_t kTypeWithinExtensionMask = (1 << kLowBitsType) - 1;
 
diff --git a/nn/runtime/test/fibonacci_extension/FibonacciDriver.h b/nn/runtime/test/fibonacci_extension/FibonacciDriver.h
index 9bb1e86..f269dc1 100644
--- a/nn/runtime/test/fibonacci_extension/FibonacciDriver.h
+++ b/nn/runtime/test/fibonacci_extension/FibonacciDriver.h
@@ -17,6 +17,7 @@
 #ifndef FRAMEWORKS_ML_RUNTIME_TEST_FIBONACCI_EXTENSION_FIBONACCI_DRIVER_H
 #define FRAMEWORKS_ML_RUNTIME_TEST_FIBONACCI_EXTENSION_FIBONACCI_DRIVER_H
 
+#include "HalInterfaces.h"
 #include "OperationResolver.h"
 #include "SampleDriver.h"
 
@@ -33,7 +34,7 @@
         return &instance;
     }
 
-    const OperationRegistration* findOperation(OperationType operationType) const override;
+    const OperationRegistration* findOperation(hal::OperationType operationType) const override;
 
    private:
     FibonacciOperationResolver() {}
@@ -44,10 +45,10 @@
 class FibonacciDriver : public SampleDriver {
    public:
     FibonacciDriver() : SampleDriver(kDriverName, FibonacciOperationResolver::get()) {}
-    Return<void> getSupportedExtensions(getSupportedExtensions_cb cb) override;
-    Return<void> getCapabilities_1_2(getCapabilities_1_2_cb cb) override;
-    Return<void> getSupportedOperations_1_2(const V1_2::Model& model,
-                                            getSupportedOperations_1_2_cb cb) override;
+    hal::Return<void> getSupportedExtensions(getSupportedExtensions_cb cb) override;
+    hal::Return<void> getCapabilities_1_2(getCapabilities_1_2_cb cb) override;
+    hal::Return<void> getSupportedOperations_1_2(const hal::V1_2::Model& model,
+                                                 getSupportedOperations_1_2_cb cb) override;
 
     static constexpr char kDriverName[] = "sample-driver-fibonacci-extension";
 };
diff --git a/nn/runtime/test/fuzzing/TestRandomGraph.cpp b/nn/runtime/test/fuzzing/TestRandomGraph.cpp
index 804d77c..9cf4dea 100644
--- a/nn/runtime/test/fuzzing/TestRandomGraph.cpp
+++ b/nn/runtime/test/fuzzing/TestRandomGraph.cpp
@@ -27,10 +27,12 @@
 #ifndef NNTEST_CTS
 #include <android-base/properties.h>
 #include <vector>
+#include "HalInterfaces.h"
 #include "Manager.h"
 #include "SampleDriverFull.h"
 
 using android::nn::sample_driver::SampleDriverFull;
+using namespace android::nn::hal;
 
 #endif
 
diff --git a/nn/runtime/test/generated/examples/strided_slice_invalid_output_dims.example.cpp b/nn/runtime/test/generated/examples/strided_slice_invalid_output_dims.example.cpp
new file mode 100644
index 0000000..0640833
--- /dev/null
+++ b/nn/runtime/test/generated/examples/strided_slice_invalid_output_dims.example.cpp
@@ -0,0 +1,116 @@
+// clang-format off
+// Generated file (from: strided_slice_invalid_output_dims.mod.py). Do not edit
+std::vector<MixedTypedExample>& get_examples() {
+static std::vector<MixedTypedExample> examples = {
+// Begin of an example
+{
+.operands = {
+//Input(s)
+{ // See tools/test_generator/include/TestHarness.h:MixedTyped
+  // int -> Dimensions map
+  .operandDimensions = {{0, {2, 3}}},
+  // int -> FLOAT32 map
+  .float32Operands = {{0, {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}}},
+  // int -> INT32 map
+  .int32Operands = {},
+  // int -> QUANT8_ASYMM map
+  .quant8AsymmOperands = {},
+  // int -> QUANT16_SYMM map
+  .quant16SymmOperands = {},
+  // int -> FLOAT16 map
+  .float16Operands = {},
+  // int -> BOOL8 map
+  .bool8Operands = {},
+  // int -> QUANT8_SYMM_PER_CHANNEL map
+  .quant8ChannelOperands = {},
+  // int -> QUANT16_ASYMM map
+  .quant16AsymmOperands = {},
+  // int -> QUANT8_SYMM map
+  .quant8SymmOperands = {},
+},
+//Output(s)
+{ // See tools/test_generator/include/TestHarness.h:MixedTyped
+  // int -> Dimensions map
+  .operandDimensions = {{0, {3}}},
+  // int -> FLOAT32 map
+  .float32Operands = {{0, {1.0f, 2.0f, 3.0f}}},
+  // int -> INT32 map
+  .int32Operands = {},
+  // int -> QUANT8_ASYMM map
+  .quant8AsymmOperands = {},
+  // int -> QUANT16_SYMM map
+  .quant16SymmOperands = {},
+  // int -> FLOAT16 map
+  .float16Operands = {},
+  // int -> BOOL8 map
+  .bool8Operands = {},
+  // int -> QUANT8_SYMM_PER_CHANNEL map
+  .quant8ChannelOperands = {},
+  // int -> QUANT16_ASYMM map
+  .quant16AsymmOperands = {},
+  // int -> QUANT8_SYMM map
+  .quant8SymmOperands = {},
+}
+},
+}, // End of an example
+};
+return examples;
+};
+
+std::vector<MixedTypedExample>& get_examples_dynamic_output_shape() {
+static std::vector<MixedTypedExample> examples_dynamic_output_shape = {
+// Begin of an example
+{
+.operands = {
+//Input(s)
+{ // See tools/test_generator/include/TestHarness.h:MixedTyped
+  // int -> Dimensions map
+  .operandDimensions = {{0, {2, 3}}},
+  // int -> FLOAT32 map
+  .float32Operands = {{0, {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}}},
+  // int -> INT32 map
+  .int32Operands = {},
+  // int -> QUANT8_ASYMM map
+  .quant8AsymmOperands = {},
+  // int -> QUANT16_SYMM map
+  .quant16SymmOperands = {},
+  // int -> FLOAT16 map
+  .float16Operands = {},
+  // int -> BOOL8 map
+  .bool8Operands = {},
+  // int -> QUANT8_SYMM_PER_CHANNEL map
+  .quant8ChannelOperands = {},
+  // int -> QUANT16_ASYMM map
+  .quant16AsymmOperands = {},
+  // int -> QUANT8_SYMM map
+  .quant8SymmOperands = {},
+},
+//Output(s)
+{ // See tools/test_generator/include/TestHarness.h:MixedTyped
+  // int -> Dimensions map
+  .operandDimensions = {{0, {3}}},
+  // int -> FLOAT32 map
+  .float32Operands = {{0, {1.0f, 2.0f, 3.0f}}},
+  // int -> INT32 map
+  .int32Operands = {},
+  // int -> QUANT8_ASYMM map
+  .quant8AsymmOperands = {},
+  // int -> QUANT16_SYMM map
+  .quant16SymmOperands = {},
+  // int -> FLOAT16 map
+  .float16Operands = {},
+  // int -> BOOL8 map
+  .bool8Operands = {},
+  // int -> QUANT8_SYMM_PER_CHANNEL map
+  .quant8ChannelOperands = {},
+  // int -> QUANT16_ASYMM map
+  .quant16AsymmOperands = {},
+  // int -> QUANT8_SYMM map
+  .quant8SymmOperands = {},
+}
+},
+}, // End of an example
+};
+return examples_dynamic_output_shape;
+};
+
diff --git a/nn/runtime/test/generated/models/strided_slice_invalid_output_dims.model.cpp b/nn/runtime/test/generated/models/strided_slice_invalid_output_dims.model.cpp
new file mode 100644
index 0000000..c8aedeb
--- /dev/null
+++ b/nn/runtime/test/generated/models/strided_slice_invalid_output_dims.model.cpp
@@ -0,0 +1,82 @@
+// clang-format off
+// Generated file (from: strided_slice_invalid_output_dims.mod.py). Do not edit
+void CreateModel(Model *model) {
+  OperandType type0(Type::TENSOR_FLOAT32, {2, 3});
+  OperandType type1(Type::TENSOR_INT32, {2});
+  OperandType type2(Type::INT32, {});
+  OperandType type3(Type::TENSOR_FLOAT32, {3});
+  // Phase 1, operands
+  auto input = model->addOperand(&type0);
+  auto begins = model->addOperand(&type1);
+  auto ends = model->addOperand(&type1);
+  auto strides = model->addOperand(&type1);
+  auto beginMask = model->addOperand(&type2);
+  auto endMask = model->addOperand(&type2);
+  auto shrinkAxisMask = model->addOperand(&type2);
+  auto output = model->addOperand(&type3);
+  // Phase 2, operations
+  static int32_t begins_init[] = {0, 0};
+  model->setOperandValue(begins, begins_init, sizeof(int32_t) * 2);
+  static int32_t ends_init[] = {2, 3};
+  model->setOperandValue(ends, ends_init, sizeof(int32_t) * 2);
+  static int32_t strides_init[] = {1, 1};
+  model->setOperandValue(strides, strides_init, sizeof(int32_t) * 2);
+  static int32_t beginMask_init[] = {0};
+  model->setOperandValue(beginMask, beginMask_init, sizeof(int32_t) * 1);
+  static int32_t endMask_init[] = {0};
+  model->setOperandValue(endMask, endMask_init, sizeof(int32_t) * 1);
+  static int32_t shrinkAxisMask_init[] = {1};
+  model->setOperandValue(shrinkAxisMask, shrinkAxisMask_init, sizeof(int32_t) * 1);
+  model->addOperation(ANEURALNETWORKS_STRIDED_SLICE, {input, begins, ends, strides, beginMask, endMask, shrinkAxisMask}, {output});
+  // Phase 3, inputs and outputs
+  model->identifyInputsAndOutputs(
+    {input},
+    {output});
+  assert(model->isValid());
+}
+
+inline bool is_ignored(int i) {
+  static std::set<int> ignore = {};
+  return ignore.find(i) != ignore.end();
+}
+
+void CreateModel_dynamic_output_shape(Model *model) {
+  OperandType type0(Type::TENSOR_FLOAT32, {2, 3});
+  OperandType type1(Type::TENSOR_INT32, {2});
+  OperandType type2(Type::INT32, {});
+  OperandType type4(Type::TENSOR_FLOAT32, {0});
+  // Phase 1, operands
+  auto input = model->addOperand(&type0);
+  auto begins = model->addOperand(&type1);
+  auto ends = model->addOperand(&type1);
+  auto strides = model->addOperand(&type1);
+  auto beginMask = model->addOperand(&type2);
+  auto endMask = model->addOperand(&type2);
+  auto shrinkAxisMask = model->addOperand(&type2);
+  auto output = model->addOperand(&type4);
+  // Phase 2, operations
+  static int32_t begins_init[] = {0, 0};
+  model->setOperandValue(begins, begins_init, sizeof(int32_t) * 2);
+  static int32_t ends_init[] = {2, 3};
+  model->setOperandValue(ends, ends_init, sizeof(int32_t) * 2);
+  static int32_t strides_init[] = {1, 1};
+  model->setOperandValue(strides, strides_init, sizeof(int32_t) * 2);
+  static int32_t beginMask_init[] = {0};
+  model->setOperandValue(beginMask, beginMask_init, sizeof(int32_t) * 1);
+  static int32_t endMask_init[] = {0};
+  model->setOperandValue(endMask, endMask_init, sizeof(int32_t) * 1);
+  static int32_t shrinkAxisMask_init[] = {1};
+  model->setOperandValue(shrinkAxisMask, shrinkAxisMask_init, sizeof(int32_t) * 1);
+  model->addOperation(ANEURALNETWORKS_STRIDED_SLICE, {input, begins, ends, strides, beginMask, endMask, shrinkAxisMask}, {output});
+  // Phase 3, inputs and outputs
+  model->identifyInputsAndOutputs(
+    {input},
+    {output});
+  assert(model->isValid());
+}
+
+inline bool is_ignored_dynamic_output_shape(int i) {
+  static std::set<int> ignore = {};
+  return ignore.find(i) != ignore.end();
+}
+
diff --git a/nn/runtime/test/generated/tests/strided_slice_invalid_output_dims.mod.py.cpp b/nn/runtime/test/generated/tests/strided_slice_invalid_output_dims.mod.py.cpp
new file mode 100644
index 0000000..7af9af4
--- /dev/null
+++ b/nn/runtime/test/generated/tests/strided_slice_invalid_output_dims.mod.py.cpp
@@ -0,0 +1,23 @@
+// clang-format off
+// Generated file (from: strided_slice_invalid_output_dims.mod.py). Do not edit
+#include "../../TestGenerated.h"
+
+namespace strided_slice_invalid_output_dims {
+// Generated strided_slice_invalid_output_dims test
+#include "generated/examples/strided_slice_invalid_output_dims.example.cpp"
+// Generated model constructor
+#include "generated/models/strided_slice_invalid_output_dims.model.cpp"
+} // namespace strided_slice_invalid_output_dims
+
+TEST_F(GeneratedValidationTests, strided_slice_invalid_output_dims) {
+    execute(strided_slice_invalid_output_dims::CreateModel,
+            strided_slice_invalid_output_dims::is_ignored,
+            strided_slice_invalid_output_dims::get_examples());
+}
+
+TEST_F(GeneratedValidationTests, strided_slice_invalid_output_dims_dynamic_output_shape) {
+    execute(strided_slice_invalid_output_dims::CreateModel_dynamic_output_shape,
+            strided_slice_invalid_output_dims::is_ignored_dynamic_output_shape,
+            strided_slice_invalid_output_dims::get_examples_dynamic_output_shape());
+}
+
diff --git a/nn/runtime/test/generated/vts/V1_2/all_generated_V1_2_vts_tests.cpp b/nn/runtime/test/generated/vts/V1_2/all_generated_V1_2_vts_tests.cpp
index 3a9fe0d..6256de4 100644
--- a/nn/runtime/test/generated/vts/V1_2/all_generated_V1_2_vts_tests.cpp
+++ b/nn/runtime/test/generated/vts/V1_2/all_generated_V1_2_vts_tests.cpp
@@ -69061,6 +69061,28 @@
 }
 
 
+// Generated from: strided_slice_invalid_output_dims.mod.py.
+namespace strided_slice_invalid_output_dims {
+// Generated strided_slice_invalid_output_dims test
+#include "examples/strided_slice_invalid_output_dims.example.cpp"
+// Generated model constructor
+#include "vts/V1_2/models/strided_slice_invalid_output_dims.model.cpp"
+} // namespace strided_slice_invalid_output_dims
+
+TEST_F(ValidationTest, strided_slice_invalid_output_dims) {
+  const Model model = strided_slice_invalid_output_dims::createTestModel();
+  const std::vector<Request> requests = createRequests(strided_slice_invalid_output_dims::get_examples());
+  validateFailure(model, requests);
+}
+
+
+TEST_F(ValidationTest, strided_slice_invalid_output_dims_dynamic_output_shape) {
+  const Model model = strided_slice_invalid_output_dims::createTestModel_dynamic_output_shape();
+  const std::vector<Request> requests = createRequests(strided_slice_invalid_output_dims::get_examples_dynamic_output_shape());
+  validateFailure(model, requests);
+}
+
+
 // Generated from: sub_quantized_different_scales.mod.py.
 namespace sub_quantized_different_scales {
 // Generated sub_quantized_different_scales test
diff --git a/nn/runtime/test/generated/vts/V1_2/models/strided_slice_invalid_output_dims.model.cpp b/nn/runtime/test/generated/vts/V1_2/models/strided_slice_invalid_output_dims.model.cpp
new file mode 100644
index 0000000..106655a
--- /dev/null
+++ b/nn/runtime/test/generated/vts/V1_2/models/strided_slice_invalid_output_dims.model.cpp
@@ -0,0 +1,216 @@
+// clang-format off
+// Generated file (from: strided_slice_invalid_output_dims.mod.py). Do not edit
+// Create the model
+Model createTestModel() {
+    const std::vector<Operand> operands = {
+        {
+            .type = OperandType::TENSOR_FLOAT32,
+            .dimensions = {2, 3},
+            .numberOfConsumers = 1,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .lifetime = OperandLifeTime::MODEL_INPUT,
+            .location = {.poolIndex = 0, .offset = 0, .length = 0},
+        },
+        {
+            .type = OperandType::TENSOR_INT32,
+            .dimensions = {2},
+            .numberOfConsumers = 1,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .lifetime = OperandLifeTime::CONSTANT_COPY,
+            .location = {.poolIndex = 0, .offset = 0, .length = 8},
+        },
+        {
+            .type = OperandType::TENSOR_INT32,
+            .dimensions = {2},
+            .numberOfConsumers = 1,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .lifetime = OperandLifeTime::CONSTANT_COPY,
+            .location = {.poolIndex = 0, .offset = 8, .length = 8},
+        },
+        {
+            .type = OperandType::TENSOR_INT32,
+            .dimensions = {2},
+            .numberOfConsumers = 1,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .lifetime = OperandLifeTime::CONSTANT_COPY,
+            .location = {.poolIndex = 0, .offset = 16, .length = 8},
+        },
+        {
+            .type = OperandType::INT32,
+            .dimensions = {},
+            .numberOfConsumers = 1,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .lifetime = OperandLifeTime::CONSTANT_COPY,
+            .location = {.poolIndex = 0, .offset = 24, .length = 4},
+        },
+        {
+            .type = OperandType::INT32,
+            .dimensions = {},
+            .numberOfConsumers = 1,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .lifetime = OperandLifeTime::CONSTANT_COPY,
+            .location = {.poolIndex = 0, .offset = 28, .length = 4},
+        },
+        {
+            .type = OperandType::INT32,
+            .dimensions = {},
+            .numberOfConsumers = 1,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .lifetime = OperandLifeTime::CONSTANT_COPY,
+            .location = {.poolIndex = 0, .offset = 32, .length = 4},
+        },
+        {
+            .type = OperandType::TENSOR_FLOAT32,
+            .dimensions = {3},
+            .numberOfConsumers = 0,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .lifetime = OperandLifeTime::MODEL_OUTPUT,
+            .location = {.poolIndex = 0, .offset = 0, .length = 0},
+        }
+    };
+
+    const std::vector<Operation> operations = {
+        {
+            .type = OperationType::STRIDED_SLICE,
+            .inputs = {0, 1, 2, 3, 4, 5, 6},
+            .outputs = {7},
+        }
+    };
+
+    const std::vector<uint32_t> inputIndexes = {0};
+    const std::vector<uint32_t> outputIndexes = {7};
+    std::vector<uint8_t> operandValues = {
+      0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0
+    };
+    const std::vector<hidl_memory> pools = {};
+
+    return {
+        .operands = operands,
+        .operations = operations,
+        .inputIndexes = inputIndexes,
+        .outputIndexes = outputIndexes,
+        .operandValues = operandValues,
+        .pools = pools,
+    };
+}
+
+inline bool is_ignored(int i) {
+  static std::set<int> ignore = {};
+  return ignore.find(i) != ignore.end();
+}
+
+// Create the model
+Model createTestModel_dynamic_output_shape() {
+    const std::vector<Operand> operands = {
+        {
+            .type = OperandType::TENSOR_FLOAT32,
+            .dimensions = {2, 3},
+            .numberOfConsumers = 1,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .lifetime = OperandLifeTime::MODEL_INPUT,
+            .location = {.poolIndex = 0, .offset = 0, .length = 0},
+        },
+        {
+            .type = OperandType::TENSOR_INT32,
+            .dimensions = {2},
+            .numberOfConsumers = 1,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .lifetime = OperandLifeTime::CONSTANT_COPY,
+            .location = {.poolIndex = 0, .offset = 0, .length = 8},
+        },
+        {
+            .type = OperandType::TENSOR_INT32,
+            .dimensions = {2},
+            .numberOfConsumers = 1,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .lifetime = OperandLifeTime::CONSTANT_COPY,
+            .location = {.poolIndex = 0, .offset = 8, .length = 8},
+        },
+        {
+            .type = OperandType::TENSOR_INT32,
+            .dimensions = {2},
+            .numberOfConsumers = 1,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .lifetime = OperandLifeTime::CONSTANT_COPY,
+            .location = {.poolIndex = 0, .offset = 16, .length = 8},
+        },
+        {
+            .type = OperandType::INT32,
+            .dimensions = {},
+            .numberOfConsumers = 1,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .lifetime = OperandLifeTime::CONSTANT_COPY,
+            .location = {.poolIndex = 0, .offset = 24, .length = 4},
+        },
+        {
+            .type = OperandType::INT32,
+            .dimensions = {},
+            .numberOfConsumers = 1,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .lifetime = OperandLifeTime::CONSTANT_COPY,
+            .location = {.poolIndex = 0, .offset = 28, .length = 4},
+        },
+        {
+            .type = OperandType::INT32,
+            .dimensions = {},
+            .numberOfConsumers = 1,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .lifetime = OperandLifeTime::CONSTANT_COPY,
+            .location = {.poolIndex = 0, .offset = 32, .length = 4},
+        },
+        {
+            .type = OperandType::TENSOR_FLOAT32,
+            .dimensions = {0},
+            .numberOfConsumers = 0,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .lifetime = OperandLifeTime::MODEL_OUTPUT,
+            .location = {.poolIndex = 0, .offset = 0, .length = 0},
+        }
+    };
+
+    const std::vector<Operation> operations = {
+        {
+            .type = OperationType::STRIDED_SLICE,
+            .inputs = {0, 1, 2, 3, 4, 5, 6},
+            .outputs = {7},
+        }
+    };
+
+    const std::vector<uint32_t> inputIndexes = {0};
+    const std::vector<uint32_t> outputIndexes = {7};
+    std::vector<uint8_t> operandValues = {
+      0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0
+    };
+    const std::vector<hidl_memory> pools = {};
+
+    return {
+        .operands = operands,
+        .operations = operations,
+        .inputIndexes = inputIndexes,
+        .outputIndexes = outputIndexes,
+        .operandValues = operandValues,
+        .pools = pools,
+    };
+}
+
+inline bool is_ignored_dynamic_output_shape(int i) {
+  static std::set<int> ignore = {};
+  return ignore.find(i) != ignore.end();
+}
+
diff --git a/nn/runtime/test/specs/V1_2/strided_slice_invalid_output_dims.mod.py b/nn/runtime/test/specs/V1_2/strided_slice_invalid_output_dims.mod.py
new file mode 100644
index 0000000..76d2179
--- /dev/null
+++ b/nn/runtime/test/specs/V1_2/strided_slice_invalid_output_dims.mod.py
@@ -0,0 +1,41 @@
+#
+# Copyright (C) 2019 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.
+#
+
+# TODO: Move this spec to V1_3 directory?
+#
+# This test makes sure that executing STRIDED_SLICE results in a failure when
+# the output dimensions do not match shrinkAxisMask.
+#
+# Based on strided_slice_float_11.mod.py.
+
+model = Model()
+i1 = Input("input", "TENSOR_FLOAT32", "{2, 3}")
+begins = Parameter("begins", "TENSOR_INT32", "{2}", [0, 0])
+# The value "2" below makes the test invalid. See http://b/79856511#comment2.
+ends = Parameter("ends", "TENSOR_INT32", "{2}", [2, 3])
+strides = Parameter("strides", "TENSOR_INT32", "{2}", [1, 1])
+beginMask = Int32Scalar("beginMask", 0)
+endMask = Int32Scalar("endMask", 0)
+shrinkAxisMask = Int32Scalar("shrinkAxisMask", 1)
+
+output = Output("output", "TENSOR_FLOAT32", "{3}")
+
+model = model.Operation("STRIDED_SLICE", i1, begins, ends, strides, beginMask, endMask, shrinkAxisMask).To(output)
+
+Example({
+    i1: [1, 2, 3, 4, 5, 6],
+    output: [1, 2, 3],
+}).ExpectFailure()
diff --git a/nn/runtime/test/specs/generate_test.sh b/nn/runtime/test/specs/generate_test.sh
index ba752e3..b44358d 100755
--- a/nn/runtime/test/specs/generate_test.sh
+++ b/nn/runtime/test/specs/generate_test.sh
@@ -19,80 +19,10 @@
 
 NNAPI_VERSIONS="V1_0 V1_1 V1_2"
 
-# Process one test spec, and optionally provide the log file argument
-# for the slicing tool. The first argument is the test spec file; the
-# second optional argument specifies the log file this test should dump
-# results into. Only used by the test slicing tool to collect reference
-# outputs from the CPU. Also, it outputs the right #includes in the
-# test harness so the test would be invoked by TestGenerated.cpp
-#
-# This function shouldn't be directly called from other scripts. Use
-# generate_wrapper below for generating models and examples and updating the
-# test framework in one shot.
-
 export NNAPI_BASE=$ANDROID_BUILD_TOP/frameworks/ml/nn
 : ${TEST_DIR:=frameworks/ml/nn/runtime/test}
 : ${FORCE:=""}
 
-function generate_one_testcase {
-  # Generate one testcase
-  local LOGFILE=$2
-  if [ -n "$2" ]; then
-    local LOGFILE="-l $2"
-  fi
-  local BASENAME=`basename -s .mod.py $1`
-  local MODEL="-m $ANDROID_BUILD_TOP/$TEST_DIR/generated/models/$BASENAME.model.cpp"
-  local EXAMPLE="-e $ANDROID_BUILD_TOP/$TEST_DIR/generated/examples/$BASENAME.example.cpp"
-  local TEST="-t $ANDROID_BUILD_TOP/$TEST_DIR/generated/tests/$(basename $1).cpp"
-
-  $NNAPI_BASE/tools/test_generator/cts_generator.py $FORCE ./`basename $1` \
-    $MODEL $EXAMPLE $TEST $LOGFILE
-  ret=$?
-  return $ret
-}
-
-# Driver for generate_one_testcase. Append the output of generate_one_testcase
-# (which are C++ snippets that invokes the test harness) to the
-# all_generated_tests.cpp
-# Optionally, the "LOG" file ($2), only used by the slicing tool, would be
-# passed to generate_one_testcase.
-#
-# This function should be called to process one test spec from other scripts.
-function generate_wrapper {
-  local LOGFILE=""
-  if [ $1 = "log" ]; then
-    local LOGFILE=$2
-    shift
-    shift
-  fi
-  cd $ANDROID_BUILD_TOP/$TEST_DIR/specs
-  FOUND=0
-
-  for ver in $NNAPI_VERSIONS;
-  do
-    VER_DIR=$ANDROID_BUILD_TOP/$TEST_DIR/specs/$ver
-    [ ! -d $VER_DIR ] && continue
-    pushd $VER_DIR > /dev/null
-    for f in $@;
-    do
-      if [ -f $(basename $f) ]; then
-        generate_one_testcase $f "$LOGFILE"
-        if [ $? -ne 0 ]; then
-          echo "Failed processing $f"
-          return $?
-        fi
-        FOUND=1
-      fi
-    done
-    popd > /dev/null
-  done
-  if [[ $FOUND -eq 0 ]]; then
-    echo did not find any files for $@
-    exit 1
-  fi
-  return $?
-}
-
 # Process all test spec directory specified by NNAPI_VERSIONS.
 function generate_spec_dirs {
   cd $ANDROID_BUILD_TOP/$TEST_DIR/specs
@@ -103,12 +33,14 @@
     [ ! -d $VER_DIR ] && continue
     pushd $VER_DIR > /dev/null
 
-    TARGET_MODEL_DIR="-m $ANDROID_BUILD_TOP/$TEST_DIR/generated/models"
-    TARGET_EXAMPLE_DIR="-e $ANDROID_BUILD_TOP/$TEST_DIR/generated/examples"
-    TARGET_TEST_DIR="-t $ANDROID_BUILD_TOP/$TEST_DIR/generated/tests"
+    mkdir -p "$ANDROID_BUILD_TOP/$TEST_DIR/generated/models"
+    mkdir -p "$ANDROID_BUILD_TOP/$TEST_DIR/generated/tests"
+    mkdir -p "$ANDROID_BUILD_TOP/$TEST_DIR/generated/examples"
 
     $NNAPI_BASE/tools/test_generator/cts_generator.py $FORCE $VER_DIR \
-        $TARGET_MODEL_DIR $TARGET_EXAMPLE_DIR $TARGET_TEST_DIR
+      --model "$ANDROID_BUILD_TOP/$TEST_DIR/generated/models" \
+      --test "$ANDROID_BUILD_TOP/$TEST_DIR/generated/tests" \
+      --example "$ANDROID_BUILD_TOP/$TEST_DIR/generated/examples"
     if [ $? -ne 0 ]; then
         echo "Failed processing $VER_DIR"
         return $?
@@ -118,23 +50,15 @@
   return $?
 }
 
-# Only run the following when not sourced by another script
-if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
-  set -eu
-  if [ $# -gt 0 ]; then
-    if  [ $1 = "-f" ] || [ $1 = "--force" ]; then
-      FORCE="-f"
-      shift
-    fi
+if [ $# -gt 0 ]; then
+  if  [ $1 = "-f" ] || [ $1 = "--force" ]; then
+    FORCE="-f"
+    shift
   fi
-  if [ $# -eq 0 ]; then
-    generate_spec_dirs $FORCE
-  else
-    FILES="$@"
-    generate_wrapper $FILES
-  fi
-  if [ $? -ne 0 ]; then
-    exit $?
-  fi
-fi # [[ "${BASH_SOURCE[0]}" == "${0}" ]]
-
+fi
+if [ $# -eq 0 ]; then
+  generate_spec_dirs $FORCE
+else
+  echo "generate_wrapper is deprecated. See http://b/136099076" >&2
+  exit 1
+fi
diff --git a/nn/runtime/test/specs/generate_vts_test.sh b/nn/runtime/test/specs/generate_vts_test.sh
index c3eb487..25631e6 100755
--- a/nn/runtime/test/specs/generate_vts_test.sh
+++ b/nn/runtime/test/specs/generate_vts_test.sh
@@ -13,26 +13,26 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# usage: generate_vts_test.sh <tests>
-# usage: HAL_VERSION=V1_0 generate_vts_test.sh <tests>
-# usage: HAL_VERSION=all generate_vts_test.sh <tests>
+# usage: generate_vts_test.sh
+# usage: generate_vts_test.sh V1_0
+# usage: generate_vts_test.sh all
 
 set -Eeuo pipefail
 
 NNAPI_VERSIONS="V1_0 V1_1 V1_2"
 LATEST_NNAPI_VERSION="V1_2"
 
-# TODO: Refactor the script to make this a command-line flag.
-HAL_VERSION="${HAL_VERSION:-$LATEST_NNAPI_VERSION}"
+HAL_VERSION="${1:-$LATEST_NNAPI_VERSION}"
 
 if [[ "$HAL_VERSION" == "all" ]]; then
   # Re-call this script with each version explicitly.
   for ver in $NNAPI_VERSIONS; do
-    HAL_VERSION="$ver" "$0" "$@"
+    "$0" "$ver"
   done
   exit
 elif [[ " $NNAPI_VERSIONS " != *" $HAL_VERSION "* || "$HAL_VERSION" == *" "* ]]; then
-  echo "Unknown HAL version: $HAL_VERSION; expected one of: $NNAPI_VERSIONS all"
+  echo "Unknown HAL version: $HAL_VERSION; expected one of: $NNAPI_VERSIONS all" >&2
+  echo "Note that generate_wrapper is deprecated. See http://b/136099076" >&2
   exit 1
 fi
 
@@ -41,44 +41,6 @@
 cd "$(dirname $0)"
 
 VTS_PATH=`realpath ../`
-function generate_one_testcase {
-  # Generate one testcase
-  BASENAME=`basename -s .mod.py $1`
-  $VTS_PATH/../../tools/test_generator/vts_generator.py ./`basename $1` \
-    --model $VTS_PATH/generated/vts/$HAL_VERSION/models/$BASENAME.model.cpp \
-    --test $VTS_PATH/generated/vts/$HAL_VERSION/tests/$BASENAME.mod.py.cpp \
-    --example $VTS_PATH/generated/examples/$BASENAME.example.cpp \
-    --target_hal_version $HAL_VERSION
-}
-
-function generate_wrapper {
-  for ver in $NNAPI_VERSIONS;
-  do
-    if [[ "$ver" > "$HAL_VERSION" ]]; then
-      break
-    fi
-    VER_DIR=$VTS_PATH/specs/$ver
-    [ ! -d $VER_DIR ] && continue
-    pushd $VER_DIR > /dev/null
-    OUTFILE=$VTS_PATH/generated/vts/$HAL_VERSION/all_generated_${ver}_vts_tests.cpp
-    echo "// Generated by ml/nn/runtime/test/specs/generate_vts_test.sh" >"$OUTFILE"
-    echo "// DO NOT EDIT" >>"$OUTFILE"
-    echo "// clang-format off" >>"$OUTFILE"
-    for f in $@;
-    do
-      BASENAME="$(basename "$f")"
-      if [ -f "$BASENAME" ]; then
-        generate_one_testcase $f
-        echo "#include "\""vts/$HAL_VERSION/tests/${BASENAME}.cpp"\" >>"$OUTFILE"
-        if [ $? -ne 0 ]; then
-          echo "Failed processing $f"
-          return $?
-        fi
-      fi
-    done
-    popd > /dev/null
-  done
-}
 
 function generate_spec_dirs {
   for ver in $NNAPI_VERSIONS;
@@ -88,6 +50,9 @@
     fi
     VER_DIR=$VTS_PATH/specs/$ver
     [ ! -d $VER_DIR ] && continue
+    mkdir -p "$VTS_PATH/generated/vts/$HAL_VERSION/models"
+    mkdir -p "$VTS_PATH/generated/vts/$HAL_VERSION/tests"
+    mkdir -p "$VTS_PATH/generated/examples"
     $VTS_PATH/../../tools/test_generator/vts_generator.py $VER_DIR \
       --model $VTS_PATH/generated/vts/$HAL_VERSION/models \
       --test $VTS_PATH/generated/vts/$HAL_VERSION/tests \
@@ -105,9 +70,4 @@
   done
 }
 
-if [ $# -eq 0 ]; then
-  generate_spec_dirs
-else
-  FILES="$@"
-  generate_wrapper $FILES
-fi
+generate_spec_dirs
diff --git a/nn/tools/test_generator/README.md b/nn/tools/test_generator/README.md
index 4c6ff51..75dfef7 100644
--- a/nn/tools/test_generator/README.md
+++ b/nn/tools/test_generator/README.md
@@ -336,6 +336,14 @@
 
 This is useful when only a subset of variations has a different version.
 
+### Creating negative tests
+
+Negative test, also known as validation test, is a testing method that supplies invalid model or request, and expects the target framework or driver to fail gracefully. You can use `ExpectFailure` to tag a example as invalid.
+
+```Python
+Example.ExpectFailure()
+```
+
 ### A Complete Example
 
 ```Python
@@ -382,16 +390,6 @@
 $ANDROID_BUILD_TOP/frameworks/ml/nn/runtime/test/specs/generate_vts_test.sh
 ```
 
-It will read and generate all CTS/VTS unit tests based on spec files in `nn/runtime/test/specs/V1_*/*` if needed. CTS test generator is able to identify which spec files are modified since last generation and only regenerate those files to reduce compilation time. To force a regeneration, use `-f` flag.
-
-```
-$ANDROID_BUILD_TOP/frameworks/ml/nn/runtime/test/specs/generate_test.sh -f
-```
-
-If you only want to regenerate a certain set of files, simply append the file names to the end of the command, and optionally, use `-f` flag.
-
-```
-$ANDROID_BUILD_TOP/frameworks/ml/nn/runtime/test/specs/generate_test.sh -f file1.mod.py file2.mod.py ...
-```
+It will read and generate all CTS/VTS unit tests based on spec files in `nn/runtime/test/specs/V1_*/*` if needed. CTS test generator is able to identify which spec files are modified since last generation and only regenerate those files to reduce compilation time. To force a regeneration, use `-f` flag. The VTS test generator will regenerate tests targeting the latest HAL version by default. Pass the `all` positional argument to override.
 
 Rebuild with mm afterwards.
diff --git a/nn/tools/test_generator/cts_generator.py b/nn/tools/test_generator/cts_generator.py
index ac640da..b675c67 100755
--- a/nn/tools/test_generator/cts_generator.py
+++ b/nn/tools/test_generator/cts_generator.py
@@ -270,12 +270,19 @@
     execute({namespace}::{create_model_name},
             {namespace}::{is_ignored_name},
             {namespace}::get_{examples_name}(){log_file});\n}}\n"""
-    if example.model.version is not None:
+    if example.model.version is not None and not example.expectFailure:
         testTemplate += """\
 TEST_AVAILABLE_SINCE({version}, {test_name}, {namespace}::{create_model_name})\n"""
+
+    if example.expectFailure:
+        testCaseName = "GeneratedValidationTests"
+    elif example.model.hasDynamicOutputShape:
+        testCaseName = "DynamicOutputShapeTest"
+    else:
+        testCaseName = "GeneratedTests"
+
     print(testTemplate.format(
-        test_case_name="DynamicOutputShapeTest" if example.model.hasDynamicOutputShape \
-                       else "GeneratedTests",
+        test_case_name=testCaseName,
         test_name=str(example.testName),
         namespace=tg.FileNames.specName,
         create_model_name=str(example.model.createFunctionName),
diff --git a/nn/tools/test_generator/test_generator.py b/nn/tools/test_generator/test_generator.py
index 59fd080..a3f98ea 100755
--- a/nn/tools/test_generator/test_generator.py
+++ b/nn/tools/test_generator/test_generator.py
@@ -978,6 +978,7 @@
         self.model = Model.models[-1] if model is None else model
         self.name = name
         self.expectedMultinomialDistributionTolerance = None
+        self.expectFailure = False
         self.feedDicts = []
         for feedDict in args:
             if type(feedDict) is tuple or type(feedDict) is list:
@@ -1159,9 +1160,16 @@
     # If set to greater than zero, the input is compared as log-probabilities
     # to the output and must be within this tolerance to pass.
     def WithMultinomialDistributionTolerance(self, expectedTolerance):
+      assert self.expectFailure is False
       self.expectedMultinomialDistributionTolerance = expectedTolerance
       return self
 
+    # Specifies that this example is expected to fail during compilation or execution.
+    def ExpectFailure(self):
+      assert self.expectedMultinomialDistributionTolerance is None
+      self.expectFailure = True
+      return self
+
     # For backward-compatibility with slicing.py
     # Similar to dump_dict, but in python. Used by the slicing tool
     # if referenced is not None, only print operands that are present there
diff --git a/nn/tools/test_generator/vts_generator.py b/nn/tools/test_generator/vts_generator.py
index a222ec8..fd93520 100755
--- a/nn/tools/test_generator/vts_generator.py
+++ b/nn/tools/test_generator/vts_generator.py
@@ -287,19 +287,24 @@
     if example.model.hasDynamicOutputShape and target_hal_version < "V1_2":
         return
 
-    testTemplate = """\
+    generatedTestTemplate = """\
 TEST_F({test_case_name}, {test_name}) {{
   generated_tests::Execute(device,
                            {namespace}::{create_model_name},
                            {namespace}::{is_ignored_name},
-                           {namespace}::get_{examples_name}(){test_dynamic_output_shape});\n}}
-
+                           {namespace}::get_{examples_name}(){test_dynamic_output_shape});\n}}\n
+"""
+    validationTestTemplate = """\
 TEST_F(ValidationTest, {test_name}) {{
   const Model model = {namespace}::{create_model_name}();
   const std::vector<Request> requests = createRequests({namespace}::get_{examples_name}());
-  validateEverything(model, requests);
+  {validation_method}(model, requests);
 }}\n
 """
+
+    testTemplate = validationTestTemplate if example.expectFailure \
+                   else generatedTestTemplate + validationTestTemplate
+
     print(testTemplate.format(
             test_case_name="DynamicOutputShapeTest" if example.model.hasDynamicOutputShape \
                            else "NeuralnetworksHidlTest",
@@ -308,7 +313,8 @@
             create_model_name=str(example.model.createTestFunctionName),
             is_ignored_name=str(example.model.isIgnoredFunctionName),
             examples_name=str(example.examplesName),
-            test_dynamic_output_shape=", true" if example.model.hasDynamicOutputShape else ""
+            test_dynamic_output_shape=", true" if example.model.hasDynamicOutputShape else "",
+            validation_method="validateFailure" if example.expectFailure else "validateEverything"
         ), file=test_fd)
 
 def InitializeFiles(model_fd, example_fd, test_fd):