1 /*
2 * Copyright (c) 2024 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 "set_watermark_image_plugin.h"
16
17 #include <fcntl.h>
18 #include <fstream>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22 #include "edm_constants.h"
23 #include "edm_ipc_interface_code.h"
24 #include "func_code_utils.h"
25 #include "ipolicy_manager.h"
26 #include "iservice_registry.h"
27 #include "iplugin_manager.h"
28 #include "iwatermark_observer_manager.h"
29 #include "security_label.h"
30 #include "system_ability_definition.h"
31 #include "transaction/rs_interfaces.h"
32 #include "watermark_image_serializer.h"
33 #include "window_manager.h"
34 #include "wm_common.h"
35
36 namespace OHOS {
37 namespace EDM {
38 const bool REGISTER_RESULT =
39 IPluginManager::GetInstance()->AddPlugin(std::make_shared<SetWatermarkImagePlugin>());
40 const std::string WATERMARK_IMAGE_DIR_PATH = "/data/service/el1/public/edm/watermark/";
41 const std::string FILE_PREFIX = "edm_";
42 const std::string DATA_LEVEL_S4 = "s4";
43 constexpr int32_t MAX_POLICY_NUM = 100;
SetWatermarkImagePlugin()44 SetWatermarkImagePlugin::SetWatermarkImagePlugin()
45 {
46 EDMLOGI("SetWatermarkImagePlugin InitPlugin...");
47 policyCode_ = EdmInterfaceCode::WATERMARK_IMAGE;
48 policyName_ = PolicyName::POLICY_WATERMARK_IMAGE_POLICY;
49 permissionConfig_.typePermissions.emplace(IPlugin::PermissionType::SUPER_DEVICE_ADMIN,
50 EdmPermission::PERMISSION_ENTERPRISE_MANAGE_SECURITY);
51 permissionConfig_.apiType = IPlugin::ApiType::PUBLIC;
52 needSave_ = true;
53 }
54
OnHandlePolicy(std::uint32_t funcCode,MessageParcel & data,MessageParcel & reply,HandlePolicyData & policyData,int32_t userId)55 ErrCode SetWatermarkImagePlugin::OnHandlePolicy(std::uint32_t funcCode, MessageParcel &data, MessageParcel &reply,
56 HandlePolicyData &policyData, int32_t userId)
57 {
58 uint32_t typeCode = FUNC_TO_OPERATE(funcCode);
59 FuncOperateType type = FuncCodeUtils::ConvertOperateType(typeCode);
60 std::map<std::pair<std::string, int32_t>, WatermarkImageType> currentData;
61 std::map<std::pair<std::string, int32_t>, WatermarkImageType> mergeData;
62 auto serializer = WatermarkImageSerializer::GetInstance();
63 if (!serializer->Deserialize(policyData.policyData, currentData) ||
64 !serializer->Deserialize(policyData.mergePolicyData, mergeData)) {
65 EDMLOGE("SetWatermarkImagePlugin::CancelWatermarkImage Deserialize current policy and merge policy failed.");
66 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
67 }
68 if (type != FuncOperateType::SET && type != FuncOperateType::REMOVE) {
69 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
70 }
71 ErrCode ret = EdmReturnErrCode::SYSTEM_ABNORMALLY;
72 if (type == FuncOperateType::SET) {
73 ret = SetPolicy(data, currentData, mergeData);
74 } else if (type == FuncOperateType::REMOVE) {
75 ret = CancelWatermarkImage(data, currentData, mergeData);
76 }
77 if (FAILED(ret)) {
78 return ret;
79 }
80
81 std::string afterHandle;
82 std::string afterMerge;
83 if (!serializer->Serialize(currentData, afterHandle) || !serializer->Serialize(mergeData, afterMerge)) {
84 EDMLOGE("FingerprintAuthPlugin Serialize current policy and merge policy failed.");
85 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
86 }
87 policyData.isChanged = (afterHandle != policyData.policyData);
88 if (policyData.isChanged) {
89 policyData.policyData = afterHandle;
90 }
91 policyData.mergePolicyData = afterMerge;
92 return ERR_OK;
93 }
94
SetPolicy(MessageParcel & data,std::map<std::pair<std::string,int32_t>,WatermarkImageType> & currentData,std::map<std::pair<std::string,int32_t>,WatermarkImageType> & mergeData)95 ErrCode SetWatermarkImagePlugin::SetPolicy(MessageParcel &data,
96 std::map<std::pair<std::string, int32_t>, WatermarkImageType> ¤tData,
97 std::map<std::pair<std::string, int32_t>, WatermarkImageType> &mergeData)
98 {
99 EDMLOGD("SetWatermarkImagePlugin start SetPolicy");
100 std::string type = data.ReadString();
101 if (type == EdmConstants::SecurityManager::SET_SINGLE_WATERMARK_TYPE) {
102 WatermarkParam param;
103 if (!GetWatermarkParam(param, data)) {
104 return EdmReturnErrCode::PARAM_ERROR;
105 }
106 return SetSingleWatermarkImage(param, currentData, mergeData);
107 }
108 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
109 }
110
CancelWatermarkImage(MessageParcel & data,std::map<std::pair<std::string,int32_t>,WatermarkImageType> & currentData,std::map<std::pair<std::string,int32_t>,WatermarkImageType> & mergeData)111 ErrCode SetWatermarkImagePlugin::CancelWatermarkImage(MessageParcel &data,
112 std::map<std::pair<std::string, int32_t>, WatermarkImageType> ¤tData,
113 std::map<std::pair<std::string, int32_t>, WatermarkImageType> &mergeData)
114 {
115 EDMLOGI("SetWatermarkImagePlugin CancelWatermarkImage start");
116 std::string bundleName = data.ReadString();
117 int32_t accountId = data.ReadInt32();
118 if (bundleName.empty() || accountId <= 0) {
119 EDMLOGE("SetWatermarkImagePlugin CancelWatermarkImage param error");
120 return EdmReturnErrCode::PARAM_ERROR;
121 }
122 auto key = std::make_pair(bundleName, accountId);
123 auto it = currentData.find(key);
124 if (it != currentData.end()) {
125 std::string filePath = WATERMARK_IMAGE_DIR_PATH + it->second.fileName;
126 SetProcessWatermark(bundleName, it->second.fileName, accountId, false);
127 if (!SetWatermarkToRS(it->second.fileName, nullptr)) {
128 EDMLOGE("SetWatermarkToRS fail");
129 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
130 }
131 currentData.erase(key);
132 int32_t ret = remove(filePath.c_str());
133 if (ret != 0) {
134 EDMLOGE("SetWatermarkImagePlugin SetWatermarkImage remove failed");
135 }
136 }
137 for (auto item : currentData) {
138 mergeData[item.first] = item.second;
139 }
140 if (mergeData.empty()) {
141 UnsubscribeAppState();
142 }
143 return ERR_OK;
144 }
145
SetAllWatermarkImage()146 void SetWatermarkImagePlugin::SetAllWatermarkImage()
147 {
148 EDMLOGI("SetAllWatermarkImage");
149 std::string policyData;
150 auto policyManager = IPolicyManager::GetInstance();
151 policyManager->GetPolicy("", PolicyName::POLICY_WATERMARK_IMAGE_POLICY, policyData, DEFAULT_USER_ID);
152 std::map<std::pair<std::string, int32_t>, WatermarkImageType> currentData;
153 auto serializer = WatermarkImageSerializer::GetInstance();
154 serializer->Deserialize(policyData, currentData);
155 if (currentData.empty()) {
156 return;
157 }
158 for (auto it = currentData.begin(); it != currentData.end(); it++) {
159 EDMLOGI("SetAllWatermarkImage fileName=%{public}s", it->second.fileName.c_str());
160 auto pixelMap = GetImageFromUrlUint8(it->second);
161 if (pixelMap == nullptr) {
162 EDMLOGE("SetAllWatermarkImage GetImageFromUrlUint8 null");
163 continue;
164 }
165 if (!SetWatermarkToRS(it->second.fileName, pixelMap)) {
166 EDMLOGE("SetWatermarkToRS fail");
167 return;
168 }
169 }
170 if (!SubscribeAppState()) {
171 EDMLOGE("SetWatermarkImagePlugin SubscribeAppState error");
172 }
173 }
174
SetSingleWatermarkImage(WatermarkParam & param,std::map<std::pair<std::string,int32_t>,WatermarkImageType> & currentData,std::map<std::pair<std::string,int32_t>,WatermarkImageType> & mergeData)175 ErrCode SetWatermarkImagePlugin::SetSingleWatermarkImage(WatermarkParam ¶m,
176 std::map<std::pair<std::string, int32_t>, WatermarkImageType> ¤tData,
177 std::map<std::pair<std::string, int32_t>, WatermarkImageType> &mergeData)
178 {
179 auto pixelMap =
180 CreatePixelMapFromUint8(reinterpret_cast<const uint8_t *>(param.pixels), param.size, param.width, param.height);
181 auto key = std::make_pair(param.bundleName, param.accountId);
182 if (mergeData.find(key) != mergeData.end()) {
183 EDMLOGE("SetWatermarkImagePlugin policy failed, other admin have already set the watermark for this bundle.");
184 return EdmReturnErrCode::PARAM_ERROR;
185 }
186 std::string oldFileName;
187 if (currentData.find(key) != currentData.end()) {
188 oldFileName = currentData[key].fileName;
189 }
190 std::string fileName = FILE_PREFIX + std::to_string(time(nullptr));
191 std::string filePath = WATERMARK_IMAGE_DIR_PATH + fileName;
192 currentData[key] = WatermarkImageType{fileName, param.width, param.height};
193 for (auto item : currentData) {
194 mergeData[item.first] = item.second;
195 }
196 if (mergeData.size() > MAX_POLICY_NUM) {
197 EDMLOGE("SetWatermarkImagePlugin policy max");
198 return EdmReturnErrCode::PARAM_ERROR;
199 }
200
201 if (!SetWatermarkToRS(fileName, pixelMap)) {
202 EDMLOGE("SetWatermarkToRS fail");
203 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
204 }
205 if (!SetImageUint8(param.pixels, param.size, filePath)) {
206 EDMLOGE("SetWatermarkImagePlugin SetImageUint8 error.fileName=%{public}s", fileName.c_str());
207 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
208 }
209 if (!SubscribeAppState()) {
210 EDMLOGE("SetWatermarkImagePlugin SubscribeAppState error");
211 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
212 }
213 if (!oldFileName.empty()) {
214 std::string oldFilePath = WATERMARK_IMAGE_DIR_PATH + oldFileName;
215 int32_t ret = remove(oldFilePath.c_str());
216 if (ret != 0) {
217 EDMLOGE("SetWatermarkImagePlugin SetWatermarkImage remove failed");
218 }
219 SetProcessWatermark(param.bundleName, oldFileName, param.accountId, false);
220 }
221 SetProcessWatermark(param.bundleName, fileName, param.accountId, true);
222 return ERR_OK;
223 }
224
GetWatermarkParam(WatermarkParam & param,MessageParcel & data)225 bool SetWatermarkImagePlugin::GetWatermarkParam(WatermarkParam ¶m, MessageParcel &data)
226 {
227 param.bundleName = data.ReadString();
228 param.accountId = data.ReadInt32();
229 param.width = data.ReadInt32();
230 param.height = data.ReadInt32();
231 param.size = data.ReadInt32();
232 if (param.size <= 0 || param.size > static_cast<int32_t>(data.GetRawDataCapacity())) {
233 EDMLOGE("GetWatermarkParam size error");
234 return false;
235 }
236 param.SetPixels(const_cast<void*>(data.ReadRawData(param.size)));
237 if (param.pixels == nullptr) {
238 EDMLOGE("GetWatermarkParam pixels error");
239 return false;
240 }
241 if (param.bundleName.empty() || param.width <= 0 || param.height <= 0 || param.accountId <= 0) {
242 EDMLOGE("GetWatermarkParam param error");
243 return false;
244 }
245 return true;
246 }
247
SetWatermarkToRS(const std::string & name,std::shared_ptr<Media::PixelMap> watermarkImg)248 bool SetWatermarkImagePlugin::SetWatermarkToRS(const std::string &name, std::shared_ptr<Media::PixelMap> watermarkImg)
249 {
250 EDMLOGI("SetWatermarkToRS %{public}s", name.c_str());
251 return Rosen::RSInterfaces::GetInstance().SetWatermark(name, watermarkImg);
252 }
253
SetProcessWatermark(const std::string & bundleName,const std::string & fileName,int32_t accountId,bool enabled)254 void SetWatermarkImagePlugin::SetProcessWatermark(const std::string &bundleName, const std::string &fileName,
255 int32_t accountId, bool enabled)
256 {
257 EDMLOGI("SetProcessWatermark start");
258 if (fileName.empty()) {
259 return;
260 }
261 auto appManager = GetAppManager();
262 if (appManager == nullptr) {
263 EDMLOGE("SetProcessWatermark IAppMgr null.");
264 return;
265 }
266 std::vector<AppExecFwk::RunningProcessInfo> infos;
267 int res = appManager->GetRunningProcessInformation(bundleName, accountId, infos);
268 if (res != ERR_OK) {
269 EDMLOGE("GetRunningProcessInformation fail!");
270 return;
271 }
272 if (infos.empty() || infos[0].pid_ == 0) {
273 EDMLOGD("GetRunning Process Information pid empty");
274 return;
275 }
276
277 Rosen::WMError ret = Rosen::WindowManager::GetInstance().SetProcessWatermark(infos[0].pid_, fileName, enabled);
278 if (ret != Rosen::WMError::WM_OK) {
279 EDMLOGE("SetProcessWatermark fail!code: %{public}d", ret);
280 }
281 }
282
SetImageUint8(const void * pixels,int32_t size,const std::string & url)283 bool SetWatermarkImagePlugin::SetImageUint8(const void *pixels, int32_t size, const std::string &url)
284 {
285 EDMLOGI("SetImageUint8 start");
286 std::ofstream outfile(url, std::ios::binary);
287 if (outfile.fail()) {
288 EDMLOGE("SetImageUint8 Open file fail!");
289 return false;
290 }
291 outfile.write(reinterpret_cast<const char *>(pixels), static_cast<std::streamsize>(size));
292 outfile.close();
293 if (chmod(url.c_str(), S_IRUSR | S_IWUSR) != 0) {
294 EDMLOGE("SetImageUint8 chmod fail!");
295 return false;
296 }
297 if (!FileManagement::ModuleSecurityLabel::SecurityLabel::SetSecurityLabel(url, DATA_LEVEL_S4)) {
298 EDMLOGE("SetImageUint8 SetSecurityLabel fail!");
299 return false;
300 }
301 return true;
302 }
303
GetImageFromUrlUint8(const WatermarkImageType & imageType)304 std::shared_ptr<Media::PixelMap> SetWatermarkImagePlugin::GetImageFromUrlUint8(const WatermarkImageType &imageType)
305 {
306 EDMLOGI("GetImageFromUrlUint8 start");
307 std::string filePath = WATERMARK_IMAGE_DIR_PATH + imageType.fileName;
308 std::ifstream infile(filePath, std::ios::binary | std::ios::ate);
309 if (infile.fail()) {
310 EDMLOGE("Open file fail! fileName=%{public}s", imageType.fileName.c_str());
311 return nullptr;
312 }
313 std::streamsize size = infile.tellg();
314 if (size <= 0) {
315 EDMLOGE("GetImageFromUrlUint8 size %{public}d", (int32_t)size);
316 infile.close();
317 return nullptr;
318 }
319 infile.seekg(0, std::ios::beg);
320 uint8_t data[size];
321 infile.read(reinterpret_cast<char *>(data), size);
322 infile.close();
323 return CreatePixelMapFromUint8(data, size, imageType.width, imageType.height);
324 }
325
CreatePixelMapFromUint8(const uint8_t * data,size_t size,int32_t width,int32_t height)326 std::shared_ptr<Media::PixelMap> SetWatermarkImagePlugin::CreatePixelMapFromUint8(const uint8_t *data, size_t size,
327 int32_t width, int32_t height)
328 {
329 Media::InitializationOptions opt;
330 opt.size.width = width;
331 opt.size.height = height;
332 opt.editable = true;
333 auto pixelMap = Media::PixelMap::Create(opt);
334 if (pixelMap == nullptr) {
335 EDMLOGE("CreatePixelMapFromUint8 Create PixelMap error");
336 return nullptr;
337 }
338 uint32_t ret = pixelMap->WritePixels(data, size);
339 if (ret != ERR_OK) {
340 EDMLOGE("CreatePixelMapFromUint8 WritePixels error");
341 return nullptr;
342 }
343 return pixelMap;
344 }
345
SubscribeAppState()346 bool SetWatermarkImagePlugin::SubscribeAppState()
347 {
348 return IWatermarkObserverManager::GetInstance()->SubscribeAppStateObserver();
349 }
350
UnsubscribeAppState()351 bool SetWatermarkImagePlugin::UnsubscribeAppState()
352 {
353 return IWatermarkObserverManager::GetInstance()->UnSubscribeAppStateObserver();
354 }
355
GetAppManager()356 sptr<AppExecFwk::IAppMgr> SetWatermarkImagePlugin::GetAppManager()
357 {
358 auto sysAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
359 if (sysAbilityMgr == nullptr) {
360 EDMLOGE("GetRemoteObjectOfSystemAbility fail.");
361 return nullptr;
362 }
363 auto remoteObject = sysAbilityMgr->GetSystemAbility(APP_MGR_SERVICE_ID);
364 if (remoteObject == nullptr) {
365 EDMLOGE("GetSystemAbility fail.");
366 return nullptr;
367 }
368 return iface_cast<AppExecFwk::IAppMgr>(remoteObject);
369 }
370
OnAdminRemove(const std::string & adminName,const std::string & policyData,const std::string & mergeData,int32_t userId)371 ErrCode SetWatermarkImagePlugin::OnAdminRemove(const std::string &adminName, const std::string &policyData,
372 const std::string &mergeData, int32_t userId)
373 {
374 std::map<std::pair<std::string, int32_t>, WatermarkImageType> currentData;
375 auto serializer = WatermarkImageSerializer::GetInstance();
376 serializer->Deserialize(policyData, currentData);
377 for (auto it = currentData.begin(); it != currentData.end(); ++it) {
378 SetProcessWatermark(it->first.first, it->second.fileName, it->first.second, false);
379 if (!SetWatermarkToRS(it->second.fileName, nullptr)) {
380 EDMLOGE("SetWatermarkToRS fail");
381 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
382 }
383 }
384 if (mergeData.empty() && !UnsubscribeAppState()) {
385 EDMLOGE("SetWatermarkImagePlugin OnAdminRemove UnsubscribeAppState fail");
386 }
387 return ERR_OK;
388 }
389
GetOthersMergePolicyData(const std::string & adminName,int32_t userId,std::string & othersMergePolicyData)390 ErrCode SetWatermarkImagePlugin::GetOthersMergePolicyData(const std::string &adminName, int32_t userId,
391 std::string &othersMergePolicyData)
392 {
393 AdminValueItemsMap adminValues;
394 IPolicyManager::GetInstance()->GetAdminByPolicyName(GetPolicyName(), adminValues);
395 EDMLOGD("IPluginTemplate::GetOthersMergePolicyData %{public}s value size %{public}d.", GetPolicyName().c_str(),
396 (uint32_t)adminValues.size());
397 if (adminValues.empty()) {
398 return ERR_OK;
399 }
400 auto entry = adminValues.find(adminName);
401 if (entry != adminValues.end()) {
402 adminValues.erase(entry);
403 }
404 if (adminValues.empty()) {
405 return ERR_OK;
406 }
407 std::map<std::pair<std::string, int32_t>, WatermarkImageType> mergeData;
408 auto serializer = WatermarkImageSerializer::GetInstance();
409 for (const auto &item : adminValues) {
410 std::map<std::pair<std::string, int32_t>, WatermarkImageType> dataItem;
411 if (!item.second.empty()) {
412 if (!serializer->Deserialize(item.second, dataItem)) {
413 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
414 }
415 }
416 for (auto policy : dataItem) {
417 mergeData[policy.first] = policy.second;
418 }
419 }
420 if (!serializer->Serialize(mergeData, othersMergePolicyData)) {
421 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
422 }
423 return ERR_OK;
424 }
425
OnOtherServiceStart(int32_t systemAbilityId)426 void SetWatermarkImagePlugin::OnOtherServiceStart(int32_t systemAbilityId)
427 {
428 SetAllWatermarkImage();
429 }
430 } // namespace EDM
431 } // namespace OHOS
432