• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "devhost_service_full.h"
17 #include "dev_attribute_serialize.h"
18 #include "devmgr_service_clnt.h"
19 #include "hdf_base.h"
20 #include "hdf_device_info.h"
21 #include "hdf_device_node.h"
22 #include "hdf_log.h"
23 #include "osal_message.h"
24 #include "power_state_token.h"
25 
26 #define HDF_LOG_TAG devhost_service_full
27 
DevHostServiceFullDispatchMessage(struct HdfMessageTask * task,struct HdfMessage * msg)28 static int32_t DevHostServiceFullDispatchMessage(struct HdfMessageTask *task, struct HdfMessage *msg)
29 {
30     struct DevHostServiceFull *hostService =
31         HDF_SLIST_CONTAINER_OF(struct HdfMessageTask, task, struct DevHostServiceFull, task);
32 
33     int status = HDF_SUCCESS;
34     switch (msg->messageId) {
35         case DEVHOST_MESSAGE_ADD_DEVICE: {
36             struct HdfDeviceInfo *attribute = (struct HdfDeviceInfo *)msg->data[0];
37             status = DevHostServiceAddDevice(&hostService->super.super, attribute);
38             if (status != HDF_SUCCESS) {
39                 HDF_LOGE("DevHostServiceAddDevice failed and return %{public}d", status);
40             }
41             break;
42         }
43         case DEVHOST_MESSAGE_DEL_DEVICE: {
44             devid_t devid = (devid_t)((uintptr_t)msg->data[0]);
45             status = DevHostServiceDelDevice(&hostService->super.super, devid);
46             if (status != HDF_SUCCESS) {
47                 HDF_LOGE("DevHostServiceDelDevice failed and return %{public}d", status);
48             }
49             break;
50         }
51         default: {
52             HDF_LOGE("DevHostServiceFullDispatchMessage unknown message %{public}d", msg->messageId);
53             break;
54         }
55     }
56 
57     return status;
58 }
59 
DevHostServiceFullOpsDevice(struct IDevHostService * devHostService,uintptr_t parm,int cmdCode)60 static int DevHostServiceFullOpsDevice(struct IDevHostService *devHostService, uintptr_t parm, int cmdCode)
61 {
62     if (devHostService == NULL) {
63         HDF_LOGE("input is null");
64         return HDF_FAILURE;
65     }
66     struct DevHostServiceFull *inst = (struct DevHostServiceFull *)devHostService;
67     struct HdfMessageTask *task = &inst->task;
68     struct HdfMessage *message = HdfMessageObtain(0);
69     if (message == NULL) {
70         HDF_LOGE("HdfMessageObtain(0) return null");
71         return HDF_ERR_MALLOC_FAIL;
72     }
73 
74     message->messageId = cmdCode;
75     message->data[0] = (void *)parm;
76     return task->SendMessage(task, message, true);
77 }
78 
DevHostServiceFullAddDevice(struct IDevHostService * devHostService,const struct HdfDeviceInfo * attribute)79 static int DevHostServiceFullAddDevice(struct IDevHostService *devHostService, const struct HdfDeviceInfo *attribute)
80 {
81     return DevHostServiceFullOpsDevice(devHostService, (uintptr_t)attribute, DEVHOST_MESSAGE_ADD_DEVICE);
82 }
83 
DevHostServiceFullDelDevice(struct IDevHostService * devHostService,devid_t devid)84 static int DevHostServiceFullDelDevice(struct IDevHostService *devHostService, devid_t devid)
85 {
86     return DevHostServiceFullOpsDevice(devHostService, (uintptr_t)devid, DEVHOST_MESSAGE_DEL_DEVICE);
87 }
88 
DevHostServiceFullDispatchPowerState(struct HdfDevice * device,uint32_t state)89 static int DevHostServiceFullDispatchPowerState(struct HdfDevice *device, uint32_t state)
90 {
91     struct HdfDeviceNode *deviceNode = NULL;
92     int ret = HDF_SUCCESS;
93     int result = HDF_SUCCESS;
94 
95     if (IsPowerWakeState(state)) {
96         DLIST_FOR_EACH_ENTRY(deviceNode, &device->devNodes, struct HdfDeviceNode, entry) {
97             if (deviceNode->powerToken != NULL) {
98                 ret = PowerStateChange(deviceNode->powerToken, state);
99                 if (ret != HDF_SUCCESS) {
100                     HDF_LOGE("device %{public}s failed to resume(%{public}d) %{public}d",
101                         deviceNode->driver->entry->moduleName, state, ret);
102                     result = HDF_FAILURE;
103                 }
104             }
105         }
106     } else {
107         DLIST_FOR_EACH_ENTRY_REVERSE(deviceNode, &device->devNodes, struct HdfDeviceNode, entry) {
108             if (deviceNode->powerToken != NULL) {
109                 ret = PowerStateChange(deviceNode->powerToken, state);
110                 if (ret != HDF_SUCCESS) {
111                     HDF_LOGE("device %{public}s failed to suspend(%{public}d) %{public}d",
112                         deviceNode->driver->entry->moduleName, state, ret);
113                     result = HDF_FAILURE;
114                 }
115             }
116         }
117     }
118 
119     return result;
120 }
121 
SysEventToPowerState(uint32_t sysEvent)122 static uint32_t SysEventToPowerState(uint32_t sysEvent)
123 {
124     switch (sysEvent) {
125         case KEVENT_POWER_SUSPEND:
126             return POWER_STATE_SUSPEND;
127         case KEVENT_POWER_DISPLAY_OFF:
128             return POWER_STATE_DOZE_SUSPEND;
129         case KEVENT_POWER_RESUME:
130             return POWER_STATE_RESUME;
131         case KEVENT_POWER_DISPLAY_ON:
132             return POWER_STATE_DOZE_RESUME;
133         default:
134             return POWER_STATE_MAX;
135     }
136 }
137 
OnSysEventReceived(struct HdfSysEventNotifyNode * self,uint64_t eventClass,uint32_t event,const char * content)138 static int OnSysEventReceived(
139     struct HdfSysEventNotifyNode *self, uint64_t eventClass, uint32_t event, const char *content)
140 {
141     (void)(content);
142     if (self == NULL) {
143         return HDF_ERR_INVALID_PARAM;
144     }
145 
146     struct DevHostService *hostService = CONTAINER_OF(self, struct DevHostService, sysEventNotifyNode);
147     HDF_LOGI("host receive eventClass=%{public}llu, event=%{public}u", (unsigned long long)eventClass, event);
148     return hostService->super.PmNotify(&hostService->super, SysEventToPowerState(event));
149 }
150 
DevHostServiceFullStartService(struct IDevHostService * service)151 static int DevHostServiceFullStartService(struct IDevHostService *service)
152 {
153     struct DevHostService *hostService = (struct DevHostService *)service;
154     if (hostService == NULL) {
155         HDF_LOGE("Start device service failed, hostService is null");
156         return HDF_FAILURE;
157     }
158 
159     int ret = DevmgrServiceClntAttachDeviceHost(hostService->hostId, service);
160     if (ret != HDF_SUCCESS) {
161         HDF_LOGE("failed to start host service, attach host error %{public}d", ret);
162         return ret;
163     }
164 
165     hostService->sysEventNotifyNode.callback = OnSysEventReceived;
166     ret = HdfSysEventNotifyRegister(&hostService->sysEventNotifyNode, HDF_SYSEVENT_CLASS_POWER);
167     if (ret != HDF_SUCCESS) {
168         HDF_LOGW("failed to register power event listener");
169     } else {
170         HDF_LOGD("host register power event listener success");
171     }
172 
173     return HDF_SUCCESS;
174 }
175 
DevHostServiceFullPmNotify(struct IDevHostService * service,uint32_t state)176 int DevHostServiceFullPmNotify(struct IDevHostService *service, uint32_t state)
177 {
178     struct DevHostService *hostService = (struct DevHostService *)service;
179     int result = HDF_SUCCESS;
180 
181     if (hostService == NULL || !IsValidPowerState(state)) {
182         return HDF_ERR_INVALID_PARAM;
183     }
184 
185     struct HdfDevice *device = NULL;
186     if (IsPowerWakeState(state)) {
187         DLIST_FOR_EACH_ENTRY_REVERSE(device, &hostService->devices, struct HdfDevice, node) {
188             if (DevHostServiceFullDispatchPowerState(device, state) != HDF_SUCCESS) {
189                 result = HDF_FAILURE;
190             }
191         }
192     } else {
193         DLIST_FOR_EACH_ENTRY(device, &hostService->devices, struct HdfDevice, node) {
194             if (DevHostServiceFullDispatchPowerState(device, state)) {
195                 result = HDF_FAILURE;
196             }
197         }
198     }
199 
200     return result;
201 }
202 
DevHostServiceFullConstruct(struct DevHostServiceFull * inst)203 void DevHostServiceFullConstruct(struct DevHostServiceFull *inst)
204 {
205     struct IDevHostService *hostServiceIf = &inst->super.super;
206     static struct IHdfMessageHandler handler = {
207         .Dispatch = DevHostServiceFullDispatchMessage
208     };
209     DevHostServiceConstruct(&inst->super);
210     hostServiceIf->AddDevice = DevHostServiceFullAddDevice;
211     hostServiceIf->DelDevice = DevHostServiceFullDelDevice;
212     hostServiceIf->StartService = DevHostServiceFullStartService;
213     hostServiceIf->PmNotify = DevHostServiceFullPmNotify;
214     HdfMessageLooperConstruct(&inst->looper);
215     HdfMessageTaskConstruct(&inst->task, &inst->looper, &handler);
216 }
217 
DevHostServiceFullDestruct(struct DevHostServiceFull * inst)218 void DevHostServiceFullDestruct(struct DevHostServiceFull *inst)
219 {
220     if (inst != NULL) {
221         DevHostServiceDestruct(&inst->super);
222         if (inst->looper.Stop != NULL) {
223             inst->looper.Stop(&inst->looper);
224         }
225     }
226 }
227