• 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 "dbinder_service_stub.h"
17 
18 #include <cinttypes>
19 #include "sys_binder.h"
20 #include "string_ex.h"
21 #include "dbinder_log.h"
22 #include "dbinder_service.h"
23 #include "dbinder_death_recipient.h"
24 #include "ipc_skeleton.h"
25 
26 namespace OHOS {
DBinderServiceStub(const std::string & service,const std::string & device,binder_uintptr_t object)27 DBinderServiceStub::DBinderServiceStub(const std::string &service, const std::string &device, binder_uintptr_t object)
28     : IPCObjectStub(Str8ToStr16(device + service)), serviceName_(service), deviceID_(device), binderObject_(object)
29 {
30     DBINDER_LOGI("new DBinderServiceStub created");
31 }
32 
~DBinderServiceStub()33 DBinderServiceStub::~DBinderServiceStub()
34 {
35     DBINDER_LOGI("DBinderServiceStub delete");
36 }
37 
GetServiceName()38 const std::string &DBinderServiceStub::GetServiceName()
39 {
40     return serviceName_;
41 }
42 
GetDeviceID()43 const std::string &DBinderServiceStub::GetDeviceID()
44 {
45     return deviceID_;
46 }
47 
GetBinderObject() const48 binder_uintptr_t DBinderServiceStub::GetBinderObject() const
49 {
50     return binderObject_;
51 }
52 
ProcessProto(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)53 int32_t DBinderServiceStub::ProcessProto(uint32_t code, MessageParcel &data, MessageParcel &reply,
54     MessageOption &option)
55 {
56     int result = ERR_NONE;
57     sptr<DBinderService> dBinderService = DBinderService::GetInstance();
58     if (dBinderService == nullptr) {
59         DBINDER_LOGE("DBinderService is nullptr");
60         return DBINDER_SERVICE_PROCESS_PROTO_ERR;
61     }
62     auto session = dBinderService->QuerySessionObject(reinterpret_cast<binder_uintptr_t>(this));
63     if (session == nullptr) {
64         DBINDER_LOGE("client find session is null");
65         return DBINDER_SERVICE_PROCESS_PROTO_ERR;
66     }
67 
68     DBINDER_LOGI("stubIndex = %" PRIu64 ", socketFd = %" PRIu32 "", session->stubIndex, session->socketFd);
69     DBINDER_LOGI("serviceName = %s", session->serviceName.c_str());
70 
71     int uid = IPCSkeleton::GetCallingUid();
72     int pid = IPCSkeleton::GetCallingPid();
73     if (uid < 0 || pid < 0) {
74         DBINDER_LOGE("uid or pid err");
75         return DBINDER_SERVICE_PROCESS_PROTO_ERR;
76     }
77 
78     std::string localBusName = dBinderService->CreateDatabusName(uid, pid);
79     if (localBusName.empty()) {
80         DBINDER_LOGE("local busname nil");
81         return DBINDER_SERVICE_PROCESS_PROTO_ERR;
82     }
83 
84     switch (session->type) {
85         case IRemoteObject::DATABUS_TYPE: {
86             if (!reply.WriteUint32(IRemoteObject::IF_PROT_DATABUS) || !reply.WriteUint64(session->stubIndex) ||
87                 !reply.WriteString(session->serviceName) || !reply.WriteString(session->deviceIdInfo.toDeviceId) ||
88                 !reply.WriteString(session->deviceIdInfo.fromDeviceId) || !reply.WriteString(localBusName)) {
89                 DBINDER_LOGE("write to parcel fail");
90                 return DBINDER_SERVICE_PROCESS_PROTO_ERR;
91             }
92             break;
93         }
94         default: {
95             DBINDER_LOGE("Invalid Type");
96             return DBINDER_SERVICE_PROCESS_PROTO_ERR;
97         }
98     }
99 
100     return result;
101 }
102 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)103 int32_t DBinderServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
104     MessageOption &option)
105 {
106     int32_t result = ERR_NONE;
107     switch (code) {
108         case GET_PROTO_INFO: {
109             result = ProcessProto(code, data, reply, option);
110             break;
111         }
112         case DBINDER_OBITUARY_TRANSACTION: {
113             result = ProcessDeathRecipient(data, reply);
114             break;
115         }
116         default: {
117             DBINDER_LOGI("unknown code = %{public}u", code);
118             result = DBINDER_SERVICE_UNKNOW_TRANS_ERR;
119             break;
120         }
121     }
122 
123     return result;
124 }
125 
ProcessDeathRecipient(MessageParcel & data,MessageParcel & reply)126 int32_t DBinderServiceStub::ProcessDeathRecipient(MessageParcel &data, MessageParcel &reply)
127 {
128     int32_t processType = data.ReadInt32();
129     if (processType == IRemoteObject::DeathRecipient::ADD_DEATH_RECIPIENT) {
130         return AddDbinderDeathRecipient(data, reply);
131     }
132 
133     if (processType == IRemoteObject::DeathRecipient::REMOVE_DEATH_RECIPIENT) {
134         return RemoveDbinderDeathRecipient(data, reply);
135     }
136 
137     return DBINDER_SERVICE_UNKNOW_TRANS_ERR;
138 }
139 
AddDbinderDeathRecipient(MessageParcel & data,MessageParcel & reply)140 int32_t DBinderServiceStub::AddDbinderDeathRecipient(MessageParcel &data, MessageParcel &reply)
141 {
142     sptr<IRemoteObject> object = data.ReadRemoteObject();
143     if (object == nullptr) {
144         DBINDER_LOGE("received proxy is null");
145         return DBINDER_SERVICE_INVALID_DATA_ERR;
146     }
147 
148     IPCObjectProxy *callbackProxy = reinterpret_cast<IPCObjectProxy *>(object.GetRefPtr());
149     sptr<IRemoteObject::DeathRecipient> death(new DbinderDeathRecipient());
150 
151     // If the client dies, notify DBS to delete information of callbackProxy
152     if (!callbackProxy->AddDeathRecipient(death)) {
153         DBINDER_LOGE("fail to add death recipient");
154         return DBINDER_SERVICE_ADD_DEATH_ERR;
155     }
156 
157     sptr<DBinderService> dBinderService = DBinderService::GetInstance();
158     if (dBinderService == nullptr) {
159         DBINDER_LOGE("dBinder service is null");
160         return DBINDER_SERVICE_ADD_DEATH_ERR;
161     }
162 
163     if (!dBinderService->AttachDeathRecipient(object, death)) {
164         DBINDER_LOGE("fail to attach death recipient");
165         return DBINDER_SERVICE_ADD_DEATH_ERR;
166     }
167 
168     if (!dBinderService->AttachCallbackProxy(object, this)) {
169         DBINDER_LOGE("fail to attach callback proxy");
170         return DBINDER_SERVICE_ADD_DEATH_ERR;
171     }
172 
173     return ERR_NONE;
174 }
175 
RemoveDbinderDeathRecipient(MessageParcel & data,MessageParcel & reply)176 int32_t DBinderServiceStub::RemoveDbinderDeathRecipient(MessageParcel &data, MessageParcel &reply)
177 {
178     sptr<IRemoteObject> object = data.ReadRemoteObject();
179     if (object == nullptr) {
180         DBINDER_LOGE("received proxy is null");
181         return DBINDER_SERVICE_REMOVE_DEATH_ERR;
182     }
183 
184     IPCObjectProxy *callbackProxy = reinterpret_cast<IPCObjectProxy *>(object.GetRefPtr());
185 
186     sptr<DBinderService> dBinderService = DBinderService::GetInstance();
187     if (dBinderService == nullptr) {
188         DBINDER_LOGE("dBinder service is null");
189         return DBINDER_SERVICE_REMOVE_DEATH_ERR;
190     }
191 
192     sptr<IRemoteObject::DeathRecipient> death = dBinderService->QueryDeathRecipient(object);
193     if (death != nullptr) {
194         // Continue to clear subsequent data
195         callbackProxy->RemoveDeathRecipient(death);
196     }
197 
198     if (!dBinderService->DetachDeathRecipient(object)) {
199         DBINDER_LOGE("fail to detach death recipient");
200         return DBINDER_SERVICE_REMOVE_DEATH_ERR;
201     }
202 
203     if (!dBinderService->DetachCallbackProxy(object)) {
204         DBINDER_LOGE("fail to detach callback proxy");
205         return DBINDER_SERVICE_REMOVE_DEATH_ERR;
206     }
207 
208     return ERR_NONE;
209 }
210 } // namespace OHOS
211