• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     if (connMap_.count(workStatus->workId_) > 0) {
63         WS_HILOGE("Work has started with id: %{public}s, bundleName: %{public}s, abilityName: %{public}s",
64             workStatus->workId_.c_str(), workStatus->bundleName_.c_str(), workStatus->abilityName_.c_str());
65         return false;
66     }
67 
68     WS_HILOGD("Start Work with id: %{public}s, bundleName: %{public}s, abilityName: %{public}s",
69         workStatus->workId_.c_str(), workStatus->bundleName_.c_str(), workStatus->abilityName_.c_str());
70     sptr<ISystemAbilityManager> systemAbilityManager =
71         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
72     if (systemAbilityManager == nullptr) {
73         WS_HILOGE("Failed to get system ability manager service.");
74         return false;
75     }
76     sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
77     if (remoteObject == nullptr) {
78         WS_HILOGE("Failed to ability manager service.");
79         return false;
80     }
81     sptr<AAFwk::IAbilityManager> abilityMgr_ = iface_cast<AAFwk::IAbilityManager>(remoteObject);
82     if ((abilityMgr_ == nullptr) || (abilityMgr_->AsObject() == nullptr)) {
83         WS_HILOGE("Failed to get ability manager services object");
84         return false;
85     }
86 
87     WS_HILOGI("Begin to connect bundle:%{public}s, abilityName:%{public}s, userId:%{public}d",
88         workStatus->bundleName_.c_str(), workStatus->abilityName_.c_str(), workStatus->userId_);
89     sptr<WorkSchedulerConnection> connection(new (std::nothrow) WorkSchedulerConnection(workStatus->workInfo_));
90     if (connection == nullptr) {
91         WS_HILOGE("Failed to new connection.");
92         return false;
93     }
94 
95     Want want;
96     want.SetElementName(workStatus->bundleName_, workStatus->abilityName_);
97     int32_t ret = abilityMgr_->ConnectAbility(want, connection, nullptr, workStatus->userId_);
98     if (ret != ERR_OK) {
99         WS_HILOGE("connect failed");
100         return false;
101     }
102     AddConnInfo(workStatus->workId_, connection);
103 
104     // Notify work add event to battery statistics
105     WriteStartWorkEvent(workStatus);
106 
107     return true;
108 }
109 
DisConnect(sptr<WorkSchedulerConnection> connect)110 bool WorkConnManager::DisConnect(sptr<WorkSchedulerConnection> connect)
111 {
112     sptr<ISystemAbilityManager> systemAbilityManager =
113         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
114     if (systemAbilityManager == nullptr) {
115         WS_HILOGE("Failed to get system ability manager service.");
116         return false;
117     }
118     sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
119     if (remoteObject == nullptr) {
120         WS_HILOGE("Failed to ability manager service.");
121         return false;
122     }
123     sptr<AAFwk::IAbilityManager> abilityMgr_ = iface_cast<AAFwk::IAbilityManager>(remoteObject);
124     if ((abilityMgr_ == nullptr) || (abilityMgr_->AsObject() == nullptr)) {
125         WS_HILOGE("Failed to  get ability manager services object.");
126         return false;
127     }
128     int32_t ret = abilityMgr_->DisconnectAbility(connect);
129     if (ret != ERR_OK) {
130         WS_HILOGE("disconnect failed");
131         return false;
132     }
133     return true;
134 }
135 
StopWork(shared_ptr<WorkStatus> workStatus)136 bool WorkConnManager::StopWork(shared_ptr<WorkStatus> workStatus)
137 {
138     bool ret = false;
139     sptr<WorkSchedulerConnection> conn = GetConnInfo(workStatus->workId_);
140     if (conn != nullptr) {
141         conn->StopWork();
142         ret = DisConnect(conn);
143     } else {
144         WS_HILOGE("connection is null");
145     }
146     RemoveConnInfo(workStatus->workId_);
147 
148     // Notify work remove event to battery statistics only work has started
149     if (ret) {
150         int32_t pid = IPCSkeleton::GetCallingPid();
151         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::WORK_SCHEDULER, "WORK_STOP",
152             HiSysEvent::EventType::STATISTIC, "UID",
153             workStatus->uid_, "PID", pid, "NAME", workStatus->bundleName_, "WORKID", workStatus->workId_);
154 #ifdef DEVICE_STANDBY_ENABLE
155         WS_HILOGI("OnWorkStop uid: %{public}d", workStatus->uid_);
156         DevStandbyMgr::StandbyServiceClient::GetInstance().ReportWorkSchedulerStatus(false,
157             workStatus->uid_, workStatus->bundleName_);
158 #endif // DEVICE_STANDBY_ENABLE
159     }
160     return ret;
161 }
162 
WriteStartWorkEvent(shared_ptr<WorkStatus> workStatus)163 void WorkConnManager::WriteStartWorkEvent(shared_ptr<WorkStatus> workStatus)
164 {
165     int32_t pid = IPCSkeleton::GetCallingPid();
166     string conditions = "";
167     if (workStatus->workInfo_->GetConditionMap()->count(WorkCondition::Type::NETWORK) > 0) {
168         conditions.append("NETWORK-");
169     }
170 
171     if (workStatus->workInfo_->GetConditionMap()->count(WorkCondition::Type::CHARGER) > 0) {
172         conditions.append("CHARGER-");
173     }
174 
175     if (workStatus->workInfo_->GetConditionMap()->count(WorkCondition::Type::BATTERY_STATUS) > 0) {
176         conditions.append("BATTERY_STATUS-");
177     }
178 
179     if (workStatus->workInfo_->GetConditionMap()->count(WorkCondition::Type::BATTERY_LEVEL) > 0) {
180         conditions.append("BATTERY_LEVEL-");
181     }
182 
183     if (workStatus->workInfo_->GetConditionMap()->count(WorkCondition::Type::STORAGE) > 0) {
184         conditions.append("STORAGE-");
185     }
186 
187     if (workStatus->workInfo_->GetConditionMap()->count(WorkCondition::Type::TIMER) > 0) {
188         conditions.append("TIMER-");
189     }
190     conditions.pop_back();
191 
192     string type = "Repeat";
193     if (!workStatus->workInfo_->IsRepeat()) {
194         type = "Not Repeat";
195     }
196 
197     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::WORK_SCHEDULER, "WORK_START",
198         HiSysEvent::EventType::STATISTIC, "UID",
199         workStatus->uid_, "PID", pid, "NAME", workStatus->bundleName_, "WORKID", workStatus->workId_, "TRIGGER",
200         conditions, "TYPE", type, "INTERVAL", workStatus->workInfo_->GetTimeInterval());
201 #ifdef DEVICE_STANDBY_ENABLE
202     WS_HILOGI("OnWorkStart uid: %{public}d", workStatus->uid_);
203     DevStandbyMgr::StandbyServiceClient::GetInstance().ReportWorkSchedulerStatus(true,
204         workStatus->uid_, workStatus->bundleName_);
205 #endif // DEVICE_STANDBY_ENABLE
206 }
207 } // namespace WorkScheduler
208 } // namespace OHOS
209