1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "buffer_hub.h"
2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
3cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka#include <inttypes.h>
44fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko#include <log/log.h>
5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <poll.h>
6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <utils/Trace.h>
7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <iomanip>
9a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai#include <memory>
10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sstream>
11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <string>
12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <thread>
13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/default_transport/service_endpoint.h>
15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <private/dvr/bufferhub_rpc.h>
16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "consumer_channel.h"
17a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai#include "detached_buffer_channel.h"
18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "producer_channel.h"
19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "producer_queue_channel.h"
20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::Channel;
221db8a5d7e3b0565b976e77859e28d77f6a451a2bCorey Tabakausing android::pdx::ErrorStatus;
23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::Message;
241db8a5d7e3b0565b976e77859e28d77f6a451a2bCorey Tabakausing android::pdx::Status;
25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::default_transport::Endpoint;
2652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabakausing android::pdx::rpc::DispatchRemoteMethod;
27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android {
29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace dvr {
30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoBufferHubService::BufferHubService()
32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    : BASE("BufferHub", Endpoint::Create(BufferHubRPC::kClientPath)) {}
33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoBufferHubService::~BufferHubService() {}
35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
361db8a5d7e3b0565b976e77859e28d77f6a451a2bCorey Tabakabool BufferHubService::IsInitialized() const { return BASE::IsInitialized(); }
37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::string BufferHubService::DumpState(size_t /*max_length*/) {
39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::ostringstream stream;
40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto channels = GetChannels<BufferHubChannel>();
41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::sort(channels.begin(), channels.end(),
43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            [](const std::shared_ptr<BufferHubChannel>& a,
44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko               const std::shared_ptr<BufferHubChannel>& b) {
45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko              return a->buffer_id() < b->buffer_id();
46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            });
47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << "Active Producer Buffers:\n";
49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << std::right;
50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << std::setw(6) << "Id";
51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << " ";
52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << std::setw(9) << "Consumers";
53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << " ";
54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << std::setw(14) << "Geometry";
55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << " ";
56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << std::setw(6) << "Format";
57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << " ";
5852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka  stream << std::setw(10) << "Usage";
5952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka  stream << " ";
6052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka  stream << std::setw(9) << "Pending";
6152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka  stream << " ";
6252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka  stream << std::setw(18) << "State";
6352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka  stream << " ";
6452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka  stream << std::setw(18) << "Signaled";
6552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka  stream << " ";
6652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka  stream << std::setw(10) << "Index";
67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << std::endl;
68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  for (const auto& channel : channels) {
70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (channel->channel_type() == BufferHubChannel::kProducerType) {
71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::right;
74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::setw(6) << info.id;
75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << " ";
76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::setw(9) << info.consumer_count;
77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << " ";
78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      if (info.format == HAL_PIXEL_FORMAT_BLOB) {
79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        std::string size = std::to_string(info.width) + " B";
80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        stream << std::setw(14) << size;
81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      } else {
82108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar        std::string dimensions = std::to_string(info.width) + "x" +
83108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar                                 std::to_string(info.height) + "x" +
84108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar                                 std::to_string(info.layer_count);
85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        stream << std::setw(14) << dimensions;
86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      }
87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << " ";
88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::setw(6) << info.format;
89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << " ";
90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << "0x" << std::hex << std::setfill('0');
910057fddc71d1c3c3de8f9d0bd45a51bb293bfa3cJiwen 'Steve' Cai      stream << std::setw(8) << info.usage;
92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::dec << std::setfill(' ');
93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << " ";
9452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka      stream << std::setw(9) << info.pending_count;
95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << " ";
9652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka      stream << "0x" << std::hex << std::setfill('0');
9752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka      stream << std::setw(16) << info.state;
9852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka      stream << " ";
9952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka      stream << "0x" << std::setw(16) << info.signaled_mask;
10052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka      stream << std::dec << std::setfill(' ');
10152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka      stream << " ";
10252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka      stream << std::setw(8) << info.index;
103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::endl;
104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
10523c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai
10623c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai    if (channel->channel_type() == BufferHubChannel::kDetachedBufferType) {
10723c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
10823c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai
10923c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << std::right;
11023c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << std::setw(6) << info.id;
11123c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << " ";
11223c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << std::setw(9) << "N/A";
11323c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << " ";
11423c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      if (info.format == HAL_PIXEL_FORMAT_BLOB) {
11523c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai        std::string size = std::to_string(info.width) + " B";
11623c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai        stream << std::setw(14) << size;
11723c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      } else {
11823c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai        std::string dimensions = std::to_string(info.width) + "x" +
11923c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai                                 std::to_string(info.height) + "x" +
12023c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai                                 std::to_string(info.layer_count);
12123c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai        stream << std::setw(14) << dimensions;
12223c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      }
12323c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << " ";
12423c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << std::setw(6) << info.format;
12523c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << " ";
12623c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << "0x" << std::hex << std::setfill('0');
12723c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << std::setw(8) << info.usage;
12823c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << std::dec << std::setfill(' ');
12923c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << " ";
13023c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << std::setw(9) << "N/A";
13123c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << " ";
13223c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << std::hex << std::setfill(' ');
13323c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << std::setw(18) << "Detached";
13423c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << " ";
13523c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << std::setw(18) << "N/A";
13623c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << " ";
13723c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << std::setw(10) << "N/A";
13823c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      stream << std::endl;
13923c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai    }
140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << std::endl;
143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << "Active Producer Queues:\n";
144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << std::right << std::setw(6) << "Id";
1458a4e6a90e6b7edf73fa0d79dd5b439f8e52eb9f0Corey Tabaka  stream << std::right << std::setw(12) << " Capacity";
146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << std::right << std::setw(12) << " Consumers";
147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << " UsageSetMask";
148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << " UsageClearMask";
149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << " UsageDenySetMask";
150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << " UsageDenyClearMask";
151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << " ";
152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << std::endl;
153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  for (const auto& channel : channels) {
155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (channel->channel_type() == BufferHubChannel::kProducerQueueType) {
156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::dec << std::setfill(' ');
159e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::right << std::setw(6) << info.id;
160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::right << std::setw(12) << info.capacity;
161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::right << std::setw(12) << info.consumer_count;
162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::setw(5) << std::setfill(' ') << "0x";
163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::hex << std::setfill('0');
1640057fddc71d1c3c3de8f9d0bd45a51bb293bfa3cJiwen 'Steve' Cai      stream << std::setw(8) << info.usage_policy.usage_set_mask;
165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::setw(7) << std::setfill(' ') << "0x";
166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::hex << std::setfill('0');
1670057fddc71d1c3c3de8f9d0bd45a51bb293bfa3cJiwen 'Steve' Cai      stream << std::setw(8) << info.usage_policy.usage_clear_mask;
168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::setw(9) << std::setfill(' ') << "0x";
169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::hex << std::setfill('0');
1700057fddc71d1c3c3de8f9d0bd45a51bb293bfa3cJiwen 'Steve' Cai      stream << std::setw(8) << info.usage_policy.usage_deny_set_mask;
171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::setw(11) << std::setfill(' ') << "0x";
172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::hex << std::setfill('0');
1730057fddc71d1c3c3de8f9d0bd45a51bb293bfa3cJiwen 'Steve' Cai      stream << std::setw(8) << info.usage_policy.usage_deny_clear_mask;
174cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka      stream << std::hex << std::setfill('0');
175cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka      stream << std::endl;
176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << std::endl;
180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << "Active Consumer Queues:\n";
181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << std::dec << std::setfill(' ');
182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << std::right << std::setw(6) << "Id";
183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << std::right << std::setw(12) << " Imported";
184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << " ";
185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  stream << std::endl;
186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  for (const auto& channel : channels) {
188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (channel->channel_type() == BufferHubChannel::kConsumerQueueType) {
189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::right << std::setw(6) << info.id;
192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      stream << std::right << std::setw(12) << info.capacity;
193cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka      stream << std::endl;
194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
19752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka  stream << std::endl;
19852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka  stream << "Orphaned Consumer Buffers:\n";
19952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka  stream << std::right;
20052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka  stream << std::setw(6) << "Id";
20152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka  stream << " ";
2022f260339e4b32f41db6699c69cf0d568c396bcf5Jiwen 'Steve' Cai  stream << std::setw(14) << "Info";
20352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka  stream << std::endl;
20452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka
20552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka  for (const auto& channel : channels) {
20652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka    BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
20752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka    // consumer_count is tracked by producer. When it's zero, producer must have
20852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka    // already hung up and the consumer is orphaned.
20952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka    if (channel->channel_type() == BufferHubChannel::kConsumerType &&
21052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka        info.consumer_count == 0) {
21152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka      stream << std::right;
21252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka      stream << std::setw(6) << info.id;
21352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka      stream << " ";
21452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka
21552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka      stream << std::setw(14) << "Orphaned.";
21652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka      stream << (" channel_id=" + std::to_string(channel->channel_id()));
21752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka      stream << std::endl;
21852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka    }
21952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka  }
22052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka
221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return stream.str();
222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid BufferHubService::HandleImpulse(Message& message) {
225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ATRACE_NAME("BufferHubService::HandleImpulse");
226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (auto channel = message.GetChannel<BufferHubChannel>())
227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    channel->HandleImpulse(message);
228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
230f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenkopdx::Status<void> BufferHubService::HandleMessage(Message& message) {
231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ATRACE_NAME("BufferHubService::HandleMessage");
232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto channel = message.GetChannel<BufferHubChannel>();
233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ALOGD_IF(
235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      TRACE,
236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      "BufferHubService::HandleMessage: channel=%p channel_id=%d opcode=%d",
237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      channel.get(), message.GetChannelId(), message.GetOp());
238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // If the channel is already set up, let it handle the message.
240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (channel && !channel->HandleMessage(message))
241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DefaultHandleMessage(message);
242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // This channel has not been set up yet, the following are valid operations.
244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  switch (message.GetOp()) {
245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    case BufferHubRPC::CreateBuffer::Opcode:
246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      DispatchRemoteMethod<BufferHubRPC::CreateBuffer>(
247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          *this, &BufferHubService::OnCreateBuffer, message);
248f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      return {};
249e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
250a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai    case DetachedBufferRPC::Create::Opcode:
251a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai      DispatchRemoteMethod<DetachedBufferRPC::Create>(
252a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai          *this, &BufferHubService::OnCreateDetachedBuffer, message);
253a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai      return {};
254a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai
255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    case BufferHubRPC::CreateProducerQueue::Opcode:
256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      DispatchRemoteMethod<BufferHubRPC::CreateProducerQueue>(
257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          *this, &BufferHubService::OnCreateProducerQueue, message);
258f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      return {};
259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
26023c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai    case BufferHubRPC::ProducerBufferDetach::Opcode:
26123c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      // In addition to the message handler in the ProducerChannel's
26223c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      // HandleMessage method, we also need to invalid the producer channel (and
26323c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      // all associated consumer channels). Note that this has to be done after
26423c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      // HandleMessage returns to make sure the IPC request has went back to the
26523c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      // client first.
26623c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      SetChannel(channel->channel_id(), nullptr);
26723c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai      return {};
26823c1a735b673a9310f05b893a3d01de38d8c1166Jiwen 'Steve' Cai
2690728fa93c12145c2337a0033eb69056520b7bcd8Jiwen 'Steve' Cai    case DetachedBufferRPC::Promote::Opcode:
2700728fa93c12145c2337a0033eb69056520b7bcd8Jiwen 'Steve' Cai      // In addition to the message handler in the DetachedBufferChannel's
2710728fa93c12145c2337a0033eb69056520b7bcd8Jiwen 'Steve' Cai      // HandleMessage method, we also need to invalid the channel. Note that
2720728fa93c12145c2337a0033eb69056520b7bcd8Jiwen 'Steve' Cai      // this has to be done after HandleMessage returns to make sure the IPC
2730728fa93c12145c2337a0033eb69056520b7bcd8Jiwen 'Steve' Cai      // request has went back to the client first.
2740728fa93c12145c2337a0033eb69056520b7bcd8Jiwen 'Steve' Cai      SetChannel(channel->channel_id(), nullptr);
2750728fa93c12145c2337a0033eb69056520b7bcd8Jiwen 'Steve' Cai      return {};
2760728fa93c12145c2337a0033eb69056520b7bcd8Jiwen 'Steve' Cai
277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    default:
278e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return DefaultHandleMessage(message);
279e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
282cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey TabakaStatus<void> BufferHubService::OnCreateBuffer(Message& message, uint32_t width,
283cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka                                              uint32_t height, uint32_t format,
2840057fddc71d1c3c3de8f9d0bd45a51bb293bfa3cJiwen 'Steve' Cai                                              uint64_t usage,
2854d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar                                              size_t meta_size_bytes) {
286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Use the producer channel id as the global buffer id.
287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const int buffer_id = message.GetChannelId();
288e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ALOGD_IF(TRACE,
289cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka           "BufferHubService::OnCreateBuffer: buffer_id=%d width=%u height=%u "
2904d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar           "format=%u usage=%" PRIx64 " meta_size_bytes=%zu",
2914d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar           buffer_id, width, height, format, usage, meta_size_bytes);
292e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
293e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // See if this channel is already attached to a buffer.
294e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto channel = message.GetChannel<BufferHubChannel>()) {
295e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    ALOGE("BufferHubService::OnCreateBuffer: Buffer already created: buffer=%d",
296e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          buffer_id);
297cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka    return ErrorStatus(EALREADY);
298e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
299108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar  const uint32_t kDefaultLayerCount = 1;
300108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar  auto status = ProducerChannel::Create(this, buffer_id, width, height,
301108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar                                        kDefaultLayerCount, format, usage,
302108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar                                        meta_size_bytes);
303cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka  if (status) {
304cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka    message.SetChannel(status.take());
305cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka    return {};
306e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
307cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka    ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer: %s",
308cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka          status.GetErrorMessage().c_str());
309cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka    return status.error_status();
310e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
311e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
312e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
313a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Caipdx::Status<void> BufferHubService::OnCreateDetachedBuffer(
314a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai    pdx::Message& message, uint32_t width, uint32_t height,
315a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai    uint32_t layer_count, uint32_t format, uint64_t usage,
316a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai    size_t user_metadata_size) {
317a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai  // Use the producer channel id as the global buffer id.
318a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai  const int buffer_id = message.GetChannelId();
319a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai  ALOGD_IF(TRACE,
320a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai           "BufferHubService::OnCreateDetachedBuffer: buffer_id=%d width=%u "
321a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai           "height=%u layer_count=%u format=%u usage=%" PRIx64
322a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai           " user_metadata_size=%zu",
323a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai           buffer_id, width, height, layer_count, format, usage,
324a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai           user_metadata_size);
325a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai
326a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai  // See if this channel is already attached to a buffer.
327a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai  if (const auto channel = message.GetChannel<BufferHubChannel>()) {
328a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai    ALOGE(
329a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai        "BufferHubService::OnCreateDetachedBuffer: Buffer already created: "
330a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai        "buffer=%d",
331a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai        buffer_id);
332a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai    return ErrorStatus(EALREADY);
333a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai  }
334a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai
335a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai  std::unique_ptr<DetachedBufferChannel> channel =
336a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai      DetachedBufferChannel::Create(this, buffer_id, width, height, layer_count,
337a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai                                    format, usage, user_metadata_size);
338a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai  if (!channel) {
339a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai    ALOGE(
340a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai        "BufferHubService::OnCreateDetachedBuffer: Failed to allocate buffer, "
341a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai        "buffer=%d.",
342a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai        buffer_id);
343a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai    return ErrorStatus(ENOMEM);
344a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai  }
345a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai
346a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai  message.SetChannel(std::move(channel));
347a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai  return {};
348a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai}
349a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai
3501db8a5d7e3b0565b976e77859e28d77f6a451a2bCorey TabakaStatus<QueueInfo> BufferHubService::OnCreateProducerQueue(
3516bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai    pdx::Message& message, const ProducerQueueConfig& producer_config,
352cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka    const UsagePolicy& usage_policy) {
353e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Use the producer channel id as the global queue id.
354e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const int queue_id = message.GetChannelId();
355e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ALOGD_IF(TRACE, "BufferHubService::OnCreateProducerQueue: queue_id=%d",
356e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko           queue_id);
357e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
358e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // See if this channel is already attached to another object.
359e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto channel = message.GetChannel<BufferHubChannel>()) {
360e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    ALOGE("BufferHubService::OnCreateProducerQueue: already created: queue=%d",
361e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          queue_id);
3621db8a5d7e3b0565b976e77859e28d77f6a451a2bCorey Tabaka    return ErrorStatus(EALREADY);
363e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
364e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
3656bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai  auto status = ProducerQueueChannel::Create(this, queue_id, producer_config,
366cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka                                             usage_policy);
367cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka  if (status) {
368cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka    message.SetChannel(status.take());
3696bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai    return {{producer_config, queue_id}};
370e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
371e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer!!");
372cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka    return status.error_status();
373e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
374e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
375e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
376e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid BufferHubChannel::SignalAvailable() {
377e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ATRACE_NAME("BufferHubChannel::SignalAvailable");
3783079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka  ALOGD_IF(TRACE,
3793079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka           "BufferHubChannel::SignalAvailable: channel_id=%d buffer_id=%d",
3803079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka           channel_id(), buffer_id());
3812f260339e4b32f41db6699c69cf0d568c396bcf5Jiwen 'Steve' Cai  signaled_ = true;
3822f260339e4b32f41db6699c69cf0d568c396bcf5Jiwen 'Steve' Cai  const auto status = service_->ModifyChannelEvents(channel_id_, 0, POLLIN);
3832f260339e4b32f41db6699c69cf0d568c396bcf5Jiwen 'Steve' Cai  ALOGE_IF(!status,
3842f260339e4b32f41db6699c69cf0d568c396bcf5Jiwen 'Steve' Cai           "BufferHubChannel::SignalAvailable: failed to signal availability "
3852f260339e4b32f41db6699c69cf0d568c396bcf5Jiwen 'Steve' Cai           "channel_id=%d: %s",
3862f260339e4b32f41db6699c69cf0d568c396bcf5Jiwen 'Steve' Cai           channel_id_, status.GetErrorMessage().c_str());
387e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
388e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
389e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid BufferHubChannel::ClearAvailable() {
390e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ATRACE_NAME("BufferHubChannel::ClearAvailable");
3913079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka  ALOGD_IF(TRACE,
3923079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka           "BufferHubChannel::ClearAvailable: channel_id=%d buffer_id=%d",
3933079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka           channel_id(), buffer_id());
3942f260339e4b32f41db6699c69cf0d568c396bcf5Jiwen 'Steve' Cai  signaled_ = false;
3952f260339e4b32f41db6699c69cf0d568c396bcf5Jiwen 'Steve' Cai  const auto status = service_->ModifyChannelEvents(channel_id_, POLLIN, 0);
3962f260339e4b32f41db6699c69cf0d568c396bcf5Jiwen 'Steve' Cai  ALOGE_IF(!status,
3972f260339e4b32f41db6699c69cf0d568c396bcf5Jiwen 'Steve' Cai           "BufferHubChannel::ClearAvailable: failed to clear availability "
3982f260339e4b32f41db6699c69cf0d568c396bcf5Jiwen 'Steve' Cai           "channel_id=%d: %s",
3992f260339e4b32f41db6699c69cf0d568c396bcf5Jiwen 'Steve' Cai           channel_id_, status.GetErrorMessage().c_str());
400e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
401e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
402e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid BufferHubChannel::Hangup() {
403e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ATRACE_NAME("BufferHubChannel::Hangup");
4043079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka  ALOGD_IF(TRACE, "BufferHubChannel::Hangup: channel_id=%d buffer_id=%d",
4053079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka           channel_id(), buffer_id());
4062f260339e4b32f41db6699c69cf0d568c396bcf5Jiwen 'Steve' Cai  const auto status = service_->ModifyChannelEvents(channel_id_, 0, POLLHUP);
4072f260339e4b32f41db6699c69cf0d568c396bcf5Jiwen 'Steve' Cai  ALOGE_IF(
4082f260339e4b32f41db6699c69cf0d568c396bcf5Jiwen 'Steve' Cai      !status,
4092f260339e4b32f41db6699c69cf0d568c396bcf5Jiwen 'Steve' Cai      "BufferHubChannel::Hangup: failed to signal hangup channel_id=%d: %s",
4102f260339e4b32f41db6699c69cf0d568c396bcf5Jiwen 'Steve' Cai      channel_id_, status.GetErrorMessage().c_str());
411e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
412e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
413e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace dvr
414e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace android
415