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 #include "JTvInputHal.h"
18 
19 // Implement all HIDL related functions here.
20 
21 namespace android {
22 
hidlSetUpAudioInfo(JNIEnv * env,jobject & builder,const TvInputDeviceInfoWrapper & info)23 void JTvInputHal::hidlSetUpAudioInfo(JNIEnv* env, jobject& builder,
24                                      const TvInputDeviceInfoWrapper& info) {
25     env->CallObjectMethod(builder, gTvInputHardwareInfoBuilderClassInfo.audioType,
26                           info.hidlAudioType);
27     if (info.hidlAudioType != HidlAudioDevice::NONE) {
28         uint8_t buffer[info.hidlAudioAddress.size() + 1];
29         memcpy(buffer, info.hidlAudioAddress.data(), info.hidlAudioAddress.size());
30         buffer[info.hidlAudioAddress.size()] = '\0';
31         jstring audioAddress = env->NewStringUTF(reinterpret_cast<const char*>(buffer));
32         env->CallObjectMethod(builder, gTvInputHardwareInfoBuilderClassInfo.audioAddress,
33                               audioAddress);
34         env->DeleteLocalRef(audioAddress);
35     }
36 }
37 
38 JTvInputHal::TvInputDeviceInfoWrapper
createDeviceInfoWrapper(const HidlTvInputDeviceInfo & hidlTvInputDeviceInfo)39 JTvInputHal::TvInputDeviceInfoWrapper::createDeviceInfoWrapper(
40         const HidlTvInputDeviceInfo& hidlTvInputDeviceInfo) {
41     TvInputDeviceInfoWrapper deviceInfo;
42     deviceInfo.isHidl = true;
43     deviceInfo.deviceId = hidlTvInputDeviceInfo.deviceId;
44     deviceInfo.type = TvInputType(static_cast<int32_t>(hidlTvInputDeviceInfo.type));
45     deviceInfo.portId = hidlTvInputDeviceInfo.portId;
46     deviceInfo.cableConnectionStatus = CableConnectionStatus(
47             static_cast<int32_t>(hidlTvInputDeviceInfo.cableConnectionStatus));
48     deviceInfo.hidlAudioType = hidlTvInputDeviceInfo.audioType;
49     deviceInfo.hidlAudioAddress = hidlTvInputDeviceInfo.audioAddress;
50     return deviceInfo;
51 }
52 
createEventWrapper(const HidlTvInputEvent & hidlTvInputEvent)53 JTvInputHal::TvInputEventWrapper JTvInputHal::TvInputEventWrapper::createEventWrapper(
54         const HidlTvInputEvent& hidlTvInputEvent) {
55     TvInputEventWrapper event;
56     event.type = TvInputEventType(static_cast<int32_t>(hidlTvInputEvent.type));
57     event.deviceInfo =
58             TvInputDeviceInfoWrapper::createDeviceInfoWrapper(hidlTvInputEvent.deviceInfo);
59     return event;
60 }
61 
notify(const HidlTvInputEvent & event)62 Return<void> JTvInputHal::TvInputCallback::notify(const HidlTvInputEvent& event) {
63     mHal->mLooper->sendMessage(new NotifyHandler(mHal,
64                                                  TvInputEventWrapper::createEventWrapper(event)),
65                                static_cast<int>(event.type));
66     return Void();
67 }
68 
ITvInputWrapper(sp<HidlITvInput> & hidlTvInput)69 JTvInputHal::ITvInputWrapper::ITvInputWrapper(sp<HidlITvInput>& hidlTvInput)
70       : mIsHidl(true), mHidlTvInput(hidlTvInput) {}
71 
hidlSetCallback(const std::shared_ptr<TvInputCallback> & in_callback)72 ::ndk::ScopedAStatus JTvInputHal::ITvInputWrapper::hidlSetCallback(
73         const std::shared_ptr<TvInputCallback>& in_callback) {
74     mHidlTvInput->setCallback(in_callback == nullptr ? nullptr
75                                                      : sp<TvInputCallback>(in_callback.get()));
76     return ::ndk::ScopedAStatus::ok();
77 }
78 
hidlGetStreamConfigurations(int32_t in_deviceId,std::vector<AidlTvStreamConfig> * _aidl_return)79 ::ndk::ScopedAStatus JTvInputHal::ITvInputWrapper::hidlGetStreamConfigurations(
80         int32_t in_deviceId, std::vector<AidlTvStreamConfig>* _aidl_return) {
81     Result result = Result::UNKNOWN;
82     hidl_vec<HidlTvStreamConfig> list;
83     mHidlTvInput->getStreamConfigurations(in_deviceId,
84                                           [&result, &list](Result res,
85                                                            hidl_vec<HidlTvStreamConfig> configs) {
86                                               result = res;
87                                               if (res == Result::OK) {
88                                                   list = configs;
89                                               }
90                                           });
91     if (result != Result::OK) {
92         ALOGE("Couldn't get stream configs for device id:%d result:%d", in_deviceId, result);
93         return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(result));
94     }
95     for (size_t i = 0; i < list.size(); ++i) {
96         AidlTvStreamConfig config;
97         config.streamId = list[i].streamId;
98         config.maxVideoHeight = list[i].maxVideoHeight;
99         config.maxVideoWidth = list[i].maxVideoWidth;
100         _aidl_return->push_back(config);
101     }
102     return ::ndk::ScopedAStatus::ok();
103 }
104 
hidlOpenStream(int32_t in_deviceId,int32_t in_streamId,AidlNativeHandle * _aidl_return)105 ::ndk::ScopedAStatus JTvInputHal::ITvInputWrapper::hidlOpenStream(int32_t in_deviceId,
106                                                                   int32_t in_streamId,
107                                                                   AidlNativeHandle* _aidl_return) {
108     Result result = Result::UNKNOWN;
109     native_handle_t* sidebandStream;
110     mHidlTvInput->openStream(in_deviceId, in_streamId,
111                              [&result, &sidebandStream](Result res, const native_handle_t* handle) {
112                                  result = res;
113                                  if (res == Result::OK) {
114                                      if (handle) {
115                                          sidebandStream = native_handle_clone(handle);
116                                      }
117                                  }
118                              });
119     if (result != Result::OK) {
120         ALOGE("Couldn't open stream. device id:%d stream id:%d result:%d", in_deviceId, in_streamId,
121               result);
122         return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(result));
123     }
124     *_aidl_return = makeToAidl(sidebandStream);
125     native_handle_delete(sidebandStream);
126     return ::ndk::ScopedAStatus::ok();
127 }
128 
hidlCloseStream(int32_t in_deviceId,int32_t in_streamId)129 ::ndk::ScopedAStatus JTvInputHal::ITvInputWrapper::hidlCloseStream(int32_t in_deviceId,
130                                                                    int32_t in_streamId) {
131     Result result = mHidlTvInput->closeStream(in_deviceId, in_streamId);
132     if (result != Result::OK) {
133         return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(result));
134     }
135     return ::ndk::ScopedAStatus::ok();
136 }
137 
138 } // namespace android
139