• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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