blob: 6c10e3e2e98b66869986081f574468c83ff2ec2d [file] [log] [blame]
Hangyu Kuang71b9fb42019-11-27 10:33:32 -08001/*
2 * Copyright (C) 2019 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 "MediaTranscodingService"
Chong Zhang182b06a2020-04-09 14:38:05 -070019#include "MediaTranscodingService.h"
20
Hangyu Kuang71b9fb42019-11-27 10:33:32 -080021#include <android/binder_manager.h>
22#include <android/binder_process.h>
Chong Zhang182b06a2020-04-09 14:38:05 -070023#include <media/TranscodingClientManager.h>
24#include <media/TranscodingJobScheduler.h>
Chong Zhangacb33502020-04-20 11:04:48 -070025#include <media/TranscodingUidPolicy.h>
hkuang9c04b8d2020-01-22 10:03:21 -080026#include <private/android_filesystem_config.h>
Hangyu Kuang71b9fb42019-11-27 10:33:32 -080027#include <utils/Log.h>
28#include <utils/Vector.h>
29
30namespace android {
31
hkuang9c04b8d2020-01-22 10:03:21 -080032// Convenience methods for constructing binder::Status objects for error returns
33#define STATUS_ERROR_FMT(errorCode, errorString, ...) \
34 Status::fromServiceSpecificErrorWithMessage( \
35 errorCode, \
36 String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, ##__VA_ARGS__))
37
38// Can MediaTranscoding service trust the caller based on the calling UID?
39// TODO(hkuang): Add MediaProvider's UID.
40static bool isTrustedCallingUid(uid_t uid) {
41 switch (uid) {
42 case AID_ROOT: // root user
43 case AID_SYSTEM:
44 case AID_SHELL:
45 case AID_MEDIA: // mediaserver
46 return true;
47 default:
48 return false;
49 }
50}
51
Chong Zhangacb33502020-04-20 11:04:48 -070052// DummyTranscoder is currently used to instantiate MediaTranscodingService on
53// service side for testing, so that we could actually test the IPC calls of
54// MediaTranscodingService to expose some issues that's observable only over IPC.
Chong Zhang182b06a2020-04-09 14:38:05 -070055class DummyTranscoder : public TranscoderInterface {
56 void start(int64_t clientId, int32_t jobId) override {
57 (void)clientId;
58 (void)jobId;
59 }
60 void pause(int64_t clientId, int32_t jobId) override {
61 (void)clientId;
62 (void)jobId;
63 }
64 void resume(int64_t clientId, int32_t jobId) override {
65 (void)clientId;
66 (void)jobId;
67 }
68};
69
hkuang5172cab2020-01-31 12:40:28 -080070MediaTranscodingService::MediaTranscodingService()
Chong Zhang182b06a2020-04-09 14:38:05 -070071 : MediaTranscodingService(std::make_shared<DummyTranscoder>(),
Chong Zhangacb33502020-04-20 11:04:48 -070072 std::make_shared<TranscodingUidPolicy>()) {}
Chong Zhang182b06a2020-04-09 14:38:05 -070073
74MediaTranscodingService::MediaTranscodingService(
75 const std::shared_ptr<TranscoderInterface>& transcoder,
Chong Zhang7ae4e2f2020-04-17 15:24:34 -070076 const std::shared_ptr<UidPolicyInterface>& uidPolicy)
77 : mJobScheduler(new TranscodingJobScheduler(transcoder, uidPolicy)),
Chong Zhang182b06a2020-04-09 14:38:05 -070078 mClientManager(new TranscodingClientManager(mJobScheduler)) {
Hangyu Kuang71b9fb42019-11-27 10:33:32 -080079 ALOGV("MediaTranscodingService is created");
Chong Zhangacb33502020-04-20 11:04:48 -070080 uidPolicy->setCallback(mJobScheduler);
Hangyu Kuang71b9fb42019-11-27 10:33:32 -080081}
82
83MediaTranscodingService::~MediaTranscodingService() {
84 ALOGE("Should not be in ~MediaTranscodingService");
85}
86
hkuang9c04b8d2020-01-22 10:03:21 -080087binder_status_t MediaTranscodingService::dump(int fd, const char** /*args*/, uint32_t /*numArgs*/) {
88 String8 result;
89 const size_t SIZE = 256;
90 char buffer[SIZE];
91
92 snprintf(buffer, SIZE, "MediaTranscodingService: %p\n", this);
93 result.append(buffer);
94 write(fd, result.string(), result.size());
95
96 Vector<String16> args;
Chong Zhang182b06a2020-04-09 14:38:05 -070097 mClientManager->dumpAllClients(fd, args);
Hangyu Kuang71b9fb42019-11-27 10:33:32 -080098 return OK;
99}
100
101//static
102void MediaTranscodingService::instantiate() {
103 std::shared_ptr<MediaTranscodingService> service =
104 ::ndk::SharedRefBase::make<MediaTranscodingService>();
105 binder_status_t status =
106 AServiceManager_addService(service->asBinder().get(), getServiceName());
107 if (status != STATUS_OK) {
108 return;
109 }
110}
111
112Status MediaTranscodingService::registerClient(
Chong Zhang182b06a2020-04-09 14:38:05 -0700113 const std::shared_ptr<ITranscodingClientCallback>& in_callback,
114 const std::string& in_clientName, const std::string& in_opPackageName, int32_t in_clientUid,
115 int32_t in_clientPid, std::shared_ptr<ITranscodingClient>* _aidl_return) {
116 if (in_callback == nullptr) {
117 ALOGE("Client callback can not be null");
Chong Zhang8e062632020-03-31 10:56:37 -0700118 *_aidl_return = nullptr;
hkuang9c04b8d2020-01-22 10:03:21 -0800119 return Status::fromServiceSpecificError(ERROR_ILLEGAL_ARGUMENT);
120 }
121
122 int32_t callingPid = AIBinder_getCallingPid();
123 int32_t callingUid = AIBinder_getCallingUid();
124
Chong Zhang8e062632020-03-31 10:56:37 -0700125 // Check if we can trust clientUid. Only privilege caller could forward the
126 // uid on app client's behalf.
hkuang9c04b8d2020-01-22 10:03:21 -0800127 if (in_clientUid == USE_CALLING_UID) {
128 in_clientUid = callingUid;
129 } else if (!isTrustedCallingUid(callingUid)) {
130 ALOGE("MediaTranscodingService::registerClient failed (calling PID %d, calling UID %d) "
131 "rejected "
132 "(don't trust clientUid %d)",
133 in_clientPid, in_clientUid, in_clientUid);
134 return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
135 "Untrusted caller (calling PID %d, UID %d) trying to "
136 "register client",
137 in_clientPid, in_clientUid);
138 }
139
Chong Zhang8e062632020-03-31 10:56:37 -0700140 // Check if we can trust clientPid. Only privilege caller could forward the
141 // pid on app client's behalf.
hkuang9c04b8d2020-01-22 10:03:21 -0800142 if (in_clientPid == USE_CALLING_PID) {
143 in_clientPid = callingPid;
144 } else if (!isTrustedCallingUid(callingUid)) {
145 ALOGE("MediaTranscodingService::registerClient client failed (calling PID %d, calling UID "
146 "%d) rejected "
147 "(don't trust clientPid %d)",
148 in_clientPid, in_clientUid, in_clientPid);
149 return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
150 "Untrusted caller (calling PID %d, UID %d) trying to "
151 "register client",
152 in_clientPid, in_clientUid);
153 }
154
hkuang9c04b8d2020-01-22 10:03:21 -0800155 // Creates the client and uses its process id as client id.
Chong Zhang8e062632020-03-31 10:56:37 -0700156 std::shared_ptr<ITranscodingClient> newClient;
157
Chong Zhang182b06a2020-04-09 14:38:05 -0700158 status_t err = mClientManager->addClient(in_callback, in_clientPid, in_clientUid, in_clientName,
159 in_opPackageName, &newClient);
hkuang9c04b8d2020-01-22 10:03:21 -0800160 if (err != OK) {
Chong Zhang8e062632020-03-31 10:56:37 -0700161 *_aidl_return = nullptr;
hkuang9c04b8d2020-01-22 10:03:21 -0800162 return STATUS_ERROR_FMT(err, "Failed to add client to TranscodingClientManager");
163 }
164
Chong Zhang8e062632020-03-31 10:56:37 -0700165 *_aidl_return = newClient;
hkuang9c04b8d2020-01-22 10:03:21 -0800166 return Status::ok();
167}
168
169Status MediaTranscodingService::getNumOfClients(int32_t* _aidl_return) {
170 ALOGD("MediaTranscodingService::getNumOfClients");
Chong Zhang182b06a2020-04-09 14:38:05 -0700171 *_aidl_return = mClientManager->getNumOfClients();
Hangyu Kuang71b9fb42019-11-27 10:33:32 -0800172 return Status::ok();
173}
174
Hangyu Kuang71b9fb42019-11-27 10:33:32 -0800175} // namespace android