Home | History | Annotate | Download | only in jni
      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 
     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:
     65     explicit VideoService(MojoProcessSupport* mojoProcessSupport)
     66           : mMojoProcessSupport(mojoProcessSupport), mBinding(this) {
     67         mMojoProcessSupport->arc_bridge_support().requestArcBridgeProxyAsync(
     68                 this, kMinimumArcBridgeHostVersion);
     69     }
     70 
     71     ~VideoService() override { mMojoProcessSupport->disconnect(&mBinding, &mHostPtr); }
     72 
     73     // VideoInstance overrides:
     74     void InitDeprecated(mojom::VideoHostPtr hostPtr) override {
     75         Init(std::move(hostPtr), base::Bind(&base::DoNothing));
     76     }
     77 
     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:
     96     void ready(mojom::ArcBridgeHostPtr* bridgeHost) override {
     97         (*bridgeHost)->OnVideoInstanceReady(mBinding.CreateInterfacePtrAndBind());
     98     }
     99 
    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:
    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 
    116     int32_t hostVersion() override {
    117         ALOGV("VideoService::hostVersion");
    118         return mHostPtr.version();
    119     }
    120 
    121 private:
    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 
    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