1 /*
2  * Copyright 2018 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 "android.hardware.media.c2@1.1-service"
19 
20 #include <android-base/logging.h>
21 #include <binder/ProcessState.h>
22 #include <codec2/hidl/1.1/ComponentStore.h>
23 #include <hidl/HidlTransportSupport.h>
24 #include <minijail.h>
25 
26 #include <util/C2InterfaceHelper.h>
27 #include <C2Component.h>
28 #include <C2Config.h>
29 
30 // This is the absolute on-device path of the prebuild_etc module
31 // "android.hardware.media.c2@1.1-default-seccomp_policy" in Android.bp.
32 static constexpr char kBaseSeccompPolicyPath[] =
33         "/vendor/etc/seccomp_policy/"
34         "android.hardware.media.c2@1.1-default-seccomp-policy";
35 
36 // Additional seccomp permissions can be added in this file.
37 // This file does not exist by default.
38 static constexpr char kExtSeccompPolicyPath[] =
39         "/vendor/etc/seccomp_policy/"
40         "android.hardware.media.c2@1.1-extended-seccomp-policy";
41 
42 class StoreImpl : public C2ComponentStore {
43 public:
StoreImpl()44     StoreImpl()
45         : mReflectorHelper(std::make_shared<C2ReflectorHelper>()),
46           mInterface(mReflectorHelper) {
47     }
48 
49     virtual ~StoreImpl() override = default;
50 
getName() const51     virtual C2String getName() const override {
52         return "default";
53     }
54 
createComponent(C2String,std::shared_ptr<C2Component> * const)55     virtual c2_status_t createComponent(
56             C2String /*name*/,
57             std::shared_ptr<C2Component>* const /*component*/) override {
58         return C2_NOT_FOUND;
59     }
60 
createInterface(C2String,std::shared_ptr<C2ComponentInterface> * const)61     virtual c2_status_t createInterface(
62             C2String /* name */,
63             std::shared_ptr<C2ComponentInterface>* const /* interface */) override {
64         return C2_NOT_FOUND;
65     }
66 
67     virtual std::vector<std::shared_ptr<const C2Component::Traits>>
listComponents()68             listComponents() override {
69         return {};
70     }
71 
copyBuffer(std::shared_ptr<C2GraphicBuffer>,std::shared_ptr<C2GraphicBuffer>)72     virtual c2_status_t copyBuffer(
73             std::shared_ptr<C2GraphicBuffer> /* src */,
74             std::shared_ptr<C2GraphicBuffer> /* dst */) override {
75         return C2_OMITTED;
76     }
77 
query_sm(const std::vector<C2Param * > & stackParams,const std::vector<C2Param::Index> & heapParamIndices,std::vector<std::unique_ptr<C2Param>> * const heapParams) const78     virtual c2_status_t query_sm(
79         const std::vector<C2Param*>& stackParams,
80         const std::vector<C2Param::Index>& heapParamIndices,
81         std::vector<std::unique_ptr<C2Param>>* const heapParams) const override {
82         return mInterface.query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams);
83     }
84 
config_sm(const std::vector<C2Param * > & params,std::vector<std::unique_ptr<C2SettingResult>> * const failures)85     virtual c2_status_t config_sm(
86             const std::vector<C2Param*>& params,
87             std::vector<std::unique_ptr<C2SettingResult>>* const failures) override {
88         return mInterface.config(params, C2_MAY_BLOCK, failures);
89     }
90 
getParamReflector() const91     virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override {
92         return mReflectorHelper;
93     }
94 
querySupportedParams_nb(std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const95     virtual c2_status_t querySupportedParams_nb(
96             std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const override {
97         return mInterface.querySupportedParams(params);
98     }
99 
querySupportedValues_sm(std::vector<C2FieldSupportedValuesQuery> & fields) const100     virtual c2_status_t querySupportedValues_sm(
101             std::vector<C2FieldSupportedValuesQuery>& fields) const override {
102         return mInterface.querySupportedValues(fields, C2_MAY_BLOCK);
103     }
104 
105 private:
106     class Interface : public C2InterfaceHelper {
107     public:
Interface(const std::shared_ptr<C2ReflectorHelper> & helper)108         Interface(const std::shared_ptr<C2ReflectorHelper> &helper)
109             : C2InterfaceHelper(helper) {
110             setDerivedInstance(this);
111 
112             addParameter(
113                 DefineParam(mIonUsageInfo, "ion-usage")
114                 .withDefault(new C2StoreIonUsageInfo())
115                 .withFields({
116                     C2F(mIonUsageInfo, usage).flags(
117                             {C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE}),
118                     C2F(mIonUsageInfo, capacity).inRange(0, UINT32_MAX, 1024),
119                     C2F(mIonUsageInfo, heapMask).any(),
120                     C2F(mIonUsageInfo, allocFlags).flags({}),
121                     C2F(mIonUsageInfo, minAlignment).equalTo(0)
122                 })
123                 .withSetter(SetIonUsage)
124                 .build());
125         }
126 
127         virtual ~Interface() = default;
128 
129     private:
SetIonUsage(bool,C2P<C2StoreIonUsageInfo> & me)130         static C2R SetIonUsage(bool /* mayBlock */, C2P<C2StoreIonUsageInfo> &me) {
131             // Vendor's TODO: put appropriate mapping logic
132             me.set().heapMask = ~0;
133             me.set().allocFlags = 0;
134             me.set().minAlignment = 0;
135             return C2R::Ok();
136         }
137 
138         std::shared_ptr<C2StoreIonUsageInfo> mIonUsageInfo;
139     };
140     std::shared_ptr<C2ReflectorHelper> mReflectorHelper;
141     Interface mInterface;
142 };
143 
main(int,char **)144 int main(int /* argc */, char** /* argv */) {
145     using namespace ::android;
146     LOG(DEBUG) << "android.hardware.media.c2@1.1-service starting...";
147 
148     // Set up minijail to limit system calls.
149     signal(SIGPIPE, SIG_IGN);
150     SetUpMinijail(kBaseSeccompPolicyPath, kExtSeccompPolicyPath);
151 
152     // Enable vndbinder to allow vendor-to-vendor binder calls.
153     ProcessState::initWithDriver("/dev/vndbinder");
154 
155     ProcessState::self()->startThreadPool();
156     // Extra threads may be needed to handle a stacked IPC sequence that
157     // contains alternating binder and hwbinder calls. (See b/35283480.)
158     hardware::configureRpcThreadpool(8, true /* callerWillJoin */);
159 
160     // Create IComponentStore service.
161     {
162         using namespace ::android::hardware::media::c2::V1_1;
163         sp<IComponentStore> store;
164 
165         // TODO: Replace this with
166         // store = new utils::ComponentStore(
167         //         /* implementation of C2ComponentStore */);
168         LOG(DEBUG) << "Instantiating Codec2's IComponentStore service...";
169         store = new utils::ComponentStore(
170                 std::make_shared<StoreImpl>());
171 
172         if (store == nullptr) {
173             LOG(ERROR) << "Cannot create Codec2's IComponentStore service.";
174         } else {
175             constexpr char const* serviceName = "default";
176             if (store->registerAsService(serviceName) != OK) {
177                 LOG(ERROR) << "Cannot register Codec2's IComponentStore service"
178                               " with instance name << \""
179                            << serviceName << "\".";
180             } else {
181                 LOG(DEBUG) << "Codec2's IComponentStore service registered. "
182                               "Instance name: \"" << serviceName << "\".";
183             }
184         }
185     }
186 
187     hardware::joinRpcThreadpool();
188     return 0;
189 }
190