blob: ae1f7a5112d971512e002d5ed8b901e951403812 [file] [log] [blame]
hkuang26587cb2020-01-16 10:36:08 -08001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// #define LOG_NDEBUG 0
18#define LOG_TAG "TranscodingClientManager"
19
Chong Zhang8e062632020-03-31 10:56:37 -070020#include <aidl/android/media/BnTranscodingClient.h>
Chong Zhang15c192a2020-05-05 16:24:00 -070021#include <aidl/android/media/IMediaTranscodingService.h>
Chong Zhang8e062632020-03-31 10:56:37 -070022#include <android/binder_ibinder.h>
hkuang9c04b8d2020-01-22 10:03:21 -080023#include <inttypes.h>
hkuang26587cb2020-01-16 10:36:08 -080024#include <media/TranscodingClientManager.h>
Chong Zhang6d58e4b2020-03-31 09:41:10 -070025#include <media/TranscodingRequest.h>
Chong Zhangc37bdfe2020-10-06 13:54:09 -070026#include <media/TranscodingUidPolicy.h>
Chong Zhang3f23e982020-09-24 14:03:41 -070027#include <private/android_filesystem_config.h>
hkuang26587cb2020-01-16 10:36:08 -080028#include <utils/Log.h>
Chong Zhangc37bdfe2020-10-06 13:54:09 -070029#include <utils/String16.h>
hkuang26587cb2020-01-16 10:36:08 -080030namespace android {
31
Chong Zhang15c192a2020-05-05 16:24:00 -070032static_assert(sizeof(ClientIdType) == sizeof(void*), "ClientIdType should be pointer-sized");
33
Chong Zhang3fea2862020-10-21 08:46:03 -070034static constexpr const char* MEDIA_PROVIDER_PKG_NAMES[] = {
35 "com.android.providers.media.module",
36 "com.google.android.providers.media.module",
37};
Chong Zhangc37bdfe2020-10-06 13:54:09 -070038
Chong Zhang8e062632020-03-31 10:56:37 -070039using ::aidl::android::media::BnTranscodingClient;
Chong Zhang15c192a2020-05-05 16:24:00 -070040using ::aidl::android::media::IMediaTranscodingService; // For service error codes
Chong Zhang8e062632020-03-31 10:56:37 -070041using ::aidl::android::media::TranscodingRequestParcel;
Chong Zhangbc062482020-10-14 16:43:53 -070042using ::aidl::android::media::TranscodingSessionParcel;
hkuang26587cb2020-01-16 10:36:08 -080043using Status = ::ndk::ScopedAStatus;
Chong Zhang8e062632020-03-31 10:56:37 -070044using ::ndk::SpAIBinder;
45
Chong Zhang3fa408f2020-04-30 11:04:28 -070046//static
47std::atomic<ClientIdType> TranscodingClientManager::sCookieCounter = 0;
48//static
49std::mutex TranscodingClientManager::sCookie2ClientLock;
50//static
51std::map<ClientIdType, std::shared_ptr<TranscodingClientManager::ClientImpl>>
52 TranscodingClientManager::sCookie2Client;
Chong Zhang8e062632020-03-31 10:56:37 -070053///////////////////////////////////////////////////////////////////////////////
54
Chong Zhang3f23e982020-09-24 14:03:41 -070055// Convenience methods for constructing binder::Status objects for error returns
56#define STATUS_ERROR_FMT(errorCode, errorString, ...) \
57 Status::fromServiceSpecificErrorWithMessage( \
58 errorCode, \
59 String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, ##__VA_ARGS__))
60
Chong Zhang8e062632020-03-31 10:56:37 -070061/**
62 * ClientImpl implements a single client and contains all its information.
63 */
64struct TranscodingClientManager::ClientImpl : public BnTranscodingClient {
Chong Zhang6d58e4b2020-03-31 09:41:10 -070065 /* The remote client callback that this ClientInfo is associated with.
Chong Zhang8e062632020-03-31 10:56:37 -070066 * Once the ClientInfo is created, we hold an SpAIBinder so that the binder
67 * object doesn't get created again, otherwise the binder object pointer
68 * may not be unique.
69 */
Chong Zhangacb33502020-04-20 11:04:48 -070070 SpAIBinder mClientBinder;
71 std::shared_ptr<ITranscodingClientCallback> mClientCallback;
Chong Zhang8e062632020-03-31 10:56:37 -070072 /* A unique id assigned to the client by the service. This number is used
73 * by the service for indexing. Here we use the binder object's pointer
74 * (casted to int64t_t) as the client id.
75 */
76 ClientIdType mClientId;
Chong Zhang8e062632020-03-31 10:56:37 -070077 std::string mClientName;
78 std::string mClientOpPackageName;
Chong Zhang6d58e4b2020-03-31 09:41:10 -070079
Chong Zhangbc062482020-10-14 16:43:53 -070080 // Next sessionId to assign.
81 std::atomic<int32_t> mNextSessionId;
Chong Zhang15c192a2020-05-05 16:24:00 -070082 // Whether this client has been unregistered already.
83 std::atomic<bool> mAbandoned;
84 // Weak pointer to the client manager for this client.
85 std::weak_ptr<TranscodingClientManager> mOwner;
Chong Zhang8e062632020-03-31 10:56:37 -070086
Chong Zhang3f23e982020-09-24 14:03:41 -070087 ClientImpl(const std::shared_ptr<ITranscodingClientCallback>& callback,
hkuang08b38d02020-04-17 14:29:33 -070088 const std::string& clientName, const std::string& opPackageName,
Chong Zhang15c192a2020-05-05 16:24:00 -070089 const std::weak_ptr<TranscodingClientManager>& owner);
Chong Zhang8e062632020-03-31 10:56:37 -070090
91 Status submitRequest(const TranscodingRequestParcel& /*in_request*/,
Chong Zhangbc062482020-10-14 16:43:53 -070092 TranscodingSessionParcel* /*out_session*/,
93 bool* /*_aidl_return*/) override;
Chong Zhang8e062632020-03-31 10:56:37 -070094
Chong Zhangbc062482020-10-14 16:43:53 -070095 Status cancelSession(int32_t /*in_sessionId*/, bool* /*_aidl_return*/) override;
Chong Zhang8e062632020-03-31 10:56:37 -070096
Chong Zhangbc062482020-10-14 16:43:53 -070097 Status getSessionWithId(int32_t /*in_sessionId*/, TranscodingSessionParcel* /*out_session*/,
98 bool* /*_aidl_return*/) override;
Chong Zhang8e062632020-03-31 10:56:37 -070099
100 Status unregister() override;
101};
102
103TranscodingClientManager::ClientImpl::ClientImpl(
Chong Zhang3f23e982020-09-24 14:03:41 -0700104 const std::shared_ptr<ITranscodingClientCallback>& callback, const std::string& clientName,
105 const std::string& opPackageName, const std::weak_ptr<TranscodingClientManager>& owner)
Chong Zhangacb33502020-04-20 11:04:48 -0700106 : mClientBinder((callback != nullptr) ? callback->asBinder() : nullptr),
107 mClientCallback(callback),
Chong Zhang3fa408f2020-04-30 11:04:28 -0700108 mClientId(sCookieCounter.fetch_add(1, std::memory_order_relaxed)),
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700109 mClientName(clientName),
110 mClientOpPackageName(opPackageName),
Chong Zhangbc062482020-10-14 16:43:53 -0700111 mNextSessionId(0),
Chong Zhang15c192a2020-05-05 16:24:00 -0700112 mAbandoned(false),
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700113 mOwner(owner) {}
Chong Zhang8e062632020-03-31 10:56:37 -0700114
115Status TranscodingClientManager::ClientImpl::submitRequest(
Chong Zhangbc062482020-10-14 16:43:53 -0700116 const TranscodingRequestParcel& in_request, TranscodingSessionParcel* out_session,
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700117 bool* _aidl_return) {
Chong Zhang15c192a2020-05-05 16:24:00 -0700118 *_aidl_return = false;
119
120 std::shared_ptr<TranscodingClientManager> owner;
121 if (mAbandoned || (owner = mOwner.lock()) == nullptr) {
122 return Status::fromServiceSpecificError(IMediaTranscodingService::ERROR_DISCONNECTED);
123 }
124
hkuang72d105f2020-05-21 10:48:55 -0700125 if (in_request.sourceFilePath.empty() || in_request.destinationFilePath.empty()) {
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700126 return Status::ok();
127 }
128
Chong Zhang3f23e982020-09-24 14:03:41 -0700129 int32_t callingPid = AIBinder_getCallingPid();
130 int32_t callingUid = AIBinder_getCallingUid();
131 int32_t in_clientUid = in_request.clientUid;
132 int32_t in_clientPid = in_request.clientPid;
133
134 // Check if we can trust clientUid. Only privilege caller could forward the
135 // uid on app client's behalf.
136 if (in_clientUid == IMediaTranscodingService::USE_CALLING_UID) {
137 in_clientUid = callingUid;
138 } else if (in_clientUid < 0) {
139 return Status::ok();
Chong Zhangc37bdfe2020-10-06 13:54:09 -0700140 } else if (in_clientUid != callingUid && !owner->isTrustedCallingUid(callingUid)) {
Chong Zhang3f23e982020-09-24 14:03:41 -0700141 ALOGE("MediaTranscodingService::registerClient rejected (clientPid %d, clientUid %d) "
142 "(don't trust callingUid %d)",
143 in_clientPid, in_clientUid, callingUid);
144 return STATUS_ERROR_FMT(
145 IMediaTranscodingService::ERROR_PERMISSION_DENIED,
146 "MediaTranscodingService::registerClient rejected (clientPid %d, clientUid %d) "
147 "(don't trust callingUid %d)",
148 in_clientPid, in_clientUid, callingUid);
149 }
150
151 // Check if we can trust clientPid. Only privilege caller could forward the
152 // pid on app client's behalf.
153 if (in_clientPid == IMediaTranscodingService::USE_CALLING_PID) {
154 in_clientPid = callingPid;
155 } else if (in_clientPid < 0) {
156 return Status::ok();
Chong Zhangc37bdfe2020-10-06 13:54:09 -0700157 } else if (in_clientPid != callingPid && !owner->isTrustedCallingUid(callingUid)) {
Chong Zhang3f23e982020-09-24 14:03:41 -0700158 ALOGE("MediaTranscodingService::registerClient rejected (clientPid %d, clientUid %d) "
159 "(don't trust callingUid %d)",
160 in_clientPid, in_clientUid, callingUid);
161 return STATUS_ERROR_FMT(
162 IMediaTranscodingService::ERROR_PERMISSION_DENIED,
163 "MediaTranscodingService::registerClient rejected (clientPid %d, clientUid %d) "
164 "(don't trust callingUid %d)",
165 in_clientPid, in_clientUid, callingUid);
166 }
167
Chong Zhangbc062482020-10-14 16:43:53 -0700168 int32_t sessionId = mNextSessionId.fetch_add(1);
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700169
Chong Zhangbc062482020-10-14 16:43:53 -0700170 *_aidl_return = owner->mSessionController->submit(mClientId, sessionId, in_clientUid,
171 in_request, mClientCallback);
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700172
173 if (*_aidl_return) {
Chong Zhangbc062482020-10-14 16:43:53 -0700174 out_session->sessionId = sessionId;
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700175
Chong Zhangbc062482020-10-14 16:43:53 -0700176 // TODO(chz): is some of this coming from SessionController?
177 *(TranscodingRequest*)&out_session->request = in_request;
178 out_session->awaitNumberOfSessions = 0;
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700179 }
Chong Zhang15c192a2020-05-05 16:24:00 -0700180
Chong Zhang8e062632020-03-31 10:56:37 -0700181 return Status::ok();
182}
183
Chong Zhangbc062482020-10-14 16:43:53 -0700184Status TranscodingClientManager::ClientImpl::cancelSession(int32_t in_sessionId,
185 bool* _aidl_return) {
Chong Zhang15c192a2020-05-05 16:24:00 -0700186 *_aidl_return = false;
187
188 std::shared_ptr<TranscodingClientManager> owner;
189 if (mAbandoned || (owner = mOwner.lock()) == nullptr) {
190 return Status::fromServiceSpecificError(IMediaTranscodingService::ERROR_DISCONNECTED);
191 }
192
Chong Zhangbc062482020-10-14 16:43:53 -0700193 if (in_sessionId < 0) {
Chong Zhang15c192a2020-05-05 16:24:00 -0700194 return Status::ok();
195 }
196
Chong Zhangbc062482020-10-14 16:43:53 -0700197 *_aidl_return = owner->mSessionController->cancel(mClientId, in_sessionId);
Chong Zhang8e062632020-03-31 10:56:37 -0700198 return Status::ok();
199}
200
Chong Zhangbc062482020-10-14 16:43:53 -0700201Status TranscodingClientManager::ClientImpl::getSessionWithId(int32_t in_sessionId,
202 TranscodingSessionParcel* out_session,
203 bool* _aidl_return) {
Chong Zhang15c192a2020-05-05 16:24:00 -0700204 *_aidl_return = false;
205
206 std::shared_ptr<TranscodingClientManager> owner;
207 if (mAbandoned || (owner = mOwner.lock()) == nullptr) {
208 return Status::fromServiceSpecificError(IMediaTranscodingService::ERROR_DISCONNECTED);
209 }
210
Chong Zhangbc062482020-10-14 16:43:53 -0700211 if (in_sessionId < 0) {
Chong Zhang15c192a2020-05-05 16:24:00 -0700212 return Status::ok();
213 }
214
Chong Zhangbc062482020-10-14 16:43:53 -0700215 *_aidl_return =
216 owner->mSessionController->getSession(mClientId, in_sessionId, &out_session->request);
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700217
218 if (*_aidl_return) {
Chong Zhangbc062482020-10-14 16:43:53 -0700219 out_session->sessionId = in_sessionId;
220 out_session->awaitNumberOfSessions = 0;
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700221 }
Chong Zhang8e062632020-03-31 10:56:37 -0700222 return Status::ok();
223}
224
225Status TranscodingClientManager::ClientImpl::unregister() {
Chong Zhang15c192a2020-05-05 16:24:00 -0700226 bool abandoned = mAbandoned.exchange(true);
227
228 std::shared_ptr<TranscodingClientManager> owner;
229 if (abandoned || (owner = mOwner.lock()) == nullptr) {
230 return Status::fromServiceSpecificError(IMediaTranscodingService::ERROR_DISCONNECTED);
231 }
232
Chong Zhangbc062482020-10-14 16:43:53 -0700233 // Use sessionId == -1 to cancel all realtime sessions for this client with the controller.
234 owner->mSessionController->cancel(mClientId, -1);
Chong Zhang15c192a2020-05-05 16:24:00 -0700235 owner->removeClient(mClientId);
236
Chong Zhang8e062632020-03-31 10:56:37 -0700237 return Status::ok();
238}
239
240///////////////////////////////////////////////////////////////////////////////
hkuang26587cb2020-01-16 10:36:08 -0800241
242// static
hkuang9c04b8d2020-01-22 10:03:21 -0800243void TranscodingClientManager::BinderDiedCallback(void* cookie) {
Chong Zhang3fa408f2020-04-30 11:04:28 -0700244 ClientIdType clientId = reinterpret_cast<ClientIdType>(cookie);
245
246 ALOGD("Client %lld is dead", (long long)clientId);
247
248 std::shared_ptr<ClientImpl> client;
249
250 {
251 std::scoped_lock lock{sCookie2ClientLock};
252
253 auto it = sCookie2Client.find(clientId);
254 if (it != sCookie2Client.end()) {
255 client = it->second;
256 }
257 }
258
259 if (client != nullptr) {
260 client->unregister();
261 }
hkuang9c04b8d2020-01-22 10:03:21 -0800262}
263
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700264TranscodingClientManager::TranscodingClientManager(
Chong Zhangbc062482020-10-14 16:43:53 -0700265 const std::shared_ptr<ControllerClientInterface>& controller)
Chong Zhangc37bdfe2020-10-06 13:54:09 -0700266 : mDeathRecipient(AIBinder_DeathRecipient_new(BinderDiedCallback)),
Chong Zhang3fea2862020-10-21 08:46:03 -0700267 mSessionController(controller) {
hkuang26587cb2020-01-16 10:36:08 -0800268 ALOGD("TranscodingClientManager started");
Chong Zhangc37bdfe2020-10-06 13:54:09 -0700269 uid_t mpuid;
Chong Zhang3fea2862020-10-21 08:46:03 -0700270 for (const char* pkgName : MEDIA_PROVIDER_PKG_NAMES) {
271 if (TranscodingUidPolicy::getUidForPackage(String16(pkgName), mpuid) == NO_ERROR) {
272 ALOGI("Found %s's uid: %d", pkgName, mpuid);
273 mMediaProviderUid.insert(mpuid);
274 } else {
275 ALOGW("Couldn't get uid for %s.", pkgName);
276 }
Chong Zhangc37bdfe2020-10-06 13:54:09 -0700277 }
hkuang26587cb2020-01-16 10:36:08 -0800278}
279
280TranscodingClientManager::~TranscodingClientManager() {
281 ALOGD("TranscodingClientManager exited");
282}
283
hkuang26587cb2020-01-16 10:36:08 -0800284void TranscodingClientManager::dumpAllClients(int fd, const Vector<String16>& args __unused) {
285 String8 result;
286
287 const size_t SIZE = 256;
288 char buffer[SIZE];
hkuang08b38d02020-04-17 14:29:33 -0700289 std::scoped_lock lock{mLock};
hkuang26587cb2020-01-16 10:36:08 -0800290
Chong Zhang8e062632020-03-31 10:56:37 -0700291 if (mClientIdToClientMap.size() > 0) {
Chong Zhang0579c6f2020-10-05 12:03:34 -0700292 snprintf(buffer, SIZE, "\n========== Dumping all clients =========\n");
hkuang26587cb2020-01-16 10:36:08 -0800293 result.append(buffer);
294 }
295
Chong Zhang0579c6f2020-10-05 12:03:34 -0700296 snprintf(buffer, SIZE, " Total num of Clients: %zu\n", mClientIdToClientMap.size());
297 result.append(buffer);
298
Chong Zhang8e062632020-03-31 10:56:37 -0700299 for (const auto& iter : mClientIdToClientMap) {
Chong Zhang0579c6f2020-10-05 12:03:34 -0700300 snprintf(buffer, SIZE, " Client %lld: pkg: %s\n", (long long)iter.first,
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700301 iter.second->mClientName.c_str());
hkuang26587cb2020-01-16 10:36:08 -0800302 result.append(buffer);
303 }
304
305 write(fd, result.string(), result.size());
306}
307
Chong Zhangc37bdfe2020-10-06 13:54:09 -0700308bool TranscodingClientManager::isTrustedCallingUid(uid_t uid) {
Chong Zhang3fea2862020-10-21 08:46:03 -0700309 if (uid > 0 && mMediaProviderUid.count(uid) > 0) {
Chong Zhangc37bdfe2020-10-06 13:54:09 -0700310 return true;
311 }
312
313 switch (uid) {
314 case AID_ROOT: // root user
315 case AID_SYSTEM:
316 case AID_SHELL:
317 case AID_MEDIA: // mediaserver
318 return true;
319 default:
320 return false;
321 }
322}
323
Chong Zhang8e062632020-03-31 10:56:37 -0700324status_t TranscodingClientManager::addClient(
Chong Zhang3f23e982020-09-24 14:03:41 -0700325 const std::shared_ptr<ITranscodingClientCallback>& callback, const std::string& clientName,
326 const std::string& opPackageName, std::shared_ptr<ITranscodingClient>* outClient) {
hkuang26587cb2020-01-16 10:36:08 -0800327 // Validate the client.
Chong Zhang3f23e982020-09-24 14:03:41 -0700328 if (callback == nullptr || clientName.empty() || opPackageName.empty()) {
hkuang26587cb2020-01-16 10:36:08 -0800329 ALOGE("Invalid client");
Chong Zhang15c192a2020-05-05 16:24:00 -0700330 return IMediaTranscodingService::ERROR_ILLEGAL_ARGUMENT;
hkuang26587cb2020-01-16 10:36:08 -0800331 }
332
Chong Zhang3fa408f2020-04-30 11:04:28 -0700333 SpAIBinder binder = callback->asBinder();
Chong Zhang8e062632020-03-31 10:56:37 -0700334
hkuang26587cb2020-01-16 10:36:08 -0800335 std::scoped_lock lock{mLock};
336
Chong Zhang8e062632020-03-31 10:56:37 -0700337 // Checks if the client already registers.
Chong Zhang3fa408f2020-04-30 11:04:28 -0700338 if (mRegisteredCallbacks.count((uintptr_t)binder.get()) > 0) {
Chong Zhang15c192a2020-05-05 16:24:00 -0700339 return IMediaTranscodingService::ERROR_ALREADY_EXISTS;
hkuang26587cb2020-01-16 10:36:08 -0800340 }
341
Chong Zhang3f23e982020-09-24 14:03:41 -0700342 // Creates the client (with the id assigned by ClientImpl).
Chong Zhang3fa408f2020-04-30 11:04:28 -0700343 std::shared_ptr<ClientImpl> client = ::ndk::SharedRefBase::make<ClientImpl>(
Chong Zhang3f23e982020-09-24 14:03:41 -0700344 callback, clientName, opPackageName, shared_from_this());
Chong Zhang3fa408f2020-04-30 11:04:28 -0700345
Chong Zhang3f23e982020-09-24 14:03:41 -0700346 ALOGD("Adding client id %lld, name %s, package %s", (long long)client->mClientId,
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700347 client->mClientName.c_str(), client->mClientOpPackageName.c_str());
hkuang9c04b8d2020-01-22 10:03:21 -0800348
Chong Zhang3fa408f2020-04-30 11:04:28 -0700349 {
350 std::scoped_lock lock{sCookie2ClientLock};
351 sCookie2Client.emplace(std::make_pair(client->mClientId, client));
352 }
353
354 AIBinder_linkToDeath(binder.get(), mDeathRecipient.get(),
355 reinterpret_cast<void*>(client->mClientId));
hkuang26587cb2020-01-16 10:36:08 -0800356
357 // Adds the new client to the map.
Chong Zhang3fa408f2020-04-30 11:04:28 -0700358 mRegisteredCallbacks.insert((uintptr_t)binder.get());
Chong Zhang8e062632020-03-31 10:56:37 -0700359 mClientIdToClientMap[client->mClientId] = client;
360
361 *outClient = client;
hkuang26587cb2020-01-16 10:36:08 -0800362
363 return OK;
364}
365
Chong Zhang8e062632020-03-31 10:56:37 -0700366status_t TranscodingClientManager::removeClient(ClientIdType clientId) {
367 ALOGD("Removing client id %lld", (long long)clientId);
hkuang26587cb2020-01-16 10:36:08 -0800368 std::scoped_lock lock{mLock};
369
370 // Checks if the client is valid.
Chong Zhang8e062632020-03-31 10:56:37 -0700371 auto it = mClientIdToClientMap.find(clientId);
372 if (it == mClientIdToClientMap.end()) {
373 ALOGE("Client id %lld does not exist", (long long)clientId);
Chong Zhang15c192a2020-05-05 16:24:00 -0700374 return IMediaTranscodingService::ERROR_INVALID_OPERATION;
hkuang26587cb2020-01-16 10:36:08 -0800375 }
376
Chong Zhang3fa408f2020-04-30 11:04:28 -0700377 SpAIBinder binder = it->second->mClientBinder;
hkuang26587cb2020-01-16 10:36:08 -0800378
379 // Check if the client still live. If alive, unlink the death.
Chong Zhang3fa408f2020-04-30 11:04:28 -0700380 if (binder.get() != nullptr) {
381 AIBinder_unlinkToDeath(binder.get(), mDeathRecipient.get(),
382 reinterpret_cast<void*>(it->second->mClientId));
383 }
384
385 {
386 std::scoped_lock lock{sCookie2ClientLock};
387 sCookie2Client.erase(it->second->mClientId);
hkuang26587cb2020-01-16 10:36:08 -0800388 }
389
390 // Erase the entry.
Chong Zhang8e062632020-03-31 10:56:37 -0700391 mClientIdToClientMap.erase(it);
Chong Zhang3fa408f2020-04-30 11:04:28 -0700392 mRegisteredCallbacks.erase((uintptr_t)binder.get());
hkuang26587cb2020-01-16 10:36:08 -0800393
394 return OK;
395}
396
397size_t TranscodingClientManager::getNumOfClients() const {
398 std::scoped_lock lock{mLock};
Chong Zhang8e062632020-03-31 10:56:37 -0700399 return mClientIdToClientMap.size();
hkuang26587cb2020-01-16 10:36:08 -0800400}
401
hkuang26587cb2020-01-16 10:36:08 -0800402} // namespace android