• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 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/android_hardware_buffer_compat.h"
6 
7 #include "base/android/build_info.h"
8 #include "base/lazy_instance.h"
9 #include "base/logging.h"
10 
11 #include <dlfcn.h>
12 
13 namespace base {
14 
15 namespace {
16 
17 static base::LazyInstance<AndroidHardwareBufferCompat>::Leaky g_compat =
18     LAZY_INSTANCE_INITIALIZER;
19 
20 }  // namespace
21 
AndroidHardwareBufferCompat()22 AndroidHardwareBufferCompat::AndroidHardwareBufferCompat() {
23   DCHECK(IsSupportAvailable());
24 
25   // TODO(klausw): If the Chromium build requires __ANDROID_API__ >= 26 at some
26   // point in the future, we could directly use the global functions instead of
27   // dynamic loading. However, since this would be incompatible with pre-Oreo
28   // devices, this is unlikely to happen in the foreseeable future, so just
29   // unconditionally use dynamic loading.
30 
31   // cf. base/android/linker/modern_linker_jni.cc
32   void* main_dl_handle = dlopen(nullptr, RTLD_NOW);
33 
34   *reinterpret_cast<void**>(&allocate_) =
35       dlsym(main_dl_handle, "AHardwareBuffer_allocate");
36   DCHECK(allocate_);
37 
38   *reinterpret_cast<void**>(&acquire_) =
39       dlsym(main_dl_handle, "AHardwareBuffer_acquire");
40   DCHECK(acquire_);
41 
42   *reinterpret_cast<void**>(&describe_) =
43       dlsym(main_dl_handle, "AHardwareBuffer_describe");
44   DCHECK(describe_);
45 
46   *reinterpret_cast<void**>(&lock_) =
47       dlsym(main_dl_handle, "AHardwareBuffer_lock");
48   DCHECK(lock_);
49 
50   *reinterpret_cast<void**>(&recv_handle_) =
51       dlsym(main_dl_handle, "AHardwareBuffer_recvHandleFromUnixSocket");
52   DCHECK(recv_handle_);
53 
54   *reinterpret_cast<void**>(&release_) =
55       dlsym(main_dl_handle, "AHardwareBuffer_release");
56   DCHECK(release_);
57 
58   *reinterpret_cast<void**>(&send_handle_) =
59       dlsym(main_dl_handle, "AHardwareBuffer_sendHandleToUnixSocket");
60   DCHECK(send_handle_);
61 
62   *reinterpret_cast<void**>(&unlock_) =
63       dlsym(main_dl_handle, "AHardwareBuffer_unlock");
64   DCHECK(unlock_);
65 }
66 
67 // static
IsSupportAvailable()68 bool AndroidHardwareBufferCompat::IsSupportAvailable() {
69   return base::android::BuildInfo::GetInstance()->sdk_int() >=
70          base::android::SDK_VERSION_OREO;
71 }
72 
73 // static
GetInstance()74 AndroidHardwareBufferCompat AndroidHardwareBufferCompat::GetInstance() {
75   return g_compat.Get();
76 }
77 
Allocate(const AHardwareBuffer_Desc * desc,AHardwareBuffer ** out_buffer)78 void AndroidHardwareBufferCompat::Allocate(const AHardwareBuffer_Desc* desc,
79                                            AHardwareBuffer** out_buffer) {
80   DCHECK(IsSupportAvailable());
81   allocate_(desc, out_buffer);
82 }
83 
Acquire(AHardwareBuffer * buffer)84 void AndroidHardwareBufferCompat::Acquire(AHardwareBuffer* buffer) {
85   DCHECK(IsSupportAvailable());
86   acquire_(buffer);
87 }
88 
Describe(const AHardwareBuffer * buffer,AHardwareBuffer_Desc * out_desc)89 void AndroidHardwareBufferCompat::Describe(const AHardwareBuffer* buffer,
90                                            AHardwareBuffer_Desc* out_desc) {
91   DCHECK(IsSupportAvailable());
92   describe_(buffer, out_desc);
93 }
94 
Lock(AHardwareBuffer * buffer,uint64_t usage,int32_t fence,const ARect * rect,void ** out_virtual_address)95 int AndroidHardwareBufferCompat::Lock(AHardwareBuffer* buffer,
96                                       uint64_t usage,
97                                       int32_t fence,
98                                       const ARect* rect,
99                                       void** out_virtual_address) {
100   DCHECK(IsSupportAvailable());
101   return lock_(buffer, usage, fence, rect, out_virtual_address);
102 }
103 
RecvHandleFromUnixSocket(int socket_fd,AHardwareBuffer ** out_buffer)104 int AndroidHardwareBufferCompat::RecvHandleFromUnixSocket(
105     int socket_fd,
106     AHardwareBuffer** out_buffer) {
107   DCHECK(IsSupportAvailable());
108   return recv_handle_(socket_fd, out_buffer);
109 }
110 
Release(AHardwareBuffer * buffer)111 void AndroidHardwareBufferCompat::Release(AHardwareBuffer* buffer) {
112   DCHECK(IsSupportAvailable());
113   release_(buffer);
114 }
115 
SendHandleToUnixSocket(const AHardwareBuffer * buffer,int socket_fd)116 int AndroidHardwareBufferCompat::SendHandleToUnixSocket(
117     const AHardwareBuffer* buffer,
118     int socket_fd) {
119   DCHECK(IsSupportAvailable());
120   return send_handle_(buffer, socket_fd);
121 }
122 
Unlock(AHardwareBuffer * buffer,int32_t * fence)123 int AndroidHardwareBufferCompat::Unlock(AHardwareBuffer* buffer,
124                                         int32_t* fence) {
125   DCHECK(IsSupportAvailable());
126   return unlock_(buffer, fence);
127 }
128 
129 }  // namespace base
130