• 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/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 
13 #define LOAD_FUNCTION(lib, func)                            \
14   do {                                                      \
15     func##_ = reinterpret_cast<p##func>(dlsym(lib, #func)); \
16     if (!func##_) {                                         \
17       DLOG(ERROR) << "Unable to load function " << #func;   \
18       return false;                                         \
19     }                                                       \
20   } while (0)
21 
22 namespace base {
23 namespace android {
24 
GetInstance()25 AndroidImageReader& AndroidImageReader::GetInstance() {
26   // C++11 static local variable initialization is
27   // thread-safe.
28   static base::NoDestructor<AndroidImageReader> instance;
29   return *instance;
30 }
31 
IsSupported()32 bool AndroidImageReader::IsSupported() {
33   return is_supported_;
34 }
35 
AndroidImageReader()36 AndroidImageReader::AndroidImageReader() {
37   is_supported_ = LoadFunctions();
38 }
39 
LoadFunctions()40 bool AndroidImageReader::LoadFunctions() {
41   // If the Chromium build requires __ANDROID_API__ >= 26 at some
42   // point in the future, we could directly use the global functions instead of
43   // dynamic loading. However, since this would be incompatible with pre-Oreo
44   // devices, this is unlikely to happen in the foreseeable future, so we use
45   // dynamic loading.
46 
47   // Functions are not present for android version older than OREO
48   if (base::android::BuildInfo::GetInstance()->sdk_int() <
49       base::android::SDK_VERSION_OREO) {
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, AImageReader_new);
65   LOAD_FUNCTION(libmediandk, AImageReader_setImageListener);
66   LOAD_FUNCTION(libmediandk, AImageReader_delete);
67   LOAD_FUNCTION(libmediandk, AImageReader_getWindow);
68   LOAD_FUNCTION(libmediandk, AImageReader_acquireLatestImageAsync);
69 
70   void* libandroid = dlopen("libandroid.so", RTLD_NOW);
71   if (libandroid == nullptr) {
72     LOG(ERROR) << "Couldnt open libandroid.so";
73     return false;
74   }
75 
76   LOAD_FUNCTION(libandroid, ANativeWindow_toSurface);
77 
78   return true;
79 }
80 
AImage_delete(AImage * image)81 void AndroidImageReader::AImage_delete(AImage* image) {
82   AImage_delete_(image);
83 }
84 
AImage_deleteAsync(AImage * image,int releaseFenceFd)85 void AndroidImageReader::AImage_deleteAsync(AImage* image, int releaseFenceFd) {
86   AImage_deleteAsync_(image, releaseFenceFd);
87 }
88 
AImage_getHardwareBuffer(const AImage * image,AHardwareBuffer ** buffer)89 media_status_t AndroidImageReader::AImage_getHardwareBuffer(
90     const AImage* image,
91     AHardwareBuffer** buffer) {
92   return AImage_getHardwareBuffer_(image, buffer);
93 }
94 
AImage_getWidth(const AImage * image,int32_t * width)95 media_status_t AndroidImageReader::AImage_getWidth(const AImage* image,
96                                                    int32_t* width) {
97   return AImage_getWidth_(image, width);
98 }
99 
AImage_getHeight(const AImage * image,int32_t * height)100 media_status_t AndroidImageReader::AImage_getHeight(const AImage* image,
101                                                     int32_t* height) {
102   return AImage_getHeight_(image, height);
103 }
104 
AImageReader_new(int32_t width,int32_t height,int32_t format,int32_t maxImages,AImageReader ** reader)105 media_status_t AndroidImageReader::AImageReader_new(int32_t width,
106                                                     int32_t height,
107                                                     int32_t format,
108                                                     int32_t maxImages,
109                                                     AImageReader** reader) {
110   return AImageReader_new_(width, height, format, maxImages, reader);
111 }
112 
AImageReader_setImageListener(AImageReader * reader,AImageReader_ImageListener * listener)113 media_status_t AndroidImageReader::AImageReader_setImageListener(
114     AImageReader* reader,
115     AImageReader_ImageListener* listener) {
116   return AImageReader_setImageListener_(reader, listener);
117 }
118 
AImageReader_delete(AImageReader * reader)119 void AndroidImageReader::AImageReader_delete(AImageReader* reader) {
120   AImageReader_delete_(reader);
121 }
122 
AImageReader_getWindow(AImageReader * reader,ANativeWindow ** window)123 media_status_t AndroidImageReader::AImageReader_getWindow(
124     AImageReader* reader,
125     ANativeWindow** window) {
126   return AImageReader_getWindow_(reader, window);
127 }
128 
AImageReader_acquireLatestImageAsync(AImageReader * reader,AImage ** image,int * acquireFenceFd)129 media_status_t AndroidImageReader::AImageReader_acquireLatestImageAsync(
130     AImageReader* reader,
131     AImage** image,
132     int* acquireFenceFd) {
133   return AImageReader_acquireLatestImageAsync_(reader, image, acquireFenceFd);
134 }
135 
ANativeWindow_toSurface(JNIEnv * env,ANativeWindow * window)136 jobject AndroidImageReader::ANativeWindow_toSurface(JNIEnv* env,
137                                                     ANativeWindow* window) {
138   return ANativeWindow_toSurface_(env, window);
139 }
140 
141 }  // namespace android
142 }  // namespace base
143