rjw | 1f88458 | 2022-01-06 17:20:42 +0800 | [diff] [blame^] | 1 | #include "AudioParamParserPriv.h" |
| 2 | |
| 3 | #ifdef WIN32 |
| 4 | #include <windows.h> |
| 5 | #include <io.h> |
| 6 | /* MediaTek Inc. (C) 2016. All rights reserved. |
| 7 | * |
| 8 | * Copyright Statement: |
| 9 | * This software/firmware and related documentation ("MediaTek Software") are |
| 10 | * protected under relevant copyright laws. The information contained herein is |
| 11 | * confidential and proprietary to MediaTek Inc. and/or its licensors. Without |
| 12 | * the prior written permission of MediaTek inc. and/or its licensors, any |
| 13 | * reproduction, modification, use or disclosure of MediaTek Software, and |
| 14 | * information contained herein, in whole or in part, shall be strictly |
| 15 | * prohibited. |
| 16 | */ |
| 17 | |
| 18 | /* |
| 19 | * Description: |
| 20 | * Implement C++ & windows related APIs |
| 21 | */ |
| 22 | |
| 23 | #include <iostream> |
| 24 | #include <fstream> |
| 25 | #include <fcntl.h> |
| 26 | #include <stdio.h> |
| 27 | |
| 28 | #ifndef _USE_OLD_IOSTREAMS |
| 29 | using namespace std; |
| 30 | #endif |
| 31 | #else /* !WIN32 */ |
| 32 | #include <inttypes.h> |
| 33 | |
| 34 | #if !defined(SYS_IMPL) |
| 35 | #if !defined(MTK_YOCTO_AUDIO) |
| 36 | #include "AudioCustParam.h" |
| 37 | #endif |
| 38 | #else |
| 39 | #include <binder/ProcessState.h> |
| 40 | #include <media/AudioSystem.h> |
| 41 | #endif |
| 42 | |
| 43 | using namespace android; |
| 44 | #endif |
| 45 | |
| 46 | |
| 47 | #ifndef WIN32 |
| 48 | #if defined(SYS_IMPL) |
| 49 | #include <android/hardware/audio/4.0/IDevicesFactory.h> |
| 50 | #include <android/hardware/audio/4.0/IDevice.h> |
| 51 | #include <vendor/mediatek/hardware/audio/4.1/IMTKPrimaryDevice.h> |
| 52 | #include <vendor/mediatek/hardware/audio/4.1/IAudioParameterChangedCallback.h> |
| 53 | #include "MTKPrimaryDevicesHalClientInterface.h" |
| 54 | |
| 55 | |
| 56 | using ::android::hardware::audio::V4_0::IDevicesFactory; |
| 57 | using ::android::hardware::audio::V4_0::IDevice; |
| 58 | using ::android::hardware::audio::V4_0::Result; |
| 59 | using ::android::hardware::hidl_death_recipient; |
| 60 | using ::android::hardware::hidl_string; |
| 61 | using ::android::hardware::Return; |
| 62 | using ::android::hidl::base::V1_0::IBase; |
| 63 | using ::vendor::mediatek::hardware::audio::V4_1::IAudioParameterChangedCallback; |
| 64 | using ::vendor::mediatek::hardware::audio::V4_1::IMTKPrimaryDevice; |
| 65 | |
| 66 | |
| 67 | /* |
| 68 | * Class declaration |
| 69 | */ |
| 70 | class AudioHalDeathRecipient : public hidl_death_recipient { |
| 71 | public: |
| 72 | AudioHalDeathRecipient(void) {} |
| 73 | void serviceDied(uint64_t cookie, const wp<::android::hidl::base::V1_0::IBase> & /*who*/) override { |
| 74 | #if 1 |
| 75 | ERR_LOG("%s() AudioServer die... exit!(cookie = %" PRIu64 ")", __FUNCTION__, cookie); |
| 76 | exit(1); |
| 77 | #else |
| 78 | /* Re-connect to server */ |
| 79 | registerAudioParameterChangedCallback(appOpsGetInstance()->appHandleGetInstance()); |
| 80 | #endif |
| 81 | } |
| 82 | }; |
| 83 | |
| 84 | class AudioParameterChangedCallback : public IAudioParameterChangedCallback { |
| 85 | Return<void> audioParameterChangedCallback(const hidl_string &audioTypeName) override { |
| 86 | INFO_LOG("%s() got callback! (audioType: %s)", __FUNCTION__, audioTypeName.c_str()); |
| 87 | AudioType* audioType = appHandleGetAudioTypeByName(appHandleGetInstance(), audioTypeName.c_str()); |
| 88 | if (audioType) { |
| 89 | audioType->allowReload = 1; |
| 90 | } |
| 91 | |
| 92 | /* Notify all callback function */ |
| 93 | appHandleNotifyAllCallbacks(appHandleGetInstance(), audioTypeName.c_str()); |
| 94 | |
| 95 | return ::android::hardware::Void(); |
| 96 | } |
| 97 | }; |
| 98 | |
| 99 | |
| 100 | /* |
| 101 | * Global variable |
| 102 | */ |
| 103 | const sp<IDevice> *gDevice; |
| 104 | sp<AudioHalDeathRecipient> gDeathRecipient; |
| 105 | Result gRetval = Result::NOT_INITIALIZED; |
| 106 | |
| 107 | |
| 108 | EXPORT APP_STATUS registerAudioParameterChangedCallback(AppHandle *appHandle) { |
| 109 | /* Get IDevicesFactory */ |
| 110 | sp<IDevicesFactory> devicesFactory = IDevicesFactory::getService(); |
| 111 | if (devicesFactory == 0) { |
| 112 | ALOGE("Failed to obtain IDevicesFactory service, terminating process."); |
| 113 | exit(1); |
| 114 | } |
| 115 | |
| 116 | /* Open Device */ |
| 117 | Return<void> ret = devicesFactory->openDevice( |
| 118 | "primary", |
| 119 | [&](Result r, const sp<IDevice> &result) { |
| 120 | gRetval = r; |
| 121 | if (gRetval == Result::OK) { |
| 122 | gDevice = new sp<IDevice>(result); |
| 123 | } |
| 124 | }); |
| 125 | |
| 126 | if (!ret.isOk() || gRetval != Result::OK) { |
| 127 | ERR_LOG("%s(), Load audio interface fail, (ret: %d, Result: %d)", __FUNCTION__, ret.isOk(), gRetval == Result::OK); |
| 128 | return APP_ERROR; |
| 129 | } |
| 130 | INFO_LOG("%s() audio interface loaded, dev %p", __FUNCTION__, gDevice->get()); |
| 131 | |
| 132 | /* Register AudioParameterChangedCallback */ |
| 133 | sp<IAudioParameterChangedCallback> callback = new AudioParameterChangedCallback(); |
| 134 | sp<IMTKPrimaryDevice> mtkPrimaryDev = IMTKPrimaryDevice::castFrom(*gDevice); |
| 135 | Return<Result> result = mtkPrimaryDev->setAudioParameterChangedCallback(callback); |
| 136 | |
| 137 | if (!result.isOk()) { |
| 138 | ERR_LOG("setAudioParameterChangedCallback return fail!"); |
| 139 | return APP_ERROR; |
| 140 | } |
| 141 | |
| 142 | /* Link to death */ |
| 143 | gDeathRecipient = new AudioHalDeathRecipient(); |
| 144 | devicesFactory->linkToDeath(gDeathRecipient, 123456); |
| 145 | INFO_LOG("%s() linkToDeath success", __FUNCTION__); |
| 146 | |
| 147 | return APP_NO_ERROR; |
| 148 | } |
| 149 | |
| 150 | EXPORT APP_STATUS unregisterAudioParameterChangedCallback(AppHandle *appHandle) { |
| 151 | INFO_LOG("%s()", __FUNCTION__); |
| 152 | |
| 153 | /* Clear callback first */ |
| 154 | sp<IMTKPrimaryDevice> mtkPrimaryDev = IMTKPrimaryDevice::castFrom(*gDevice); |
| 155 | mtkPrimaryDev->clearAudioParameterChangedCallback(); |
| 156 | |
| 157 | /* unlinkToDeath */ |
| 158 | sp<IDevicesFactory> devicesFactory = IDevicesFactory::getService(); |
| 159 | devicesFactory->unlinkToDeath(gDeathRecipient); |
| 160 | |
| 161 | gDevice = NULL; |
| 162 | |
| 163 | return APP_NO_ERROR; |
| 164 | } |
| 165 | |
| 166 | #endif |
| 167 | |
| 168 | #if defined(SYS_IMPL) |
| 169 | void initProcessState() { |
| 170 | static int processStateInited = 0; |
| 171 | |
| 172 | /* Init ProcessState, */ |
| 173 | if (!processStateInited) { |
| 174 | ProcessState::self()->startThreadPool(); |
| 175 | sp<ProcessState> proc(ProcessState::self()); |
| 176 | processStateInited = 1; |
| 177 | } |
| 178 | } |
| 179 | #endif |
| 180 | |
| 181 | EXPORT int isCustXmlEnable(void) { |
| 182 | #if !defined(APP_FORCE_ENABLE_CUS_XML) && !defined(CONFIG_MT_ENG_BUILD) |
| 183 | int res = 0; |
| 184 | #if !defined(SYS_IMPL) |
| 185 | /* Only vnd AudioParamParser can query NVRam */ |
| 186 | AUDIO_CUSTOM_AUDIO_FUNC_SWITCH_PARAM_STRUCT eParaAudioFuncSwitch; |
| 187 | res = GetAudioFuncSwitchParamFromNV(&eParaAudioFuncSwitch); |
| 188 | if (res) { |
| 189 | INFO_LOG("%s(), Not eng load, Get cust xml enabled from NVRam: GET_CUST_XML_ENABLE=%d\n", __FUNCTION__, (eParaAudioFuncSwitch.cust_xml_enable == 1)); |
| 190 | return (eParaAudioFuncSwitch.cust_xml_enable == 1); |
| 191 | } else |
| 192 | #endif |
| 193 | { |
| 194 | /* If process cannot get parameter due to permission issue, using AudioSystem API instead */ |
| 195 | ALOGW("%s(), Query nvram fail! don't enable cust XML", __FUNCTION__); |
| 196 | return 0; |
| 197 | } |
| 198 | #else |
| 199 | INFO_LOG("%s(), always return 1\n", __FUNCTION__); |
| 200 | return 1; |
| 201 | #endif |
| 202 | } |
| 203 | |
| 204 | EXPORT char *audioSystemGetParameters(const char *str) { |
| 205 | #if defined(SYS_IMPL) |
| 206 | String8 res; |
| 207 | const char* ret = NULL; |
| 208 | initProcessState(); |
| 209 | res = AudioSystem::getParameters(0, String8(str)); |
| 210 | ret = res.string() + strlen(str) + 1; |
| 211 | return strdup(ret); |
| 212 | #else |
| 213 | return strdup(""); |
| 214 | #endif |
| 215 | } |
| 216 | |
| 217 | EXPORT void audioSystemSetParameters(const char *str) { |
| 218 | #if defined(SYS_IMPL) |
| 219 | initProcessState(); |
| 220 | AudioSystem::setParameters(0, String8(str)); |
| 221 | #endif |
| 222 | } |
| 223 | #else /* WIN32 */ |
| 224 | |
| 225 | /* For Tuning Tool show the debug message */ |
| 226 | EXPORT void redirectIOToConsole() { |
| 227 | CONSOLE_SCREEN_BUFFER_INFO consoleScreenBufferHandle; |
| 228 | AllocConsole(); |
| 229 | GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleScreenBufferHandle); |
| 230 | consoleScreenBufferHandle.dwSize.Y = 600; |
| 231 | SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), consoleScreenBufferHandle.dwSize); |
| 232 | |
| 233 | long stdHandle = (long) GetStdHandle(STD_INPUT_HANDLE); |
| 234 | int osfHandle = _open_osfhandle(stdHandle, _O_TEXT); |
| 235 | FILE *fp = _fdopen(osfHandle, "r"); |
| 236 | *stdin = *fp; |
| 237 | setvbuf(stdin, NULL, _IONBF, 0); |
| 238 | |
| 239 | stdHandle = (long) GetStdHandle(STD_OUTPUT_HANDLE); |
| 240 | osfHandle = _open_osfhandle(stdHandle, _O_TEXT); |
| 241 | fp = _fdopen(osfHandle, "w"); |
| 242 | *stdout = *fp; |
| 243 | setvbuf(stdout, NULL, _IONBF, 0); |
| 244 | |
| 245 | stdHandle = (long) GetStdHandle(STD_ERROR_HANDLE); |
| 246 | osfHandle = _open_osfhandle(stdHandle, _O_TEXT); |
| 247 | fp = _fdopen(osfHandle, "w"); |
| 248 | *stderr = *fp; |
| 249 | setvbuf(stderr, NULL, _IONBF, 0); |
| 250 | |
| 251 | ios::sync_with_stdio(); |
| 252 | |
| 253 | } |
| 254 | #endif |