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 "allocator_proxy.h"
17 #include <message_parcel.h>
18 #include "buffer_handle_parcel.h"
19 #include "iremote_object.h"
20 #include "iservmgr_hdi.h"
21 #include "parcel_utils.h"
22 #include "unistd.h"
23 #include "refbase.h"
24 
25 #define HDF_LOG_TAG HDI_DISP_PROXY
26 
27 namespace OHOS {
28 namespace HDI {
29 namespace Display {
30 namespace V1_0 {
Get(const char * serviceName)31 sptr<IDisplayAllocator> IDisplayAllocator::Get(const char *serviceName)
32 {
33     constexpr uint32_t sleepTime = 10000;
34     constexpr uint32_t waitSvcTimeout = 1000;
35     constexpr uint32_t waitSvcMgrTimeout = 10;
36     constexpr uint32_t printPeriod = 100;
37     using namespace OHOS::HDI::ServiceManager::V1_0;
38 
39     static sptr<IServiceManager> servMgr = IServiceManager::Get();
40     uint32_t cnt = 0;
41     while (servMgr == nullptr) {
42         if (cnt > waitSvcMgrTimeout) {
43             HDF_LOGE("%{public}s: wait IServiceManager timeout cnt:%{public}u", __func__, cnt);
44             return nullptr;
45         }
46         usleep(sleepTime);  // 10 ms
47         servMgr = IServiceManager::Get();
48         cnt++;
49         HDF_LOGI("%{public}s: IServiceManager cnt:%{public}u", __func__, cnt);
50     }
51     HDF_LOGI("%{public}s: get IServiceManager success cnt:%{public}u", __func__, cnt);
52 
53     cnt = 0;
54     sptr<IRemoteObject> remote = servMgr->GetService(serviceName);
55     while (remote == nullptr) {
56         if (cnt > waitSvcTimeout) {
57             HDF_LOGE("%{public}s: wait service:%{public}s timeout cnt:%{public}u", __func__, serviceName, cnt);
58             return nullptr;
59         }
60         usleep(sleepTime);  // 10 ms
61         remote = servMgr->GetService(serviceName);
62         if (((cnt++) % printPeriod) == 0) {
63             HDF_LOGI("%{public}s: get service:%{public}s cnt:%{public}u", __func__, serviceName, cnt);
64         }
65     }
66     HDF_LOGI("%{public}s: get service:%{public}s success cnt:%{public}u", __func__, serviceName, cnt);
67 
68     sptr<AllocatorProxy> hostSptr = iface_cast<AllocatorProxy>(remote);
69     if (hostSptr == nullptr) {
70         HDF_LOGE("%{public}s: IServiceManager GetService null ptr", __func__);
71         return nullptr;
72     }
73     HDF_LOGE("%{public}s: GetService %{public}s ok", __func__, serviceName);
74     return hostSptr;
75 }
76 
AllocMem(const AllocInfo & info,BufferHandle * & handle)77 int32_t AllocatorProxy::AllocMem(const AllocInfo &info, BufferHandle *&handle)
78 {
79     MessageParcel data;
80     MessageParcel reply;
81     MessageOption option;
82     if (!data.WriteInterfaceToken(AllocatorProxy::GetDescriptor())) {
83         return HDF_FAILURE;
84     }
85     auto ret = ParcelUtils::PackAllocInfo(data, &info);
86     if (ret != DISPLAY_SUCCESS) {
87         return ret;
88     }
89     int32_t retCode = Remote()->SendRequest(CMD_REMOTE_ALLOCATOR_ALLOCMEM, data, reply, option);
90     if (retCode != HDF_SUCCESS) {
91         HDF_LOGE("%{public}s: SendRequest failed, error code is %{public}x", __func__, retCode);
92         return retCode;
93     }
94 
95     retCode = reply.ReadInt32();
96     if (retCode != HDF_SUCCESS) {
97         HDF_LOGE("%{public}s: Read return code failed, error code is %{public}x", __func__, retCode);
98         return retCode;
99     }
100 
101     auto retHandle = ReadBufferHandle(reply);
102     if (retHandle != nullptr) {
103         handle = retHandle;
104         retCode = DISPLAY_SUCCESS;
105     } else {
106         retCode = DISPLAY_NULL_PTR;
107     }
108     return retCode;
109 }
110 } // namespace V1_0
111 } // namespace Display
112 } // namespace HDI
113 } // namespace OHOS
114