1 /*
2  * Copyright (C) 2022 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_config_manager.h"
16 
17 #include <fstream>
18 
19 #include "common_utils.h"
20 #include "constant_definition.h"
21 #include "location_log.h"
22 
23 #include "parameter.h"
24 #include "location_data_rdb_manager.h"
25 #include "ipc_skeleton.h"
26 #include "ui_extension_ability_connection.h"
27 
28 namespace OHOS {
29 namespace Location {
30 const int UNKNOW_ERROR = -1;
31 const int MAX_SIZE = 100;
32 const char* LOCATION_PRIVACY_MODE = "persist.location.privacy_mode";
GetInstance()33 LocationConfigManager* LocationConfigManager::GetInstance()
34 {
35     static LocationConfigManager gLocationConfigManager;
36     return &gLocationConfigManager;
37 }
38 
LocationConfigManager()39 LocationConfigManager::LocationConfigManager()
40 {
41     mLocationSwitchState = STATE_CLOSE;
42     mPrivacyTypeState[PRIVACY_TYPE_OTHERS] = STATE_CLOSE; // for OTHERS
43     mPrivacyTypeState[PRIVACY_TYPE_STARTUP] = STATE_CLOSE; // for STARTUP
44     mPrivacyTypeState[PRIVACY_TYPE_CORE_LOCATION] = STATE_CLOSE; // for CORE_LOCATION
45 }
46 
~LocationConfigManager()47 LocationConfigManager::~LocationConfigManager()
48 {
49 }
50 
Init()51 int LocationConfigManager::Init()
52 {
53     LBSLOGI(LOCATOR, "LocationConfigManager::Init");
54     if (!IsExistFile(GetLocationSwitchConfigPath())) {
55         CreateFile(GetLocationSwitchConfigPath(), "0");
56     }
57     return 0;
58 }
59 
IsExistFile(const std::string & filename)60 bool LocationConfigManager::IsExistFile(const std::string& filename)
61 {
62     bool bExist = false;
63     std::fstream ioFile;
64     char path[PATH_MAX + 1] = {0x00};
65     if (strlen(filename.c_str()) > PATH_MAX || realpath(filename.c_str(), path) == NULL) {
66         return false;
67     }
68     ioFile.open(path, std::ios::in);
69     if (ioFile) {
70         bExist = true;
71     } else {
72         return false;
73     }
74     ioFile.clear();
75     ioFile.close();
76     LBSLOGD(LOCATOR, "IsExistFile = %{public}d", bExist ? 1 : 0);
77     return bExist;
78 }
79 
CreateFile(const std::string & filename,const std::string & filedata)80 bool LocationConfigManager::CreateFile(const std::string& filename, const std::string& filedata)
81 {
82     LBSLOGD(LOCATOR, "CreateFile");
83     std::ofstream outFile;
84     outFile.open(filename.c_str());
85     if (!outFile) {
86         LBSLOGE(LOCATOR, "file open failed");
87         return false;
88     }
89     outFile.flush();
90     outFile << filedata << std::endl;
91     outFile.clear();
92     outFile.close();
93     return true;
94 }
95 
GetLocationSwitchConfigPath()96 std::string LocationConfigManager::GetLocationSwitchConfigPath()
97 {
98     int userId = 0;
99     bool ret = CommonUtils::GetCurrentUserId(userId);
100     if (!ret) {
101         LBSLOGE(LOCATOR, "%{public}s GetCurrentUserId failed", __func__);
102     }
103     std::string filePath = LOCATION_DIR + SWITCH_CONFIG_NAME + "_" + std::to_string(userId) + ".conf";
104     return filePath;
105 }
106 
GetPrivacyTypeConfigPath(const int type)107 std::string LocationConfigManager::GetPrivacyTypeConfigPath(const int type)
108 {
109     int userId = 0;
110     bool ret = CommonUtils::GetCurrentUserId(userId);
111     if (!ret) {
112         LBSLOGE(LOCATOR, "%{public}s GetCurrentUserId failed", __func__);
113     }
114     std::string filePath;
115     switch (type) {
116         case PRIVACY_TYPE_OTHERS: {
117             filePath = "others_";
118             break;
119         }
120         case PRIVACY_TYPE_STARTUP: {
121             filePath = "startup_";
122             break;
123         }
124         case PRIVACY_TYPE_CORE_LOCATION: {
125             filePath = "core_location_";
126             break;
127         }
128         default: {
129             filePath = "";
130             break;
131         }
132     }
133     return LOCATION_DIR + PRIVACY_CONFIG_NAME + "_" + filePath + std::to_string(userId) + ".conf";
134 }
135 
GetLocationSwitchState()136 int LocationConfigManager::GetLocationSwitchState()
137 {
138     std::unique_lock<std::mutex> lock(mutex_);
139     if (!IsExistFile(GetLocationSwitchConfigPath())) {
140         CreateFile(GetLocationSwitchConfigPath(), "0");
141     }
142     std::ifstream fs(GetLocationSwitchConfigPath());
143     if (!fs.is_open()) {
144         LBSLOGE(LOCATOR, "LocationConfigManager: fs.is_open false, return");
145         return -1;
146     }
147     std::string line;
148     while (std::getline(fs, line)) {
149         if (line.empty()) {
150             break;
151         }
152         if (line[0] == '0') {
153             mLocationSwitchState = STATE_CLOSE;
154         } else if (line[0] == '1') {
155             mLocationSwitchState = STATE_OPEN;
156         }
157         break;
158     }
159     fs.clear();
160     fs.close();
161     return mLocationSwitchState;
162 }
163 
GetStringParameter(const std::string & type,std::string & value)164 bool LocationConfigManager::GetStringParameter(const std::string& type, std::string& value)
165 {
166     char result[MAX_BUFF_SIZE] = {0};
167     auto res = GetParameter(type.c_str(), "", result, MAX_BUFF_SIZE);
168     if (res <= 0) {
169         LBSLOGE(LOCATOR, "%{public}s get para value failed, res: %{public}d",
170             __func__, res);
171         return false;
172     }
173     value = result;
174     return true;
175 }
176 
GetIntParameter(const std::string & type)177 int LocationConfigManager::GetIntParameter(const std::string& type)
178 {
179     char result[MAX_BUFF_SIZE] = {0};
180     std::string value = "";
181     auto res = GetParameter(type.c_str(), "", result, MAX_BUFF_SIZE);
182     if (res < 0 || strlen(result) == 0) {
183         LBSLOGE(LOCATOR, "%{public}s get para value failed, res: %{public}d",
184             __func__, res);
185         return UNKNOW_ERROR;
186     }
187     value = result;
188     for (auto ch : value) {
189         if (std::isdigit(ch) == 0) {
190             LBSLOGE(LOCATOR, "wrong para");
191             return UNKNOW_ERROR;
192         }
193     }
194     if (value.size() == 0) {
195         return UNKNOW_ERROR;
196     }
197     return std::stoi(value);
198 }
199 
GetSettingsBundleName(std::string & name)200 bool LocationConfigManager::GetSettingsBundleName(std::string& name)
201 {
202     return GetStringParameter(SETTINGS_BUNDLE_NAME, name);
203 }
204 
GetNlpServiceName(std::string & name)205 bool LocationConfigManager::GetNlpServiceName(std::string& name)
206 {
207     return GetStringParameter(NLP_SERVICE_NAME, name);
208 }
209 
GetNlpAbilityName(std::string & name)210 bool LocationConfigManager::GetNlpAbilityName(std::string& name)
211 {
212     return GetStringParameter(NLP_ABILITY_NAME, name);
213 }
214 
GetGeocodeServiceName(std::string & name)215 bool LocationConfigManager::GetGeocodeServiceName(std::string& name)
216 {
217     return GetStringParameter(GEOCODE_SERVICE_NAME, name);
218 }
219 
GetGeocodeAbilityName(std::string & name)220 bool LocationConfigManager::GetGeocodeAbilityName(std::string& name)
221 {
222     return GetStringParameter(GEOCODE_ABILITY_NAME, name);
223 }
224 
GetSuplMode()225 int LocationConfigManager::GetSuplMode()
226 {
227     return GetIntParameter(SUPL_MODE_NAME);
228 }
229 
GetAgnssServerAddr(std::string & name)230 bool LocationConfigManager::GetAgnssServerAddr(std::string& name)
231 {
232     return GetStringParameter(AGNSS_SERVER_ADDR, name);
233 }
234 
GetAgnssServerPort()235 int LocationConfigManager::GetAgnssServerPort()
236 {
237     return GetIntParameter(AGNSS_SERVER_PORT);
238 }
239 
SetLocationSwitchState(int state)240 int LocationConfigManager::SetLocationSwitchState(int state)
241 {
242     std::unique_lock<std::mutex> lock(mutex_);
243     if (!IsExistFile(GetLocationSwitchConfigPath())) {
244         CreateFile(GetLocationSwitchConfigPath(), "0");
245     }
246     std::fstream fs(GetLocationSwitchConfigPath());
247     if (state != STATE_CLOSE && state != STATE_OPEN) {
248         LBSLOGE(LOCATOR, "LocationConfigManager:SetLocationSwitchState state = %{public}d, return", state);
249         return -1;
250     }
251     if (!fs.is_open()) {
252         LBSLOGE(LOCATOR, "LocationConfigManager: fs.is_open false, return");
253         return -1;
254     }
255     std::string content = "1";
256     if (state == STATE_CLOSE) {
257         content = "0";
258     }
259     fs.write(content.c_str(), content.length());
260     fs.clear();
261     fs.close();
262     mLocationSwitchState = state;
263     return 0;
264 }
265 
GetPrivacyTypeState(const int type,bool & isConfirmed)266 LocationErrCode LocationConfigManager::GetPrivacyTypeState(const int type, bool& isConfirmed)
267 {
268     int status = 0;
269     if (!LocationDataRdbManager::GetLocationEnhanceStatus(status)) {
270         return ERRCODE_SERVICE_UNAVAILABLE;
271     }
272     isConfirmed = (status == 1);
273     return ERRCODE_SUCCESS;
274 }
275 
SetCachePrivacyType(int value)276 bool LocationConfigManager::SetCachePrivacyType(int value)
277 {
278     char valueArray[MAX_SIZE] = {0};
279     (void)sprintf_s(valueArray, sizeof(valueArray), "%d", value);
280     int res = SetParameter(LOCATION_PRIVACY_MODE, valueArray);
281     if (res < 0) {
282         LBSLOGE(COMMON_UTILS, "%{public}s failed, res: %{public}d", __func__, res);
283         return false;
284     }
285     return true;
286 }
287 
SetPrivacyTypeState(const int type,bool isConfirmed)288 LocationErrCode LocationConfigManager::SetPrivacyTypeState(const int type, bool isConfirmed)
289 {
290     int status = isConfirmed ? 1 : 0;
291     if (!LocationDataRdbManager::SetLocationEnhanceStatus(status)) {
292         return ERRCODE_SERVICE_UNAVAILABLE;
293     }
294     return ERRCODE_SUCCESS;
295 }
296 
GenerateStartCommand()297 std::string LocationConfigManager::GenerateStartCommand()
298 {
299     nlohmann::json param;
300     std::string uiType = "sysDialog/common";
301     param["ability.want.params.uiExtensionType"] = uiType;
302     std::string cmdData = param.dump();
303     LBSLOGD(GNSS, "cmdData is: %{public}s.", cmdData.c_str());
304     return cmdData;
305 }
306 
OpenPrivacyDialog()307 void LocationConfigManager::OpenPrivacyDialog()
308 {
309     LBSLOGI(LOCATOR, "ConnectExtension");
310     AAFwk::Want want;
311     std::string bundleName = "com.ohos.sceneboard";
312     std::string abilityName = "com.ohos.sceneboard.systemdialog";
313     want.SetElementName(bundleName, abilityName);
314     std::string connectStr = GenerateStartCommand();
315     ConnectExtensionAbility(want, connectStr);
316 }
317 
ConnectExtensionAbility(const AAFwk::Want & want,const std::string & commandStr)318 void LocationConfigManager::ConnectExtensionAbility(const AAFwk::Want &want, const std::string &commandStr)
319 {
320     std::string bundleName = "com.ohos.locationdialog";
321     std::string abilityName = "LocationPrivacyExtAbility";
322     sptr<UIExtensionAbilityConnection> connection(
323         new (std::nothrow) UIExtensionAbilityConnection(commandStr, bundleName, abilityName));
324     if (connection == nullptr) {
325         LBSLOGE(LOCATOR, "connect UIExtensionAbilityConnection fail");
326         return;
327     }
328 
329     std::string identity = IPCSkeleton::ResetCallingIdentity();
330     auto ret =
331         AAFwk::ExtensionManagerClient::GetInstance().ConnectServiceExtensionAbility(want, connection, nullptr, -1);
332     LBSLOGI(LOCATOR, "connect service extension ability result = %{public}d", ret);
333     IPCSkeleton::SetCallingIdentity(identity);
334     return;
335 }
336 }  // namespace Location
337 }  // namespace OHOS
338