• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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> &currentData,
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> &currentData,
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 &param,
176     std::map<std::pair<std::string, int32_t>, WatermarkImageType> &currentData,
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 &param, 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