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)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 operator =(ScopedHardwareBufferHandle && other)31ScopedHardwareBufferHandle& ScopedHardwareBufferHandle::operator=( 32 ScopedHardwareBufferHandle&& other) { 33 reset(); 34 std::swap(buffer_, other.buffer_); 35 return *this; 36 } 37 is_valid() const38bool ScopedHardwareBufferHandle::is_valid() const { 39 return buffer_ != nullptr; 40 } 41 get() const42AHardwareBuffer* ScopedHardwareBufferHandle::get() const { 43 return buffer_; 44 } 45 reset()46void ScopedHardwareBufferHandle::reset() { 47 if (buffer_) { 48 AndroidHardwareBufferCompat::GetInstance().Release(buffer_); 49 buffer_ = nullptr; 50 } 51 } 52 Take()53AHardwareBuffer* ScopedHardwareBufferHandle::Take() { 54 AHardwareBuffer* buffer = nullptr; 55 std::swap(buffer, buffer_); 56 return buffer; 57 } 58 Clone() const59ScopedHardwareBufferHandle ScopedHardwareBufferHandle::Clone() const { 60 DCHECK(buffer_); 61 AndroidHardwareBufferCompat::GetInstance().Acquire(buffer_); 62 return ScopedHardwareBufferHandle(buffer_); 63 } 64 SerializeAsFileDescriptor() const65ScopedFD 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)90ScopedHardwareBufferHandle::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)108ScopedHardwareBufferHandle::ScopedHardwareBufferHandle(AHardwareBuffer* buffer) 109 : buffer_(buffer) { 110 DCHECK(AndroidHardwareBufferCompat::IsSupportAvailable()); 111 } 112 113 } // namespace android 114 } // namespace base 115