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 std::mutex LocationDataRdbManager::locationSwitchModeMutex_;
29 std::mutex LocationDataRdbManager::locationWorkingStateMutex_;
30 std::mutex LocationDataRdbManager::gnssSessionStateMutex_;
GetLocationDataUriByCurrentUserId(std::string key)31 std::string LocationDataRdbManager::GetLocationDataUriByCurrentUserId(std::string key)
32 {
33 int userId = 0;
34 if (!CommonUtils::GetCurrentUserId(userId)) {
35 userId = DEFAULT_USERID;
36 }
37 std::string uri = "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_" +
38 std::to_string(userId) +
39 "?Proxy=true&key=" + key;
40 return uri;
41 }
42
GetLocationDataUriForUser(std::string key,int32_t userId)43 std::string LocationDataRdbManager::GetLocationDataUriForUser(std::string key, int32_t userId)
44 {
45 std::string uri = "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_" +
46 std::to_string(userId) +
47 "?Proxy=true&key=" + key;
48 return uri;
49 }
50
GetLocationDataSecureUri(std::string key)51 std::string LocationDataRdbManager::GetLocationDataSecureUri(std::string key)
52 {
53 int userId = 0;
54 if (!CommonUtils::GetCurrentUserId(userId)) {
55 userId = DEFAULT_USERID;
56 }
57 std::string uri = "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_SECURE_" +
58 std::to_string(userId) +
59 "?Proxy=true&key=" + key;
60 return uri;
61 }
62
QuerySwitchState()63 int LocationDataRdbManager::QuerySwitchState()
64 {
65 int res = LocationDataRdbManager::GetSwitchStateFromSysparaForCurrentUser();
66 if (res == DISABLED || res == ENABLED) {
67 return res;
68 }
69 int32_t state = DEFAULT_SWITCH_STATE;
70 Uri locationDataEnableUri(GetLocationDataUriByCurrentUserId("location_enable"));
71 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
72 GetValue(locationDataEnableUri, LOCATION_DATA_COLUMN_ENABLE, state);
73 if (errCode != ERRCODE_SUCCESS) {
74 LBSLOGE(COMMON_UTILS, "%{public}s: query state failed, errcode = %{public}d", __func__, errCode);
75 return DEFAULT_SWITCH_STATE;
76 }
77 if (res == DEFAULT_SWITCH_STATE && state != DEFAULT_SWITCH_STATE) {
78 LocationDataRdbManager::SetSwitchStateToSysparaForCurrentUser(state);
79 }
80 return state;
81 }
82
SetSwitchStateToDb(int modeValue)83 LocationErrCode LocationDataRdbManager::SetSwitchStateToDb(int modeValue)
84 {
85 Uri locationDataEnableUri(GetLocationDataUriByCurrentUserId("location_enable"));
86 return LocationDataRdbHelper::GetInstance()->
87 SetValue(locationDataEnableUri, LOCATION_DATA_COLUMN_ENABLE, modeValue);
88 }
89
SetSwitchStateToDbForUser(int modeValue,int32_t userId)90 LocationErrCode LocationDataRdbManager::SetSwitchStateToDbForUser(int modeValue, int32_t userId)
91 {
92 Uri locationDataEnableUri(GetLocationDataUriForUser("location_enable", userId));
93 return LocationDataRdbHelper::GetInstance()->
94 SetValue(locationDataEnableUri, LOCATION_DATA_COLUMN_ENABLE, modeValue);
95 }
96
GetSwitchStateFromDbForUser(int32_t & state,int32_t userId)97 LocationErrCode LocationDataRdbManager::GetSwitchStateFromDbForUser(int32_t& state, int32_t userId)
98 {
99 Uri locationDataEnableUri(GetLocationDataUriForUser("location_enable", userId));
100 return LocationDataRdbHelper::GetInstance()->
101 GetValue(locationDataEnableUri, LOCATION_DATA_COLUMN_ENABLE, state);
102 }
103
SetLocationWorkingState(int32_t state)104 bool LocationDataRdbManager::SetLocationWorkingState(int32_t state)
105 {
106 std::unique_lock<std::mutex> lock(locationWorkingStateMutex_);
107 Uri locationWorkingStateUri(GetLocationDataUriByCurrentUserId(LOCATION_WORKING_STATE));
108 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
109 SetValue(locationWorkingStateUri, LOCATION_WORKING_STATE, state);
110 if (errCode != ERRCODE_SUCCESS) {
111 LBSLOGE(COMMON_UTILS, "%{public}s: can not set value to db, errcode = %{public}d", __func__, errCode);
112 return false;
113 }
114 return true;
115 }
116
GetLocationWorkingState(int32_t & state)117 bool LocationDataRdbManager::GetLocationWorkingState(int32_t& state)
118 {
119 std::unique_lock<std::mutex> lock(locationWorkingStateMutex_);
120 Uri locationWorkingStateUri(GetLocationDataUriByCurrentUserId(LOCATION_WORKING_STATE));
121 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
122 GetValue(locationWorkingStateUri, LOCATION_WORKING_STATE, state);
123 if (errCode != ERRCODE_SUCCESS) {
124 LBSLOGE(COMMON_UTILS, "%{public}s: can not get value, errcode = %{public}d", __func__, errCode);
125 return false;
126 }
127 return true;
128 }
129
SetGnssSessionState(int32_t state,std::string uri,std::string colName)130 bool LocationDataRdbManager::SetGnssSessionState(int32_t state, std::string uri, std::string colName)
131 {
132 std::unique_lock<std::mutex> lock(gnssSessionStateMutex_);
133 Uri gnssSessionStateUri(uri);
134 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
135 SetValue(gnssSessionStateUri, colName, state);
136 if (errCode != ERRCODE_SUCCESS) {
137 LBSLOGE(COMMON_UTILS, "%{public}s: can not set value to db, errcode = %{public}d", __func__, errCode);
138 return false;
139 }
140 return true;
141 }
142
GetSwitchStateFromSysparaForCurrentUser()143 int LocationDataRdbManager::GetSwitchStateFromSysparaForCurrentUser()
144 {
145 int32_t userId = 0;
146 if (!CommonUtils::GetCurrentUserId(userId)) {
147 userId = DEFAULT_USERID;
148 }
149 return GetSwitchStateFromSysparaForUser(userId);
150 }
151
SetSwitchStateToSysparaForCurrentUser(int value)152 bool LocationDataRdbManager::SetSwitchStateToSysparaForCurrentUser(int value)
153 {
154 int32_t userId = 0;
155 if (!CommonUtils::GetCurrentUserId(userId)) {
156 userId = DEFAULT_USERID;
157 }
158 return SetSwitchStateToSysparaForUser(value, userId);
159 }
160
GetSwitchStateFromSysparaForUser(int32_t userId)161 int LocationDataRdbManager::GetSwitchStateFromSysparaForUser(int32_t userId)
162 {
163 char result[MAX_SIZE] = {0};
164 std::string value = "";
165 std::unique_lock<std::mutex> lock(locationSwitchModeMutex_);
166 auto res = GetParameter(LOCATION_SWITCH_MODE, "", result, MAX_SIZE);
167 if (res < 0 || strlen(result) == 0) {
168 LBSLOGE(COMMON_UTILS, "%{public}s get para value failed, res: %{public}d", __func__, res);
169 return DEFAULT_SWITCH_STATE;
170 }
171 value = result;
172 nlohmann::json switchInfo = nlohmann::json::parse(value, nullptr, false);
173 if (switchInfo.is_discarded()) {
174 LBSLOGE(COMMON_UTILS, "switchInfo parse failed");
175 return DEFAULT_SWITCH_STATE;
176 }
177 if (!switchInfo.contains(std::to_string(userId))) {
178 LBSLOGE(COMMON_UTILS, "userId switch %{public}d is not exist", userId);
179 return DEFAULT_SWITCH_STATE;
180 }
181 auto jsonItem = switchInfo.at(std::to_string(userId));
182 if (!jsonItem.is_number()) {
183 LBSLOGE(COMMON_UTILS, "switch state is invalid");
184 return DEFAULT_SWITCH_STATE;
185 }
186 auto state = jsonItem.get<int>();
187 return state;
188 }
189
SetSwitchStateToSysparaForUser(int value,int32_t userId)190 bool LocationDataRdbManager::SetSwitchStateToSysparaForUser(int value, int32_t userId)
191 {
192 char result[MAX_SIZE] = {0};
193 std::unique_lock<std::mutex> lock(locationSwitchModeMutex_);
194 nlohmann::json oldSwitchInfo;
195 auto res = GetParameter(LOCATION_SWITCH_MODE, "", result, MAX_SIZE);
196 if (res < 0 || strlen(result) == 0) {
197 // If there is no value in sysparam, go on and write it.
198 LBSLOGI(COMMON_UTILS, "%{public}s get para value failed, res: %{public}d", __func__, res);
199 } else {
200 std::string SwitchStr = result;
201 oldSwitchInfo = nlohmann::json::parse(SwitchStr, nullptr, false);
202 if (oldSwitchInfo.is_discarded()) {
203 LBSLOGI(COMMON_UTILS, "switchInfo parse failed");
204 // If there is no valid value in sysparam, go on and overwrite it.
205 }
206 }
207 nlohmann::json newSwitchInfo;
208 std::vector<int> activeIds;
209 // copy oldSwitchInfo to newSwitchInfo
210 if (CommonUtils::GetAllUserId(activeIds)) {
211 for (auto && [key, state] : oldSwitchInfo.items()) {
212 if (IsUserIdInActiveIds(activeIds, key)) {
213 newSwitchInfo[key] = state;
214 }
215 }
216 }
217 newSwitchInfo[std::to_string(userId)] = value;
218 std::string newSwitchStr = newSwitchInfo.dump();
219 char valueArray[MAX_SIZE] = {0};
220 auto ret = sprintf_s(valueArray, sizeof(valueArray), "%s", newSwitchStr.c_str());
221 if (ret <= 0) {
222 LBSLOGE(COMMON_UTILS, "sprintf_s failed, ret: %{public}d", ret);
223 return false;
224 }
225 res = SetParameter(LOCATION_SWITCH_MODE, valueArray);
226 if (res < 0) {
227 LBSLOGE(COMMON_UTILS, "%{public}s failed, res: %{public}d", __func__, res);
228 return false;
229 }
230 return true;
231 }
232
SyncSwitchStatus()233 void LocationDataRdbManager::SyncSwitchStatus()
234 {
235 int dbState = DEFAULT_SWITCH_STATE;
236 Uri locationDataEnableUri(GetLocationDataUriByCurrentUserId("location_enable"));
237 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
238 GetValue(locationDataEnableUri, LOCATION_DATA_COLUMN_ENABLE, dbState);
239 if (errCode != ERRCODE_SUCCESS) {
240 // It needs to be updated when it is the default, and there is no need to return.
241 LBSLOGE(COMMON_UTILS, "%{public}s: query state failed, errcode = %{public}d", __func__, errCode);
242 }
243 int sysparaState = LocationDataRdbManager::GetSwitchStateFromSysparaForCurrentUser();
244 if (sysparaState == DEFAULT_SWITCH_STATE && dbState != DEFAULT_SWITCH_STATE) {
245 LocationDataRdbManager::SetSwitchStateToSysparaForCurrentUser(dbState);
246 } else if (sysparaState != DEFAULT_SWITCH_STATE && dbState != sysparaState) {
247 LocationDataRdbManager::SetSwitchStateToDb(sysparaState);
248 }
249 }
250
SetLocationEnhanceStatus(int32_t state)251 bool LocationDataRdbManager::SetLocationEnhanceStatus(int32_t state)
252 {
253 Uri locationWorkingStateUri(GetLocationDataSecureUri(LOCATION_ENHANCE_STATUS));
254 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
255 SetValue(locationWorkingStateUri, LOCATION_ENHANCE_STATUS, state);
256 if (errCode != ERRCODE_SUCCESS) {
257 LBSLOGE(COMMON_UTILS,
258 "can not set value, key = %{public}s, errcode = %{public}d", LOCATION_ENHANCE_STATUS.c_str(), errCode);
259 return false;
260 }
261 return true;
262 }
263
GetLocationEnhanceStatus(int32_t & state)264 bool LocationDataRdbManager::GetLocationEnhanceStatus(int32_t& state)
265 {
266 Uri locationWorkingStateUri(GetLocationDataSecureUri(LOCATION_ENHANCE_STATUS));
267 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
268 GetValue(locationWorkingStateUri, LOCATION_ENHANCE_STATUS, state);
269 if (errCode != ERRCODE_SUCCESS) {
270 LBSLOGE(COMMON_UTILS,
271 "can not get value, key = %{public}s, errcode = %{public}d", LOCATION_ENHANCE_STATUS.c_str(), errCode);
272 return false;
273 }
274 return true;
275 }
276
IsUserIdInActiveIds(std::vector<int> activeIds,std::string userId)277 bool LocationDataRdbManager::IsUserIdInActiveIds(std::vector<int> activeIds, std::string userId)
278 {
279 for (auto id : activeIds) {
280 if (std::to_string(id).compare(userId) == 0) {
281 return true;
282 }
283 }
284 return false;
285 }
286 } // namespace Location
287 } // namespace OHOS