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 "work_conn_manager.h"
16
17 #include <hisysevent.h>
18 #include <if_system_ability_manager.h>
19 #include <ipc_skeleton.h>
20 #include <iservice_registry.h>
21 #include <string_ex.h>
22 #include <system_ability_definition.h>
23
24 #include "ability_manager_client.h"
25 #include "ability_manager_proxy.h"
26 #include "work_sched_hilog.h"
27 #include "errors.h"
28
29 #ifdef DEVICE_STANDBY_ENABLE
30 #include "standby_service_client.h"
31 #endif // DEVICE_STANDBY_ENABLE
32
33 using namespace std;
34 using namespace OHOS::AAFwk;
35 using namespace OHOS::HiviewDFX;
36
37 namespace OHOS {
38 namespace WorkScheduler {
AddConnInfo(string & workId,sptr<WorkSchedulerConnection> & connection)39 void WorkConnManager::AddConnInfo(string &workId, sptr<WorkSchedulerConnection> &connection)
40 {
41 std::lock_guard<std::mutex> lock(connMapMutex_);
42 connMap_.emplace(workId, connection);
43 }
44
RemoveConnInfo(string & workId)45 void WorkConnManager::RemoveConnInfo(string &workId)
46 {
47 std::lock_guard<std::mutex> lock(connMapMutex_);
48 connMap_.erase(workId);
49 }
50
GetConnInfo(string & workId)51 sptr<WorkSchedulerConnection> WorkConnManager::GetConnInfo(string &workId)
52 {
53 std::lock_guard<std::mutex> lock(connMapMutex_);
54 if (connMap_.count(workId) > 0) {
55 return connMap_.at(workId);
56 }
57 return nullptr;
58 }
59
StartWork(shared_ptr<WorkStatus> workStatus)60 bool WorkConnManager::StartWork(shared_ptr<WorkStatus> workStatus)
61 {
62 WS_HILOGD("Start Work with id: %{public}s, bundleName: %{public}s, abilityName: %{public}s",
63 workStatus->workId_.c_str(), workStatus->bundleName_.c_str(), workStatus->abilityName_.c_str());
64 sptr<ISystemAbilityManager> systemAbilityManager =
65 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
66 if (systemAbilityManager == nullptr) {
67 WS_HILOGE("Failed to get system ability manager service.");
68 return false;
69 }
70 sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
71 if (remoteObject == nullptr) {
72 WS_HILOGE("Failed to ability manager service.");
73 return false;
74 }
75 sptr<AAFwk::IAbilityManager> abilityMgr_ = iface_cast<AAFwk::IAbilityManager>(remoteObject);
76 if ((abilityMgr_ == nullptr) || (abilityMgr_->AsObject() == nullptr)) {
77 WS_HILOGE("Failed to get ability manager services object");
78 return false;
79 }
80
81 WS_HILOGI("Begin to connect bundle:%{public}s, abilityName:%{public}s, userId:%{public}d",
82 workStatus->bundleName_.c_str(), workStatus->abilityName_.c_str(), workStatus->userId_);
83 sptr<WorkSchedulerConnection> connection(new (std::nothrow) WorkSchedulerConnection(workStatus->workInfo_));
84 if (connection == nullptr) {
85 WS_HILOGE("Failed to new connection.");
86 return false;
87 }
88
89 Want want;
90 want.SetElementName(workStatus->bundleName_, workStatus->abilityName_);
91 int32_t ret = abilityMgr_->ConnectAbility(want, connection, nullptr, workStatus->userId_);
92 if (ret != ERR_OK) {
93 WS_HILOGE("connect failed");
94 return false;
95 }
96 AddConnInfo(workStatus->workId_, connection);
97
98 // Notify work add event to battery statistics
99 WriteStartWorkEvent(workStatus);
100
101 return true;
102 }
103
DisConnect(sptr<WorkSchedulerConnection> connect)104 bool WorkConnManager::DisConnect(sptr<WorkSchedulerConnection> connect)
105 {
106 sptr<ISystemAbilityManager> systemAbilityManager =
107 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
108 if (systemAbilityManager == nullptr) {
109 WS_HILOGE("Failed to get system ability manager service.");
110 return false;
111 }
112 sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
113 if (remoteObject == nullptr) {
114 WS_HILOGE("Failed to ability manager service.");
115 return false;
116 }
117 sptr<AAFwk::IAbilityManager> abilityMgr_ = iface_cast<AAFwk::IAbilityManager>(remoteObject);
118 if ((abilityMgr_ == nullptr) || (abilityMgr_->AsObject() == nullptr)) {
119 WS_HILOGE("Failed to get ability manager services object.");
120 return false;
121 }
122 int32_t ret = abilityMgr_->DisconnectAbility(connect);
123 if (ret != ERR_OK) {
124 WS_HILOGE("disconnect failed");
125 return false;
126 }
127 return true;
128 }
129
StopWork(shared_ptr<WorkStatus> workStatus)130 bool WorkConnManager::StopWork(shared_ptr<WorkStatus> workStatus)
131 {
132 bool ret = false;
133 sptr<WorkSchedulerConnection> conn = GetConnInfo(workStatus->workId_);
134 if (conn != nullptr) {
135 conn->StopWork();
136 ret = DisConnect(conn);
137 } else {
138 WS_HILOGE("connection is null");
139 }
140 RemoveConnInfo(workStatus->workId_);
141
142 // Notify work remove event to battery statistics only work has started
143 if (ret) {
144 int32_t pid = IPCSkeleton::GetCallingPid();
145 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::WORK_SCHEDULER, "WORK_STOP",
146 HiSysEvent::EventType::STATISTIC, "UID",
147 workStatus->uid_, "PID", pid, "NAME", workStatus->bundleName_, "WORKID", workStatus->workId_);
148 #ifdef DEVICE_STANDBY_ENABLE
149 WS_HILOGI("OnWorkStop uid: %{public}d", workStatus->uid_);
150 DevStandbyMgr::StandbyServiceClient::GetInstance().ReportWorkSchedulerStatus(false,
151 workStatus->uid_, workStatus->bundleName_);
152 #endif // DEVICE_STANDBY_ENABLE
153 }
154 return ret;
155 }
156
WriteStartWorkEvent(shared_ptr<WorkStatus> workStatus)157 void WorkConnManager::WriteStartWorkEvent(shared_ptr<WorkStatus> workStatus)
158 {
159 int32_t pid = IPCSkeleton::GetCallingPid();
160 string conditions = "";
161 if (workStatus->workInfo_->GetConditionMap()->count(WorkCondition::Type::NETWORK) > 0) {
162 conditions.append("NETWORK-");
163 }
164
165 if (workStatus->workInfo_->GetConditionMap()->count(WorkCondition::Type::CHARGER) > 0) {
166 conditions.append("CHARGER-");
167 }
168
169 if (workStatus->workInfo_->GetConditionMap()->count(WorkCondition::Type::BATTERY_STATUS) > 0) {
170 conditions.append("BATTERY_STATUS-");
171 }
172
173 if (workStatus->workInfo_->GetConditionMap()->count(WorkCondition::Type::BATTERY_LEVEL) > 0) {
174 conditions.append("BATTERY_LEVEL-");
175 }
176
177 if (workStatus->workInfo_->GetConditionMap()->count(WorkCondition::Type::STORAGE) > 0) {
178 conditions.append("STORAGE-");
179 }
180
181 if (workStatus->workInfo_->GetConditionMap()->count(WorkCondition::Type::TIMER) > 0) {
182 conditions.append("TIMER-");
183 }
184 conditions.pop_back();
185
186 string type = "Repeat";
187 if (!workStatus->workInfo_->IsRepeat()) {
188 type = "Not Repeat";
189 }
190
191 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::WORK_SCHEDULER, "WORK_START",
192 HiSysEvent::EventType::STATISTIC, "UID",
193 workStatus->uid_, "PID", pid, "NAME", workStatus->bundleName_, "WORKID", workStatus->workId_, "TRIGGER",
194 conditions, "TYPE", type, "INTERVAL", workStatus->workInfo_->GetTimeInterval());
195 #ifdef DEVICE_STANDBY_ENABLE
196 WS_HILOGI("OnWorkStart uid: %{public}d", workStatus->uid_);
197 DevStandbyMgr::StandbyServiceClient::GetInstance().ReportWorkSchedulerStatus(true,
198 workStatus->uid_, workStatus->bundleName_);
199 #endif // DEVICE_STANDBY_ENABLE
200 }
201 } // namespace WorkScheduler
202 } // namespace OHOS
203