Home | History | Annotate | Download | only in android
      1 // Copyright 2013 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 // The file defines the symbols from OpenSLES that android is using. It then
      6 // loads the library dynamically on first use.
      7 
      8 // The openSLES API is using constant as part of the API. This file will define
      9 // proxies for those constants and redefine those when the library is first
     10 // loaded. For this, it need to be able to change their content and so import
     11 // the headers without const.  This is correct because OpenSLES.h is a C API.
     12 #define const
     13 #include <SLES/OpenSLES.h>
     14 #include <SLES/OpenSLES_Android.h>
     15 #undef const
     16 
     17 #include "base/basictypes.h"
     18 #include "base/files/file_path.h"
     19 #include "base/logging.h"
     20 #include "base/native_library.h"
     21 
     22 // The constants used in chromium. SLInterfaceID is actually a pointer to
     23 // SLInterfaceID_. Those symbols are defined as extern symbols in the OpenSLES
     24 // headers. They will be initialized to their correct values when the library is
     25 // loaded.
     26 SLInterfaceID SL_IID_ENGINE = NULL;
     27 SLInterfaceID SL_IID_ANDROIDSIMPLEBUFFERQUEUE = NULL;
     28 SLInterfaceID SL_IID_ANDROIDCONFIGURATION = NULL;
     29 SLInterfaceID SL_IID_RECORD = NULL;
     30 SLInterfaceID SL_IID_BUFFERQUEUE = NULL;
     31 SLInterfaceID SL_IID_VOLUME = NULL;
     32 SLInterfaceID SL_IID_PLAY = NULL;
     33 
     34 namespace {
     35 
     36 // The name of the library to load.
     37 const char kOpenSLLibraryName[] = "libOpenSLES.so";
     38 
     39 // Loads the OpenSLES library, and initializes all the proxies.
     40 base::NativeLibrary IntializeLibraryHandle() {
     41   base::NativeLibrary handle =
     42       base::LoadNativeLibrary(base::FilePath(kOpenSLLibraryName), NULL);
     43   DCHECK(handle) << "Unable to load " << kOpenSLLibraryName;
     44 
     45   // Setup the proxy for each symbol.
     46   // Attach the symbol name to the proxy address.
     47   struct SymbolDefinition {
     48     const char* name;
     49     SLInterfaceID* sl_iid;
     50   };
     51 
     52   // The list of defined symbols.
     53   const SymbolDefinition kSymbols[] = {
     54       {"SL_IID_ENGINE", &SL_IID_ENGINE},
     55       {"SL_IID_ANDROIDSIMPLEBUFFERQUEUE", &SL_IID_ANDROIDSIMPLEBUFFERQUEUE},
     56       {"SL_IID_ANDROIDCONFIGURATION", &SL_IID_ANDROIDCONFIGURATION},
     57       {"SL_IID_RECORD", &SL_IID_RECORD},
     58       {"SL_IID_BUFFERQUEUE", &SL_IID_BUFFERQUEUE},
     59       {"SL_IID_VOLUME", &SL_IID_VOLUME},
     60       {"SL_IID_PLAY", &SL_IID_PLAY}
     61   };
     62 
     63   for (size_t i = 0; i < sizeof(kSymbols) / sizeof(kSymbols[0]); ++i) {
     64     memcpy(kSymbols[i].sl_iid,
     65            base::GetFunctionPointerFromNativeLibrary(handle, kSymbols[i].name),
     66            sizeof(SLInterfaceID));
     67     DCHECK(*kSymbols[i].sl_iid) << "Unable to find symbol for "
     68                                 << kSymbols[i].name;
     69   }
     70   return handle;
     71 }
     72 
     73 // Returns the handler to the shared library. The library itself will be lazily
     74 // loaded during the first call to this function.
     75 base::NativeLibrary LibraryHandle() {
     76   // The handle is lazily initialized on the first call.
     77   static base::NativeLibrary g_opensles_LibraryHandle =
     78       IntializeLibraryHandle();
     79   return g_opensles_LibraryHandle;
     80 }
     81 
     82 }  // namespace
     83 
     84 // Redefine slCreateEngine symbol.
     85 SLresult slCreateEngine(SLObjectItf* engine,
     86                         SLuint32 num_options,
     87                         SLEngineOption* engine_options,
     88                         SLuint32 num_interfaces,
     89                         SLInterfaceID* interface_ids,
     90                         SLboolean* interfaces_required) {
     91   typedef SLresult (*SlCreateEngineSignature)(SLObjectItf*,
     92                                               SLuint32,
     93                                               SLEngineOption*,
     94                                               SLuint32,
     95                                               SLInterfaceID*,
     96                                               SLboolean*);
     97   static SlCreateEngineSignature g_sl_create_engine_handle =
     98       reinterpret_cast<SlCreateEngineSignature>(
     99           base::GetFunctionPointerFromNativeLibrary(LibraryHandle(),
    100                                                     "slCreateEngine"));
    101   DCHECK(g_sl_create_engine_handle)
    102       << "Unable to find symbol for slCreateEngine";
    103   return g_sl_create_engine_handle(engine,
    104                                    num_options,
    105                                    engine_options,
    106                                    num_interfaces,
    107                                    interface_ids,
    108                                    interfaces_required);
    109 }
    110