1 /*
2 * Copyright (c) 2021-2022, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     media_user_setting_configure.cpp
24 //! \brief    The interface of media user setting configure.
25 
26 #include "mos_os.h"
27 #include "media_user_setting_configure.h"
28 
29 namespace MediaUserSetting {
30 namespace Internal {
31 
32 const UFKEY_NEXT Configure::m_rootKey = UFKEY_INTERNAL_NEXT;
33 const char *Configure::m_configPath = USER_SETTING_CONFIG_PATH;
34 const char *Configure::m_reportPath = USER_SETTING_REPORT_PATH;
35 
Configure(MOS_USER_FEATURE_KEY_PATH_INFO * keyPathInfo)36 Configure::Configure(MOS_USER_FEATURE_KEY_PATH_INFO *keyPathInfo):Configure()
37 {
38     m_keyPathInfo = keyPathInfo;
39 
40     std::string subPath = "";
41 
42     if (m_keyPathInfo != nullptr && m_keyPathInfo->Path != nullptr)
43     {
44         subPath = m_keyPathInfo->Path;
45     }
46 
47     //when statePath set, will init m_statedConfigPath and m_statedReportPath with m_keyPathInfo
48     m_statedConfigPath = subPath + m_configPath;
49     m_statedReportPath = subPath + m_reportPath;
50 }
51 
Configure()52 Configure::Configure()
53 {
54 #if (_DEBUG || _RELEASE_INTERNAL)
55         m_isDebugMode = true;
56 #endif
57     m_statedConfigPath = m_configPath;
58     m_statedReportPath = m_reportPath;
59 
60     MosUtilities::MosInitializeReg(m_regBufferMap);
61 }
62 
~Configure()63 Configure::~Configure()
64 {
65     MosUtilities::MosUninitializeReg(m_regBufferMap);
66 }
67 
Register(const std::string & valueName,const Group & group,const Value & defaultValue,bool isReportKey,bool debugOnly,bool useCustomPath,const std::string & customPath,bool statePath)68 MOS_STATUS Configure::Register(
69     const std::string &valueName,
70     const Group &group,
71     const Value &defaultValue,
72     bool isReportKey,
73     bool debugOnly,
74     bool useCustomPath,
75     const std::string &customPath,
76     bool statePath)
77 {
78     m_mutexLock.Lock();
79 
80     if (IsDefinitionExist(valueName))
81     {
82         m_mutexLock.Unlock();
83         return MOS_STATUS_FILE_EXISTS;
84     }
85 
86     auto &defs = GetDefinitions(group);
87     std::string subPath = "";
88     if (useCustomPath)
89     {
90         if (statePath && m_keyPathInfo != nullptr && m_keyPathInfo->Path != nullptr)
91         {
92             subPath = m_keyPathInfo->Path;
93         }
94         subPath += customPath;
95     }
96     else
97     {
98         if (statePath)
99         {
100             subPath = m_statedConfigPath;
101         }
102         else
103         {
104             subPath = m_configPath;
105         }
106     }
107 
108     defs.insert(
109         std::make_pair(
110             MakeHash(valueName),
111             std::make_shared<Definition>(
112                 valueName,
113                 defaultValue,
114                 isReportKey,
115                 debugOnly,
116                 useCustomPath,
117                 subPath,
118                 m_rootKey,
119                 statePath)));
120 
121     m_mutexLock.Unlock();
122 
123     return MOS_STATUS_SUCCESS;
124 }
125 
Read(Value & value,const std::string & valueName,const Group & group,const Value & customValue,bool useCustomValue,uint32_t option)126 MOS_STATUS Configure::Read(Value &value,
127     const std::string &valueName,
128     const Group &group,
129     const Value &customValue,
130     bool useCustomValue,
131     uint32_t option)
132 {
133     int32_t     ret     = 0;
134     MOS_STATUS  status  = MOS_STATUS_SUCCESS;
135     auto        &defs   = GetDefinitions(group);
136     auto        def     = defs[MakeHash(valueName)];
137     if (def == nullptr)
138     {
139         return MOS_STATUS_INVALID_HANDLE;
140     }
141     auto        defaultType = def->DefaultValue().ValueType();
142 
143     if (def->IsDebugOnly() && !m_isDebugMode)
144     {
145         value = useCustomValue ? customValue : def->DefaultValue();
146         return MOS_STATUS_SUCCESS;
147     }
148     //First, Read user setting. If succeed, return;
149     {
150         std::string path = GetReadPath(def, option);
151         UFKEY_NEXT  key  = {};
152 
153         m_mutexLock.Lock();
154 
155         status = MosUtilities::MosOpenRegKey(m_rootKey, path, KEY_READ, &key, m_regBufferMap);
156         if (status == MOS_STATUS_SUCCESS)
157         {
158             status = MosUtilities::MosGetRegValue(key, valueName, defaultType, value, m_regBufferMap);
159             MosUtilities::MosCloseRegKey(key);
160         }
161 
162         m_mutexLock.Unlock();
163     }
164 
165     //Second, if 1st failed, read envionment variable. External user setting does not set env varaible now.
166     if (status != MOS_STATUS_SUCCESS && option == MEDIA_USER_SETTING_INTERNAL)
167     {
168         // read env variable if no user setting set
169         status = MosUtilities::MosReadEnvVariable(def->ItemEnvName(), defaultType, value);
170     }
171 
172     if (status != MOS_STATUS_SUCCESS)
173     {
174         // customValue is only for internal user setting Read
175         if (option == MEDIA_USER_SETTING_INTERNAL)
176         {
177             value = useCustomValue ? customValue : def->DefaultValue();
178         }
179         else
180         {
181             // For external user setting, no customValue
182             if (useCustomValue == true)
183             {
184                 MOS_OS_ASSERTMESSAGE("External user setting %s customValue will not be used.", valueName.c_str());
185             }
186         }
187     }
188 
189     return status;
190 }
191 
Write(const std::string & valueName,const Value & value,const Group & group,bool isForReport,uint32_t option)192 MOS_STATUS Configure::Write(
193     const std::string &valueName,
194     const Value &value,
195     const Group &group,
196     bool isForReport,
197     uint32_t option)
198 {
199     auto &defs = GetDefinitions(group);
200 
201     auto def = defs[MakeHash(valueName)];
202     if (def == nullptr)
203     {
204         return MOS_STATUS_INVALID_HANDLE;
205     }
206 
207     if (def->IsDebugOnly() && !m_isDebugMode)
208     {
209         return MOS_STATUS_SUCCESS;
210     }
211 
212     if (!def->IsReportKey() && isForReport)
213     {
214         return MOS_STATUS_INVALID_PARAMETER;
215     }
216 
217     std::string path = GetReportPath(def, option);
218 
219     UFKEY_NEXT key = {};
220     MOS_STATUS status = MOS_STATUS_UNKNOWN;
221 
222     m_mutexLock.Lock();
223     status = MosUtilities::MosCreateRegKey(m_rootKey, path, KEY_WRITE, &key, m_regBufferMap);
224 
225     if (status == MOS_STATUS_SUCCESS)
226     {
227         status = MosUtilities::MosSetRegValue(key, valueName, value, m_regBufferMap);
228 
229         MosUtilities::MosCloseRegKey(key);
230     }
231     m_mutexLock.Unlock();
232 
233     if (status != MOS_STATUS_SUCCESS)
234     {
235         // When any fail happen, just print out a critical message, but not return error to break normal call sequence.
236         MOS_OS_NORMALMESSAGE("Failed to write media user setting %s value.", valueName.c_str());
237     }
238 
239     return MOS_STATUS_SUCCESS;
240 }
241 
GetReadPath(std::shared_ptr<Definition> def,uint32_t option)242 std::string Configure::GetReadPath(
243     std::shared_ptr<Definition> def,
244     uint32_t option)
245 {
246     std::string path = "";
247     if (def == nullptr)
248     {
249         return path;
250     }
251 
252     if (option == MEDIA_USER_SETTING_INTERNAL)
253     {
254         return def->GetSubPath();
255     }
256     else if (option == MEDIA_USER_SETTING_INTERNAL_REPORT)
257     {
258         return m_statedReportPath;
259     }
260     else
261     {
262         return GetExternalPath(option);
263     }
264 }
265 
GetReportPath(std::shared_ptr<Definition> def,uint32_t option)266 std::string Configure::GetReportPath(
267     std::shared_ptr<Definition> def,
268     uint32_t option)
269 {
270     std::string path = "";
271     if (def == nullptr)
272     {
273         return path;
274     }
275     if (option == MEDIA_USER_SETTING_INTERNAL)
276     {
277         return m_statedReportPath;
278     }
279     else
280     {
281         return GetExternalPath(option);
282     }
283 }
284 
GetExternalPath(uint32_t option)285 std::string Configure::GetExternalPath(uint32_t option)
286 {
287     std::string path = "";
288     auto it = m_pathOption.find(option);
289     if (it != m_pathOption.end())
290     {
291         if (it->second.bStated && m_keyPathInfo != nullptr && m_keyPathInfo->Path != nullptr)
292         {
293             path = m_keyPathInfo->Path;
294         }
295         path += it->second.subPath;
296         return path;
297     }
298     else
299     {
300         MOS_OS_ASSERTMESSAGE("Invalid Option");
301         return "";
302     }
303 }
304 
305 }}