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