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
16 #include "location_data_manager.h"
17
18 #include "uri.h"
19
20 #include "switch_callback_proxy.h"
21 #include "constant_definition.h"
22 #include "location_data_rdb_helper.h"
23 #include "location_data_rdb_manager.h"
24 #include "location_log.h"
25 #include "common_hisysevent.h"
26 #include "parameter.h"
27 #include "permission_manager.h"
28 namespace OHOS {
29 namespace Location {
30 const int MAX_SWITCH_CALLBACK_NUM = 1000;
GetInstance()31 LocationDataManager* LocationDataManager::GetInstance()
32 {
33 static LocationDataManager data;
34 return &data;
35 }
36
LocationDataManager()37 LocationDataManager::LocationDataManager()
38 {
39 }
40
~LocationDataManager()41 LocationDataManager::~LocationDataManager()
42 {
43 }
44
ReportSwitchState(bool isEnabled)45 LocationErrCode LocationDataManager::ReportSwitchState(bool isEnabled)
46 {
47 int state = isEnabled ? ENABLED : DISABLED;
48 std::unique_lock<std::mutex> lock(mutex_);
49 for (auto item = switchCallbackMap_.begin(); item != switchCallbackMap_.end(); item++) {
50 AppSwitchState *appInfo = &(item->second);
51 if (appInfo == nullptr) {
52 continue;
53 }
54 int uid = appInfo->appIdentity.GetUid();
55 int tokenId = appInfo->appIdentity.GetTokenId();
56 std::string bundleName = appInfo->appIdentity.GetBundleName();
57 int lastState = appInfo->lastState;
58 if (!PermissionManager::CheckIsSystemSa(tokenId) &&
59 !CommonUtils::CheckAppForUser(uid, bundleName)) {
60 appInfo->lastState = DEFAULT_SWITCH_STATE;
61 LBSLOGE(LOCATOR, "It is not a listener of Current user, no need to report. uid : %{public}d", uid);
62 continue;
63 }
64 if (state == lastState) {
65 // current state is same to before, no need to report
66 continue;
67 }
68 sptr<IRemoteObject> remoteObject = item->first;
69 if (remoteObject == nullptr) {
70 LBSLOGE(LOCATOR, "remoteObject callback is nullptr");
71 continue;
72 }
73 auto callback = std::make_unique<SwitchCallbackProxy>(remoteObject);
74 LBSLOGI(LOCATOR, "ReportSwitchState to uid : %{public}d , state = %{public}d", uid, state);
75 callback->OnSwitchChange(state);
76 appInfo->lastState = state;
77 }
78 return ERRCODE_SUCCESS;
79 }
80
RegisterSwitchCallback(const sptr<IRemoteObject> & callback,AppIdentity & identity)81 LocationErrCode LocationDataManager::RegisterSwitchCallback(const sptr<IRemoteObject>& callback,
82 AppIdentity& identity)
83 {
84 if (callback == nullptr) {
85 LBSLOGE(LOCATOR, "register an invalid switch callback");
86 return ERRCODE_INVALID_PARAM;
87 }
88 std::unique_lock<std::mutex> lock(mutex_);
89 auto iter = switchCallbackMap_.find(callback);
90 if (iter != switchCallbackMap_.end()) {
91 LBSLOGE(LOCATOR, "callback has registered");
92 return ERRCODE_SUCCESS;
93 }
94 std::string bundleName = "";
95 int uid = identity.GetUid();
96 if (CommonUtils::GetBundleNameByUid(uid, bundleName)) {
97 identity.SetBundleName(bundleName);
98 }
99 AppSwitchState appInfo{.appIdentity = identity, .lastState = DEFAULT_SWITCH_STATE};
100 if (switchCallbackMap_.size() <= MAX_SWITCH_CALLBACK_NUM) {
101 switchCallbackMap_.emplace(callback, appInfo);
102 } else {
103 LBSLOGE(LOCATOR, "RegisterSwitchCallback num max");
104 return ERRCODE_SERVICE_UNAVAILABLE;
105 }
106 if (!IsSwitchObserverReg()) {
107 RegisterLocationSwitchObserver();
108 }
109 return ERRCODE_SUCCESS;
110 }
111
UnregisterSwitchCallback(const sptr<IRemoteObject> & callback)112 LocationErrCode LocationDataManager::UnregisterSwitchCallback(const sptr<IRemoteObject>& callback)
113 {
114 if (callback == nullptr) {
115 LBSLOGE(LOCATOR, "unregister an invalid switch callback");
116 return ERRCODE_INVALID_PARAM;
117 }
118 std::unique_lock<std::mutex> lock(mutex_);
119 auto iter = switchCallbackMap_.find(callback);
120 if (iter != switchCallbackMap_.end()) {
121 switchCallbackMap_.erase(iter);
122 }
123 LBSLOGD(LOCATOR, "after unregister, switch callback size:%{public}s",
124 std::to_string(switchCallbackMap_.size()).c_str());
125 return ERRCODE_SUCCESS;
126 }
127
IsSwitchObserverReg()128 bool LocationDataManager::IsSwitchObserverReg()
129 {
130 std::unique_lock<std::mutex> lock(isSwitchObserverRegMutex_);
131 return isSwitchObserverReg_;
132 }
133
SetIsSwitchObserverReg(bool isSwitchObserverReg)134 void LocationDataManager::SetIsSwitchObserverReg(bool isSwitchObserverReg)
135 {
136 std::unique_lock<std::mutex> lock(isSwitchObserverRegMutex_);
137 isSwitchObserverReg_ = isSwitchObserverReg;
138 }
139
IsFirstReport()140 bool LocationDataManager::IsFirstReport()
141 {
142 std::unique_lock<std::mutex> lock(isFirstReportMutex_);
143 return isFirstReport_;
144 }
145
SetIsFirstReport(bool isFirstReport)146 void LocationDataManager::SetIsFirstReport(bool isFirstReport)
147 {
148 std::unique_lock<std::mutex> lock(isFirstReportMutex_);
149 isFirstReport_ = isFirstReport;
150 }
151
RegisterLocationSwitchObserver()152 void LocationDataManager::RegisterLocationSwitchObserver()
153 {
154 auto eventCallback = [](const char *key, const char *value, void *context) {
155 int32_t state = DEFAULT_SWITCH_STATE;
156 state = LocationDataRdbManager::QuerySwitchState();
157 auto manager = LocationDataManager::GetInstance();
158 if (manager->IsFirstReport()) {
159 LBSLOGI(LOCATOR, "first switch callback, no need to report");
160 manager->SetIsFirstReport(false);
161 return;
162 }
163 if (state == DEFAULT_SWITCH_STATE) {
164 LBSLOGE(LOCATOR, "LOCATION_SWITCH_MODE changed. state %{public}d. do not report", state);
165 return;
166 }
167 bool switchState = (state == ENABLED);
168 LBSLOGI(LOCATOR, "LOCATION_SWITCH_MODE changed. switchState %{public}d", switchState);
169 manager->ReportSwitchState(switchState);
170 };
171
172 int ret = WatchParameter(LOCATION_SWITCH_MODE, eventCallback, nullptr);
173 if (ret != SUCCESS) {
174 LBSLOGE(LOCATOR, "WatchParameter fail");
175 return;
176 }
177 SetIsSwitchObserverReg(true);
178 return;
179 }
180 } // namespace Location
181 } // namespace OHOS
182