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 "continuous_task_record.h"
17 
18 #include "common_utils.h"
19 #include "iremote_object.h"
20 #include "background_mode.h"
21 #include "continuous_task_log.h"
22 
23 namespace OHOS {
24 namespace BackgroundTaskMgr {
25 const char *g_continuousTaskModeName[10] = {
26     "dataTransfer",
27     "audioPlayback",
28     "audioRecording",
29     "location",
30     "bluetoothInteraction",
31     "multiDeviceConnection",
32     "wifiInteraction",
33     "voip",
34     "taskKeeping",
35     "default",
36 };
37 
ContinuousTaskRecord(const std::string & bundleName,const std::string & abilityName,int32_t uid,int32_t pid,uint32_t bgModeId,bool isBatchApi,const std::vector<uint32_t> & bgModeIds,int32_t abilityId)38 ContinuousTaskRecord::ContinuousTaskRecord(const std::string &bundleName, const std::string &abilityName, int32_t uid,
39     int32_t pid, uint32_t bgModeId, bool isBatchApi, const std::vector<uint32_t> &bgModeIds, int32_t abilityId)
40     : bundleName_(bundleName), abilityName_(abilityName), uid_(uid), pid_(pid), bgModeId_(bgModeId),
41       isBatchApi_(isBatchApi), bgModeIds_(bgModeIds), abilityId_(abilityId) {
42     if (isBatchApi_) {
43         auto findNonDataTransfer = [](const auto &target) {
44             return  target != BackgroundMode::DATA_TRANSFER;
45         };
46         auto iter = std::find_if(bgModeIds_.begin(), bgModeIds_.end(), findNonDataTransfer);
47         if (iter != bgModeIds_.end()) {
48             bgModeId_ = *iter;
49             BGTASK_LOGI("batch api, find non-datatransfer mode, set %{public}d", bgModeId_);
50         } else {
51             bgModeId_ = bgModeIds_[0];
52         }
53     } else {
54         bgModeIds_.push_back(bgModeId);
55     }
56 }
57 
GetBundleName() const58 std::string ContinuousTaskRecord::GetBundleName() const
59 {
60     return bundleName_;
61 }
62 
GetAbilityName() const63 std::string ContinuousTaskRecord::GetAbilityName() const
64 {
65     return abilityName_;
66 }
67 
IsNewApi() const68 bool ContinuousTaskRecord::IsNewApi() const
69 {
70     return isNewApi_;
71 }
72 
IsFromWebview() const73 bool ContinuousTaskRecord::IsFromWebview() const
74 {
75     return isFromWebview_;
76 }
77 
GetBgModeId() const78 uint32_t ContinuousTaskRecord::GetBgModeId() const
79 {
80     return bgModeId_;
81 }
82 
GetUserId() const83 int32_t ContinuousTaskRecord::GetUserId() const
84 {
85     return userId_;
86 }
87 
GetUid() const88 int32_t ContinuousTaskRecord::GetUid() const
89 {
90     return uid_;
91 }
92 
GetPid() const93 pid_t ContinuousTaskRecord::GetPid() const
94 {
95     return pid_;
96 }
97 
GetNotificationLabel() const98 std::string ContinuousTaskRecord::GetNotificationLabel() const
99 {
100     return notificationLabel_;
101 }
102 
GetNotificationId() const103 int32_t ContinuousTaskRecord::GetNotificationId() const
104 {
105     return notificationId_;
106 }
107 
GetWantAgent() const108 std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> ContinuousTaskRecord::GetWantAgent() const
109 {
110     return wantAgent_;
111 }
112 
ToString(std::vector<uint32_t> & bgmodes)113 std::string ContinuousTaskRecord::ToString(std::vector<uint32_t> &bgmodes)
114 {
115     std::string result;
116     for (auto it : bgmodes) {
117         result += std::to_string(it);
118         result += ",";
119     }
120     return result;
121 }
122 
ToVector(std::string & str)123 std::vector<uint32_t> ContinuousTaskRecord::ToVector(std::string &str)
124 {
125     std::vector<std::string> stringTokens;
126     std::vector<uint32_t> modeTokens;
127     OHOS::SplitStr(str, ",", stringTokens);
128     for (auto mode : stringTokens) {
129         modeTokens.push_back(std::atoi(mode.c_str()));
130     }
131     return modeTokens;
132 }
133 
GetAbilityId() const134 int32_t ContinuousTaskRecord::GetAbilityId() const
135 {
136     return abilityId_;
137 }
138 
IsSystem() const139 bool ContinuousTaskRecord::IsSystem() const
140 {
141     return isSystem_;
142 }
143 
ParseToJsonStr()144 std::string ContinuousTaskRecord::ParseToJsonStr()
145 {
146     nlohmann::json root;
147     root["bundleName"] = bundleName_;
148     root["abilityName"] = abilityName_;
149     root["userId"] = userId_;
150     root["uid"] = uid_;
151     root["pid"] = pid_;
152     root["bgModeId"] = bgModeId_;
153     root["isNewApi"] = isNewApi_;
154     root["isFromWebview"] = isFromWebview_;
155     root["notificationLabel"] = notificationLabel_;
156     root["notificationId"] = notificationId_;
157     root["isBatchApi"] = isBatchApi_;
158     root["bgModeIds"] = ToString(bgModeIds_);
159     root["isSystem"] = isSystem_;
160     if (wantAgentInfo_ != nullptr) {
161         nlohmann::json info;
162         info["bundleName"] = wantAgentInfo_->bundleName_;
163         info["abilityName"] = wantAgentInfo_->abilityName_;
164         root["wantAgentInfo"] = info;
165     }
166     return root.dump(CommonUtils::jsonFormat_);
167 }
168 
CheckContinuousRecod(const nlohmann::json & value)169 bool CheckContinuousRecod(const nlohmann::json &value)
170 {
171     return !value["bundleName"].is_string() || !value["abilityName"].is_string()
172         || !value["userId"].is_number_integer() || !value["uid"].is_number_integer()
173         || !value["pid"].is_number_integer() || !value["bgModeId"].is_number_integer()
174         || !value["isNewApi"].is_boolean() || !value["isFromWebview"].is_boolean()
175         || !value["notificationLabel"].is_string() || !value["isSystem"].is_boolean();
176 }
177 
ParseFromJson(const nlohmann::json & value)178 bool ContinuousTaskRecord::ParseFromJson(const nlohmann::json &value)
179 {
180     if (value.is_null() || !value.is_object() || !CommonUtils::CheckJsonValue(value, { "bundleName",
181         "abilityName", "userId", "uid", "pid", "bgModeId", "isNewApi", "isFromWebview", "notificationLabel",
182         "isSystem"})) {
183         return false;
184     }
185     if (CheckContinuousRecod(value)) {
186         BGTASK_LOGE("continuoustaskrecord parse from json fail");
187         return false;
188     }
189     this->bundleName_ = value.at("bundleName").get<std::string>();
190     this->abilityName_ = value.at("abilityName").get<std::string>();
191     this->userId_ = value.at("userId").get<int32_t>();
192     this->uid_ = value.at("uid").get<int32_t>();
193     this->pid_ = value.at("pid").get<int32_t>();
194     this->bgModeId_ = value.at("bgModeId").get<uint32_t>();
195     this->isNewApi_ = value.at("isNewApi").get<bool>();
196     this->isFromWebview_ = value.at("isFromWebview").get<bool>();
197     this->notificationLabel_ = value.at("notificationLabel").get<std::string>();
198     this->isSystem_ = value.at("isSystem").get<bool>();
199     if (value.contains("isBatchApi") && value["isBatchApi"].is_boolean()) {
200         this->isBatchApi_ = value.at("isBatchApi").get<bool>();
201     }
202     if (value.contains("bgModeIds") && value["bgModeIds"].is_string()) {
203         auto modes = value.at("bgModeIds").get<std::string>();
204         this->bgModeIds_ = ToVector(modes);
205     }
206     if (value.find("wantAgentInfo") != value.end()) {
207         nlohmann::json infoVal = value["wantAgentInfo"];
208         if (!CommonUtils::CheckJsonValue(infoVal, { "bundleName", "abilityName" })
209             || !infoVal["bundleName"].is_string() || !infoVal["abilityName"].is_string()) {
210             return false;
211         }
212         std::shared_ptr<WantAgentInfo> info = std::make_shared<WantAgentInfo>();
213         info->bundleName_ = infoVal.at("bundleName").get<std::string>();
214         info->abilityName_ = infoVal.at("abilityName").get<std::string>();
215         this->wantAgentInfo_ = info;
216     }
217     if (value.contains("notificationId") && value["notificationId"].is_number_integer()) {
218         this->notificationId_ = value.at("notificationId").get<int32_t>();
219     }
220     return true;
221 }
222 }  // namespace BackgroundTaskMgr
223 }  // namespace OHOS