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