• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     mQueue = shared_ptr<AidlMessageQueue<int8_t, SynchronizedReadWrite>>(
48             new (std::nothrow) AidlMessageQueue<int8_t, SynchronizedReadWrite>(8));
49 }
50 
setCallback(const shared_ptr<ITvInputCallback> & in_callback)51 ::ndk::ScopedAStatus TvInput::setCallback(const shared_ptr<ITvInputCallback>& in_callback) {
52     ALOGV("%s", __FUNCTION__);
53 
54     mCallback = in_callback;
55 
56     TvInputEvent event;
57     event.type = TvInputEventType::DEVICE_AVAILABLE;
58 
59     event.deviceInfo = mDeviceInfos[0]->deviceInfo;
60     mCallback->notify(event);
61 
62     event.deviceInfo = mDeviceInfos[1]->deviceInfo;
63     mCallback->notify(event);
64 
65     event.deviceInfo = mDeviceInfos[3]->deviceInfo;
66     mCallback->notify(event);
67 
68     return ::ndk::ScopedAStatus::ok();
69 }
70 
setTvMessageEnabled(int32_t deviceId,int32_t streamId,TvMessageEventType in_type,bool enabled)71 ::ndk::ScopedAStatus TvInput::setTvMessageEnabled(int32_t deviceId, int32_t streamId,
72                                                   TvMessageEventType in_type, bool enabled) {
73     ALOGV("%s", __FUNCTION__);
74 
75     if (mStreamConfigs.count(deviceId) == 0) {
76         ALOGW("Device with id %d isn't available", deviceId);
77         return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
78     }
79 
80     // When calling notifyTvMessage, make sure to verify against this map.
81     mTvMessageEventEnabled[deviceId][streamId][in_type] = enabled;
82 
83     return ::ndk::ScopedAStatus::ok();
84 }
85 
getTvMessageQueueDesc(MQDescriptor<int8_t,SynchronizedReadWrite> * out_queue,int32_t in_deviceId,int32_t in_streamId)86 ::ndk::ScopedAStatus TvInput::getTvMessageQueueDesc(
87         MQDescriptor<int8_t, SynchronizedReadWrite>* out_queue, int32_t in_deviceId,
88         int32_t in_streamId) {
89     ALOGV("%s", __FUNCTION__);
90     ::ndk::ScopedAStatus status = ::ndk::ScopedAStatus::ok();
91     if (mStreamConfigs.count(in_deviceId) == 0) {
92         ALOGW("Device with id %d isn't available", in_deviceId);
93         status = ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
94     } else if (!mQueue->isValid()) {
95         ALOGE("Tv Message Queue was not properly initialized");
96         status = ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_STATE);
97     } else {
98         *out_queue = mQueue->dupeDesc();
99     }
100     return status;
101 }
102 
getStreamConfigurations(int32_t in_deviceId,vector<TvStreamConfig> * _aidl_return)103 ::ndk::ScopedAStatus TvInput::getStreamConfigurations(int32_t in_deviceId,
104                                                       vector<TvStreamConfig>* _aidl_return) {
105     ALOGV("%s", __FUNCTION__);
106 
107     if (mStreamConfigs.count(in_deviceId) == 0) {
108         ALOGW("Device with id %d isn't available", in_deviceId);
109         return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
110     }
111 
112     for (auto const& iconfig : mStreamConfigs[in_deviceId]) {
113         _aidl_return->push_back(iconfig.second->streamConfig);
114     }
115 
116     return ::ndk::ScopedAStatus::ok();
117 }
118 
openStream(int32_t in_deviceId,int32_t in_streamId,NativeHandle * _aidl_return)119 ::ndk::ScopedAStatus TvInput::openStream(int32_t in_deviceId, int32_t in_streamId,
120                                          NativeHandle* _aidl_return) {
121     ALOGV("%s", __FUNCTION__);
122 
123     if (mStreamConfigs.count(in_deviceId) == 0 ||
124         mStreamConfigs[in_deviceId].count(in_streamId) == 0) {
125         ALOGW("Stream with device id %d, stream id %d isn't available", in_deviceId, in_streamId);
126         return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
127     }
128     if (mStreamConfigs[in_deviceId][in_streamId]->isOpen) {
129         ALOGW("Stream with device id %d, stream id %d is already opened", in_deviceId, in_streamId);
130         return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_STATE);
131     }
132     mStreamConfigs[in_deviceId][in_streamId]->handle = createNativeHandle(in_streamId);
133     *_aidl_return = makeToAidl(mStreamConfigs[in_deviceId][in_streamId]->handle);
134     mStreamConfigs[in_deviceId][in_streamId]->isOpen = true;
135     return ::ndk::ScopedAStatus::ok();
136 }
137 
closeStream(int32_t in_deviceId,int32_t in_streamId)138 ::ndk::ScopedAStatus TvInput::closeStream(int32_t in_deviceId, int32_t in_streamId) {
139     ALOGV("%s", __FUNCTION__);
140 
141     if (mStreamConfigs.count(in_deviceId) == 0 ||
142         mStreamConfigs[in_deviceId].count(in_streamId) == 0) {
143         ALOGW("Stream with device id %d, stream id %d isn't available", in_deviceId, in_streamId);
144         return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
145     }
146     if (!mStreamConfigs[in_deviceId][in_streamId]->isOpen) {
147         ALOGW("Stream with device id %d, stream id %d is already closed", in_deviceId, in_streamId);
148         return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_STATE);
149     }
150     native_handle_delete(mStreamConfigs[in_deviceId][in_streamId]->handle);
151     mStreamConfigs[in_deviceId][in_streamId]->handle = nullptr;
152     mStreamConfigs[in_deviceId][in_streamId]->isOpen = false;
153     return ::ndk::ScopedAStatus::ok();
154 }
155 
createNativeHandle(int fd)156 native_handle_t* TvInput::createNativeHandle(int fd) {
157     native_handle_t* handle = native_handle_create(1, 1);
158     if (handle == nullptr) {
159         ALOGE("[TVInput] Failed to create native_handle %d", errno);
160         return nullptr;
161     }
162     handle->data[0] = dup(0);
163     handle->data[1] = fd;
164     return handle;
165 }
166 
167 }  // namespace input
168 }  // namespace tv
169 }  // namespace hardware
170 }  // namespace android
171 }  // namespace aidl
172