• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/android_image_reader_compat.h"
6 
7 #include <dlfcn.h>
8 
9 #include "base/android/build_info.h"
10 #include "base/feature_list.h"
11 #include "base/logging.h"
12 #include "base/strings/string_util.h"
13 
14 #define LOAD_FUNCTION(lib, func)                            \
15   do {                                                      \
16     func##_ = reinterpret_cast<p##func>(dlsym(lib, #func)); \
17     if (!func##_) {                                         \
18       DLOG(ERROR) << "Unable to load function " << #func;   \
19       return false;                                         \
20     }                                                       \
21   } while (0)
22 
23 namespace base {
24 namespace android {
25 
GetInstance()26 AndroidImageReader& AndroidImageReader::GetInstance() {
27   // C++11 static local variable initialization is
28   // thread-safe.
29   static AndroidImageReader instance;
30   return instance;
31 }
32 
IsSupported()33 bool AndroidImageReader::IsSupported() {
34   return is_supported_;
35 }
36 
AndroidImageReader()37 AndroidImageReader::AndroidImageReader() : is_supported_(LoadFunctions()) {}
38 
LoadFunctions()39 bool AndroidImageReader::LoadFunctions() {
40   // If the Chromium build requires __ANDROID_API__ >= 26 at some
41   // point in the future, we could directly use the global functions instead of
42   // dynamic loading. However, since this would be incompatible with pre-Oreo
43   // devices, this is unlikely to happen in the foreseeable future, so we use
44   // dynamic loading.
45 
46   // Functions are not present for android version older than OREO.
47   // Currently we want to enable AImageReader only for android P+ devices.
48   if (base::android::BuildInfo::GetInstance()->sdk_int() <
49       base::android::SDK_VERSION_P) {
50     return false;
51   }
52 
53   void* libmediandk = dlopen("libmediandk.so", RTLD_NOW);
54   if (libmediandk == nullptr) {
55     LOG(ERROR) << "Couldnt open libmediandk.so";
56     return false;
57   }
58 
59   LOAD_FUNCTION(libmediandk, AImage_delete);
60   LOAD_FUNCTION(libmediandk, AImage_deleteAsync);
61   LOAD_FUNCTION(libmediandk, AImage_getHardwareBuffer);
62   LOAD_FUNCTION(libmediandk, AImage_getWidth);
63   LOAD_FUNCTION(libmediandk, AImage_getHeight);
64   LOAD_FUNCTION(libmediandk, AImage_getCropRect);
65   LOAD_FUNCTION(libmediandk, AImageReader_newWithUsage);
66   LOAD_FUNCTION(libmediandk, AImageReader_setImageListener);
67   LOAD_FUNCTION(libmediandk, AImageReader_delete);
68   LOAD_FUNCTION(libmediandk, AImageReader_getFormat);
69   LOAD_FUNCTION(libmediandk, AImageReader_getWindow);
70   LOAD_FUNCTION(libmediandk, AImageReader_acquireLatestImageAsync);
71   LOAD_FUNCTION(libmediandk, AImageReader_acquireNextImageAsync);
72 
73   void* libandroid = dlopen("libandroid.so", RTLD_NOW);
74   if (libandroid == nullptr) {
75     LOG(ERROR) << "Couldnt open libandroid.so";
76     return false;
77   }
78 
79   LOAD_FUNCTION(libandroid, ANativeWindow_toSurface);
80 
81   return true;
82 }
83 
AImage_delete(AImage * image)84 void AndroidImageReader::AImage_delete(AImage* image) {
85   AImage_delete_(image);
86 }
87 
AImage_deleteAsync(AImage * image,int releaseFenceFd)88 void AndroidImageReader::AImage_deleteAsync(AImage* image, int releaseFenceFd) {
89   AImage_deleteAsync_(image, releaseFenceFd);
90 }
91 
AImage_getHardwareBuffer(const AImage * image,AHardwareBuffer ** buffer)92 media_status_t AndroidImageReader::AImage_getHardwareBuffer(
93     const AImage* image,
94     AHardwareBuffer** buffer) {
95   return AImage_getHardwareBuffer_(image, buffer);
96 }
97 
AImage_getWidth(const AImage * image,int32_t * width)98 media_status_t AndroidImageReader::AImage_getWidth(const AImage* image,
99                                                    int32_t* width) {
100   return AImage_getWidth_(image, width);
101 }
102 
AImage_getHeight(const AImage * image,int32_t * height)103 media_status_t AndroidImageReader::AImage_getHeight(const AImage* image,
104                                                     int32_t* height) {
105   return AImage_getHeight_(image, height);
106 }
107 
AImage_getCropRect(const AImage * image,AImageCropRect * rect)108 media_status_t AndroidImageReader::AImage_getCropRect(const AImage* image,
109                                                       AImageCropRect* rect) {
110   return AImage_getCropRect_(image, rect);
111 }
112 
AImageReader_newWithUsage(int32_t width,int32_t height,int32_t format,uint64_t usage,int32_t maxImages,AImageReader ** reader)113 media_status_t AndroidImageReader::AImageReader_newWithUsage(
114     int32_t width,
115     int32_t height,
116     int32_t format,
117     uint64_t usage,
118     int32_t maxImages,
119     AImageReader** reader) {
120   return AImageReader_newWithUsage_(width, height, format, usage, maxImages,
121                                     reader);
122 }
123 
AImageReader_setImageListener(AImageReader * reader,AImageReader_ImageListener * listener)124 media_status_t AndroidImageReader::AImageReader_setImageListener(
125     AImageReader* reader,
126     AImageReader_ImageListener* listener) {
127   return AImageReader_setImageListener_(reader, listener);
128 }
129 
AImageReader_delete(AImageReader * reader)130 void AndroidImageReader::AImageReader_delete(AImageReader* reader) {
131   AImageReader_delete_(reader);
132 }
133 
AImageReader_getFormat(const AImageReader * reader,int32_t * format)134 media_status_t AndroidImageReader::AImageReader_getFormat(
135     const AImageReader* reader,
136     int32_t* format) {
137   return AImageReader_getFormat_(reader, format);
138 }
139 
AImageReader_getWindow(AImageReader * reader,ANativeWindow ** window)140 media_status_t AndroidImageReader::AImageReader_getWindow(
141     AImageReader* reader,
142     ANativeWindow** window) {
143   return AImageReader_getWindow_(reader, window);
144 }
145 
AImageReader_acquireLatestImageAsync(AImageReader * reader,AImage ** image,int * acquireFenceFd)146 media_status_t AndroidImageReader::AImageReader_acquireLatestImageAsync(
147     AImageReader* reader,
148     AImage** image,
149     int* acquireFenceFd) {
150   return AImageReader_acquireLatestImageAsync_(reader, image, acquireFenceFd);
151 }
152 
AImageReader_acquireNextImageAsync(AImageReader * reader,AImage ** image,int * acquireFenceFd)153 media_status_t AndroidImageReader::AImageReader_acquireNextImageAsync(
154     AImageReader* reader,
155     AImage** image,
156     int* acquireFenceFd) {
157   return AImageReader_acquireNextImageAsync_(reader, image, acquireFenceFd);
158 }
159 
ANativeWindow_toSurface(JNIEnv * env,ANativeWindow * window)160 jobject AndroidImageReader::ANativeWindow_toSurface(JNIEnv* env,
161                                                     ANativeWindow* window) {
162   return ANativeWindow_toSurface_(env, window);
163 }
164 
165 }  // namespace android
166 }  // namespace base
167