1 /*
2 * Copyright (C) 2019 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 // Unit Test for ECOService.
18
19 #define LOG_NDEBUG 0
20 #define LOG_TAG "ECOServiceTest"
21
22 #include <android-base/unique_fd.h>
23 #include <android/binder_auto_utils.h>
24 #include <android/binder_manager.h>
25 #include <android/binder_parcel.h>
26 #include <cutils/ashmem.h>
27 #include <gtest/gtest.h>
28 #include <math.h>
29 #include <stdlib.h>
30 #include <sys/mman.h>
31 #include <utils/Log.h>
32 #include <utils/Timers.h>
33
34 #include "FakeECOServiceInfoListener.h"
35 #include "FakeECOServiceStatsProvider.h"
36 #include "eco/ECOService.h"
37 #include "eco/ECOUtils.h"
38
39 namespace android {
40 namespace media {
41 namespace eco {
42
43 using ::ndk::ScopedAStatus;
44
45 namespace {
46
47 static constexpr uint32_t kTestWidth = 1280;
48 static constexpr uint32_t kTestHeight = 720;
49 static constexpr bool kIsCameraRecording = true;
50 static constexpr float kFrameRate = 30.0f;
51
52 } // namespace
53
54 // A helper class to help create ECOService and manage ECOService.
55 class EcoServiceTest : public ::testing::Test {
56 public:
EcoServiceTest()57 EcoServiceTest() { ALOGD("EcoServiceTest created"); }
58
createService()59 std::shared_ptr<IECOService> createService() {
60 mECOService = IECOService::fromBinder(
61 ndk::SpAIBinder(AServiceManager_waitForService("media.ecoservice")));
62 if (mECOService == nullptr) {
63 ALOGE("Failed to connect to ecoservice");
64 return nullptr;
65 }
66
67 return mECOService;
68 }
69
~EcoServiceTest()70 ~EcoServiceTest() { ALOGD("EcoServiceTest destroyed"); }
71
72 private:
73 std::shared_ptr<IECOService> mECOService = nullptr;
74 };
75
TEST_F(EcoServiceTest,NormalObtainSessionWithInvalidWidth)76 TEST_F(EcoServiceTest, NormalObtainSessionWithInvalidWidth) {
77 std::shared_ptr<IECOService> service = createService();
78 EXPECT_TRUE(service != nullptr);
79
80 // Provider obtains the session from the service.
81 std::shared_ptr<IECOSession> session = nullptr;
82
83 service->obtainSession(-1 /* width */, kTestHeight, kIsCameraRecording, &session);
84 EXPECT_FALSE(session);
85 }
86
TEST_F(EcoServiceTest,NormalObtainSessionWithInvalidHeight)87 TEST_F(EcoServiceTest, NormalObtainSessionWithInvalidHeight) {
88 std::shared_ptr<IECOService> service = createService();
89
90 // Provider obtains the session from the service.
91 std::shared_ptr<IECOSession> session = nullptr;
92
93 service->obtainSession(kTestWidth, -1 /* height */, kIsCameraRecording, &session);
94 EXPECT_FALSE(session);
95 }
96
TEST_F(EcoServiceTest,NormalObtainSessionWithCameraRecordingFalse)97 TEST_F(EcoServiceTest, NormalObtainSessionWithCameraRecordingFalse) {
98 std::shared_ptr<IECOService> service = createService();
99
100 // Provider obtains the session from the service.
101 std::shared_ptr<IECOSession> session = nullptr;
102
103 service->obtainSession(kTestWidth, kTestHeight, false /* isCameraRecording */, &session);
104 EXPECT_TRUE(session);
105 }
106
TEST_F(EcoServiceTest,NormalObtainSingleSession)107 TEST_F(EcoServiceTest, NormalObtainSingleSession) {
108 std::shared_ptr<IECOService> service = createService();
109 EXPECT_TRUE(service != nullptr);
110
111 // Provider obtains the session from the service.
112 std::shared_ptr<IECOSession> session = nullptr;
113
114 service->obtainSession(kTestWidth, kTestHeight, kIsCameraRecording, &session);
115 EXPECT_TRUE(session);
116 }
117
TEST_F(EcoServiceTest,NormalObtainSessionTwice)118 TEST_F(EcoServiceTest, NormalObtainSessionTwice) {
119 std::shared_ptr<IECOService> service = createService();
120 EXPECT_TRUE(service != nullptr);
121
122 // Provider obtains the session from the service.
123 std::shared_ptr<IECOSession> session1 = nullptr;
124
125 service->obtainSession(kTestWidth, kTestHeight, kIsCameraRecording, &session1);
126 EXPECT_TRUE(session1);
127
128 std::shared_ptr<IECOSession> session2 = nullptr;
129
130 service->obtainSession(kTestWidth, kTestHeight, kIsCameraRecording, &session2);
131 EXPECT_TRUE(session2);
132
133 // The two session instances should be the same.
134 EXPECT_TRUE(session1->asBinder() == session2->asBinder());
135 }
136
TEST_F(EcoServiceTest,ObtainTwoSessions)137 TEST_F(EcoServiceTest, ObtainTwoSessions) {
138 std::shared_ptr<IECOService> service = createService();
139 EXPECT_TRUE(service != nullptr);
140
141 // Provider obtains the session from the service.
142 std::shared_ptr<IECOSession> session1 = nullptr;
143
144 service->obtainSession(kTestWidth, kTestHeight, kIsCameraRecording, &session1);
145 EXPECT_TRUE(session1);
146
147 std::shared_ptr<IECOSession> session2 = nullptr;
148
149 service->obtainSession(kTestWidth - 1, kTestHeight - 1, kIsCameraRecording, &session2);
150 EXPECT_TRUE(session2);
151
152 // The two session instances must not be the same.
153 EXPECT_TRUE(session1->asBinder() != session2->asBinder());
154
155 // Check the session number.
156 int32_t count = 0;
157 service->getNumOfSessions(&count);
158 EXPECT_EQ(count, 2);
159
160 // Get the list of sessions from service.
161 std::vector<::ndk::SpAIBinder> sessionList;
162 service->getSessions(&sessionList);
163 bool foundFirstSession = false, foundSecondSession = false;
164
165 for (std::vector<::ndk::SpAIBinder>::iterator it = sessionList.begin(); it != sessionList.end();
166 ++it) {
167 if (session1->asBinder() == it->get()) {
168 foundFirstSession = true;
169 }
170 if (session2->asBinder() == it->get()) {
171 foundSecondSession = true;
172 }
173 }
174
175 // Expect found both sessions.
176 EXPECT_TRUE(foundFirstSession);
177 EXPECT_TRUE(foundSecondSession);
178 }
179
TEST_F(EcoServiceTest,TestNormalFlowWithOneListenerAndOneProvider)180 TEST_F(EcoServiceTest, TestNormalFlowWithOneListenerAndOneProvider) {
181 std::shared_ptr<IECOService> service = createService();
182 EXPECT_TRUE(service != nullptr);
183
184 // Provider obtains the session from the service.
185 std::shared_ptr<IECOSession> session = nullptr;
186
187 service->obtainSession(kTestWidth, kTestHeight, kIsCameraRecording, &session);
188 EXPECT_TRUE(session);
189
190 // Create provider and add it to the session.
191 std::shared_ptr<FakeECOServiceStatsProvider> fakeProvider =
192 ndk::SharedRefBase::make<FakeECOServiceStatsProvider>(kTestWidth, kTestHeight,
193 kIsCameraRecording, kFrameRate);
194 fakeProvider->setECOSession(session);
195
196 ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG,
197 systemTime(SYSTEM_TIME_BOOTTIME));
198 providerConfig.setString(KEY_PROVIDER_NAME, "FakeECOServiceStatsProvider");
199 providerConfig.setInt32(KEY_PROVIDER_TYPE,
200 ECOServiceStatsProvider::STATS_PROVIDER_TYPE_VIDEO_ENCODER);
201 bool res;
202 ScopedAStatus status = session->addStatsProvider(fakeProvider, providerConfig, &res);
203
204 // Create listener and add it to the session.
205 std::shared_ptr<FakeECOServiceInfoListener> fakeListener =
206 ndk::SharedRefBase::make<FakeECOServiceInfoListener>(kTestWidth, kTestHeight,
207 kIsCameraRecording);
208 fakeListener->setECOSession(session);
209
210 // Create the listener config.
211 ECOData listenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG,
212 systemTime(SYSTEM_TIME_BOOTTIME));
213 listenerConfig.setString(KEY_LISTENER_NAME, "FakeECOServiceInfoListener");
214 listenerConfig.setInt32(KEY_LISTENER_TYPE, ECOServiceInfoListener::INFO_LISTENER_TYPE_CAMERA);
215
216 // Specify the qp thresholds for receiving notification.
217 listenerConfig.setInt32(KEY_LISTENER_QP_BLOCKINESS_THRESHOLD, 40);
218 listenerConfig.setInt32(KEY_LISTENER_QP_CHANGE_THRESHOLD, 5);
219
220 status = session->addInfoListener(fakeListener, listenerConfig, &res);
221 }
222
223 } // namespace eco
224 } // namespace media
225 } // namespace android
226