1 /*
2  * Copyright (c) 2023 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 "emit_event_manager.h"
17 #include "ipc_skeleton.h"
18 #include <hdf_log.h>
19 #include "ipc_skeleton.h"
20 
21 #define HDF_LOG_TAG emit_event_manager
22 
23 namespace OHOS {
24 namespace ExternalDeviceManager {
25 constexpr uint16_t MAX_VIRTUAL_DEVICE_NUM = 200;
GetInstance(void)26 EmitEventManager& EmitEventManager::GetInstance(void)
27 {
28     static EmitEventManager instance;
29     return instance;
30 }
CreateDevice(const Hid_Device & hidDevice,const Hid_EventProperties & hidEventProperties)31 int32_t EmitEventManager::CreateDevice(const Hid_Device &hidDevice, const Hid_EventProperties &hidEventProperties)
32 {
33     std::lock_guard<std::mutex> lock(mutex_);
34     // check device number
35     if (virtualDeviceMap_.size() >= MAX_VIRTUAL_DEVICE_NUM) {
36         HDF_LOGE("%{public}s device num exceeds maximum %{public}d", __func__, MAX_VIRTUAL_DEVICE_NUM);
37         return HID_DDK_FAILURE;
38     }
39     // get device id
40     int32_t id = GetCurDeviceId();
41     if (id < 0) {
42         HDF_LOGE("%{public}s faild to generate device id", __func__);
43         return HID_DDK_FAILURE;
44     }
45 
46     uint32_t callingToken = IPCSkeleton::GetCallingTokenID();
47     HDF_LOGD("calling token of %{public}s : %{public}u", __func__, callingToken);
48 
49     // create device
50     virtualDeviceMap_[id] = std::make_unique<VirtualDeviceInject>(
51         std::make_shared<VirtualDevice>(hidDevice, hidEventProperties), callingToken);
52     return id;
53 }
54 
EmitEvent(uint32_t deviceId,const std::vector<Hid_EmitItem> & items)55 int32_t EmitEventManager::EmitEvent(uint32_t deviceId, const std::vector<Hid_EmitItem> &items)
56 {
57     std::lock_guard<std::mutex> lock(mutex_);
58     if (virtualDeviceMap_.count(deviceId) == 0) {
59         HDF_LOGE("%{public}s device is not exit", __func__);
60         return HID_DDK_FAILURE;
61     }
62 
63     if (virtualDeviceMap_[deviceId] == nullptr) {
64         HDF_LOGE("%{public}s VirtualDeviceInject is null", __func__);
65         return HID_DDK_NULL_PTR;
66     }
67     uint32_t callingToken = IPCSkeleton::GetCallingTokenID();
68     HDF_LOGD("calling token of %{public}s : %{public}u", __func__, callingToken);
69     if (virtualDeviceMap_[deviceId]->GetCreatorToken() != callingToken) {
70         HDF_LOGE("caller of %{public}s is invalid, callingToken:%{public}u", __func__, callingToken);
71         return HID_DDK_INVALID_OPERATION;
72     }
73 
74     virtualDeviceMap_[deviceId]->EmitEvent(items);
75     return HID_DDK_SUCCESS;
76 }
77 
DestroyDevice(uint32_t deviceId)78 int32_t EmitEventManager::DestroyDevice(uint32_t deviceId)
79 {
80     std::lock_guard<std::mutex> lock(mutex_);
81     if (virtualDeviceMap_.count(deviceId) == 0) {
82         HDF_LOGE("%{public}s device is not exit", __func__);
83         return HID_DDK_FAILURE;
84     }
85     uint32_t callingToken = IPCSkeleton::GetCallingTokenID();
86     HDF_LOGD("calling token of %{public}s : %{public}u", __func__, callingToken);
87     if (virtualDeviceMap_[deviceId] != nullptr
88         && virtualDeviceMap_[deviceId]->GetCreatorToken() != callingToken) {
89         HDF_LOGE("caller of %{public}s is invalid, callingToken:%{public}u", __func__, callingToken);
90         return HID_DDK_INVALID_OPERATION;
91     }
92     virtualDeviceMap_.erase(deviceId);
93     lastDeviceId_ = deviceId;
94     return HID_DDK_SUCCESS;
95 }
96 
GetCurDeviceId(void)97 int32_t EmitEventManager::GetCurDeviceId(void)
98 {
99     if (virtualDeviceMap_.count(lastDeviceId_) == 0) {
100         return lastDeviceId_;
101     }
102     uint32_t id = virtualDeviceMap_.size();
103     while (virtualDeviceMap_.count(id) != 0 && virtualDeviceMap_.size() < MAX_VIRTUAL_DEVICE_NUM) {
104         id++;
105     }
106     return virtualDeviceMap_.size() < MAX_VIRTUAL_DEVICE_NUM ? id : -1;
107 }
ClearDeviceMap(void)108 void EmitEventManager::ClearDeviceMap(void)
109 {
110     std::lock_guard<std::mutex> lock(mutex_);
111     if (virtualDeviceMap_.size() > 0) {
112         virtualDeviceMap_.clear();
113         HDF_LOGI("%{public}s: clear device map success", __func__);
114     }
115 }
116 } // namespace ExternalDeviceManager
117 } // namespace OHOS