• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016, 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 "ArcVideoService"
19 
20 #include <binder/IPCThreadState.h>
21 #include <binder/IServiceManager.h>
22 #include <media/arcvideobridge/IArcVideoBridge.h>
23 #include <utils/Log.h>
24 
25 #include <base/bind.h>
26 #include <base/bind_helpers.h>
27 #include <mojo/edk/embedder/embedder.h>
28 #include <mojo/public/cpp/bindings/binding.h>
29 
30 #include <arc/ArcBridgeSupport.h>
31 #include <arc/ArcService.h>
32 #include <arc/Future.h>
33 #include <arc/IArcBridgeService.h>
34 #include <arc/MojoProcessSupport.h>
35 #include <components/arc/common/video.mojom.h>
36 
37 namespace {
38 
39 // [MinVersion] of OnVideoInstanceReady method in arc_bridge.mojom.
40 constexpr int kMinimumArcBridgeHostVersion = 6;
41 
onCaptureResult(arc::Future<arc::MojoBootstrapResult> * future,uint32_t version,mojo::ScopedHandle handle,const std::string & token)42 void onCaptureResult(arc::Future<arc::MojoBootstrapResult>* future, uint32_t version,
43                      mojo::ScopedHandle handle, const std::string& token) {
44     mojo::edk::ScopedPlatformHandle scoped_platform_handle;
45     MojoResult result =
46             mojo::edk::PassWrappedPlatformHandle(handle.release().value(), &scoped_platform_handle);
47     if (result != MOJO_RESULT_OK) {
48         ALOGE("Received invalid file descriptor.");
49         future->set(arc::MojoBootstrapResult());
50         return;
51     }
52 
53     base::ScopedFD fd(scoped_platform_handle.release().handle);
54     future->set(arc::MojoBootstrapResult(std::move(fd), token, version));
55 }
56 
57 }  // namespace
58 
59 namespace arc {
60 
61 class VideoService : public mojom::VideoInstance,
62                      public ArcService,
63                      public android::BnArcVideoBridge {
64 public:
VideoService(MojoProcessSupport * mojoProcessSupport)65     explicit VideoService(MojoProcessSupport* mojoProcessSupport)
66           : mMojoProcessSupport(mojoProcessSupport), mBinding(this) {
67         mMojoProcessSupport->arc_bridge_support().requestArcBridgeProxyAsync(
68                 this, kMinimumArcBridgeHostVersion);
69     }
70 
~VideoService()71     ~VideoService() override { mMojoProcessSupport->disconnect(&mBinding, &mHostPtr); }
72 
73     // VideoInstance overrides:
InitDeprecated(mojom::VideoHostPtr hostPtr)74     void InitDeprecated(mojom::VideoHostPtr hostPtr) override {
75         Init(std::move(hostPtr), base::Bind(&base::DoNothing));
76     }
77 
Init(mojom::VideoHostPtr hostPtr,const InitCallback & callback)78     void Init(mojom::VideoHostPtr hostPtr, const InitCallback& callback) override {
79         ALOGV("Init");
80         mHostPtr = std::move(hostPtr);
81         // A method must be called while we are still in a Mojo thread so the
82         // proxy can perform lazy initialization and be able to be called from
83         // non-Mojo threads later.
84         // This also caches the version number so it can be obtained by calling
85         // .version().
86         mHostPtr.QueryVersion(base::Bind(
87             [](const InitCallback& callback, uint32_t version) {
88                 ALOGI("VideoService ready (version=%d)", version);
89                 callback.Run();
90             },
91             callback));
92         ALOGV("Init done");
93     }
94 
95     // ArcService overrides:
ready(mojom::ArcBridgeHostPtr * bridgeHost)96     void ready(mojom::ArcBridgeHostPtr* bridgeHost) override {
97         (*bridgeHost)->OnVideoInstanceReady(mBinding.CreateInterfacePtrAndBind());
98     }
99 
versionMismatch(uint32_t version)100     void versionMismatch(uint32_t version) override {
101         ALOGE("ArcBridgeHost version %d, does not support video (version %d)\n", version,
102               kMinimumArcBridgeHostVersion);
103     }
104 
105     // BnArcVideoBridge overrides:
bootstrapVideoAcceleratorFactory()106     MojoBootstrapResult bootstrapVideoAcceleratorFactory() override {
107         ALOGV("VideoService::bootstrapVideoAcceleratorFactory");
108 
109         Future<MojoBootstrapResult> future;
110         mMojoProcessSupport->mojo_thread().getTaskRunner()->PostTask(
111                 FROM_HERE, base::Bind(&VideoService::bootstrapVideoAcceleratorFactoryOnMojoThread,
112                                       base::Unretained(this), &future));
113         return future.get();
114     }
115 
hostVersion()116     int32_t hostVersion() override {
117         ALOGV("VideoService::hostVersion");
118         return mHostPtr.version();
119     }
120 
121 private:
bootstrapVideoAcceleratorFactoryOnMojoThread(Future<MojoBootstrapResult> * future)122     void bootstrapVideoAcceleratorFactoryOnMojoThread(Future<MojoBootstrapResult>* future) {
123         if (!mHostPtr) {
124             ALOGE("mHostPtr is not ready yet");
125             future->set(MojoBootstrapResult());
126             return;
127         }
128         mHostPtr->OnBootstrapVideoAcceleratorFactory(
129                 base::Bind(&onCaptureResult, base::Unretained(future), mHostPtr.version()));
130     }
131 
132     // Outlives VideoService.
133     MojoProcessSupport* const mMojoProcessSupport;
134     mojo::Binding<mojom::VideoInstance> mBinding;
135     mojom::VideoHostPtr mHostPtr;
136 };
137 
138 }  // namespace arc
139 
140 namespace android {
141 
register_android_server_ArcVideoService()142 int register_android_server_ArcVideoService() {
143     defaultServiceManager()->addService(
144             String16("android.os.IArcVideoBridge"),
145             new arc::VideoService(arc::MojoProcessSupport::getLeakyInstance()));
146     return 0;
147 }
148 
149 }  // namespace android
150