1 /*
2 * Copyright 2022 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_TAG "android.hardware.tv.input-service.example"
18
19 #include <utils/Log.h>
20
21 #include "TvInput.h"
22
23 namespace aidl {
24 namespace android {
25 namespace hardware {
26 namespace tv {
27 namespace input {
28
TvInput()29 TvInput::TvInput() {}
30
init()31 void TvInput::init() {
32 // Set up TvInputDeviceInfo and TvStreamConfig
33 mDeviceInfos[0] = shared_ptr<TvInputDeviceInfoWrapper>(
34 new TvInputDeviceInfoWrapper(0, TvInputType::TUNER, true));
35 mDeviceInfos[1] = shared_ptr<TvInputDeviceInfoWrapper>(
36 new TvInputDeviceInfoWrapper(1, TvInputType::HDMI, true));
37 mDeviceInfos[3] = shared_ptr<TvInputDeviceInfoWrapper>(
38 new TvInputDeviceInfoWrapper(3, TvInputType::DISPLAY_PORT, true));
39
40 mStreamConfigs[0] = {
41 {1, shared_ptr<TvStreamConfigWrapper>(new TvStreamConfigWrapper(1, 720, 1080, false))}};
42 mStreamConfigs[1] = {{11, shared_ptr<TvStreamConfigWrapper>(
43 new TvStreamConfigWrapper(11, 360, 480, false))}};
44 mStreamConfigs[3] = {{5, shared_ptr<TvStreamConfigWrapper>(
45 new TvStreamConfigWrapper(5, 1080, 1920, false))}};
46 }
47
setCallback(const shared_ptr<ITvInputCallback> & in_callback)48 ::ndk::ScopedAStatus TvInput::setCallback(const shared_ptr<ITvInputCallback>& in_callback) {
49 ALOGV("%s", __FUNCTION__);
50
51 mCallback = in_callback;
52
53 TvInputEvent event;
54 event.type = TvInputEventType::DEVICE_AVAILABLE;
55
56 event.deviceInfo = mDeviceInfos[0]->deviceInfo;
57 mCallback->notify(event);
58
59 event.deviceInfo = mDeviceInfos[1]->deviceInfo;
60 mCallback->notify(event);
61
62 event.deviceInfo = mDeviceInfos[3]->deviceInfo;
63 mCallback->notify(event);
64
65 return ::ndk::ScopedAStatus::ok();
66 }
67
setTvMessageEnabled(int32_t deviceId,int32_t streamId,TvMessageEventType in_type,bool enabled)68 ::ndk::ScopedAStatus TvInput::setTvMessageEnabled(int32_t deviceId, int32_t streamId,
69 TvMessageEventType in_type, bool enabled) {
70 ALOGV("%s", __FUNCTION__);
71
72 if (mStreamConfigs.count(deviceId) == 0) {
73 ALOGW("Device with id %d isn't available", deviceId);
74 return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
75 }
76
77 mTvMessageEventEnabled[deviceId][streamId][in_type] = enabled;
78 return ::ndk::ScopedAStatus::ok();
79 }
80
getTvMessageQueueDesc(MQDescriptor<int8_t,SynchronizedReadWrite> * out_queue,int32_t in_deviceId,int32_t in_streamId)81 ::ndk::ScopedAStatus TvInput::getTvMessageQueueDesc(
82 MQDescriptor<int8_t, SynchronizedReadWrite>* out_queue, int32_t in_deviceId,
83 int32_t in_streamId) {
84 ALOGV("%s", __FUNCTION__);
85 if (mStreamConfigs.count(in_deviceId) == 0) {
86 ALOGW("Device with id %d isn't available", in_deviceId);
87 return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
88 }
89 return ::ndk::ScopedAStatus::ok();
90 }
91
getStreamConfigurations(int32_t in_deviceId,vector<TvStreamConfig> * _aidl_return)92 ::ndk::ScopedAStatus TvInput::getStreamConfigurations(int32_t in_deviceId,
93 vector<TvStreamConfig>* _aidl_return) {
94 ALOGV("%s", __FUNCTION__);
95
96 if (mStreamConfigs.count(in_deviceId) == 0) {
97 ALOGW("Device with id %d isn't available", in_deviceId);
98 return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
99 }
100
101 for (auto const& iconfig : mStreamConfigs[in_deviceId]) {
102 _aidl_return->push_back(iconfig.second->streamConfig);
103 }
104
105 return ::ndk::ScopedAStatus::ok();
106 }
107
openStream(int32_t in_deviceId,int32_t in_streamId,NativeHandle * _aidl_return)108 ::ndk::ScopedAStatus TvInput::openStream(int32_t in_deviceId, int32_t in_streamId,
109 NativeHandle* _aidl_return) {
110 ALOGV("%s", __FUNCTION__);
111
112 if (mStreamConfigs.count(in_deviceId) == 0 ||
113 mStreamConfigs[in_deviceId].count(in_streamId) == 0) {
114 ALOGW("Stream with device id %d, stream id %d isn't available", in_deviceId, in_streamId);
115 return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
116 }
117 if (mStreamConfigs[in_deviceId][in_streamId]->isOpen) {
118 ALOGW("Stream with device id %d, stream id %d is already opened", in_deviceId, in_streamId);
119 return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_STATE);
120 }
121 mStreamConfigs[in_deviceId][in_streamId]->handle = createNativeHandle(in_streamId);
122 *_aidl_return = makeToAidl(mStreamConfigs[in_deviceId][in_streamId]->handle);
123 mStreamConfigs[in_deviceId][in_streamId]->isOpen = true;
124 return ::ndk::ScopedAStatus::ok();
125 }
126
closeStream(int32_t in_deviceId,int32_t in_streamId)127 ::ndk::ScopedAStatus TvInput::closeStream(int32_t in_deviceId, int32_t in_streamId) {
128 ALOGV("%s", __FUNCTION__);
129
130 if (mStreamConfigs.count(in_deviceId) == 0 ||
131 mStreamConfigs[in_deviceId].count(in_streamId) == 0) {
132 ALOGW("Stream with device id %d, stream id %d isn't available", in_deviceId, in_streamId);
133 return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
134 }
135 if (!mStreamConfigs[in_deviceId][in_streamId]->isOpen) {
136 ALOGW("Stream with device id %d, stream id %d is already closed", in_deviceId, in_streamId);
137 return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_STATE);
138 }
139 native_handle_delete(mStreamConfigs[in_deviceId][in_streamId]->handle);
140 mStreamConfigs[in_deviceId][in_streamId]->handle = nullptr;
141 mStreamConfigs[in_deviceId][in_streamId]->isOpen = false;
142 return ::ndk::ScopedAStatus::ok();
143 }
144
createNativeHandle(int fd)145 native_handle_t* TvInput::createNativeHandle(int fd) {
146 native_handle_t* handle = native_handle_create(1, 1);
147 if (handle == nullptr) {
148 ALOGE("[TVInput] Failed to create native_handle %d", errno);
149 return nullptr;
150 }
151 handle->data[0] = dup(0);
152 handle->data[1] = fd;
153 return handle;
154 }
155
156 } // namespace input
157 } // namespace tv
158 } // namespace hardware
159 } // namespace android
160 } // namespace aidl
161