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

Commit dc5ed0b5 authored by Yixiao Luo's avatar Yixiao Luo Committed by Android (Google) Code Review
Browse files

Merge "TV Input HAL 2.0 default implementation"

parents 29b6721e aaa52301
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
package {
    // See: http://go/android-license-faq
    // A large-scale-change added 'default_applicable_licenses' to import
    // all of the 'license_kinds' from "hardware_interfaces_license"
    // to get the below license kinds:
    //   SPDX-license-identifier-Apache-2.0
    default_applicable_licenses: ["hardware_interfaces_license"],
}

cc_binary {
    name: "android.hardware.tv.input-service.example",
    relative_install_path: "hw",
    init_rc: ["input-default.rc"],
    vintf_fragments: ["input-default.xml"],
    vendor: true,
    srcs: [
        "TvInput.cpp",
        "service.cpp",
    ],
    static_libs: [
        "libaidlcommonsupport",
    ],
    shared_libs: [
        "libbase",
        "liblog",
        "libutils",
        "libcutils",
        "libbinder_ndk",
        "android.hardware.tv.input-V1-ndk",
    ],
}
+143 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022 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_TAG "android.hardware.tv.input-service.example"

#include <utils/Log.h>

#include "TvInput.h"

namespace aidl {
namespace android {
namespace hardware {
namespace tv {
namespace input {

TvInput::TvInput() {}

void TvInput::init() {
    // Set up TvInputDeviceInfo and TvStreamConfig
    mDeviceInfos[0] = shared_ptr<TvInputDeviceInfoWrapper>(
            new TvInputDeviceInfoWrapper(0, TvInputType::TUNER, true));
    mDeviceInfos[1] = shared_ptr<TvInputDeviceInfoWrapper>(
            new TvInputDeviceInfoWrapper(1, TvInputType::HDMI, true));
    mDeviceInfos[3] = shared_ptr<TvInputDeviceInfoWrapper>(
            new TvInputDeviceInfoWrapper(3, TvInputType::DISPLAY_PORT, true));

    mStreamConfigs[0] = {
            {1, shared_ptr<TvStreamConfigWrapper>(new TvStreamConfigWrapper(1, 720, 1080, false))}};
    mStreamConfigs[1] = {{11, shared_ptr<TvStreamConfigWrapper>(
                                      new TvStreamConfigWrapper(11, 360, 480, false))}};
    mStreamConfigs[3] = {{5, shared_ptr<TvStreamConfigWrapper>(
                                     new TvStreamConfigWrapper(5, 1080, 1920, false))}};
}

::ndk::ScopedAStatus TvInput::setCallback(const shared_ptr<ITvInputCallback>& in_callback) {
    ALOGV("%s", __FUNCTION__);

    mCallback = in_callback;

    TvInputEvent event;
    event.type = TvInputEventType::DEVICE_AVAILABLE;

    event.deviceInfo = mDeviceInfos[0]->deviceInfo;
    mCallback->notify(event);

    event.deviceInfo = mDeviceInfos[1]->deviceInfo;
    mCallback->notify(event);

    event.deviceInfo = mDeviceInfos[3]->deviceInfo;
    mCallback->notify(event);

    return ::ndk::ScopedAStatus::ok();
}

::ndk::ScopedAStatus TvInput::getStreamConfigurations(int32_t in_deviceId,
                                                      vector<TvStreamConfig>* _aidl_return) {
    ALOGV("%s", __FUNCTION__);

    if (mStreamConfigs.count(in_deviceId) == 0) {
        ALOGW("Device with id %d isn't available", in_deviceId);
        return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
    }

    for (auto const& iconfig : mStreamConfigs[in_deviceId]) {
        _aidl_return->push_back(iconfig.second->streamConfig);
    }

    return ::ndk::ScopedAStatus::ok();
}

::ndk::ScopedAStatus TvInput::openStream(int32_t in_deviceId, int32_t in_streamId,
                                         NativeHandle* _aidl_return) {
    ALOGV("%s", __FUNCTION__);

    if (mStreamConfigs.count(in_deviceId) == 0 ||
        mStreamConfigs[in_deviceId].count(in_streamId) == 0) {
        ALOGW("Stream with device id %d, stream id %d isn't available", in_deviceId, in_streamId);
        return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
    }
    if (mStreamConfigs[in_deviceId][in_streamId]->isOpen) {
        ALOGW("Stream with device id %d, stream id %d is already opened", in_deviceId, in_streamId);
        return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_STATE);
    }
    mStreamConfigs[in_deviceId][in_streamId]->handle = createNativeHandle(in_streamId);
    mStreamConfigs[in_deviceId][in_streamId]->isOpen = true;
    NativeHandle aidlHandle = makeToAidl(mStreamConfigs[in_deviceId][in_streamId]->handle);
    _aidl_return = &aidlHandle;
    return ::ndk::ScopedAStatus::ok();
}

::ndk::ScopedAStatus TvInput::closeStream(int32_t in_deviceId, int32_t in_streamId) {
    ALOGV("%s", __FUNCTION__);

    if (mStreamConfigs.count(in_deviceId) == 0 ||
        mStreamConfigs[in_deviceId].count(in_streamId) == 0) {
        ALOGW("Stream with device id %d, stream id %d isn't available", in_deviceId, in_streamId);
        return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
    }
    if (!mStreamConfigs[in_deviceId][in_streamId]->isOpen) {
        ALOGW("Stream with device id %d, stream id %d is already closed", in_deviceId, in_streamId);
        return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_STATE);
    }
    releaseNativeHandle(mStreamConfigs[in_deviceId][in_streamId]->handle);
    mStreamConfigs[in_deviceId][in_streamId]->handle = nullptr;
    mStreamConfigs[in_deviceId][in_streamId]->isOpen = false;
    return ::ndk::ScopedAStatus::ok();
}

native_handle_t* TvInput::createNativeHandle(int fd) {
    native_handle_t* nativeHandle = native_handle_create(1, 0);
    if (nativeHandle == nullptr) {
        ALOGE("[TVInput] Failed to create native_handle %d", errno);
        return nullptr;
    }
    if (nativeHandle->numFds > 0) {
        nativeHandle->data[0] = dup(fd);
    }
    return nativeHandle;
}

void TvInput::releaseNativeHandle(native_handle_t* handle) {
    native_handle_close(handle);
    native_handle_delete(handle);
}

}  // namespace input
}  // namespace tv
}  // namespace hardware
}  // namespace android
}  // namespace aidl
+62 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022 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.
 */

#pragma once

#include <aidl/android/hardware/tv/input/BnTvInput.h>
#include <utils/KeyedVector.h>

#include <map>
#include "TvInputDeviceInfoWrapper.h"
#include "TvStreamConfigWrapper.h"

using namespace android;
using namespace std;
using ::aidl::android::hardware::common::NativeHandle;

namespace aidl {
namespace android {
namespace hardware {
namespace tv {
namespace input {

class TvInput : public BnTvInput {
  public:
    TvInput();

    ::ndk::ScopedAStatus setCallback(const shared_ptr<ITvInputCallback>& in_callback) override;
    ::ndk::ScopedAStatus getStreamConfigurations(int32_t in_deviceId,
                                                 vector<TvStreamConfig>* _aidl_return) override;
    ::ndk::ScopedAStatus openStream(int32_t in_deviceId, int32_t in_streamId,
                                    NativeHandle* _aidl_return) override;
    ::ndk::ScopedAStatus closeStream(int32_t in_deviceId, int32_t in_streamId) override;

    void init();

  private:
    native_handle_t* createNativeHandle(int fd);
    void releaseNativeHandle(native_handle_t* handle);

    shared_ptr<ITvInputCallback> mCallback;
    map<int32_t, shared_ptr<TvInputDeviceInfoWrapper>> mDeviceInfos;
    map<int32_t, map<int32_t, shared_ptr<TvStreamConfigWrapper>>> mStreamConfigs;
};

}  // namespace input
}  // namespace tv
}  // namespace hardware
}  // namespace android
}  // namespace aidl
+43 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022 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.
 */

#pragma once

#include <aidl/android/hardware/tv/input/TvInputDeviceInfo.h>

namespace aidl {
namespace android {
namespace hardware {
namespace tv {
namespace input {

class TvInputDeviceInfoWrapper {
  public:
    TvInputDeviceInfoWrapper() {}
    TvInputDeviceInfoWrapper(int32_t deviceId_, TvInputType type_, bool isAvailable_) {
        deviceInfo.deviceId = deviceId_;
        deviceInfo.type = type_;
        isAvailable = isAvailable_;
    }

    TvInputDeviceInfo deviceInfo;
    bool isAvailable;
};
}  // namespace input
}  // namespace tv
}  // namespace hardware
}  // namespace android
}  // namespace aidl
+50 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022 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.
 */

#pragma once

#include <aidl/android/hardware/tv/input/TvStreamConfig.h>
#include <aidlcommonsupport/NativeHandle.h>

using namespace std;

namespace aidl {
namespace android {
namespace hardware {
namespace tv {
namespace input {

class TvStreamConfigWrapper {
  public:
    TvStreamConfigWrapper() {}
    TvStreamConfigWrapper(int32_t streamId_, int32_t maxVideoWidth_, int32_t maxVideoHeight_,
                          bool isOpen_) {
        streamConfig.streamId = streamId_;
        streamConfig.maxVideoWidth = maxVideoWidth_;
        streamConfig.maxVideoHeight = maxVideoHeight_;
        isOpen = isOpen_;
        handle = nullptr;
    }

    TvStreamConfig streamConfig;
    bool isOpen;
    native_handle_t* handle;
};
}  // namespace input
}  // namespace tv
}  // namespace hardware
}  // namespace android
}  // namespace aidl
Loading