• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/android/scoped_hardware_buffer_handle.h"
6 
7 #include "base/android/android_hardware_buffer_compat.h"
8 #include "base/logging.h"
9 #include "base/posix/unix_domain_socket.h"
10 
11 namespace base {
12 namespace android {
13 
14 ScopedHardwareBufferHandle::ScopedHardwareBufferHandle() = default;
15 
ScopedHardwareBufferHandle(ScopedHardwareBufferHandle && other)16 ScopedHardwareBufferHandle::ScopedHardwareBufferHandle(
17     ScopedHardwareBufferHandle&& other) {
18   *this = std::move(other);
19 }
20 
~ScopedHardwareBufferHandle()21 ScopedHardwareBufferHandle::~ScopedHardwareBufferHandle() {
22   reset();
23 }
24 
25 // static
Adopt(AHardwareBuffer * buffer)26 ScopedHardwareBufferHandle ScopedHardwareBufferHandle::Adopt(
27     AHardwareBuffer* buffer) {
28   return ScopedHardwareBufferHandle(buffer);
29 }
30 
operator =(ScopedHardwareBufferHandle && other)31 ScopedHardwareBufferHandle& ScopedHardwareBufferHandle::operator=(
32     ScopedHardwareBufferHandle&& other) {
33   reset();
34   std::swap(buffer_, other.buffer_);
35   return *this;
36 }
37 
is_valid() const38 bool ScopedHardwareBufferHandle::is_valid() const {
39   return buffer_ != nullptr;
40 }
41 
get() const42 AHardwareBuffer* ScopedHardwareBufferHandle::get() const {
43   return buffer_;
44 }
45 
reset()46 void ScopedHardwareBufferHandle::reset() {
47   if (buffer_) {
48     AndroidHardwareBufferCompat::GetInstance().Release(buffer_);
49     buffer_ = nullptr;
50   }
51 }
52 
Take()53 AHardwareBuffer* ScopedHardwareBufferHandle::Take() {
54   AHardwareBuffer* buffer = nullptr;
55   std::swap(buffer, buffer_);
56   return buffer;
57 }
58 
Clone() const59 ScopedHardwareBufferHandle ScopedHardwareBufferHandle::Clone() const {
60   DCHECK(buffer_);
61   AndroidHardwareBufferCompat::GetInstance().Acquire(buffer_);
62   return ScopedHardwareBufferHandle(buffer_);
63 }
64 
SerializeAsFileDescriptor() const65 ScopedFD ScopedHardwareBufferHandle::SerializeAsFileDescriptor() const {
66   DCHECK(is_valid());
67 
68   ScopedFD reader, writer;
69   if (!CreateSocketPair(&reader, &writer)) {
70     PLOG(ERROR) << "socketpair";
71     return ScopedFD();
72   }
73 
74   // NOTE: SendHandleToUnixSocket does NOT acquire or retain a reference to the
75   // buffer object. The caller is therefore responsible for ensuring that the
76   // buffer remains alive through the lifetime of this file descriptor.
77   int result =
78       AndroidHardwareBufferCompat::GetInstance().SendHandleToUnixSocket(
79           buffer_, writer.get());
80   if (result < 0) {
81     PLOG(ERROR) << "send";
82     return ScopedFD();
83   }
84 
85   return reader;
86 }
87 
88 // static
89 ScopedHardwareBufferHandle
DeserializeFromFileDescriptor(ScopedFD fd)90 ScopedHardwareBufferHandle::DeserializeFromFileDescriptor(ScopedFD fd) {
91   DCHECK(fd.is_valid());
92   DCHECK(AndroidHardwareBufferCompat::IsSupportAvailable());
93   AHardwareBuffer* buffer = nullptr;
94 
95   // NOTE: Upon success, RecvHandleFromUnixSocket acquires a new reference to
96   // the AHardwareBuffer.
97   int result =
98       AndroidHardwareBufferCompat::GetInstance().RecvHandleFromUnixSocket(
99           fd.get(), &buffer);
100   if (result < 0) {
101     PLOG(ERROR) << "recv";
102     return ScopedHardwareBufferHandle();
103   }
104 
105   return ScopedHardwareBufferHandle(buffer);
106 }
107 
ScopedHardwareBufferHandle(AHardwareBuffer * buffer)108 ScopedHardwareBufferHandle::ScopedHardwareBufferHandle(AHardwareBuffer* buffer)
109     : buffer_(buffer) {
110   DCHECK(AndroidHardwareBufferCompat::IsSupportAvailable());
111 }
112 
113 }  // namespace android
114 }  // namespace base
115