// Copyright 2020 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This is the boilerplate implementation of the IMapper HAL interface,
// generated by the hidl-gen tool and then modified for use on Chrome OS.
// Modifications include:
// - Removal of non boiler plate client and server related code.
// - Reformatting to meet the Chrome OS coding standards.
//
// Originally generated with the command:
// $ hidl-gen -o output -L c++ -r android.hidl:system/libhidl/transport \
//   android.hidl.memory@1.0

#include <android/hidl/memory/1.0/IMapper.h>

namespace android {
namespace hidl {
namespace memory {
namespace V1_0 {

using ::android::sp;
using ::android::hardware::hidl_death_recipient;
using ::android::hardware::hidl_handle;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;

const char* IMapper::descriptor("android.hidl.memory@1.0::IMapper");

Return<void> IMapper::interfaceChain(interfaceChain_cb _hidl_cb) {
  _hidl_cb({
      ::android::hidl::memory::V1_0::IMapper::descriptor,
      ::android::hidl::base::V1_0::IBase::descriptor,
  });
  return Void();
}

Return<void> IMapper::debug(const hidl_handle&, const hidl_vec<hidl_string>&) {
  return Void();
}

Return<void> IMapper::interfaceDescriptor(interfaceDescriptor_cb _hidl_cb) {
  _hidl_cb(::android::hidl::memory::V1_0::IMapper::descriptor);
  return Void();
}

Return<void> IMapper::getHashChain(getHashChain_cb _hidl_cb) {
  _hidl_cb(
      {/* 2b885b5dec97391c82f35e64180686dc4c8f78b2b0a01732f8536385654f27c8 */
       (uint8_t[32]){43,  136, 91,  93,  236, 151, 57,  28,  130, 243, 94,
                     100, 24,  6,   134, 220, 76,  143, 120, 178, 176, 160,
                     23,  50,  248, 83,  99,  133, 101, 79,  39,  200},
       /* ec7fd79ed02dfa85bc499426adae3ebe23ef0524f3cd6957139324b83b18ca4c */
       (uint8_t[32]){236, 127, 215, 158, 208, 45,  250, 133, 188, 73,  148,
                     38,  173, 174, 62,  190, 35,  239, 5,   36,  243, 205,
                     105, 87,  19,  147, 36,  184, 59,  24,  202, 76}});
  return Void();
}

Return<void> IMapper::setHALInstrumentation() {
  return Void();
}

Return<bool> IMapper::linkToDeath(const sp<hidl_death_recipient>& recipient,
                                  uint64_t) {
  return (recipient != nullptr);
}

Return<void> IMapper::ping() {
  return Void();
}

Return<void> IMapper::getDebugInfo(getDebugInfo_cb _hidl_cb) {
  ::android::hidl::base::V1_0::DebugInfo info = {};
  info.pid = -1;
  info.ptr = 0;
  info.arch =
#if defined(__LP64__)
      ::android::hidl::base::V1_0::DebugInfo::Architecture::IS_64BIT;
#else
      ::android::hidl::base::V1_0::DebugInfo::Architecture::IS_32BIT;
#endif

  _hidl_cb(info);
  return Void();
}

Return<void> IMapper::notifySyspropsChanged() {
  ::android::report_sysprop_change();
  return Void();
}

Return<bool> IMapper::unlinkToDeath(const sp<hidl_death_recipient>& recipient) {
  return (recipient != nullptr);
}

Return<sp<IMapper>> IMapper::castFrom(const sp<IMapper>& parent, bool) {
  return parent;
}

}  // namespace V1_0
}  // namespace memory
}  // namespace hidl
}  // namespace android
