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 "ipc_skeleton.h"
19 #include "input_uhdf_log.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 }
31 
CreateDevice(const Hid_Device &hidDevice, const Hid_EventProperties &hidEventProperties)32 int32_t EmitEventManager::CreateDevice(const Hid_Device &hidDevice, const Hid_EventProperties &hidEventProperties)
33 {
34     std::lock_guard<std::mutex> lock(mutex_);
35     // check device number
36     if (virtualDeviceMap_.size() >= MAX_VIRTUAL_DEVICE_NUM) {
37         HDF_LOGE("%{public}s device num exceeds maximum %{public}d", __func__, MAX_VIRTUAL_DEVICE_NUM);
38         return HID_DDK_FAILURE;
39     }
40     // get device id
41     int32_t id = 0;
42     if (!GetCurDeviceId(id)) {
43         HDF_LOGE("%{public}s faild to generate device id", __func__);
44         return HID_DDK_FAILURE;
45     }
46 
47     uint32_t callingToken = IPCSkeleton::GetCallingTokenID();
48     // create device
49     virtualDeviceMap_[id] = std::make_unique<VirtualDeviceInject>(
50         std::make_shared<VirtualDevice>(hidDevice, hidEventProperties), callingToken);
51     return id;
52 }
53 
EmitEvent(uint32_t deviceId, const std::vector<Hid_EmitItem> &items)54 int32_t EmitEventManager::EmitEvent(uint32_t deviceId, const std::vector<Hid_EmitItem> &items)
55 {
56     std::lock_guard<std::mutex> lock(mutex_);
57     if (virtualDeviceMap_.count(deviceId) == 0) {
58         HDF_LOGE("%{public}s device is not exit", __func__);
59         return HID_DDK_FAILURE;
60     }
61 
62     if (virtualDeviceMap_[deviceId] == nullptr) {
63         HDF_LOGE("%{public}s VirtualDeviceInject is null", __func__);
64         return HID_DDK_NULL_PTR;
65     }
66 
67     uint32_t callingToken = IPCSkeleton::GetCallingTokenID();
68     if (virtualDeviceMap_[deviceId]->GetCreatorToken() != callingToken) {
69         HDF_LOGE("caller of %{public}s is invalid", __func__);
70         return HID_DDK_INVALID_OPERATION;
71     }
72 
73     virtualDeviceMap_[deviceId]->EmitEvent(items);
74     return HID_DDK_SUCCESS;
75 }
76 
DestroyDevice(uint32_t deviceId)77 int32_t EmitEventManager::DestroyDevice(uint32_t deviceId)
78 {
79     std::lock_guard<std::mutex> lock(mutex_);
80     if (virtualDeviceMap_.count(deviceId) == 0) {
81         HDF_LOGE("%{public}s device is not exit", __func__);
82         return HID_DDK_FAILURE;
83     }
84 
85     uint32_t callingToken = IPCSkeleton::GetCallingTokenID();
86     if (virtualDeviceMap_[deviceId] != nullptr
87         && virtualDeviceMap_[deviceId]->GetCreatorToken() != callingToken) {
88         HDF_LOGE("caller of %{public}s is invalid", __func__);
89         return HID_DDK_INVALID_OPERATION;
90     }
91     virtualDeviceMap_.erase(deviceId);
92     lastDeviceId_ = deviceId;
93     return HID_DDK_SUCCESS;
94 }
95 
GetCurDeviceId(int32_t &id)96 bool EmitEventManager::GetCurDeviceId(int32_t &id)
97 {
98     if (virtualDeviceMap_.size() >= MAX_VIRTUAL_DEVICE_NUM) {
99         HDF_LOGE("%{public}s: The number of devices has reached max_num", __func__);
100         id = -1;
101         return false;
102     }
103     if (virtualDeviceMap_.count(lastDeviceId_) == 0) {
104         id = static_cast<int32_t>(lastDeviceId_);
105         return true;
106     }
107     uint32_t newId = virtualDeviceMap_.size();
108     while (virtualDeviceMap_.count(newId) != 0) {
109         newId++;
110     }
111     id = static_cast<int32_t>(newId);
112     return true;
113 }
114 
ClearDeviceMap(void)115 void EmitEventManager::ClearDeviceMap(void)
116 {
117     std::lock_guard<std::mutex> lock(mutex_);
118     if (virtualDeviceMap_.size() > 0) {
119         virtualDeviceMap_.clear();
120         HDF_LOGI("%{public}s: clear device map success", __func__);
121     }
122 }
123 } // namespace ExternalDeviceManager
124 } // namespace OHOS