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 
HidlTvInputCallback(JTvInputHal * hal)62 JTvInputHal::HidlTvInputCallback::HidlTvInputCallback(JTvInputHal* hal) {
63     mHal = hal;
64 }
65 
notify(const HidlTvInputEvent & event)66 Return<void> JTvInputHal::HidlTvInputCallback::notify(const HidlTvInputEvent& event) {
67     mHal->mLooper->sendMessage(new NotifyHandler(mHal,
68                                                  TvInputEventWrapper::createEventWrapper(event)),
69                                static_cast<int>(event.type));
70     return Void();
71 }
72 
ITvInputWrapper(sp<HidlITvInput> & hidlTvInput)73 JTvInputHal::ITvInputWrapper::ITvInputWrapper(sp<HidlITvInput>& hidlTvInput)
74       : mIsHidl(true), mHidlTvInput(hidlTvInput) {}
75 
hidlSetCallback(const sp<HidlTvInputCallback> & in_callback)76 ::ndk::ScopedAStatus JTvInputHal::ITvInputWrapper::hidlSetCallback(
77         const sp<HidlTvInputCallback>& in_callback) {
78     mHidlTvInput->setCallback(in_callback);
79     return ::ndk::ScopedAStatus::ok();
80 }
81 
hidlGetStreamConfigurations(int32_t in_deviceId,std::vector<AidlTvStreamConfig> * _aidl_return)82 ::ndk::ScopedAStatus JTvInputHal::ITvInputWrapper::hidlGetStreamConfigurations(
83         int32_t in_deviceId, std::vector<AidlTvStreamConfig>* _aidl_return) {
84     Result result = Result::UNKNOWN;
85     hidl_vec<HidlTvStreamConfig> list;
86     mHidlTvInput->getStreamConfigurations(in_deviceId,
87                                           [&result, &list](Result res,
88                                                            hidl_vec<HidlTvStreamConfig> configs) {
89                                               result = res;
90                                               if (res == Result::OK) {
91                                                   list = configs;
92                                               }
93                                           });
94     if (result != Result::OK) {
95         ALOGE("Couldn't get stream configs for device id:%d result:%d", in_deviceId, result);
96         return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(result));
97     }
98     for (size_t i = 0; i < list.size(); ++i) {
99         AidlTvStreamConfig config;
100         config.streamId = list[i].streamId;
101         config.maxVideoHeight = list[i].maxVideoHeight;
102         config.maxVideoWidth = list[i].maxVideoWidth;
103         _aidl_return->push_back(config);
104     }
105     return ::ndk::ScopedAStatus::ok();
106 }
107 
hidlOpenStream(int32_t in_deviceId,int32_t in_streamId,AidlNativeHandle * _aidl_return)108 ::ndk::ScopedAStatus JTvInputHal::ITvInputWrapper::hidlOpenStream(int32_t in_deviceId,
109                                                                   int32_t in_streamId,
110                                                                   AidlNativeHandle* _aidl_return) {
111     Result result = Result::UNKNOWN;
112     native_handle_t* sidebandStream;
113     mHidlTvInput->openStream(in_deviceId, in_streamId,
114                              [&result, &sidebandStream](Result res, const native_handle_t* handle) {
115                                  result = res;
116                                  if (res == Result::OK) {
117                                      if (handle) {
118                                          sidebandStream = native_handle_clone(handle);
119                                      }
120                                  }
121                              });
122     if (result != Result::OK) {
123         ALOGE("Couldn't open stream. device id:%d stream id:%d result:%d", in_deviceId, in_streamId,
124               result);
125         return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(result));
126     }
127     *_aidl_return = makeToAidl(sidebandStream);
128     native_handle_delete(sidebandStream);
129     return ::ndk::ScopedAStatus::ok();
130 }
131 
hidlCloseStream(int32_t in_deviceId,int32_t in_streamId)132 ::ndk::ScopedAStatus JTvInputHal::ITvInputWrapper::hidlCloseStream(int32_t in_deviceId,
133                                                                    int32_t in_streamId) {
134     Result result = mHidlTvInput->closeStream(in_deviceId, in_streamId);
135     if (result != Result::OK) {
136         return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(result));
137     }
138     return ::ndk::ScopedAStatus::ok();
139 }
140 
141 } // namespace android
142