1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "location_data_rdb_manager.h"
16
17 #include "common_utils.h"
18 #include "location_data_rdb_helper.h"
19 #include "parameter.h"
20 #include <nlohmann/json.hpp>
21
22 namespace OHOS {
23 namespace Location {
24 const int DEFAULT_USERID = 100;
25 const int MAX_SIZE = 100;
26
27 const std::string LOCATION_ENHANCE_STATUS = "location_enhance_status";
28 const std::string KEY_LOCATION_KIT_API_CONTROL_WHITE_LIST = "location_kit_api_control_white_list";
29 std::mutex LocationDataRdbManager::locationSwitchModeMutex_;
30 std::mutex LocationDataRdbManager::locationWorkingStateMutex_;
31 std::mutex LocationDataRdbManager::gnssSessionStateMutex_;
GetLocationDataUriByCurrentUserId(std::string key)32 std::string LocationDataRdbManager::GetLocationDataUriByCurrentUserId(std::string key)
33 {
34 int userId = 0;
35 if (!CommonUtils::GetCurrentUserId(userId)) {
36 userId = DEFAULT_USERID;
37 }
38 std::string uri = "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_" +
39 std::to_string(userId) +
40 "?Proxy=true&key=" + key;
41 return uri;
42 }
43
GetLocationDataUriForUser(std::string key,int32_t userId)44 std::string LocationDataRdbManager::GetLocationDataUriForUser(std::string key, int32_t userId)
45 {
46 std::string uri = "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_" +
47 std::to_string(userId) +
48 "?Proxy=true&key=" + key;
49 return uri;
50 }
51
GetLocationDataSecureUri(std::string key)52 std::string LocationDataRdbManager::GetLocationDataSecureUri(std::string key)
53 {
54 int userId = 0;
55 if (!CommonUtils::GetCurrentUserId(userId)) {
56 userId = DEFAULT_USERID;
57 }
58 std::string uri = "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_SECURE_" +
59 std::to_string(userId) +
60 "?Proxy=true&key=" + key;
61 return uri;
62 }
63
QuerySwitchState()64 int LocationDataRdbManager::QuerySwitchState()
65 {
66 int res = LocationDataRdbManager::GetSwitchStateFromSysparaForCurrentUser();
67 if (res == DISABLED || res == ENABLED) {
68 return res;
69 }
70 int32_t state = DEFAULT_SWITCH_STATE;
71 Uri locationDataEnableUri(GetLocationDataUriByCurrentUserId("location_enable"));
72 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
73 GetValue(locationDataEnableUri, LOCATION_DATA_COLUMN_ENABLE, state);
74 if (errCode != ERRCODE_SUCCESS) {
75 LBSLOGE(COMMON_UTILS, "%{public}s: query state failed, errcode = %{public}d", __func__, errCode);
76 return DEFAULT_SWITCH_STATE;
77 }
78 if (res == DEFAULT_SWITCH_STATE && state != DEFAULT_SWITCH_STATE) {
79 LocationDataRdbManager::SetSwitchStateToSysparaForCurrentUser(state);
80 }
81 return state;
82 }
83
QueryScanWhiteList()84 std::string LocationDataRdbManager::QueryScanWhiteList()
85 {
86 std::string res = "";
87 Uri locationDataEnableUri(GetLocationDataSecureUri(KEY_LOCATION_KIT_API_CONTROL_WHITE_LIST));
88 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
89 GetStringValue(locationDataEnableUri, KEY_LOCATION_KIT_API_CONTROL_WHITE_LIST, res);
90 if (errCode != ERRCODE_SUCCESS) {
91 LBSLOGE(COMMON_UTILS, "%{public}s: query scan white list failed, errcode = %{public}d",
92 __func__, errCode);
93 return res;
94 }
95 return res;
96 }
97
SetSwitchStateToDb(int modeValue)98 LocationErrCode LocationDataRdbManager::SetSwitchStateToDb(int modeValue)
99 {
100 Uri locationDataEnableUri(GetLocationDataUriByCurrentUserId("location_enable"));
101 return LocationDataRdbHelper::GetInstance()->
102 SetValue(locationDataEnableUri, LOCATION_DATA_COLUMN_ENABLE, modeValue);
103 }
104
SetSwitchStateToDbForUser(int modeValue,int32_t userId)105 LocationErrCode LocationDataRdbManager::SetSwitchStateToDbForUser(int modeValue, int32_t userId)
106 {
107 Uri locationDataEnableUri(GetLocationDataUriForUser("location_enable", userId));
108 return LocationDataRdbHelper::GetInstance()->
109 SetValue(locationDataEnableUri, LOCATION_DATA_COLUMN_ENABLE, modeValue);
110 }
111
GetSwitchStateFromDbForUser(int32_t & state,int32_t userId)112 LocationErrCode LocationDataRdbManager::GetSwitchStateFromDbForUser(int32_t& state, int32_t userId)
113 {
114 Uri locationDataEnableUri(GetLocationDataUriForUser("location_enable", userId));
115 return LocationDataRdbHelper::GetInstance()->
116 GetValue(locationDataEnableUri, LOCATION_DATA_COLUMN_ENABLE, state);
117 }
118
SetLocationWorkingState(int32_t state)119 bool LocationDataRdbManager::SetLocationWorkingState(int32_t state)
120 {
121 std::unique_lock<std::mutex> lock(locationWorkingStateMutex_);
122 Uri locationWorkingStateUri(GetLocationDataUriByCurrentUserId(LOCATION_WORKING_STATE));
123 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
124 SetValue(locationWorkingStateUri, LOCATION_WORKING_STATE, state);
125 if (errCode != ERRCODE_SUCCESS) {
126 LBSLOGE(COMMON_UTILS, "%{public}s: can not set value to db, errcode = %{public}d", __func__, errCode);
127 return false;
128 }
129 return true;
130 }
131
GetLocationWorkingState(int32_t & state)132 bool LocationDataRdbManager::GetLocationWorkingState(int32_t& state)
133 {
134 std::unique_lock<std::mutex> lock(locationWorkingStateMutex_);
135 Uri locationWorkingStateUri(GetLocationDataUriByCurrentUserId(LOCATION_WORKING_STATE));
136 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
137 GetValue(locationWorkingStateUri, LOCATION_WORKING_STATE, state);
138 if (errCode != ERRCODE_SUCCESS) {
139 LBSLOGE(COMMON_UTILS, "%{public}s: can not get value, errcode = %{public}d", __func__, errCode);
140 return false;
141 }
142 return true;
143 }
144
SetGnssSessionState(int32_t state,std::string uri,std::string colName)145 bool LocationDataRdbManager::SetGnssSessionState(int32_t state, std::string uri, std::string colName)
146 {
147 std::unique_lock<std::mutex> lock(gnssSessionStateMutex_);
148 Uri gnssSessionStateUri(uri);
149 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
150 SetValue(gnssSessionStateUri, colName, state);
151 if (errCode != ERRCODE_SUCCESS) {
152 LBSLOGE(COMMON_UTILS, "%{public}s: can not set value to db, errcode = %{public}d", __func__, errCode);
153 return false;
154 }
155 return true;
156 }
157
GetSwitchStateFromSysparaForCurrentUser()158 int LocationDataRdbManager::GetSwitchStateFromSysparaForCurrentUser()
159 {
160 int32_t userId = 0;
161 if (!CommonUtils::GetCurrentUserId(userId)) {
162 userId = DEFAULT_USERID;
163 }
164 return GetSwitchStateFromSysparaForUser(userId);
165 }
166
SetSwitchStateToSysparaForCurrentUser(int value)167 bool LocationDataRdbManager::SetSwitchStateToSysparaForCurrentUser(int value)
168 {
169 int32_t userId = 0;
170 if (!CommonUtils::GetCurrentUserId(userId)) {
171 userId = DEFAULT_USERID;
172 }
173 return SetSwitchStateToSysparaForUser(value, userId);
174 }
175
GetSwitchStateFromSysparaForUser(int32_t userId)176 int LocationDataRdbManager::GetSwitchStateFromSysparaForUser(int32_t userId)
177 {
178 char result[MAX_SIZE] = {0};
179 std::string value = "";
180 std::unique_lock<std::mutex> lock(locationSwitchModeMutex_);
181 auto res = GetParameter(LOCATION_SWITCH_MODE, "", result, MAX_SIZE);
182 if (res < 0 || strlen(result) == 0) {
183 LBSLOGE(COMMON_UTILS, "%{public}s get para value failed, res: %{public}d", __func__, res);
184 return DEFAULT_SWITCH_STATE;
185 }
186 value = result;
187 nlohmann::json switchInfo = nlohmann::json::parse(value, nullptr, false);
188 if (switchInfo.is_discarded()) {
189 LBSLOGE(COMMON_UTILS, "switchInfo parse failed");
190 return DEFAULT_SWITCH_STATE;
191 }
192 if (!switchInfo.contains(std::to_string(userId))) {
193 LBSLOGE(COMMON_UTILS, "userId switch %{public}d is not exist", userId);
194 return DEFAULT_SWITCH_STATE;
195 }
196 auto jsonItem = switchInfo.at(std::to_string(userId));
197 if (!jsonItem.is_number()) {
198 LBSLOGE(COMMON_UTILS, "switch state is invalid");
199 return DEFAULT_SWITCH_STATE;
200 }
201 auto state = jsonItem.get<int>();
202 return state;
203 }
204
SetSwitchStateToSysparaForUser(int value,int32_t userId)205 bool LocationDataRdbManager::SetSwitchStateToSysparaForUser(int value, int32_t userId)
206 {
207 char result[MAX_SIZE] = {0};
208 std::unique_lock<std::mutex> lock(locationSwitchModeMutex_);
209 nlohmann::json oldSwitchInfo;
210 auto res = GetParameter(LOCATION_SWITCH_MODE, "", result, MAX_SIZE);
211 if (res < 0 || strlen(result) == 0) {
212 // If there is no value in sysparam, go on and write it.
213 LBSLOGI(COMMON_UTILS, "%{public}s get para value failed, res: %{public}d", __func__, res);
214 } else {
215 std::string SwitchStr = result;
216 oldSwitchInfo = nlohmann::json::parse(SwitchStr, nullptr, false);
217 if (oldSwitchInfo.is_discarded()) {
218 LBSLOGI(COMMON_UTILS, "switchInfo parse failed");
219 // If there is no valid value in sysparam, go on and overwrite it.
220 }
221 }
222 nlohmann::json newSwitchInfo;
223 std::vector<int> activeIds;
224 // copy oldSwitchInfo to newSwitchInfo
225 if (CommonUtils::GetAllUserId(activeIds)) {
226 for (auto && [key, state] : oldSwitchInfo.items()) {
227 if (IsUserIdInActiveIds(activeIds, key)) {
228 newSwitchInfo[key] = state;
229 }
230 }
231 }
232 newSwitchInfo[std::to_string(userId)] = value;
233 std::string newSwitchStr = newSwitchInfo.dump();
234 char valueArray[MAX_SIZE] = {0};
235 auto ret = sprintf_s(valueArray, sizeof(valueArray), "%s", newSwitchStr.c_str());
236 if (ret <= 0) {
237 LBSLOGE(COMMON_UTILS, "sprintf_s failed, ret: %{public}d", ret);
238 return false;
239 }
240 res = SetParameter(LOCATION_SWITCH_MODE, valueArray);
241 if (res < 0) {
242 LBSLOGE(COMMON_UTILS, "%{public}s failed, res: %{public}d", __func__, res);
243 return false;
244 }
245 return true;
246 }
247
SyncSwitchStatus()248 void LocationDataRdbManager::SyncSwitchStatus()
249 {
250 int dbState = DEFAULT_SWITCH_STATE;
251 Uri locationDataEnableUri(GetLocationDataUriByCurrentUserId("location_enable"));
252 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
253 GetValue(locationDataEnableUri, LOCATION_DATA_COLUMN_ENABLE, dbState);
254 if (errCode != ERRCODE_SUCCESS) {
255 // It needs to be updated when it is the default, and there is no need to return.
256 LBSLOGE(COMMON_UTILS, "%{public}s: query state failed, errcode = %{public}d", __func__, errCode);
257 }
258 int sysparaState = LocationDataRdbManager::GetSwitchStateFromSysparaForCurrentUser();
259 if (sysparaState == DEFAULT_SWITCH_STATE && dbState != DEFAULT_SWITCH_STATE) {
260 LocationDataRdbManager::SetSwitchStateToSysparaForCurrentUser(dbState);
261 } else if (sysparaState != DEFAULT_SWITCH_STATE && dbState != sysparaState) {
262 LocationDataRdbManager::SetSwitchStateToDb(sysparaState);
263 }
264 }
265
SetLocationEnhanceStatus(int32_t state)266 bool LocationDataRdbManager::SetLocationEnhanceStatus(int32_t state)
267 {
268 Uri locationWorkingStateUri(GetLocationDataSecureUri(LOCATION_ENHANCE_STATUS));
269 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
270 SetValue(locationWorkingStateUri, LOCATION_ENHANCE_STATUS, state);
271 if (errCode != ERRCODE_SUCCESS) {
272 LBSLOGE(COMMON_UTILS,
273 "can not set value, key = %{public}s, errcode = %{public}d", LOCATION_ENHANCE_STATUS.c_str(), errCode);
274 return false;
275 }
276 return true;
277 }
278
GetLocationEnhanceStatus(int32_t & state)279 bool LocationDataRdbManager::GetLocationEnhanceStatus(int32_t& state)
280 {
281 Uri locationWorkingStateUri(GetLocationDataSecureUri(LOCATION_ENHANCE_STATUS));
282 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
283 GetValue(locationWorkingStateUri, LOCATION_ENHANCE_STATUS, state);
284 if (errCode != ERRCODE_SUCCESS) {
285 LBSLOGE(COMMON_UTILS,
286 "can not get value, key = %{public}s, errcode = %{public}d", LOCATION_ENHANCE_STATUS.c_str(), errCode);
287 return false;
288 }
289 return true;
290 }
291
IsUserIdInActiveIds(std::vector<int> activeIds,std::string userId)292 bool LocationDataRdbManager::IsUserIdInActiveIds(std::vector<int> activeIds, std::string userId)
293 {
294 for (auto id : activeIds) {
295 if (std::to_string(id).compare(userId) == 0) {
296 return true;
297 }
298 }
299 return false;
300 }
301 } // namespace Location
302 } // namespace OHOS