Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8fc10fd2 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Implement binder native side for IArcVideoBridge"

parents b5253b65 d13a93f2
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -55,6 +55,17 @@ cc_library_static {
        "frameworks/native/services",
        "system/gatekeeper/include",
    ],

    product_variables: {
        arc: {
            cflags: [
                "-DUSE_ARC",
            ],
            srcs: [
                "com_android_server_ArcVideoService.cpp",
            ],
        }
    }
}

cc_defaults {
@@ -119,4 +130,17 @@ cc_defaults {
        "android.hardware.broadcastradio@common-utils-1x-lib",
        "libscrypt_static",
    ],

    product_variables: {
        arc: {
            // TODO: remove the suffix "_bp" after finishing migration to Android.bp.
            shared_libs: [
                "libarcbridge",
                "libarcbridgeservice",
                "libarcvideobridge",
                "libchrome",
                "libmojo_bp",
            ],
        }
    }
}
+149 −0
Original line number Diff line number Diff line
/*
 * Copyright 2016, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "ArcVideoService"

#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <media/arcvideobridge/IArcVideoBridge.h>
#include <utils/Log.h>

#include <base/bind.h>
#include <base/bind_helpers.h>
#include <mojo/edk/embedder/embedder.h>
#include <mojo/public/cpp/bindings/binding.h>

#include <arc/ArcBridgeSupport.h>
#include <arc/ArcService.h>
#include <arc/Future.h>
#include <arc/IArcBridgeService.h>
#include <arc/MojoProcessSupport.h>
#include <video.mojom.h>

namespace {

// [MinVersion] of OnVideoInstanceReady method in arc_bridge.mojom.
constexpr int kMinimumArcBridgeHostVersion = 6;

void onCaptureResult(arc::Future<arc::MojoBootstrapResult>* future, uint32_t version,
                     mojo::ScopedHandle handle, const std::string& token) {
    mojo::edk::ScopedPlatformHandle scoped_platform_handle;
    MojoResult result =
            mojo::edk::PassWrappedPlatformHandle(handle.release().value(), &scoped_platform_handle);
    if (result != MOJO_RESULT_OK) {
        ALOGE("Received invalid file descriptor.");
        future->set(arc::MojoBootstrapResult());
        return;
    }

    base::ScopedFD fd(scoped_platform_handle.release().handle);
    future->set(arc::MojoBootstrapResult(std::move(fd), token, version));
}

}  // namespace

namespace arc {

class VideoService : public mojom::VideoInstance,
                     public ArcService,
                     public android::BnArcVideoBridge {
public:
    explicit VideoService(MojoProcessSupport* mojoProcessSupport)
          : mMojoProcessSupport(mojoProcessSupport), mBinding(this) {
        mMojoProcessSupport->arc_bridge_support().requestArcBridgeProxyAsync(
                this, kMinimumArcBridgeHostVersion);
    }

    ~VideoService() override { mMojoProcessSupport->disconnect(&mBinding, &mHostPtr); }

    // VideoInstance overrides:
    void InitDeprecated(mojom::VideoHostPtr hostPtr) override {
        Init(std::move(hostPtr), base::Bind(&base::DoNothing));
    }

    void Init(mojom::VideoHostPtr hostPtr, const InitCallback& callback) override {
        ALOGV("Init");
        mHostPtr = std::move(hostPtr);
        // A method must be called while we are still in a Mojo thread so the
        // proxy can perform lazy initialization and be able to be called from
        // non-Mojo threads later.
        // This also caches the version number so it can be obtained by calling
        // .version().
        mHostPtr.QueryVersion(base::Bind(
            [](const InitCallback& callback, uint32_t version) {
                ALOGI("VideoService ready (version=%d)", version);
                callback.Run();
            },
            callback));
        ALOGV("Init done");
    }

    // ArcService overrides:
    void ready(mojom::ArcBridgeHostPtr* bridgeHost) override {
        (*bridgeHost)->OnVideoInstanceReady(mBinding.CreateInterfacePtrAndBind());
    }

    void versionMismatch(uint32_t version) override {
        ALOGE("ArcBridgeHost version %d, does not support video (version %d)\n", version,
              kMinimumArcBridgeHostVersion);
    }

    // BnArcVideoBridge overrides:
    MojoBootstrapResult bootstrapVideoAcceleratorFactory() override {
        ALOGV("VideoService::bootstrapVideoAcceleratorFactory");

        Future<MojoBootstrapResult> future;
        mMojoProcessSupport->mojo_thread().getTaskRunner()->PostTask(
                FROM_HERE, base::Bind(&VideoService::bootstrapVideoAcceleratorFactoryOnMojoThread,
                                      base::Unretained(this), &future));
        return future.get();
    }

    int32_t hostVersion() override {
        ALOGV("VideoService::hostVersion");
        return mHostPtr.version();
    }

private:
    void bootstrapVideoAcceleratorFactoryOnMojoThread(Future<MojoBootstrapResult>* future) {
        if (!mHostPtr) {
            ALOGE("mHostPtr is not ready yet");
            future->set(MojoBootstrapResult());
            return;
        }
        mHostPtr->OnBootstrapVideoAcceleratorFactory(
                base::Bind(&onCaptureResult, base::Unretained(future), mHostPtr.version()));
    }

    // Outlives VideoService.
    MojoProcessSupport* const mMojoProcessSupport;
    mojo::Binding<mojom::VideoInstance> mBinding;
    mojom::VideoHostPtr mHostPtr;
};

}  // namespace arc

namespace android {

int register_android_server_ArcVideoService() {
    defaultServiceManager()->addService(
            String16("android.os.IArcVideoBridge"),
            new arc::VideoService(arc::MojoProcessSupport::getLeakyInstance()));
    return 0;
}

}  // namespace android
+6 −1
Original line number Diff line number Diff line
@@ -52,6 +52,9 @@ int register_android_server_SyntheticPasswordManager(JNIEnv* env);
int register_android_server_GraphicsStatsService(JNIEnv* env);
int register_android_hardware_display_DisplayViewport(JNIEnv* env);
int register_android_server_net_NetworkStatsService(JNIEnv* env);
#ifdef USE_ARC
int register_android_server_ArcVideoService();
#endif
};

using namespace android;
@@ -97,6 +100,8 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
    register_android_server_GraphicsStatsService(env);
    register_android_hardware_display_DisplayViewport(env);
    register_android_server_net_NetworkStatsService(env);

#ifdef USE_ARC
    register_android_server_ArcVideoService();
#endif
    return JNI_VERSION_1_4;
}