Update BufferHub service/client with support for gralloc1 usage.

- Add support for gralloc1 usage flags.
- Mimic how GraphicBuffer supports gralloc0 usage flags: (usage, usage).
- Move to using pdx::Status<T> since we're touching signatures everywhere.

Bug: 36401174
Test: bufferhub_tests; buffer_hub_queue-test
Change-Id: I0e5184197b21eda9806bbea44f63b546b030692a
diff --git a/services/vr/bufferhubd/buffer_hub.cpp b/services/vr/bufferhubd/buffer_hub.cpp
index 2ce60e5..4b1a522 100644
--- a/services/vr/bufferhubd/buffer_hub.cpp
+++ b/services/vr/bufferhubd/buffer_hub.cpp
@@ -1,5 +1,6 @@
 #include "buffer_hub.h"
 
+#include <inttypes.h>
 #include <log/log.h>
 #include <poll.h>
 #include <utils/Trace.h>
@@ -52,7 +53,7 @@
   stream << " ";
   stream << std::setw(6) << "Format";
   stream << " ";
-  stream << std::setw(10) << "Usage";
+  stream << std::setw(21) << "Usage";
   stream << " ";
   stream << "Name";
   stream << std::endl;
@@ -79,7 +80,9 @@
       stream << std::setw(6) << info.format;
       stream << " ";
       stream << "0x" << std::hex << std::setfill('0');
-      stream << std::setw(8) << info.usage;
+      stream << std::setw(8) << info.producer_usage;
+      stream << "0x";
+      stream << std::setw(8) << info.consumer_usage;
       stream << std::dec << std::setfill(' ');
       stream << " ";
       stream << info.name;
@@ -137,6 +140,10 @@
   stream << " UsageClearMask";
   stream << " UsageDenySetMask";
   stream << " UsageDenyClearMask";
+  stream << " UsageSetMask";
+  stream << " UsageClearMask";
+  stream << " UsageDenySetMask";
+  stream << " UsageDenyClearMask";
   stream << " ";
   stream << std::endl;
 
@@ -150,16 +157,30 @@
       stream << std::right << std::setw(12) << info.consumer_count;
       stream << std::setw(5) << std::setfill(' ') << "0x";
       stream << std::hex << std::setfill('0');
-      stream << std::setw(8) << info.usage_set_mask;
+      stream << std::setw(8) << info.usage_policy.producer_set_mask;
       stream << std::setw(7) << std::setfill(' ') << "0x";
       stream << std::hex << std::setfill('0');
-      stream << std::setw(8) << info.usage_clear_mask;
+      stream << std::setw(8) << info.usage_policy.producer_clear_mask;
       stream << std::setw(9) << std::setfill(' ') << "0x";
       stream << std::hex << std::setfill('0');
-      stream << std::setw(8) << info.usage_deny_set_mask;
+      stream << std::setw(8) << info.usage_policy.producer_deny_set_mask;
       stream << std::setw(11) << std::setfill(' ') << "0x";
       stream << std::hex << std::setfill('0');
-      stream << std::setw(8) << info.usage_deny_clear_mask;
+      stream << std::setw(8) << info.usage_policy.producer_deny_clear_mask;
+      stream << std::setw(5) << std::setfill(' ') << "0x";
+      stream << std::hex << std::setfill('0');
+      stream << std::setw(8) << info.usage_policy.consumer_set_mask;
+      stream << std::setw(7) << std::setfill(' ') << "0x";
+      stream << std::hex << std::setfill('0');
+      stream << std::setw(8) << info.usage_policy.consumer_clear_mask;
+      stream << std::setw(9) << std::setfill(' ') << "0x";
+      stream << std::hex << std::setfill('0');
+      stream << std::setw(8) << info.usage_policy.consumer_deny_set_mask;
+      stream << std::setw(11) << std::setfill(' ') << "0x";
+      stream << std::hex << std::setfill('0');
+      stream << std::setw(8) << info.usage_policy.consumer_deny_clear_mask;
+      stream << std::hex << std::setfill('0');
+      stream << std::endl;
     }
   }
 
@@ -177,6 +198,7 @@
 
       stream << std::right << std::setw(6) << info.id;
       stream << std::right << std::setw(12) << info.capacity;
+      stream << std::endl;
     }
   }
 
@@ -235,48 +257,53 @@
     buffer->Detach();
 }
 
-int BufferHubService::OnCreateBuffer(Message& message, int width, int height,
-                                     int format, int usage,
-                                     size_t meta_size_bytes,
-                                     size_t slice_count) {
+Status<void> BufferHubService::OnCreateBuffer(Message& message, uint32_t width,
+                                              uint32_t height, uint32_t format,
+                                              uint64_t producer_usage,
+                                              uint64_t consumer_usage,
+                                              size_t meta_size_bytes,
+                                              size_t slice_count) {
   // Use the producer channel id as the global buffer id.
   const int buffer_id = message.GetChannelId();
   ALOGD_IF(TRACE,
-           "BufferHubService::OnCreateBuffer: buffer_id=%d width=%d height=%d "
-           "format=%d usage=%d meta_size_bytes=%zu slice_count=%zu",
-           buffer_id, width, height, format, usage, meta_size_bytes,
-           slice_count);
+           "BufferHubService::OnCreateBuffer: buffer_id=%d width=%u height=%u "
+           "format=%u producer_usage=%" PRIx64 " consumer_usage=%" PRIx64
+           " meta_size_bytes=%zu slice_count=%zu",
+           buffer_id, width, height, format, producer_usage, consumer_usage,
+           meta_size_bytes, slice_count);
 
   // See if this channel is already attached to a buffer.
   if (const auto channel = message.GetChannel<BufferHubChannel>()) {
     ALOGE("BufferHubService::OnCreateBuffer: Buffer already created: buffer=%d",
           buffer_id);
-    return -EALREADY;
+    return ErrorStatus(EALREADY);
   }
 
-  int error;
-  if (const auto producer_channel =
-          ProducerChannel::Create(this, buffer_id, width, height, format, usage,
-                                  meta_size_bytes, slice_count, &error)) {
-    message.SetChannel(producer_channel);
-    return 0;
+  auto status = ProducerChannel::Create(this, buffer_id, width, height, format,
+                                        producer_usage, consumer_usage,
+                                        meta_size_bytes, slice_count);
+  if (status) {
+    message.SetChannel(status.take());
+    return {};
   } else {
-    ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer!!");
-    return error;
+    ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer: %s",
+          status.GetErrorMessage().c_str());
+    return status.error_status();
   }
 }
 
-int BufferHubService::OnCreatePersistentBuffer(
+Status<void> BufferHubService::OnCreatePersistentBuffer(
     Message& message, const std::string& name, int user_id, int group_id,
-    int width, int height, int format, int usage, size_t meta_size_bytes,
-    size_t slice_count) {
+    uint32_t width, uint32_t height, uint32_t format, uint64_t producer_usage,
+    uint64_t consumer_usage, size_t meta_size_bytes, size_t slice_count) {
   const int channel_id = message.GetChannelId();
   ALOGD_IF(TRACE,
            "BufferHubService::OnCreatePersistentBuffer: channel_id=%d name=%s "
-           "user_id=%d group_id=%d width=%d height=%d format=%d usage=%d "
-           "meta_size_bytes=%zu slice_count=%zu",
+           "user_id=%d group_id=%d width=%u height=%u format=%u "
+           "producer_usage=%" PRIx64 " consumer_usage=%" PRIx64
+           " meta_size_bytes=%zu slice_count=%zu",
            channel_id, name.c_str(), user_id, group_id, width, height, format,
-           usage, meta_size_bytes, slice_count);
+           producer_usage, consumer_usage, meta_size_bytes, slice_count);
 
   // See if this channel is already attached to a buffer.
   if (const auto channel = message.GetChannel<BufferHubChannel>()) {
@@ -284,12 +311,11 @@
         "BufferHubService::OnCreatePersistentBuffer: Channel already attached "
         "to buffer: channel_id=%d buffer_id=%d",
         channel_id, channel->buffer_id());
-    return -EALREADY;
+    return ErrorStatus(EALREADY);
   }
 
   const int euid = message.GetEffectiveUserId();
   const int egid = message.GetEffectiveGroupId();
-  int error;
 
   if (auto buffer = GetNamedBuffer(name)) {
     if (!buffer->CheckAccess(euid, egid)) {
@@ -297,41 +323,45 @@
           "BufferHubService::OnCreatePersistentBuffer: Requesting process does "
           "not have permission to access named buffer: name=%s euid=%d egid=%d",
           name.c_str(), euid, euid);
-      return -EPERM;
-    } else if (!buffer->CheckParameters(width, height, format, usage,
-                                        meta_size_bytes, slice_count)) {
+      return ErrorStatus(EPERM);
+    } else if (!buffer->CheckParameters(width, height, format, producer_usage,
+                                        consumer_usage, meta_size_bytes,
+                                        slice_count)) {
       ALOGE(
           "BufferHubService::OnCreatePersistentBuffer: Requested an existing "
           "buffer with different parameters: name=%s",
           name.c_str());
-      return -EINVAL;
+      return ErrorStatus(EINVAL);
     } else if (!buffer->IsDetached()) {
       ALOGE(
           "BufferHubService::OnCreatePersistentBuffer: Requesting a persistent "
           "buffer that is already attached to a channel: name=%s",
           name.c_str());
-      return -EINVAL;
+      return ErrorStatus(EINVAL);
     } else {
       buffer->Attach(channel_id);
       message.SetChannel(buffer);
-      return 0;
+      return {};
     }
-  } else if (auto buffer = ProducerChannel::Create(
-                 this, channel_id, width, height, format, usage,
-                 meta_size_bytes, slice_count, &error)) {
-    const int ret =
-        buffer->OnProducerMakePersistent(message, name, user_id, group_id);
-    if (!ret)
-      message.SetChannel(buffer);
-    return ret;
   } else {
-    ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer!!");
-    return error;
+    auto status = ProducerChannel::Create(
+        this, channel_id, width, height, format, producer_usage, consumer_usage,
+        meta_size_bytes, slice_count);
+    if (!status) {
+      ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer!!");
+      return status.error_status();
+    }
+    auto persistent_buffer = status.take();
+    auto make_persistent_status = persistent_buffer->OnProducerMakePersistent(
+        message, name, user_id, group_id);
+    if (make_persistent_status)
+      message.SetChannel(persistent_buffer);
+    return make_persistent_status;
   }
 }
 
-int BufferHubService::OnGetPersistentBuffer(Message& message,
-                                            const std::string& name) {
+Status<void> BufferHubService::OnGetPersistentBuffer(Message& message,
+                                                     const std::string& name) {
   const int channel_id = message.GetChannelId();
   ALOGD_IF(TRACE,
            "BufferHubService::OnGetPersistentBuffer: channel_id=%d name=%s",
@@ -343,7 +373,7 @@
         "BufferHubService::OnGetPersistentBuffer: Channel already attached to "
         "buffer: channel_id=%d buffer_id=%d",
         channel_id, channel->buffer_id());
-    return -EALREADY;
+    return ErrorStatus(EALREADY);
   }
 
   const int euid = message.GetEffectiveUserId();
@@ -355,28 +385,28 @@
           "BufferHubService::OnGetPersistentBuffer: Requesting process does "
           "not have permission to access named buffer: name=%s euid=%d egid=%d",
           name.c_str(), euid, egid);
-      return -EPERM;
+      return ErrorStatus(EPERM);
     } else if (!buffer->IsDetached()) {
       ALOGE(
           "BufferHubService::OnGetPersistentBuffer: Requesting a persistent "
           "buffer that is already attached to a channel: name=%s",
           name.c_str());
-      return -EINVAL;
+      return ErrorStatus(EINVAL);
     } else {
       buffer->Attach(channel_id);
       message.SetChannel(buffer);
-      return 0;
+      return {};
     }
   } else {
     ALOGE("BufferHubService::OnGetPersistentBuffer: Buffer \"%s\" not found!",
           name.c_str());
-    return -ENOENT;
+    return ErrorStatus(ENOENT);
   }
 }
 
 Status<QueueInfo> BufferHubService::OnCreateProducerQueue(
-    pdx::Message& message, size_t meta_size_bytes, int usage_set_mask,
-    int usage_clear_mask, int usage_deny_set_mask, int usage_deny_clear_mask) {
+    pdx::Message& message, size_t meta_size_bytes,
+    const UsagePolicy& usage_policy) {
   // Use the producer channel id as the global queue id.
   const int queue_id = message.GetChannelId();
   ALOGD_IF(TRACE, "BufferHubService::OnCreateProducerQueue: queue_id=%d",
@@ -389,15 +419,14 @@
     return ErrorStatus(EALREADY);
   }
 
-  int error;
-  if (const auto producer_channel = ProducerQueueChannel::Create(
-          this, queue_id, meta_size_bytes, usage_set_mask, usage_clear_mask,
-          usage_deny_set_mask, usage_deny_clear_mask, &error)) {
-    message.SetChannel(producer_channel);
+  auto status = ProducerQueueChannel::Create(this, queue_id, meta_size_bytes,
+                                             usage_policy);
+  if (status) {
+    message.SetChannel(status.take());
     return {{meta_size_bytes, queue_id}};
   } else {
     ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer!!");
-    return ErrorStatus(-error);
+    return status.error_status();
   }
 }
 
diff --git a/services/vr/bufferhubd/buffer_hub.h b/services/vr/bufferhubd/buffer_hub.h
index 150e399..4cb1eb9 100644
--- a/services/vr/bufferhubd/buffer_hub.h
+++ b/services/vr/bufferhubd/buffer_hub.h
@@ -48,43 +48,40 @@
     size_t consumer_count = 0;
 
     // Data field for buffer producer.
-    int width = 0;
-    int height = 0;
-    int format = 0;
-    int usage = 0;
+    uint32_t width = 0;
+    uint32_t height = 0;
+    uint32_t format = 0;
+    uint64_t producer_usage = 0;
+    uint64_t consumer_usage = 0;
     size_t slice_count = 0;
     std::string name;
 
     // Data filed for producer queue.
     size_t capacity = 0;
-    int usage_set_mask = 0;
-    int usage_clear_mask = 0;
-    int usage_deny_set_mask = 0;
-    int usage_deny_clear_mask = 0;
+    UsagePolicy usage_policy{0, 0, 0, 0, 0, 0, 0, 0};
 
-    BufferInfo(int id, size_t consumer_count, int width, int height, int format,
-               int usage, size_t slice_count, const std::string& name)
+    BufferInfo(int id, size_t consumer_count, uint32_t width, uint32_t height,
+               uint32_t format, uint64_t producer_usage,
+               uint64_t consumer_usage, size_t slice_count,
+               const std::string& name)
         : id(id),
           type(kProducerType),
           consumer_count(consumer_count),
           width(width),
           height(height),
           format(format),
-          usage(usage),
+          producer_usage(producer_usage),
+          consumer_usage(consumer_usage),
           slice_count(slice_count),
           name(name) {}
 
     BufferInfo(int id, size_t consumer_count, size_t capacity,
-               int usage_set_mask, int usage_clear_mask,
-               int usage_deny_set_mask, int usage_deny_clear_mask)
+               const UsagePolicy& usage_policy)
         : id(id),
           type(kProducerQueueType),
           consumer_count(consumer_count),
           capacity(capacity),
-          usage_set_mask(usage_set_mask),
-          usage_clear_mask(usage_clear_mask),
-          usage_deny_set_mask(usage_deny_set_mask),
-          usage_deny_clear_mask(usage_deny_clear_mask) {}
+          usage_policy(usage_policy) {}
 
     BufferInfo() {}
   };
@@ -162,16 +159,19 @@
   std::unordered_map<std::string, std::shared_ptr<ProducerChannel>>
       named_buffers_;
 
-  int OnCreateBuffer(pdx::Message& message, int width, int height, int format,
-                     int usage, size_t meta_size_bytes, size_t slice_count);
-  int OnCreatePersistentBuffer(pdx::Message& message, const std::string& name,
-                               int user_id, int group_id, int width, int height,
-                               int format, int usage, size_t meta_size_bytes,
-                               size_t slice_count);
-  int OnGetPersistentBuffer(pdx::Message& message, const std::string& name);
-  pdx::Status<QueueInfo> OnCreateProducerQueue(
-      pdx::Message& message, size_t meta_size_bytes, int usage_set_mask,
-      int usage_clear_mask, int usage_deny_set_mask, int usage_deny_clear_mask);
+  pdx::Status<void> OnCreateBuffer(pdx::Message& message, uint32_t width, uint32_t height,
+                     uint32_t format, uint64_t producer_usage,
+                     uint64_t consumer_usage, size_t meta_size_bytes,
+                     size_t slice_count);
+  pdx::Status<void> OnCreatePersistentBuffer(pdx::Message& message, const std::string& name,
+                               int user_id, int group_id, uint32_t width,
+                               uint32_t height, uint32_t format,
+                               uint64_t producer_usage, uint64_t consumer_usage,
+                               size_t meta_size_bytes, size_t slice_count);
+  pdx::Status<void> OnGetPersistentBuffer(pdx::Message& message, const std::string& name);
+  pdx::Status<QueueInfo> OnCreateProducerQueue(pdx::Message& message,
+                                               size_t meta_size_bytes,
+                                               const UsagePolicy& usage_policy);
 
   BufferHubService(const BufferHubService&) = delete;
   void operator=(const BufferHubService&) = delete;
diff --git a/services/vr/bufferhubd/consumer_channel.cpp b/services/vr/bufferhubd/consumer_channel.cpp
index 2264cef..311f5c6 100644
--- a/services/vr/bufferhubd/consumer_channel.cpp
+++ b/services/vr/bufferhubd/consumer_channel.cpp
@@ -8,9 +8,11 @@
 #include <private/dvr/bufferhub_rpc.h>
 #include "producer_channel.h"
 
+using android::pdx::ErrorStatus;
 using android::pdx::BorrowedHandle;
 using android::pdx::Channel;
 using android::pdx::Message;
+using android::pdx::Status;
 using android::pdx::rpc::DispatchRemoteMethod;
 
 namespace android {
@@ -103,53 +105,53 @@
   }
 }
 
-std::pair<BorrowedFence, ConsumerChannel::MetaData>
+Status<std::pair<BorrowedFence, ConsumerChannel::MetaData>>
 ConsumerChannel::OnConsumerAcquire(Message& message,
                                    std::size_t metadata_size) {
   ATRACE_NAME("ConsumerChannel::OnConsumerAcquire");
   auto producer = GetProducer();
   if (!producer)
-    REPLY_ERROR_RETURN(message, EPIPE, {});
+    return ErrorStatus(EPIPE);
 
   if (ignored_ || handled_) {
     ALOGE(
         "ConsumerChannel::OnConsumerAcquire: Acquire when not posted: "
         "ignored=%d handled=%d channel_id=%d buffer_id=%d",
         ignored_, handled_, message.GetChannelId(), producer->buffer_id());
-    REPLY_ERROR_RETURN(message, EBUSY, {});
+    return ErrorStatus(EBUSY);
   } else {
     ClearAvailable();
     return producer->OnConsumerAcquire(message, metadata_size);
   }
 }
 
-int ConsumerChannel::OnConsumerRelease(Message& message,
-                                       LocalFence release_fence) {
+Status<void> ConsumerChannel::OnConsumerRelease(Message& message,
+                                                LocalFence release_fence) {
   ATRACE_NAME("ConsumerChannel::OnConsumerRelease");
   auto producer = GetProducer();
   if (!producer)
-    return -EPIPE;
+    return ErrorStatus(EPIPE);
 
   if (ignored_ || handled_) {
     ALOGE(
         "ConsumerChannel::OnConsumerRelease: Release when not acquired: "
         "ignored=%d handled=%d channel_id=%d buffer_id=%d",
         ignored_, handled_, message.GetChannelId(), producer->buffer_id());
-    return -EBUSY;
+    return ErrorStatus(EBUSY);
   } else {
     ClearAvailable();
-    const int ret =
+    auto status =
         producer->OnConsumerRelease(message, std::move(release_fence));
-    handled_ = ret == 0;
-    return ret;
+    handled_ = !!status;
+    return status;
   }
 }
 
-int ConsumerChannel::OnConsumerSetIgnore(Message&, bool ignored) {
+Status<void> ConsumerChannel::OnConsumerSetIgnore(Message&, bool ignored) {
   ATRACE_NAME("ConsumerChannel::OnConsumerSetIgnore");
   auto producer = GetProducer();
   if (!producer)
-    return -EPIPE;
+    return ErrorStatus(EPIPE);
 
   ignored_ = ignored;
   if (ignored_ && !handled_) {
@@ -160,7 +162,7 @@
     handled_ = false;
   }
 
-  return 0;
+  return {};
 }
 
 bool ConsumerChannel::OnProducerPosted() {
diff --git a/services/vr/bufferhubd/consumer_channel.h b/services/vr/bufferhubd/consumer_channel.h
index d2a078f..d84055c 100644
--- a/services/vr/bufferhubd/consumer_channel.h
+++ b/services/vr/bufferhubd/consumer_channel.h
@@ -32,10 +32,11 @@
 
   std::shared_ptr<ProducerChannel> GetProducer() const;
 
-  std::pair<BorrowedFence, MetaData> OnConsumerAcquire(
+  pdx::Status<std::pair<BorrowedFence, MetaData>> OnConsumerAcquire(
       Message& message, std::size_t metadata_size);
-  int OnConsumerRelease(Message& message, LocalFence release_fence);
-  int OnConsumerSetIgnore(Message& message, bool ignore);
+  pdx::Status<void> OnConsumerRelease(Message& message,
+                                      LocalFence release_fence);
+  pdx::Status<void> OnConsumerSetIgnore(Message& message, bool ignore);
 
   bool handled_;  // True if we have processed RELEASE.
   bool ignored_;  // True if we are ignoring events.
diff --git a/services/vr/bufferhubd/consumer_queue_channel.cpp b/services/vr/bufferhubd/consumer_queue_channel.cpp
index cc16f1f..7422751 100644
--- a/services/vr/bufferhubd/consumer_queue_channel.cpp
+++ b/services/vr/bufferhubd/consumer_queue_channel.cpp
@@ -4,7 +4,9 @@
 
 #include "producer_channel.h"
 
+using android::pdx::ErrorStatus;
 using android::pdx::RemoteChannelHandle;
+using android::pdx::Status;
 using android::pdx::rpc::DispatchRemoteMethod;
 
 namespace android {
@@ -83,7 +85,7 @@
   SignalAvailable();
 }
 
-std::vector<std::pair<RemoteChannelHandle, size_t>>
+Status<std::vector<std::pair<RemoteChannelHandle, size_t>>>
 ConsumerQueueChannel::OnConsumerQueueImportBuffers(Message& message) {
   std::vector<std::pair<RemoteChannelHandle, size_t>> buffer_handles;
   ATRACE_NAME("ConsumerQueueChannel::OnConsumerQueueImportBuffers");
@@ -106,31 +108,30 @@
       continue;
     }
 
-    RemoteChannelHandle consumer_handle(
-        producer_channel->CreateConsumer(message));
+    auto status = producer_channel->CreateConsumer(message);
 
     // If no buffers are imported successfully, clear available and return an
     // error. Otherwise, return all consumer handles already imported
     // successfully, but keep available bits on, so that the client can retry
     // importing remaining consumer buffers.
-    if (!consumer_handle.valid()) {
+    if (!status) {
       ALOGE(
-          "ConsumerQueueChannel::OnConsumerQueueImportBuffers: imported "
-          "consumer handle is invalid.");
+          "ConsumerQueueChannel::OnConsumerQueueImportBuffers: Failed create "
+          "consumer: %s",
+          status.GetErrorMessage().c_str());
       if (buffer_handles.empty()) {
         ClearAvailable();
-        REPLY_ERROR_RETURN(message, EIO, {});
+        return status.error_status();
       } else {
-        return buffer_handles;
+        return {std::move(buffer_handles)};
       }
     }
 
-    // Move consumer_handle into buffer_handles.
-    buffer_handles.emplace_back(std::move(consumer_handle), producer_slot);
+    buffer_handles.emplace_back(status.take(), producer_slot);
   }
 
   ClearAvailable();
-  return buffer_handles;
+  return {std::move(buffer_handles)};
 }
 
 }  // namespace dvr
diff --git a/services/vr/bufferhubd/consumer_queue_channel.h b/services/vr/bufferhubd/consumer_queue_channel.h
index b345595..e1005e4 100644
--- a/services/vr/bufferhubd/consumer_queue_channel.h
+++ b/services/vr/bufferhubd/consumer_queue_channel.h
@@ -36,7 +36,7 @@
   // allocated. Clients uses kOpConsumerQueueImportBuffers to import new
   // consumer buffers and this handler returns a vector of fd representing
   // BufferConsumers that clients can import.
-  std::vector<std::pair<RemoteChannelHandle, size_t>>
+  pdx::Status<std::vector<std::pair<RemoteChannelHandle, size_t>>>
   OnConsumerQueueImportBuffers(Message& message);
 
  private:
diff --git a/services/vr/bufferhubd/producer_channel.cpp b/services/vr/bufferhubd/producer_channel.cpp
index 903d174..c946a8d 100644
--- a/services/vr/bufferhubd/producer_channel.cpp
+++ b/services/vr/bufferhubd/producer_channel.cpp
@@ -13,8 +13,10 @@
 #include "consumer_channel.h"
 
 using android::pdx::BorrowedHandle;
+using android::pdx::ErrorStatus;
 using android::pdx::Message;
 using android::pdx::RemoteChannelHandle;
+using android::pdx::Status;
 using android::pdx::rpc::BufferWrapper;
 using android::pdx::rpc::DispatchRemoteMethod;
 using android::pdx::rpc::WrapBuffer;
@@ -23,7 +25,9 @@
 namespace dvr {
 
 ProducerChannel::ProducerChannel(BufferHubService* service, int channel_id,
-                                 int width, int height, int format, int usage,
+                                 uint32_t width, uint32_t height,
+                                 uint32_t format, uint64_t producer_usage,
+                                 uint64_t consumer_usage,
                                  size_t meta_size_bytes, size_t slice_count,
                                  int* error)
     : BufferHubChannel(service, channel_id, channel_id, kProducerType),
@@ -33,7 +37,8 @@
       meta_size_bytes_(meta_size_bytes),
       meta_(meta_size_bytes ? new uint8_t[meta_size_bytes] : nullptr) {
   for (auto& ion_buffer : slices_) {
-    const int ret = ion_buffer.Alloc(width, height, format, usage);
+    const int ret =
+        ion_buffer.Alloc(width, height, format, producer_usage, consumer_usage);
     if (ret < 0) {
       ALOGE("ProducerChannel::ProducerChannel: Failed to allocate buffer: %s",
             strerror(-ret));
@@ -46,17 +51,18 @@
   *error = 0;
 }
 
-std::shared_ptr<ProducerChannel> ProducerChannel::Create(
-    BufferHubService* service, int channel_id, int width, int height,
-    int format, int usage, size_t meta_size_bytes, size_t slice_count,
-    int* error) {
-  std::shared_ptr<ProducerChannel> producer(
-      new ProducerChannel(service, channel_id, width, height, format, usage,
-                          meta_size_bytes, slice_count, error));
-  if (*error < 0)
-    return nullptr;
+Status<std::shared_ptr<ProducerChannel>> ProducerChannel::Create(
+    BufferHubService* service, int channel_id, uint32_t width, uint32_t height,
+    uint32_t format, uint64_t producer_usage, uint64_t consumer_usage,
+    size_t meta_size_bytes, size_t slice_count) {
+  int error;
+  std::shared_ptr<ProducerChannel> producer(new ProducerChannel(
+      service, channel_id, width, height, format, producer_usage,
+      consumer_usage, meta_size_bytes, slice_count, &error));
+  if (error < 0)
+    return ErrorStatus(-error);
   else
-    return producer;
+    return {std::move(producer)};
 }
 
 ProducerChannel::~ProducerChannel() {
@@ -70,7 +76,8 @@
 BufferHubChannel::BufferInfo ProducerChannel::GetBufferInfo() const {
   return BufferInfo(buffer_id(), consumer_channels_.size(), slices_[0].width(),
                     slices_[0].height(), slices_[0].format(),
-                    slices_[0].usage(), slices_.size(), name_);
+                    slices_[0].producer_usage(), slices_[0].consumer_usage(),
+                    slices_.size(), name_);
 }
 
 void ProducerChannel::HandleImpulse(Message& message) {
@@ -125,28 +132,28 @@
   }
 }
 
-NativeBufferHandle<BorrowedHandle> ProducerChannel::OnGetBuffer(
+Status<NativeBufferHandle<BorrowedHandle>> ProducerChannel::OnGetBuffer(
     Message& message, unsigned index) {
   ATRACE_NAME("ProducerChannel::OnGetBuffer");
   ALOGD_IF(TRACE, "ProducerChannel::OnGetBuffer: buffer=%d", buffer_id());
   if (index < slices_.size()) {
-    return NativeBufferHandle<BorrowedHandle>(slices_[index], buffer_id());
+    return {NativeBufferHandle<BorrowedHandle>(slices_[index], buffer_id())};
   } else {
-    REPLY_ERROR_RETURN(message, EINVAL, NativeBufferHandle<BorrowedHandle>());
+    return ErrorStatus(EINVAL);
   }
 }
 
-std::vector<NativeBufferHandle<BorrowedHandle>> ProducerChannel::OnGetBuffers(
-    Message&) {
+Status<std::vector<NativeBufferHandle<BorrowedHandle>>>
+ProducerChannel::OnGetBuffers(Message&) {
   ATRACE_NAME("ProducerChannel::OnGetBuffers");
   ALOGD_IF(TRACE, "ProducerChannel::OnGetBuffers: buffer_id=%d", buffer_id());
   std::vector<NativeBufferHandle<BorrowedHandle>> buffer_handles;
   for (const auto& buffer : slices_)
     buffer_handles.emplace_back(buffer, buffer_id());
-  return buffer_handles;
+  return {std::move(buffer_handles)};
 }
 
-RemoteChannelHandle ProducerChannel::CreateConsumer(Message& message) {
+Status<RemoteChannelHandle> ProducerChannel::CreateConsumer(Message& message) {
   ATRACE_NAME("ProducerChannel::CreateConsumer");
   ALOGD_IF(TRACE, "ProducerChannel::CreateConsumer: buffer_id=%d", buffer_id());
 
@@ -154,9 +161,9 @@
   auto status = message.PushChannel(0, nullptr, &channel_id);
   if (!status) {
     ALOGE(
-        "ProducerChannel::CreateConsumer: failed to push consumer channel: %s",
+        "ProducerChannel::CreateConsumer: Failed to push consumer channel: %s",
         status.GetErrorMessage().c_str());
-    return RemoteChannelHandle();
+    return ErrorStatus(ENOMEM);
   }
 
   auto consumer = std::make_shared<ConsumerChannel>(
@@ -167,7 +174,7 @@
         "ProducerChannel::CreateConsumer: failed to set new consumer channel: "
         "%s",
         channel_status.GetErrorMessage().c_str());
-    return RemoteChannelHandle();
+    return ErrorStatus(ENOMEM);
   }
 
   if (!producer_owns_) {
@@ -176,33 +183,27 @@
       pending_consumers_++;
   }
 
-  return status.take();
+  return {status.take()};
 }
 
-RemoteChannelHandle ProducerChannel::OnNewConsumer(Message& message) {
+Status<RemoteChannelHandle> ProducerChannel::OnNewConsumer(Message& message) {
   ATRACE_NAME("ProducerChannel::OnNewConsumer");
   ALOGD_IF(TRACE, "ProducerChannel::OnNewConsumer: buffer_id=%d", buffer_id());
-
-  RemoteChannelHandle consumer_handle(CreateConsumer(message));
-
-  if (consumer_handle.valid())
-    return consumer_handle;
-  else
-    REPLY_ERROR_RETURN(message, ENOMEM, RemoteChannelHandle());
+  return CreateConsumer(message);
 }
 
-int ProducerChannel::OnProducerPost(
+Status<void> ProducerChannel::OnProducerPost(
     Message&, LocalFence acquire_fence,
     BufferWrapper<std::vector<std::uint8_t>> metadata) {
   ATRACE_NAME("ProducerChannel::OnProducerPost");
   ALOGD_IF(TRACE, "ProducerChannel::OnProducerPost: buffer_id=%d", buffer_id());
   if (!producer_owns_) {
     ALOGE("ProducerChannel::OnProducerPost: Not in gained state!");
-    return -EBUSY;
+    return ErrorStatus(EBUSY);
   }
 
   if (meta_size_bytes_ != metadata.size())
-    return -EINVAL;
+    return ErrorStatus(EINVAL);
   std::copy(metadata.begin(), metadata.end(), meta_.get());
 
   post_fence_ = std::move(acquire_fence);
@@ -220,29 +221,29 @@
   ALOGD_IF(TRACE, "ProducerChannel::OnProducerPost: %d pending consumers",
            pending_consumers_);
 
-  return 0;
+  return {};
 }
 
-LocalFence ProducerChannel::OnProducerGain(Message& message) {
+Status<LocalFence> ProducerChannel::OnProducerGain(Message& message) {
   ATRACE_NAME("ProducerChannel::OnGain");
   ALOGD_IF(TRACE, "ProducerChannel::OnGain: buffer_id=%d", buffer_id());
   if (producer_owns_) {
     ALOGE("ProducerChanneL::OnGain: Already in gained state: channel=%d",
           channel_id());
-    REPLY_ERROR_RETURN(message, EALREADY, {});
+    return ErrorStatus(EALREADY);
   }
 
   // There are still pending consumers, return busy.
   if (pending_consumers_ > 0)
-    REPLY_ERROR_RETURN(message, EBUSY, {});
+    return ErrorStatus(EBUSY);
 
   ClearAvailable();
   producer_owns_ = true;
   post_fence_.close();
-  return std::move(returned_fence_);
+  return {std::move(returned_fence_)};
 }
 
-std::pair<BorrowedFence, BufferWrapper<std::uint8_t*>>
+Status<std::pair<BorrowedFence, BufferWrapper<std::uint8_t*>>>
 ProducerChannel::OnConsumerAcquire(Message& message,
                                    std::size_t metadata_size) {
   ATRACE_NAME("ProducerChannel::OnConsumerAcquire");
@@ -250,26 +251,27 @@
            buffer_id());
   if (producer_owns_) {
     ALOGE("ProducerChannel::OnConsumerAcquire: Not in posted state!");
-    REPLY_ERROR_RETURN(message, EBUSY, {});
+    return ErrorStatus(EBUSY);
   }
 
   // Return a borrowed fd to avoid unnecessary duplication of the underlying fd.
   // Serialization just needs to read the handle.
   if (metadata_size == 0)
-    return std::make_pair(post_fence_.borrow(),
-                          WrapBuffer<std::uint8_t>(nullptr, 0));
+    return {std::make_pair(post_fence_.borrow(),
+                           WrapBuffer<std::uint8_t>(nullptr, 0))};
   else
-    return std::make_pair(post_fence_.borrow(),
-                          WrapBuffer(meta_.get(), meta_size_bytes_));
+    return {std::make_pair(post_fence_.borrow(),
+                           WrapBuffer(meta_.get(), meta_size_bytes_))};
 }
 
-int ProducerChannel::OnConsumerRelease(Message&, LocalFence release_fence) {
+Status<void> ProducerChannel::OnConsumerRelease(Message&,
+                                                LocalFence release_fence) {
   ATRACE_NAME("ProducerChannel::OnConsumerRelease");
   ALOGD_IF(TRACE, "ProducerChannel::OnConsumerRelease: buffer_id=%d",
            buffer_id());
   if (producer_owns_) {
     ALOGE("ProducerChannel::OnConsumerRelease: Not in acquired state!");
-    return -EBUSY;
+    return ErrorStatus(EBUSY);
   }
 
   // Attempt to merge the fences if necessary.
@@ -282,7 +284,7 @@
       if (!merged_fence) {
         ALOGE("ProducerChannel::OnConsumerRelease: Failed to merge fences: %s",
               strerror(error));
-        return -error;
+        return ErrorStatus(error);
       }
       returned_fence_ = std::move(merged_fence);
     } else {
@@ -291,7 +293,7 @@
   }
 
   OnConsumerIgnored();
-  return 0;
+  return {};
 }
 
 void ProducerChannel::OnConsumerIgnored() {
@@ -302,9 +304,10 @@
            buffer_id(), pending_consumers_);
 }
 
-int ProducerChannel::OnProducerMakePersistent(Message& message,
-                                              const std::string& name,
-                                              int user_id, int group_id) {
+Status<void> ProducerChannel::OnProducerMakePersistent(Message& message,
+                                                       const std::string& name,
+                                                       int user_id,
+                                                       int group_id) {
   ATRACE_NAME("ProducerChannel::OnProducerMakePersistent");
   ALOGD_IF(TRACE,
            "ProducerChannel::OnProducerMakePersistent: buffer_id=%d name=%s "
@@ -313,7 +316,7 @@
 
   if (name.empty() || (user_id < 0 && user_id != kNoCheckId) ||
       (group_id < 0 && group_id != kNoCheckId)) {
-    return -EINVAL;
+    return ErrorStatus(EINVAL);
   }
 
   // Try to add this buffer with the requested name.
@@ -331,18 +334,18 @@
     owner_user_id_ = user_id;
     owner_group_id_ = group_id;
     name_ = name;
-    return 0;
+    return {};
   } else {
     // Otherwise a buffer with that name already exists.
-    return -EALREADY;
+    return ErrorStatus(EALREADY);
   }
 }
 
-int ProducerChannel::OnRemovePersistence(Message&) {
+Status<void> ProducerChannel::OnRemovePersistence(Message&) {
   if (service()->RemoveNamedBuffer(*this))
-    return 0;
+    return {};
   else
-    return -ENOENT;
+    return ErrorStatus(ENOENT);
 }
 
 void ProducerChannel::AddConsumer(ConsumerChannel* channel) {
@@ -365,12 +368,16 @@
 }
 
 // Returns true if the given parameters match the underlying buffer parameters.
-bool ProducerChannel::CheckParameters(int width, int height, int format,
-                                      int usage, size_t meta_size_bytes,
+bool ProducerChannel::CheckParameters(uint32_t width, uint32_t height,
+                                      uint32_t format, uint64_t producer_usage,
+                                      uint64_t consumer_usage,
+                                      size_t meta_size_bytes,
                                       size_t slice_count) {
   return slices_.size() == slice_count && meta_size_bytes == meta_size_bytes_ &&
          slices_[0].width() == width && slices_[0].height() == height &&
-         slices_[0].format() == format && slices_[0].usage() == usage;
+         slices_[0].format() == format &&
+         slices_[0].producer_usage() == producer_usage &&
+         slices_[0].consumer_usage() == consumer_usage;
 }
 
 }  // namespace dvr
diff --git a/services/vr/bufferhubd/producer_channel.h b/services/vr/bufferhubd/producer_channel.h
index e7ca459..f04c8a5 100644
--- a/services/vr/bufferhubd/producer_channel.h
+++ b/services/vr/bufferhubd/producer_channel.h
@@ -30,10 +30,10 @@
   template <typename T>
   using BufferWrapper = pdx::rpc::BufferWrapper<T>;
 
-  static std::shared_ptr<ProducerChannel> Create(
-      BufferHubService* service, int channel_id, int width, int height,
-      int format, int usage, size_t meta_size_bytes, size_t slice_count,
-      int* error);
+  static pdx::Status<std::shared_ptr<ProducerChannel>> Create(
+      BufferHubService* service, int channel_id, uint32_t width,
+      uint32_t height, uint32_t format, uint64_t producer_usage,
+      uint64_t consumer_usage, size_t meta_size_bytes, size_t slice_count);
 
   ~ProducerChannel() override;
 
@@ -42,17 +42,18 @@
 
   BufferInfo GetBufferInfo() const override;
 
-  NativeBufferHandle<BorrowedHandle> OnGetBuffer(Message& message,
-                                                 unsigned index);
-  std::vector<NativeBufferHandle<BorrowedHandle>> OnGetBuffers(
+  pdx::Status<NativeBufferHandle<BorrowedHandle>> OnGetBuffer(Message& message,
+                                                              unsigned index);
+  pdx::Status<std::vector<NativeBufferHandle<BorrowedHandle>>> OnGetBuffers(
       Message& message);
 
-  RemoteChannelHandle CreateConsumer(Message& message);
-  RemoteChannelHandle OnNewConsumer(Message& message);
+  pdx::Status<RemoteChannelHandle> CreateConsumer(Message& message);
+  pdx::Status<RemoteChannelHandle> OnNewConsumer(Message& message);
 
-  std::pair<BorrowedFence, BufferWrapper<std::uint8_t*>> OnConsumerAcquire(
-      Message& message, std::size_t metadata_size);
-  int OnConsumerRelease(Message& message, LocalFence release_fence);
+  pdx::Status<std::pair<BorrowedFence, BufferWrapper<std::uint8_t*>>>
+  OnConsumerAcquire(Message& message, std::size_t metadata_size);
+  pdx::Status<void> OnConsumerRelease(Message& message,
+                                      LocalFence release_fence);
 
   void OnConsumerIgnored();
 
@@ -60,12 +61,14 @@
   void RemoveConsumer(ConsumerChannel* channel);
 
   bool CheckAccess(int euid, int egid);
-  bool CheckParameters(int width, int height, int format, int usage,
+  bool CheckParameters(uint32_t width, uint32_t height, uint32_t format,
+                       uint64_t producer_usage, uint64_t consumer_usage,
                        size_t meta_size_bytes, size_t slice_count);
 
-  int OnProducerMakePersistent(Message& message, const std::string& name,
-                               int user_id, int group_id);
-  int OnRemovePersistence(Message& message);
+  pdx::Status<void> OnProducerMakePersistent(Message& message,
+                                             const std::string& name,
+                                             int user_id, int group_id);
+  pdx::Status<void> OnRemovePersistence(Message& message);
 
  private:
   std::vector<ConsumerChannel*> consumer_channels_;
@@ -91,13 +94,15 @@
 
   std::string name_;
 
-  ProducerChannel(BufferHubService* service, int channel, int width, int height,
-                  int format, int usage, size_t meta_size_bytes,
+  ProducerChannel(BufferHubService* service, int channel, uint32_t width,
+                  uint32_t height, uint32_t format, uint64_t producer_usage,
+                  uint64_t consumer_usage, size_t meta_size_bytes,
                   size_t slice_count, int* error);
 
-  int OnProducerPost(Message& message, LocalFence acquire_fence,
-                     BufferWrapper<std::vector<std::uint8_t>> metadata);
-  LocalFence OnProducerGain(Message& message);
+  pdx::Status<void> OnProducerPost(
+      Message& message, LocalFence acquire_fence,
+      BufferWrapper<std::vector<std::uint8_t>> metadata);
+  pdx::Status<LocalFence> OnProducerGain(Message& message);
 
   ProducerChannel(const ProducerChannel&) = delete;
   void operator=(const ProducerChannel&) = delete;
diff --git a/services/vr/bufferhubd/producer_queue_channel.cpp b/services/vr/bufferhubd/producer_queue_channel.cpp
index 7741058..dc2a47e 100644
--- a/services/vr/bufferhubd/producer_queue_channel.cpp
+++ b/services/vr/bufferhubd/producer_queue_channel.cpp
@@ -1,5 +1,7 @@
 #include "producer_queue_channel.h"
 
+#include <inttypes.h>
+
 #include "consumer_queue_channel.h"
 #include "producer_channel.h"
 
@@ -12,16 +14,14 @@
 namespace android {
 namespace dvr {
 
-ProducerQueueChannel::ProducerQueueChannel(
-    BufferHubService* service, int channel_id, size_t meta_size_bytes,
-    int usage_set_mask, int usage_clear_mask, int usage_deny_set_mask,
-    int usage_deny_clear_mask, int* error)
+ProducerQueueChannel::ProducerQueueChannel(BufferHubService* service,
+                                           int channel_id,
+                                           size_t meta_size_bytes,
+                                           const UsagePolicy& usage_policy,
+                                           int* error)
     : BufferHubChannel(service, channel_id, channel_id, kProducerQueueType),
       meta_size_bytes_(meta_size_bytes),
-      usage_set_mask_(usage_set_mask),
-      usage_clear_mask_(usage_clear_mask),
-      usage_deny_set_mask_(usage_deny_set_mask),
-      usage_deny_clear_mask_(usage_deny_clear_mask),
+      usage_policy_(usage_policy),
       capacity_(0) {
   *error = 0;
 }
@@ -29,28 +29,34 @@
 ProducerQueueChannel::~ProducerQueueChannel() {}
 
 /* static */
-std::shared_ptr<ProducerQueueChannel> ProducerQueueChannel::Create(
+Status<std::shared_ptr<ProducerQueueChannel>> ProducerQueueChannel::Create(
     BufferHubService* service, int channel_id, size_t meta_size_bytes,
-    int usage_set_mask, int usage_clear_mask, int usage_deny_set_mask,
-    int usage_deny_clear_mask, int* error) {
+    const UsagePolicy& usage_policy) {
   // Configuration between |usage_deny_set_mask| and |usage_deny_clear_mask|
   // should be mutually exclusive.
-  if (usage_deny_set_mask & usage_deny_clear_mask) {
+  if ((usage_policy.producer_deny_set_mask &
+       usage_policy.producer_deny_clear_mask) ||
+      (usage_policy.consumer_deny_set_mask &
+       usage_policy.consumer_deny_clear_mask)) {
     ALOGE(
         "BufferHubService::OnCreateProducerQueue: illegal usage mask "
-        "configuration: usage_deny_set_mask=%d, usage_deny_clear_mask=%d",
-        usage_deny_set_mask, usage_deny_clear_mask);
-    *error = -EINVAL;
-    return nullptr;
+        "configuration: producer_deny_set_mask=%" PRIx64
+        " producer_deny_clear_mask=%" PRIx64 " consumer_deny_set_mask=%" PRIx64
+        " consumer_deny_clear_mask=%" PRIx64,
+        usage_policy.producer_deny_set_mask,
+        usage_policy.producer_deny_clear_mask,
+        usage_policy.consumer_deny_set_mask,
+        usage_policy.consumer_deny_clear_mask);
+    return ErrorStatus(EINVAL);
   }
 
+  int error = 0;
   std::shared_ptr<ProducerQueueChannel> producer(new ProducerQueueChannel(
-      service, channel_id, meta_size_bytes, usage_set_mask, usage_clear_mask,
-      usage_deny_set_mask, usage_deny_clear_mask, error));
-  if (*error < 0)
-    return nullptr;
+      service, channel_id, meta_size_bytes, usage_policy, &error));
+  if (error < 0)
+    return ErrorStatus(-error);
   else
-    return producer;
+    return {std::move(producer)};
 }
 
 bool ProducerQueueChannel::HandleMessage(Message& message) {
@@ -88,8 +94,7 @@
 
 BufferHubChannel::BufferInfo ProducerQueueChannel::GetBufferInfo() const {
   return BufferInfo(channel_id(), consumer_channels_.size(), capacity_,
-                    usage_set_mask_, usage_clear_mask_, usage_deny_set_mask_,
-                    usage_deny_clear_mask_);
+                    usage_policy_);
 }
 
 Status<RemoteChannelHandle> ProducerQueueChannel::OnCreateConsumerQueue(
@@ -127,11 +132,10 @@
 }
 
 Status<std::vector<std::pair<RemoteChannelHandle, size_t>>>
-ProducerQueueChannel::OnProducerQueueAllocateBuffers(Message& message,
-                                                     int width, int height,
-                                                     int format, int usage,
-                                                     size_t slice_count,
-                                                     size_t buffer_count) {
+ProducerQueueChannel::OnProducerQueueAllocateBuffers(
+    Message& message, uint32_t width, uint32_t height, uint32_t format,
+    uint64_t producer_usage, uint64_t consumer_usage, size_t slice_count,
+    size_t buffer_count) {
   ATRACE_NAME("ProducerQueueChannel::OnProducerQueueAllocateBuffers");
   ALOGD_IF(TRACE,
            "ProducerQueueChannel::OnProducerQueueAllocateBuffers: "
@@ -141,31 +145,58 @@
   std::vector<std::pair<RemoteChannelHandle, size_t>> buffer_handles;
 
   // Deny buffer allocation violating preset rules.
-  if (usage & usage_deny_set_mask_) {
+  if (producer_usage & usage_policy_.producer_deny_set_mask) {
     ALOGE(
-        "ProducerQueueChannel::OnProducerQueueAllocateBuffers: usage: %d is "
-        "not permitted. Violating usage_deny_set_mask, the following bits "
-        "shall not be set: %d.",
-        usage, usage_deny_set_mask_);
+        "ProducerQueueChannel::OnProducerQueueAllocateBuffers: producer_usage: "
+        "%" PRIx64
+        " is not permitted. Violating producer_deny_set_mask, the following "
+        "bits shall not be set: %" PRIx64 ".",
+        producer_usage, usage_policy_.producer_deny_set_mask);
     return ErrorStatus(EINVAL);
   }
 
-  if (~usage & usage_deny_clear_mask_) {
+  if (consumer_usage & usage_policy_.consumer_deny_set_mask) {
     ALOGE(
-        "ProducerQueueChannel::OnProducerQueueAllocateBuffers: usage: %d is "
-        "not permitted. Violating usage_deny_clear_mask, the following bits "
-        "must be set: %d.",
-        usage, usage_deny_clear_mask_);
+        "ProducerQueueChannel::OnProducerQueueAllocateBuffers: consumer_usage: "
+        "%" PRIx64
+        " is not permitted. Violating consumer_deny_set_mask, the following "
+        "bits shall not be set: %" PRIx64 ".",
+        consumer_usage, usage_policy_.consumer_deny_set_mask);
     return ErrorStatus(EINVAL);
   }
 
-  // Force set mask and clear mask. Note that |usage_set_mask_| takes precedence
-  // and will overwrite |usage_clear_mask_|.
-  int effective_usage = (usage & ~usage_clear_mask_) | usage_set_mask_;
+  if (~producer_usage & usage_policy_.producer_deny_clear_mask) {
+    ALOGE(
+        "ProducerQueueChannel::OnProducerQueueAllocateBuffers: producer_usage: "
+        "%" PRIx64
+        " is not permitted. Violating producer_deny_clear_mask, the following "
+        "bits must be set: %" PRIx64 ".",
+        producer_usage, usage_policy_.producer_deny_clear_mask);
+    return ErrorStatus(EINVAL);
+  }
+
+  if (~consumer_usage & usage_policy_.consumer_deny_clear_mask) {
+    ALOGE(
+        "ProducerQueueChannel::OnProducerQueueAllocateBuffers: consumer_usage: "
+        "%" PRIx64
+        " is not permitted. Violating consumer_deny_clear_mask, the following "
+        "bits must be set: %" PRIx64 ".",
+        consumer_usage, usage_policy_.consumer_deny_clear_mask);
+    return ErrorStatus(EINVAL);
+  }
+  // Force set mask and clear mask. Note that |usage_policy_.X_set_mask_| takes
+  // precedence and will overwrite |usage_policy_.X_clear_mask|.
+  uint64_t effective_producer_usage =
+      (producer_usage & ~usage_policy_.producer_clear_mask) |
+      usage_policy_.producer_set_mask;
+  uint64_t effective_consumer_usage =
+      (consumer_usage & ~usage_policy_.consumer_clear_mask) |
+      usage_policy_.consumer_set_mask;
 
   for (size_t i = 0; i < buffer_count; i++) {
-    auto status = AllocateBuffer(message, width, height, format,
-                                 effective_usage, slice_count);
+    auto status =
+        AllocateBuffer(message, width, height, format, effective_producer_usage,
+                       effective_consumer_usage, slice_count);
     if (!status) {
       ALOGE(
           "ProducerQueueChannel::OnProducerQueueAllocateBuffers: Failed to "
@@ -179,8 +210,10 @@
 }
 
 Status<std::pair<RemoteChannelHandle, size_t>>
-ProducerQueueChannel::AllocateBuffer(Message& message, int width, int height,
-                                     int format, int usage,
+ProducerQueueChannel::AllocateBuffer(Message& message, uint32_t width,
+                                     uint32_t height, uint32_t format,
+                                     uint64_t producer_usage,
+                                     uint64_t consumer_usage,
                                      size_t slice_count) {
   ATRACE_NAME("ProducerQueueChannel::AllocateBuffer");
   ALOGD_IF(TRACE,
@@ -205,21 +238,24 @@
   }
 
   ALOGD_IF(TRACE,
-           "ProducerQueueChannel::AllocateBuffer: buffer_id=%d width=%d "
-           "height=%d format=%d usage=%d slice_count=%zu",
-           buffer_id, width, height, format, usage, slice_count);
+           "ProducerQueueChannel::AllocateBuffer: buffer_id=%d width=%u "
+           "height=%u format=%u producer_usage=%" PRIx64
+           " consumer_usage=%" PRIx64 " slice_count=%zu",
+           buffer_id, width, height, format, producer_usage, consumer_usage,
+           slice_count);
   auto buffer_handle = status.take();
 
-  int error;
-  const auto producer_channel =
-      ProducerChannel::Create(service(), buffer_id, width, height, format,
-                              usage, meta_size_bytes_, slice_count, &error);
-  if (!producer_channel) {
+  auto producer_channel_status = ProducerChannel::Create(
+      service(), buffer_id, width, height, format, producer_usage,
+      consumer_usage, meta_size_bytes_, slice_count);
+  if (!producer_channel_status) {
     ALOGE(
-        "ProducerQueueChannel::AllocateBuffer: Failed to create "
-        "BufferHubBuffer producer!!");
+        "ProducerQueueChannel::AllocateBuffer: Failed to create producer "
+        "buffer: %s",
+        producer_channel_status.GetErrorMessage().c_str());
     return ErrorStatus(ENOMEM);
   }
+  auto producer_channel = producer_channel_status.take();
 
   ALOGD_IF(
       TRACE,
diff --git a/services/vr/bufferhubd/producer_queue_channel.h b/services/vr/bufferhubd/producer_queue_channel.h
index a12a37d..09b0243 100644
--- a/services/vr/bufferhubd/producer_queue_channel.h
+++ b/services/vr/bufferhubd/producer_queue_channel.h
@@ -11,10 +11,9 @@
 
 class ProducerQueueChannel : public BufferHubChannel {
  public:
-  static std::shared_ptr<ProducerQueueChannel> Create(
+  static pdx::Status<std::shared_ptr<ProducerQueueChannel>> Create(
       BufferHubService* service, int channel_id, size_t meta_size_bytes,
-      int usage_set_mask, int usage_clear_mask, int usage_deny_set_mask,
-      int usage_deny_clear_mask, int* error);
+      const UsagePolicy& usage_policy);
   ~ProducerQueueChannel() override;
 
   bool HandleMessage(pdx::Message& message) override;
@@ -34,8 +33,10 @@
   // Allocate a new BufferHubProducer according to the input spec. Client may
   // handle this as if a new producer is created through kOpCreateBuffer.
   pdx::Status<std::vector<std::pair<pdx::RemoteChannelHandle, size_t>>>
-  OnProducerQueueAllocateBuffers(pdx::Message& message, int width, int height,
-                                 int format, int usage, size_t slice_count,
+  OnProducerQueueAllocateBuffers(pdx::Message& message, uint32_t width,
+                                 uint32_t height, uint32_t format,
+                                 uint64_t producer_usage,
+                                 uint64_t consumer_usage, size_t slice_count,
                                  size_t buffer_count);
 
   // Detach a BufferHubProducer indicated by |slot|. Note that the buffer must
@@ -48,18 +49,17 @@
 
  private:
   ProducerQueueChannel(BufferHubService* service, int channel_id,
-                       size_t meta_size_bytes, int usage_set_mask,
-                       int usage_clear_mask, int usage_deny_set_mask,
-                       int usage_deny_clear_mask, int* error);
+                       size_t meta_size_bytes, const UsagePolicy& usage_policy,
+                       int* error);
 
   // Allocate one single producer buffer by |OnProducerQueueAllocateBuffers|.
   // Note that the newly created buffer's file handle will be pushed to client
   // and our return type is a RemoteChannelHandle.
-  // Returns the remote channdel handle and the slot number for the newly
+  // Returns the remote channel handle and the slot number for the newly
   // allocated buffer.
   pdx::Status<std::pair<pdx::RemoteChannelHandle, size_t>> AllocateBuffer(
-      pdx::Message& message, int width, int height, int format, int usage,
-      size_t slice_count);
+      pdx::Message& message, uint32_t width, uint32_t height, uint32_t format,
+      uint64_t producer_usage, uint64_t consumer_usage, size_t slice_count);
 
   // Size of the meta data associated with all the buffers allocated from the
   // queue. Now we assume the metadata size is immutable once the queue is
@@ -68,10 +68,7 @@
 
   // A set of variables to control what |usage| bits can this ProducerQueue
   // allocate.
-  int usage_set_mask_;
-  int usage_clear_mask_;
-  int usage_deny_set_mask_;
-  int usage_deny_clear_mask_;
+  UsagePolicy usage_policy_;
 
   // Provides access to the |channel_id| of all consumer channels associated
   // with this producer.