1 /*
2  * Copyright 2020 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 <android-base/logging.h>
18 #include <android/hardware/tv/tuner/1.0/IFrontend.h>
19 #include <android/hardware/tv/tuner/1.0/IFrontendCallback.h>
20 #include <android/hardware/tv/tuner/1.0/ITuner.h>
21 #include <android/hardware/tv/tuner/1.0/types.h>
22 #include <binder/MemoryDealer.h>
23 #include <gtest/gtest.h>
24 #include <hidl/GtestPrinter.h>
25 #include <hidl/HidlSupport.h>
26 #include <hidl/HidlTransportSupport.h>
27 #include <hidl/ServiceManagement.h>
28 #include <hidl/Status.h>
29 #include <hidlmemory/FrameworkUtils.h>
30 #include <utils/Condition.h>
31 #include <utils/Mutex.h>
32 #include <map>
33 
34 #include "DvrTests.h"
35 #include "VtsHalTvTunerV1_0TestConfigurations.h"
36 
37 #define WAIT_TIMEOUT 3000000000
38 #define INVALID_ID -1
39 
40 using android::Condition;
41 using android::IMemory;
42 using android::IMemoryHeap;
43 using android::MemoryDealer;
44 using android::Mutex;
45 using android::sp;
46 using android::hardware::fromHeap;
47 using android::hardware::hidl_vec;
48 using android::hardware::Return;
49 using android::hardware::Void;
50 using android::hardware::tv::tuner::V1_0::FrontendAtscModulation;
51 using android::hardware::tv::tuner::V1_0::FrontendAtscSettings;
52 using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings;
53 using android::hardware::tv::tuner::V1_0::FrontendEventType;
54 using android::hardware::tv::tuner::V1_0::FrontendId;
55 using android::hardware::tv::tuner::V1_0::FrontendInfo;
56 using android::hardware::tv::tuner::V1_0::FrontendInnerFec;
57 using android::hardware::tv::tuner::V1_0::FrontendScanMessage;
58 using android::hardware::tv::tuner::V1_0::FrontendScanMessageType;
59 using android::hardware::tv::tuner::V1_0::FrontendScanType;
60 using android::hardware::tv::tuner::V1_0::FrontendSettings;
61 using android::hardware::tv::tuner::V1_0::IFrontend;
62 using android::hardware::tv::tuner::V1_0::IFrontendCallback;
63 using android::hardware::tv::tuner::V1_0::ITuner;
64 using android::hardware::tv::tuner::V1_0::Result;
65 
66 using ::testing::AssertionResult;
67 
68 using namespace std;
69 
70 #define INVALID_ID -1
71 #define WAIT_TIMEOUT 3000000000
72 
73 class FrontendCallback : public IFrontendCallback {
74   public:
75     virtual Return<void> onEvent(FrontendEventType frontendEventType) override;
76     virtual Return<void> onScanMessage(FrontendScanMessageType type,
77                                        const FrontendScanMessage& message) override;
78 
79     void tuneTestOnEventReceive(sp<IFrontend>& frontend, FrontendSettings settings);
80     void tuneTestOnLock(sp<IFrontend>& frontend, FrontendSettings settings);
81     void scanTest(sp<IFrontend>& frontend, FrontendConfig config, FrontendScanType type);
82 
83     // Helper methods
84     uint32_t getTargetFrequency(FrontendSettings settings, FrontendType type);
85     void resetBlindScanStartingFrequency(FrontendConfig& config, uint32_t resetingFreq);
86 
87   private:
88     bool mEventReceived = false;
89     bool mScanMessageReceived = false;
90     bool mLockMsgReceived = false;
91     bool mScanMsgProcessed = true;
92     FrontendScanMessageType mScanMessageType;
93     FrontendScanMessage mScanMessage;
94     hidl_vec<uint8_t> mEventMessage;
95     android::Mutex mMsgLock;
96     android::Condition mMsgCondition;
97     android::Condition mLockMsgCondition;
98 };
99 
100 class FrontendTests {
101   public:
102     sp<ITuner> mService;
103 
setService(sp<ITuner> tuner)104     void setService(sp<ITuner> tuner) {
105         mService = tuner;
106         getDvrTests()->setService(tuner);
107         getDefaultSoftwareFrontendPlaybackConfig(mDvrConfig);
108     }
109 
110     AssertionResult getFrontendIds();
111     AssertionResult getFrontendInfo(uint32_t frontendId);
112     AssertionResult openFrontendById(uint32_t frontendId);
113     AssertionResult setFrontendCallback();
114     AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type);
115     AssertionResult stopScanFrontend();
116     AssertionResult tuneFrontend(FrontendConfig config, bool testWithDemux);
117     AssertionResult setLnb(uint32_t lnbId);
118     void verifyFrontendStatus(vector<FrontendStatusType> statusTypes,
119                               vector<FrontendStatus> expectStatuses);
120     AssertionResult stopTuneFrontend(bool testWithDemux);
121     AssertionResult closeFrontend();
122 
123     void getFrontendIdByType(FrontendType feType, uint32_t& feId);
124     void tuneTest(FrontendConfig frontendConf);
125     void scanTest(FrontendConfig frontend, FrontendScanType type);
126 
setDvrTests(DvrTests * dvrTests)127     void setDvrTests(DvrTests* dvrTests) { mExternalDvrTests = dvrTests; }
setDemux(sp<IDemux> demux)128     void setDemux(sp<IDemux> demux) { getDvrTests()->setDemux(demux); }
setSoftwareFrontendDvrConfig(DvrConfig conf)129     void setSoftwareFrontendDvrConfig(DvrConfig conf) { mDvrConfig = conf; }
130 
131   protected:
failure()132     static AssertionResult failure() { return ::testing::AssertionFailure(); }
success()133     static AssertionResult success() { return ::testing::AssertionSuccess(); }
134 
135     // TODO: replace with customized dvr input
getDefaultSoftwareFrontendPlaybackConfig(DvrConfig & dvrConfig)136     void getDefaultSoftwareFrontendPlaybackConfig(DvrConfig& dvrConfig) {
137         PlaybackSettings playbackSettings{
138                 .statusMask = 0xf,
139                 .lowThreshold = 0x1000,
140                 .highThreshold = 0x07fff,
141                 .dataFormat = DataFormat::TS,
142                 .packetSize = 188,
143         };
144         dvrConfig.type = DvrType::PLAYBACK;
145         dvrConfig.playbackInputFile = "/data/local/tmp/segment000000.ts";
146         dvrConfig.bufferSize = FMQ_SIZE_4M;
147         dvrConfig.settings.playback(playbackSettings);
148     }
149 
getDvrTests()150     DvrTests* getDvrTests() {
151         return (mExternalDvrTests != nullptr ? mExternalDvrTests : &mDvrTests);
152     }
153 
154     sp<IFrontend> mFrontend;
155     FrontendInfo mFrontendInfo;
156     sp<FrontendCallback> mFrontendCallback;
157     hidl_vec<FrontendId> mFeIds;
158 
159     DvrTests* mExternalDvrTests = nullptr;
160     DvrTests mDvrTests;
161     bool mIsSoftwareFe = false;
162     DvrConfig mDvrConfig;
163 };
164