1 // Copyright 2018 The Chromium Authors 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)16ScopedHardwareBufferHandle::ScopedHardwareBufferHandle( 17 ScopedHardwareBufferHandle&& other) { 18 *this = std::move(other); 19 } 20 ~ScopedHardwareBufferHandle()21ScopedHardwareBufferHandle::~ScopedHardwareBufferHandle() { 22 reset(); 23 } 24 25 // static Adopt(AHardwareBuffer * buffer)26ScopedHardwareBufferHandle ScopedHardwareBufferHandle::Adopt( 27 AHardwareBuffer* buffer) { 28 return ScopedHardwareBufferHandle(buffer); 29 } 30 31 // static Create(AHardwareBuffer * buffer)32ScopedHardwareBufferHandle ScopedHardwareBufferHandle::Create( 33 AHardwareBuffer* buffer) { 34 AndroidHardwareBufferCompat::GetInstance().Acquire(buffer); 35 return ScopedHardwareBufferHandle(buffer); 36 } 37 operator =(ScopedHardwareBufferHandle && other)38ScopedHardwareBufferHandle& ScopedHardwareBufferHandle::operator=( 39 ScopedHardwareBufferHandle&& other) { 40 reset(); 41 std::swap(buffer_, other.buffer_); 42 return *this; 43 } 44 is_valid() const45bool ScopedHardwareBufferHandle::is_valid() const { 46 return buffer_ != nullptr; 47 } 48 get() const49AHardwareBuffer* ScopedHardwareBufferHandle::get() const { 50 return buffer_; 51 } 52 reset()53void ScopedHardwareBufferHandle::reset() { 54 if (buffer_) { 55 AndroidHardwareBufferCompat::GetInstance().Release(buffer_); 56 buffer_ = nullptr; 57 } 58 } 59 Take()60AHardwareBuffer* ScopedHardwareBufferHandle::Take() { 61 AHardwareBuffer* buffer = buffer_; 62 buffer_ = nullptr; 63 return buffer; 64 } 65 Clone() const66ScopedHardwareBufferHandle ScopedHardwareBufferHandle::Clone() const { 67 DCHECK(buffer_); 68 AndroidHardwareBufferCompat::GetInstance().Acquire(buffer_); 69 return ScopedHardwareBufferHandle(buffer_); 70 } 71 SerializeAsFileDescriptor() const72ScopedFD ScopedHardwareBufferHandle::SerializeAsFileDescriptor() const { 73 DCHECK(is_valid()); 74 75 ScopedFD reader, writer; 76 if (!CreateSocketPair(&reader, &writer)) { 77 PLOG(ERROR) << "socketpair"; 78 return ScopedFD(); 79 } 80 81 // NOTE: SendHandleToUnixSocket does NOT acquire or retain a reference to the 82 // buffer object. The caller is therefore responsible for ensuring that the 83 // buffer remains alive through the lifetime of this file descriptor. 84 int result = 85 AndroidHardwareBufferCompat::GetInstance().SendHandleToUnixSocket( 86 buffer_, writer.get()); 87 if (result < 0) { 88 PLOG(ERROR) << "send"; 89 return ScopedFD(); 90 } 91 92 return reader; 93 } 94 95 // static 96 ScopedHardwareBufferHandle DeserializeFromFileDescriptor(ScopedFD fd)97ScopedHardwareBufferHandle::DeserializeFromFileDescriptor(ScopedFD fd) { 98 DCHECK(fd.is_valid()); 99 DCHECK(AndroidHardwareBufferCompat::IsSupportAvailable()); 100 AHardwareBuffer* buffer = nullptr; 101 102 // NOTE: Upon success, RecvHandleFromUnixSocket acquires a new reference to 103 // the AHardwareBuffer. 104 int result = 105 AndroidHardwareBufferCompat::GetInstance().RecvHandleFromUnixSocket( 106 fd.get(), &buffer); 107 if (result < 0) { 108 PLOG(ERROR) << "recv"; 109 return ScopedHardwareBufferHandle(); 110 } 111 112 return ScopedHardwareBufferHandle(buffer); 113 } 114 ScopedHardwareBufferHandle(AHardwareBuffer * buffer)115ScopedHardwareBufferHandle::ScopedHardwareBufferHandle(AHardwareBuffer* buffer) 116 : buffer_(buffer) { 117 DCHECK(AndroidHardwareBufferCompat::IsSupportAvailable()); 118 } 119 120 } // namespace android 121 } // namespace base 122