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 #include "hook_utils.h"
22
23 namespace OHOS {
24 namespace Location {
25 const int DEFAULT_USERID = 100;
26 const int MAX_SIZE = 100;
27
28 const std::string LOCATION_ENHANCE_STATUS = "location_enhance_status";
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
SetSwitchStateToDb(int modeValue)84 LocationErrCode LocationDataRdbManager::SetSwitchStateToDb(int modeValue)
85 {
86 Uri locationDataEnableUri(GetLocationDataUriByCurrentUserId("location_enable"));
87 return LocationDataRdbHelper::GetInstance()->
88 SetValue(locationDataEnableUri, LOCATION_DATA_COLUMN_ENABLE, modeValue);
89 }
90
SetSwitchStateToDbForUser(int modeValue,int32_t userId)91 LocationErrCode LocationDataRdbManager::SetSwitchStateToDbForUser(int modeValue, int32_t userId)
92 {
93 Uri locationDataEnableUri(GetLocationDataUriForUser("location_enable", userId));
94 return LocationDataRdbHelper::GetInstance()->
95 SetValue(locationDataEnableUri, LOCATION_DATA_COLUMN_ENABLE, modeValue);
96 }
97
GetSwitchStateFromDbForUser(int32_t & state,int32_t userId)98 LocationErrCode LocationDataRdbManager::GetSwitchStateFromDbForUser(int32_t& state, int32_t userId)
99 {
100 Uri locationDataEnableUri(GetLocationDataUriForUser("location_enable", userId));
101 return LocationDataRdbHelper::GetInstance()->
102 GetValue(locationDataEnableUri, LOCATION_DATA_COLUMN_ENABLE, state);
103 }
104
SetLocationWorkingState(int32_t state)105 bool LocationDataRdbManager::SetLocationWorkingState(int32_t state)
106 {
107 std::unique_lock<std::mutex> lock(locationWorkingStateMutex_);
108 Uri locationWorkingStateUri(GetLocationDataUriByCurrentUserId(LOCATION_WORKING_STATE));
109 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
110 SetValue(locationWorkingStateUri, LOCATION_WORKING_STATE, state);
111 if (errCode != ERRCODE_SUCCESS) {
112 LBSLOGE(COMMON_UTILS, "%{public}s: can not set value to db, errcode = %{public}d", __func__, errCode);
113 return false;
114 }
115 return true;
116 }
117
GetLocationWorkingState(int32_t & state)118 bool LocationDataRdbManager::GetLocationWorkingState(int32_t& state)
119 {
120 std::unique_lock<std::mutex> lock(locationWorkingStateMutex_);
121 Uri locationWorkingStateUri(GetLocationDataUriByCurrentUserId(LOCATION_WORKING_STATE));
122 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
123 GetValue(locationWorkingStateUri, LOCATION_WORKING_STATE, state);
124 if (errCode != ERRCODE_SUCCESS) {
125 LBSLOGE(COMMON_UTILS, "%{public}s: can not get value, errcode = %{public}d", __func__, errCode);
126 return false;
127 }
128 return true;
129 }
130
SetGnssSessionState(int32_t state,std::string uri,std::string colName)131 bool LocationDataRdbManager::SetGnssSessionState(int32_t state, std::string uri, std::string colName)
132 {
133 std::unique_lock<std::mutex> lock(gnssSessionStateMutex_);
134 Uri gnssSessionStateUri(uri);
135 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
136 SetValue(gnssSessionStateUri, colName, state);
137 if (errCode != ERRCODE_SUCCESS) {
138 LBSLOGE(COMMON_UTILS, "%{public}s: can not set value to db, errcode = %{public}d", __func__, errCode);
139 return false;
140 }
141 return true;
142 }
143
GetSwitchStateFromSysparaForCurrentUser()144 int LocationDataRdbManager::GetSwitchStateFromSysparaForCurrentUser()
145 {
146 int32_t userId = 0;
147 if (!CommonUtils::GetCurrentUserId(userId)) {
148 userId = DEFAULT_USERID;
149 }
150 return GetSwitchStateFromSysparaForUser(userId);
151 }
152
SetSwitchStateToSysparaForCurrentUser(int value)153 bool LocationDataRdbManager::SetSwitchStateToSysparaForCurrentUser(int value)
154 {
155 int32_t userId = 0;
156 if (!CommonUtils::GetCurrentUserId(userId)) {
157 userId = DEFAULT_USERID;
158 }
159 return SetSwitchStateToSysparaForUser(value, userId);
160 }
161
GetSwitchStateFromSysparaForUser(int32_t userId)162 int LocationDataRdbManager::GetSwitchStateFromSysparaForUser(int32_t userId)
163 {
164 char result[MAX_SIZE] = {0};
165 std::string value = "";
166 std::unique_lock<std::mutex> lock(locationSwitchModeMutex_);
167 auto res = GetParameter(LOCATION_SWITCH_MODE, "", result, MAX_SIZE);
168 if (res < 0 || strlen(result) == 0) {
169 LBSLOGE(COMMON_UTILS, "%{public}s get para value failed, res: %{public}d", __func__, res);
170 return DEFAULT_SWITCH_STATE;
171 }
172 value = result;
173 nlohmann::json switchInfo = nlohmann::json::parse(value, nullptr, false);
174 if (switchInfo.is_discarded()) {
175 LBSLOGE(COMMON_UTILS, "switchInfo parse failed");
176 return DEFAULT_SWITCH_STATE;
177 }
178 if (!switchInfo.contains(std::to_string(userId))) {
179 LBSLOGE(COMMON_UTILS, "userId switch %{public}d is not exist", userId);
180 return DEFAULT_SWITCH_STATE;
181 }
182 auto jsonItem = switchInfo.at(std::to_string(userId));
183 if (!jsonItem.is_number()) {
184 LBSLOGE(COMMON_UTILS, "switch state is invalid");
185 return DEFAULT_SWITCH_STATE;
186 }
187 auto state = jsonItem.get<int>();
188 return state;
189 }
190
SetSwitchStateToSysparaForUser(int value,int32_t userId)191 bool LocationDataRdbManager::SetSwitchStateToSysparaForUser(int value, int32_t userId)
192 {
193 char result[MAX_SIZE] = {0};
194 std::unique_lock<std::mutex> lock(locationSwitchModeMutex_);
195 nlohmann::json oldSwitchInfo;
196 auto res = GetParameter(LOCATION_SWITCH_MODE, "", result, MAX_SIZE);
197 if (res < 0 || strlen(result) == 0) {
198 // If there is no value in sysparam, go on and write it.
199 LBSLOGI(COMMON_UTILS, "%{public}s get para value failed, res: %{public}d", __func__, res);
200 } else {
201 std::string SwitchStr = result;
202 oldSwitchInfo = nlohmann::json::parse(SwitchStr, nullptr, false);
203 if (oldSwitchInfo.is_discarded()) {
204 LBSLOGI(COMMON_UTILS, "switchInfo parse failed");
205 // If there is no valid value in sysparam, go on and overwrite it.
206 }
207 }
208 nlohmann::json newSwitchInfo;
209 std::vector<int> activeIds;
210 // copy oldSwitchInfo to newSwitchInfo
211 if (CommonUtils::GetAllUserId(activeIds)) {
212 for (auto && [key, state] : oldSwitchInfo.items()) {
213 if (IsUserIdInActiveIds(activeIds, key)) {
214 newSwitchInfo[key] = state;
215 }
216 }
217 }
218 newSwitchInfo[std::to_string(userId)] = value;
219 std::string newSwitchStr = newSwitchInfo.dump();
220 char valueArray[MAX_SIZE] = {0};
221 auto ret = sprintf_s(valueArray, sizeof(valueArray), "%s", newSwitchStr.c_str());
222 if (ret <= 0) {
223 LBSLOGE(COMMON_UTILS, "sprintf_s failed, ret: %{public}d", ret);
224 return false;
225 }
226 res = SetParameter(LOCATION_SWITCH_MODE, valueArray);
227 if (res < 0) {
228 LBSLOGE(COMMON_UTILS, "%{public}s failed, res: %{public}d", __func__, res);
229 return false;
230 }
231 return true;
232 }
233
SyncSwitchStatus()234 void LocationDataRdbManager::SyncSwitchStatus()
235 {
236 int dbState = DEFAULT_SWITCH_STATE;
237 Uri locationDataEnableUri(GetLocationDataUriByCurrentUserId("location_enable"));
238 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
239 GetValue(locationDataEnableUri, LOCATION_DATA_COLUMN_ENABLE, dbState);
240 if (errCode != ERRCODE_SUCCESS) {
241 // It needs to be updated when it is the default, and there is no need to return.
242 LBSLOGE(COMMON_UTILS, "%{public}s: query state failed, errcode = %{public}d", __func__, errCode);
243 }
244 int sysparaState = LocationDataRdbManager::GetSwitchStateFromSysparaForCurrentUser();
245 if (sysparaState == DEFAULT_SWITCH_STATE && dbState != DEFAULT_SWITCH_STATE) {
246 LocationDataRdbManager::SetSwitchStateToSysparaForCurrentUser(dbState);
247 } else if (sysparaState != DEFAULT_SWITCH_STATE && dbState != sysparaState) {
248 LocationDataRdbManager::SetSwitchStateToDb(sysparaState);
249 }
250 HookUtils::ExecuteHookWhenSyncSwitchStates(sysparaState);
251 }
252
SetLocationEnhanceStatus(int32_t state)253 bool LocationDataRdbManager::SetLocationEnhanceStatus(int32_t state)
254 {
255 Uri locationWorkingStateUri(GetLocationDataSecureUri(LOCATION_ENHANCE_STATUS));
256 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
257 SetValue(locationWorkingStateUri, LOCATION_ENHANCE_STATUS, state);
258 if (errCode != ERRCODE_SUCCESS) {
259 LBSLOGE(COMMON_UTILS,
260 "can not set value, key = %{public}s, errcode = %{public}d", LOCATION_ENHANCE_STATUS.c_str(), errCode);
261 return false;
262 }
263 return true;
264 }
265
GetLocationEnhanceStatus(int32_t & state)266 bool LocationDataRdbManager::GetLocationEnhanceStatus(int32_t& state)
267 {
268 Uri locationWorkingStateUri(GetLocationDataSecureUri(LOCATION_ENHANCE_STATUS));
269 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
270 GetValue(locationWorkingStateUri, LOCATION_ENHANCE_STATUS, state);
271 if (errCode != ERRCODE_SUCCESS) {
272 LBSLOGE(COMMON_UTILS,
273 "can not get value, key = %{public}s, errcode = %{public}d", LOCATION_ENHANCE_STATUS.c_str(), errCode);
274 return false;
275 }
276 return true;
277 }
278
IsUserIdInActiveIds(std::vector<int> activeIds,std::string userId)279 bool LocationDataRdbManager::IsUserIdInActiveIds(std::vector<int> activeIds, std::string userId)
280 {
281 for (auto id : activeIds) {
282 if (std::to_string(id).compare(userId) == 0) {
283 return true;
284 }
285 }
286 return false;
287 }
288
GetIntelligentStatus(std::string createHelperUri,std::string queryUri,std::string colName,std::string & state)289 bool LocationDataRdbManager::GetIntelligentStatus(
290 std::string createHelperUri, std::string queryUri, std::string colName, std::string& state)
291 {
292 Uri locationIntelligentUri(queryUri);
293 LocationErrCode errCode = LocationDataRdbHelper::GetInstance()->
294 GetIntelligentValue(locationIntelligentUri, createHelperUri, colName, state);
295 if (errCode != ERRCODE_SUCCESS) {
296 LBSLOGE(COMMON_UTILS,
297 "can not get value, errcode = %{public}d", errCode);
298 return false;
299 }
300 return true;
301 }
302 } // namespace Location
303 } // namespace OHOS