Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6df8c2a5 authored by Fan Xu's avatar Fan Xu
Browse files

Add createBuffer to BufferHubBinderService

When calling createBuffer, bufferhubd will now alloc the buffer via
creating a BufferNode in the server side, and return you a
BpBufferClient object for communication. A BpBufferClient is binded with
one specific buffer.

Currently you could only call isValid() on the client. More APIs will be
added in future CL.

Test: "atest buffer_hub_binder_service-test". Passed
Bug: 116681016
Change-Id: I05ec627474303af46a792b0b6c2eaa904724d1f2
parent 013f5c0d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ sourceFiles = [
    "buffer_hub_base.cpp",
    "buffer_hub_rpc.cpp",
    "consumer_buffer.cpp",
    "buffer_client_impl.cpp",
    "ion_buffer.cpp",
    "producer_buffer.cpp",
]
+55 −0
Original line number Diff line number Diff line
#include <log/log.h>
#include <private/dvr/IBufferClient.h>

namespace android {
namespace dvr {

class BpBufferClient : public BpInterface<IBufferClient> {
 public:
  explicit BpBufferClient(const sp<IBinder>& impl)
      : BpInterface<IBufferClient>(impl) {}

  bool isValid() override;
};

IMPLEMENT_META_INTERFACE(BufferClient, "android.dvr.IBufferClient");

// Transaction code
enum {
  IS_VALID = IBinder::FIRST_CALL_TRANSACTION,
};

bool BpBufferClient::isValid() {
  Parcel data, reply;
  status_t ret =
      data.writeInterfaceToken(IBufferClient::getInterfaceDescriptor());
  if (ret != NO_ERROR) {
    ALOGE("BpBufferClient::isValid: failed to write into parcel; errno=%d",
          ret);
    return false;
  }

  ret = remote()->transact(IS_VALID, data, &reply);
  if (ret == NO_ERROR) {
    return reply.readBool();
  } else {
    ALOGE("BpBufferClient::isValid: failed to transact; errno=%d", ret);
    return false;
  }
}

status_t BnBufferClient::onTransact(uint32_t code, const Parcel& data,
                                    Parcel* reply, uint32_t flags) {
  switch (code) {
    case IS_VALID: {
      CHECK_INTERFACE(IBufferClient, data, reply);
      return reply->writeBool(isValid());
    } break;
    default:
      // Should not reach except binder defined transactions such as dumpsys
      return BBinder::onTransact(code, data, reply, flags);
  }
}

}  // namespace dvr
}  // namespace android
 No newline at end of file
+29 −0
Original line number Diff line number Diff line
#ifndef ANDROID_DVR_IBUFFERCLIENT_H
#define ANDROID_DVR_IBUFFERCLIENT_H

#include <binder/IInterface.h>
#include <binder/Parcel.h>

namespace android {
namespace dvr {

// Interface for acessing BufferHubBuffer remotely.
class IBufferClient : public IInterface {
 public:
  DECLARE_META_INTERFACE(BufferClient);

  // Checks if the buffer node is valid.
  virtual bool isValid() = 0;
};

// BnInterface for IBufferClient. Should only be created in bufferhub service.
class BnBufferClient : public BnInterface<IBufferClient> {
 public:
  virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
                              uint32_t flags = 0);
};

}  // namespace dvr
}  // namespace android

#endif  // ANDROID_DVR_IBUFFERCLIENT_H
 No newline at end of file
+57 −2
Original line number Diff line number Diff line
@@ -4,14 +4,69 @@
namespace android {
namespace dvr {

class BpBufferHub : public BpInterface<IBufferHub> {
 public:
  explicit BpBufferHub(const sp<IBinder>& impl)
      : BpInterface<IBufferHub>(impl) {}

  sp<IBufferClient> createBuffer(uint32_t width, uint32_t height,
                                 uint32_t layer_count, uint32_t format,
                                 uint64_t usage,
                                 uint64_t user_metadata_size) override;
};

IMPLEMENT_META_INTERFACE(BufferHub, "android.dvr.IBufferHub");

// Transaction code
enum {
  CREATE_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
};

sp<IBufferClient> BpBufferHub::createBuffer(uint32_t width, uint32_t height,
                                            uint32_t layer_count,
                                            uint32_t format, uint64_t usage,
                                            uint64_t user_metadata_size) {
  Parcel data, reply;
  status_t ret = NO_ERROR;
  ret |= data.writeInterfaceToken(IBufferHub::getInterfaceDescriptor());
  ret |= data.writeUint32(width);
  ret |= data.writeUint32(height);
  ret |= data.writeUint32(layer_count);
  ret |= data.writeUint32(format);
  ret |= data.writeUint64(usage);
  ret |= data.writeUint64(user_metadata_size);

  if (ret != NO_ERROR) {
    ALOGE("BpBufferHub::createBuffer: failed to write into parcel");
    return nullptr;
  }

  ret = remote()->transact(CREATE_BUFFER, data, &reply);
  if (ret == NO_ERROR) {
    return interface_cast<IBufferClient>(reply.readStrongBinder());
  } else {
    ALOGE("BpBufferHub::createBuffer: failed to transact; errno=%d", ret);
    return nullptr;
  }
}

status_t BnBufferHub::onTransact(uint32_t code, const Parcel& data,
                                 Parcel* reply, uint32_t flags) {
  switch (code) {
    case CREATE_BUFFER: {
      CHECK_INTERFACE(IBufferHub, data, reply);
      uint32_t width = data.readUint32();
      uint32_t height = data.readUint32();
      uint32_t layer_count = data.readUint32();
      uint32_t format = data.readUint32();
      uint64_t usage = data.readUint64();
      uint64_t user_metadata_size = data.readUint64();
      sp<IBufferClient> ret = createBuffer(width, height, layer_count, format,
                                           usage, user_metadata_size);
      return reply->writeStrongBinder(IInterface::asBinder(ret));
    } break;
    default:
      // Should not reach
      ALOGE("onTransact(): unknown code %u received!", code);
      // Should not reach except binder defined transactions such as dumpsys
      return BBinder::onTransact(code, data, reply, flags);
  }
}
+14 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#include <binder/ProcessState.h>
#include <log/log.h>
#include <private/dvr/buffer_hub_binder.h>
#include <private/dvr/buffer_node.h>

namespace android {
namespace dvr {
@@ -77,5 +78,18 @@ sp<IBufferHub> BufferHubBinderService::getServiceProxy() {
  return ret;
}

sp<IBufferClient> BufferHubBinderService::createBuffer(
    uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
    uint64_t usage, uint64_t user_metadata_size) {
  std::shared_ptr<BufferNode> node = std::make_shared<BufferNode>(
      width, height, layer_count, format, usage, user_metadata_size);

  sp<BufferClient> client = new BufferClient(node);
  // Add it to list for bookkeeping and dumpsys.
  client_list_.push_back(client);

  return client;
}

}  // namespace dvr
}  // namespace android
Loading