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 ECOSession.
18 
19 //#define LOG_NDEBUG 0
20 #define LOG_TAG "ECOSessionTest"
21 
22 #include <android-base/unique_fd.h>
23 #include <binder/Parcel.h>
24 #include <binder/Parcelable.h>
25 #include <cutils/ashmem.h>
26 #include <gtest/gtest.h>
27 #include <math.h>
28 #include <stdlib.h>
29 #include <sys/mman.h>
30 #include <utils/Log.h>
31 
32 #include "FakeECOServiceInfoListener.h"
33 #include "FakeECOServiceStatsProvider.h"
34 #include "eco/ECOSession.h"
35 #include "eco/ECOUtils.h"
36 
37 namespace android {
38 namespace media {
39 namespace eco {
40 
41 using android::sp;
42 using ::android::binder::Status;
43 
44 static constexpr uint32_t kTestWidth = 1280;
45 static constexpr uint32_t kTestHeight = 720;
46 static constexpr bool kIsCameraRecording = true;
47 static constexpr int32_t kTargetBitrateBps = 22000000;
48 static constexpr int32_t kKeyFrameIntervalFrames = 30;
49 static constexpr float kFrameRate = 30.0f;
50 
51 // A helpful class to help create ECOSession and manage ECOSession.
52 class EcoSessionTest : public ::testing::Test {
53 public:
EcoSessionTest()54     EcoSessionTest() { ALOGD("EcoSessionTest created"); }
55 
createSession(int32_t width,int32_t height,bool isCameraRecording)56     sp<ECOSession> createSession(int32_t width, int32_t height, bool isCameraRecording) {
57         mSession = ECOSession::createECOSession(width, height, isCameraRecording);
58         if (mSession == nullptr) return nullptr;
59         return mSession;
60     }
61 
62 private:
63     sp<ECOSession> mSession = nullptr;
64 };
65 
TEST_F(EcoSessionTest,TestConstructorWithInvalidParameters)66 TEST_F(EcoSessionTest, TestConstructorWithInvalidParameters) {
67     // Expects failure as ECOService1.0 will only support up to 720P and camera recording case.
68     EXPECT_TRUE(createSession(1920 /* width */, 1080 /* height */, true /* isCameraRecording */) ==
69                 nullptr);
70 
71     // Expects failure as ECOService1.0 will only support up to 720P and camera recording case.
72     EXPECT_TRUE(createSession(1920 /* width */, 1080 /* height */, false /* isCameraRecording */) ==
73                 nullptr);
74 
75     EXPECT_TRUE(createSession(1920 /* width */, -1 /* height */, true /* isCameraRecording */) ==
76                 nullptr);
77 
78     EXPECT_TRUE(createSession(-1 /* width */, 1080 /* height */, true /* isCameraRecording */) ==
79                 nullptr);
80 }
81 
TEST_F(EcoSessionTest,TestConstructorWithValidParameters)82 TEST_F(EcoSessionTest, TestConstructorWithValidParameters) {
83     // Expects success with <= 720P and is for camera recording.
84     EXPECT_TRUE(createSession(1280 /* width */, 720 /* height */, true /* isCameraRecording */) !=
85                 nullptr);
86 
87     // Expects success with <= 720P and is for camera recording.
88     EXPECT_TRUE(createSession(640 /* width */, 480 /* height */, true /* isCameraRecording */) !=
89                 nullptr);
90 }
91 
TEST_F(EcoSessionTest,TestAddProviderWithoutSpecifyEcoDataType)92 TEST_F(EcoSessionTest, TestAddProviderWithoutSpecifyEcoDataType) {
93     sp<ECOSession> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
94     EXPECT_TRUE(ecoSession);
95 
96     sp<FakeECOServiceStatsProvider> fakeProvider = new FakeECOServiceStatsProvider(
97             kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
98 
99     ECOData providerConfig;
100     bool res;
101     Status status = ecoSession->addStatsProvider(fakeProvider, providerConfig, &res);
102     EXPECT_FALSE(status.isOk());
103 }
104 
TEST_F(EcoSessionTest,TestAddProviderWithWrongEcoDataType)105 TEST_F(EcoSessionTest, TestAddProviderWithWrongEcoDataType) {
106     sp<ECOSession> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
107     EXPECT_TRUE(ecoSession);
108 
109     sp<FakeECOServiceStatsProvider> fakeProvider = new FakeECOServiceStatsProvider(
110             kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
111 
112     ECOData providerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG,
113                            systemTime(SYSTEM_TIME_BOOTTIME));
114     bool res;
115     Status status = ecoSession->addStatsProvider(fakeProvider, providerConfig, &res);
116     EXPECT_FALSE(status.isOk());
117 }
118 
TEST_F(EcoSessionTest,TestAddNormalProvider)119 TEST_F(EcoSessionTest, TestAddNormalProvider) {
120     sp<ECOSession> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
121     EXPECT_TRUE(ecoSession);
122 
123     sp<FakeECOServiceStatsProvider> fakeProvider = new FakeECOServiceStatsProvider(
124             kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
125 
126     ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG,
127                            systemTime(SYSTEM_TIME_BOOTTIME));
128     bool res;
129     Status status = ecoSession->addStatsProvider(fakeProvider, providerConfig, &res);
130     EXPECT_TRUE(status.isOk());
131 }
132 
133 // Add two providers and expect failure as ECOService1.0 only supports one provider and one
134 // listener.
TEST_F(EcoSessionTest,TestAddTwoProvider)135 TEST_F(EcoSessionTest, TestAddTwoProvider) {
136     sp<ECOSession> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
137     EXPECT_TRUE(ecoSession);
138 
139     sp<FakeECOServiceStatsProvider> fakeProvider1 = new FakeECOServiceStatsProvider(
140             kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
141 
142     ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG,
143                            systemTime(SYSTEM_TIME_BOOTTIME));
144     bool res;
145     Status status = ecoSession->addStatsProvider(fakeProvider1, providerConfig, &res);
146     EXPECT_TRUE(status.isOk());
147 
148     sp<FakeECOServiceStatsProvider> fakeProvider2 = new FakeECOServiceStatsProvider(
149             kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
150     status = ecoSession->addStatsProvider(fakeProvider2, providerConfig, &res);
151     EXPECT_FALSE(status.isOk());
152 }
153 
TEST_F(EcoSessionTest,TestAddListenerWithDifferentHeight)154 TEST_F(EcoSessionTest, TestAddListenerWithDifferentHeight) {
155     sp<ECOSession> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
156     EXPECT_TRUE(ecoSession);
157 
158     sp<FakeECOServiceInfoListener> fakeListener = new FakeECOServiceInfoListener(
159             kTestWidth - 1, kTestHeight, kIsCameraRecording, ecoSession);
160 
161     ECOData ListenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG,
162                            systemTime(SYSTEM_TIME_BOOTTIME));
163     bool res;
164     Status status = ecoSession->addInfoListener(fakeListener, ListenerConfig, &res);
165     EXPECT_FALSE(status.isOk());
166 }
167 
TEST_F(EcoSessionTest,TestAddListenerWithDifferentWidth)168 TEST_F(EcoSessionTest, TestAddListenerWithDifferentWidth) {
169     sp<ECOSession> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
170     EXPECT_TRUE(ecoSession);
171 
172     sp<FakeECOServiceInfoListener> fakeListener = new FakeECOServiceInfoListener(
173             kTestWidth, kTestHeight - 1, kIsCameraRecording, ecoSession);
174 
175     ECOData ListenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG,
176                            systemTime(SYSTEM_TIME_BOOTTIME));
177     bool res;
178     Status status = ecoSession->addInfoListener(fakeListener, ListenerConfig, &res);
179     EXPECT_FALSE(status.isOk());
180 }
181 
TEST_F(EcoSessionTest,TestAddListenerWithCameraRecordingFalse)182 TEST_F(EcoSessionTest, TestAddListenerWithCameraRecordingFalse) {
183     sp<ECOSession> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
184     EXPECT_TRUE(ecoSession);
185 
186     sp<FakeECOServiceInfoListener> fakeListener = new FakeECOServiceInfoListener(
187             kTestWidth, kTestHeight, !kIsCameraRecording, ecoSession);
188 
189     ECOData ListenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG,
190                            systemTime(SYSTEM_TIME_BOOTTIME));
191     bool res;
192     Status status = ecoSession->addInfoListener(fakeListener, ListenerConfig, &res);
193     EXPECT_FALSE(status.isOk());
194 }
195 
196 // Test the ECOSession with FakeECOServiceStatsProvider and FakeECOServiceInfoListener. Push the
197 // stats to ECOSession through FakeECOServiceStatsProvider and check the info received in
198 // from FakeECOServiceInfoListener ECOSession.
TEST_F(EcoSessionTest,TestSessionWithProviderAndListenerSimpleTest)199 TEST_F(EcoSessionTest, TestSessionWithProviderAndListenerSimpleTest) {
200     // The time that listener needs to wait for the info from ECOService.
201     static constexpr int kServiceWaitTimeMs = 10;
202 
203     // Create the session.
204     sp<ECOSession> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
205 
206     // Add provider.
207     sp<FakeECOServiceStatsProvider> fakeProvider = new FakeECOServiceStatsProvider(
208             kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
209     ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG,
210                            systemTime(SYSTEM_TIME_BOOTTIME));
211     providerConfig.setString(KEY_PROVIDER_NAME, "FakeECOServiceStatsProvider");
212     providerConfig.setInt32(KEY_PROVIDER_TYPE,
213                             ECOServiceStatsProvider::STATS_PROVIDER_TYPE_VIDEO_ENCODER);
214     bool res;
215     Status status = ecoSession->addStatsProvider(fakeProvider, providerConfig, &res);
216 
217     // Create listener.
218     sp<FakeECOServiceInfoListener> fakeListener =
219             new FakeECOServiceInfoListener(kTestWidth, kTestHeight, kIsCameraRecording, ecoSession);
220 
221     // Create the listener config.
222     ECOData listenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG,
223                            systemTime(SYSTEM_TIME_BOOTTIME));
224     listenerConfig.setString(KEY_LISTENER_NAME, "FakeECOServiceInfoListener");
225     listenerConfig.setInt32(KEY_LISTENER_TYPE, ECOServiceInfoListener::INFO_LISTENER_TYPE_CAMERA);
226 
227     // Specify the qp thresholds for receiving notification.
228     listenerConfig.setInt32(KEY_LISTENER_QP_BLOCKINESS_THRESHOLD, 40);
229     listenerConfig.setInt32(KEY_LISTENER_QP_CHANGE_THRESHOLD, 5);
230 
231     status = ecoSession->addInfoListener(fakeListener, listenerConfig, &res);
232 
233     ECOData info;
234     bool getInfo = false;
235 
236     // Set the getInfo flag to true and copy the info from fakeListener.
237     fakeListener->setInfoAvailableCallback(
238             [&info, &getInfo](const ::android::media::eco::ECOData& newInfo) {
239                 getInfo = true;
240                 info = newInfo;
241             });
242 
243     // Inject the session stats into the ECOSession through fakeProvider.
244     SimpleEncoderConfig sessionEncoderConfig("google-avc", CodecTypeAVC, AVCProfileHigh, AVCLevel52,
245                                              kTargetBitrateBps, kKeyFrameIntervalFrames,
246                                              kFrameRate);
247     fakeProvider->injectSessionStats(sessionEncoderConfig.toEcoData(ECOData::DATA_TYPE_STATS));
248 
249     // Wait as ECOService may take some time to process.
250     std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
251     // Check the Session info matches with the session stats sent by provider.
252     EXPECT_TRUE(getInfo);
253     EXPECT_TRUE(info.getDataType() == ECOData::DATA_TYPE_INFO);
254 
255     std::string infoType;
256     EXPECT_TRUE(info.findString(KEY_INFO_TYPE, &infoType) == ECODataStatus::OK);
257     EXPECT_EQ(infoType, VALUE_INFO_TYPE_SESSION);
258 
259     // Check the session info matches the session stats provided by FakeECOServiceStatsProvider.
260     int32_t codecType;
261     EXPECT_TRUE(info.findInt32(ENCODER_TYPE, &codecType) == ECODataStatus::OK);
262     EXPECT_EQ(codecType, CodecTypeAVC);
263 
264     int32_t profile;
265     EXPECT_TRUE(info.findInt32(ENCODER_PROFILE, &profile) == ECODataStatus::OK);
266     EXPECT_EQ(profile, AVCProfileHigh);
267 
268     int32_t level;
269     EXPECT_TRUE(info.findInt32(ENCODER_LEVEL, &level) == ECODataStatus::OK);
270     EXPECT_EQ(level, AVCLevel52);
271 
272     int32_t bitrate;
273     EXPECT_TRUE(info.findInt32(ENCODER_TARGET_BITRATE_BPS, &bitrate) == ECODataStatus::OK);
274     EXPECT_EQ(bitrate, kTargetBitrateBps);
275 
276     int32_t kfi;
277     EXPECT_TRUE(info.findInt32(ENCODER_KFI_FRAMES, &kfi) == ECODataStatus::OK);
278     EXPECT_EQ(kfi, kKeyFrameIntervalFrames);
279 
280     // =======================================================================================
281     // Inject the frame stats with qp = 30. Expect receiving notification for the first frame.
282     SimpleEncodedFrameData frameStats(1 /* seq number */, FrameTypeI, 0 /* framePtsUs */,
283                                       30 /* avg-qp */, 56 /* frameSize */);
284 
285     getInfo = false;
286     fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS));
287     std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
288     // Check the Session info matches with the session stats sent by provider.
289     EXPECT_TRUE(getInfo);
290 
291     EXPECT_TRUE(info.findString(KEY_INFO_TYPE, &infoType) == ECODataStatus::OK);
292     EXPECT_EQ(infoType, VALUE_INFO_TYPE_FRAME);
293 
294     int8_t frameType;
295     EXPECT_TRUE(info.findInt8(FRAME_TYPE, &frameType) == ECODataStatus::OK);
296     EXPECT_EQ(frameType, FrameTypeI);
297 
298     int32_t frameNum;
299     EXPECT_TRUE(info.findInt32(FRAME_NUM, &frameNum) == ECODataStatus::OK);
300     EXPECT_EQ(frameNum, 1);
301 
302     int64_t framePtsUs;
303     EXPECT_TRUE(info.findInt64(FRAME_PTS_US, &framePtsUs) == ECODataStatus::OK);
304     EXPECT_EQ(framePtsUs, 0);
305 
306     int32_t frameQp;
307     EXPECT_TRUE(info.findInt32(FRAME_AVG_QP, &frameQp) == ECODataStatus::OK);
308     EXPECT_EQ(frameQp, 30);
309 
310     int32_t frameSize;
311     EXPECT_TRUE(info.findInt32(FRAME_SIZE_BYTES, &frameSize) == ECODataStatus::OK);
312     EXPECT_EQ(frameSize, 56);
313 
314     // =======================================================================================
315     // Inject the frame stats with qp = 35. Expect not receiving notification as 35 is below
316     // threshold.
317     frameStats = SimpleEncodedFrameData(2 /* seq number */, FrameTypeP, 333333 /* framePtsUs */,
318                                         35 /* avg-qp */, 56 /* frameSize */);
319     getInfo = false;
320     fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS));
321     // Wait as ECOService may take some time to process.
322     std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
323     EXPECT_FALSE(getInfo);
324 
325     // =======================================================================================
326     // Inject the frame stats with qp = 41. Expect receiving notification as 41 goes beyond
327     // threshold 40.
328     frameStats = SimpleEncodedFrameData(3 /* seq number */, FrameTypeP, 666666 /* framePtsUs */,
329                                         41 /* avg-qp */, 56 /* frameSize */);
330     getInfo = false;
331     fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS));
332     // Wait as ECOService may take some time to process.
333     std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
334 
335     // Check the frame info matches with the frame stats sent by provider.
336     EXPECT_TRUE(getInfo);
337     EXPECT_TRUE(info.findString(KEY_INFO_TYPE, &infoType) == ECODataStatus::OK);
338     EXPECT_EQ(infoType, VALUE_INFO_TYPE_FRAME);
339     EXPECT_TRUE(info.findInt8(FRAME_TYPE, &frameType) == ECODataStatus::OK);
340     EXPECT_EQ(frameType, FrameTypeP);
341     EXPECT_TRUE(info.findInt32(FRAME_NUM, &frameNum) == ECODataStatus::OK);
342     EXPECT_EQ(frameNum, 3);
343     EXPECT_TRUE(info.findInt64(FRAME_PTS_US, &framePtsUs) == ECODataStatus::OK);
344     EXPECT_EQ(framePtsUs, 666666);
345     EXPECT_TRUE(info.findInt32(FRAME_AVG_QP, &frameQp) == ECODataStatus::OK);
346     EXPECT_EQ(frameQp, 41);
347     EXPECT_TRUE(info.findInt32(FRAME_SIZE_BYTES, &frameSize) == ECODataStatus::OK);
348     EXPECT_EQ(frameSize, 56);
349 
350     // =======================================================================================
351     // Inject the frame stats with qp = 42. Expect not receiving notification as 42 goes beyond
352     // threshold 40 but delta oes not go beyond the mQpChangeThreshold threshold.
353     frameStats = SimpleEncodedFrameData(4 /* seq number */, FrameTypeP, 999999 /* framePtsUs */,
354                                         42 /* avg-qp */, 56 /* frameSize */);
355     getInfo = false;
356     fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS));
357     // Wait as ECOService may take some time to process.
358     std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
359     EXPECT_FALSE(getInfo);
360 
361     // =======================================================================================
362     // Inject the frame stats with qp = 10. Expect receiving notification as the detal from
363     // last reported QP is larger than threshold 4.
364     frameStats = SimpleEncodedFrameData(5 /* seq number */, FrameTypeB, 1333332 /* framePtsUs */,
365                                         49 /* avg-qp */, 56 /* frameSize */);
366     getInfo = false;
367     fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS));
368     // Wait as ECOService may take some time to process.
369     std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
370 
371     // Check the frame info matches with the frame stats sent by provider.
372     EXPECT_TRUE(getInfo);
373     EXPECT_TRUE(info.findString(KEY_INFO_TYPE, &infoType) == ECODataStatus::OK);
374     EXPECT_EQ(infoType, VALUE_INFO_TYPE_FRAME);
375     EXPECT_TRUE(info.findInt8(FRAME_TYPE, &frameType) == ECODataStatus::OK);
376     EXPECT_EQ(frameType, FrameTypeB);
377     EXPECT_TRUE(info.findInt32(FRAME_NUM, &frameNum) == ECODataStatus::OK);
378     EXPECT_EQ(frameNum, 5);
379     EXPECT_TRUE(info.findInt64(FRAME_PTS_US, &framePtsUs) == ECODataStatus::OK);
380     EXPECT_EQ(framePtsUs, 1333332);
381     EXPECT_TRUE(info.findInt32(FRAME_AVG_QP, &frameQp) == ECODataStatus::OK);
382     EXPECT_EQ(frameQp, 49);
383     EXPECT_TRUE(info.findInt32(FRAME_SIZE_BYTES, &frameSize) == ECODataStatus::OK);
384     EXPECT_EQ(frameSize, 56);
385 
386     // =======================================================================================
387     // Inject the frame stats with qp = 41. Expect receiving notification as the detal from
388     // last reported QP is larger than threshold 4.
389     frameStats = SimpleEncodedFrameData(6 /* seq number */, FrameTypeB, 1666665 /* framePtsUs */,
390                                         41 /* avg-qp */, 56 /* frameSize */);
391     getInfo = false;
392     fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS));
393     std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
394 
395     // Check the frame info matches with the frame stats sent by provider.
396     EXPECT_TRUE(getInfo);
397     EXPECT_TRUE(info.findString(KEY_INFO_TYPE, &infoType) == ECODataStatus::OK);
398     EXPECT_EQ(infoType, VALUE_INFO_TYPE_FRAME);
399     EXPECT_TRUE(info.findInt8(FRAME_TYPE, &frameType) == ECODataStatus::OK);
400     EXPECT_EQ(frameType, FrameTypeB);
401     EXPECT_TRUE(info.findInt32(FRAME_NUM, &frameNum) == ECODataStatus::OK);
402     EXPECT_EQ(frameNum, 6);
403     EXPECT_TRUE(info.findInt64(FRAME_PTS_US, &framePtsUs) == ECODataStatus::OK);
404     EXPECT_EQ(framePtsUs, 1666665);
405     EXPECT_TRUE(info.findInt32(FRAME_AVG_QP, &frameQp) == ECODataStatus::OK);
406     EXPECT_EQ(frameQp, 41);
407     EXPECT_TRUE(info.findInt32(FRAME_SIZE_BYTES, &frameSize) == ECODataStatus::OK);
408     EXPECT_EQ(frameSize, 56);
409 }
410 
TEST_F(EcoSessionTest,TestRemoveMatchProvider)411 TEST_F(EcoSessionTest, TestRemoveMatchProvider) {
412     sp<ECOSession> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
413     EXPECT_TRUE(ecoSession);
414 
415     sp<FakeECOServiceStatsProvider> fakeProvider1 = new FakeECOServiceStatsProvider(
416             kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
417 
418     ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG,
419                            systemTime(SYSTEM_TIME_BOOTTIME));
420     bool res;
421     Status status = ecoSession->addStatsProvider(fakeProvider1, providerConfig, &res);
422     EXPECT_TRUE(res);
423     EXPECT_TRUE(status.isOk());
424 
425     status = ecoSession->removeStatsProvider(fakeProvider1, &res);
426     EXPECT_TRUE(res);
427     EXPECT_TRUE(status.isOk());
428 }
429 
TEST_F(EcoSessionTest,TestRemoveMisMatchProvider)430 TEST_F(EcoSessionTest, TestRemoveMisMatchProvider) {
431     sp<ECOSession> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
432     EXPECT_TRUE(ecoSession);
433 
434     sp<FakeECOServiceStatsProvider> fakeProvider1 = new FakeECOServiceStatsProvider(
435             kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
436 
437     ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG,
438                            systemTime(SYSTEM_TIME_BOOTTIME));
439     bool res;
440     Status status = ecoSession->addStatsProvider(fakeProvider1, providerConfig, &res);
441     EXPECT_TRUE(res);
442     EXPECT_TRUE(status.isOk());
443 
444     sp<FakeECOServiceStatsProvider> fakeProvider2 = new FakeECOServiceStatsProvider(
445             kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
446 
447     status = ecoSession->removeStatsProvider(fakeProvider2, &res);
448     EXPECT_FALSE(res);
449     EXPECT_FALSE(status.isOk());
450 }
451 
TEST_F(EcoSessionTest,TestRemoveMatchListener)452 TEST_F(EcoSessionTest, TestRemoveMatchListener) {
453     sp<ECOSession> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
454     EXPECT_TRUE(ecoSession);
455 
456     // Create listener.
457     sp<FakeECOServiceInfoListener> fakeListener =
458             new FakeECOServiceInfoListener(kTestWidth, kTestHeight, kIsCameraRecording, ecoSession);
459 
460     // Create the listener config.
461     ECOData listenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG,
462                            systemTime(SYSTEM_TIME_BOOTTIME));
463     listenerConfig.setString(KEY_LISTENER_NAME, "FakeECOServiceInfoListener");
464     listenerConfig.setInt32(KEY_LISTENER_TYPE, ECOServiceInfoListener::INFO_LISTENER_TYPE_CAMERA);
465 
466     // Specify the qp thresholds for receiving notification.
467     listenerConfig.setInt32(KEY_LISTENER_QP_BLOCKINESS_THRESHOLD, 40);
468     listenerConfig.setInt32(KEY_LISTENER_QP_CHANGE_THRESHOLD, 5);
469 
470     bool res;
471     Status status = ecoSession->addInfoListener(fakeListener, listenerConfig, &res);
472 
473     status = ecoSession->removeInfoListener(fakeListener, &res);
474     EXPECT_TRUE(res);
475     EXPECT_TRUE(status.isOk());
476 }
477 
TEST_F(EcoSessionTest,TestRemoveMisMatchListener)478 TEST_F(EcoSessionTest, TestRemoveMisMatchListener) {
479     sp<ECOSession> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
480     EXPECT_TRUE(ecoSession);
481 
482     // Create listener.
483     sp<FakeECOServiceInfoListener> fakeListener =
484             new FakeECOServiceInfoListener(kTestWidth, kTestHeight, kIsCameraRecording, ecoSession);
485 
486     // Create the listener config.
487     ECOData listenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG,
488                            systemTime(SYSTEM_TIME_BOOTTIME));
489     listenerConfig.setString(KEY_LISTENER_NAME, "FakeECOServiceInfoListener");
490     listenerConfig.setInt32(KEY_LISTENER_TYPE, ECOServiceInfoListener::INFO_LISTENER_TYPE_CAMERA);
491 
492     // Specify the qp thresholds for receiving notification.
493     listenerConfig.setInt32(KEY_LISTENER_QP_BLOCKINESS_THRESHOLD, 40);
494     listenerConfig.setInt32(KEY_LISTENER_QP_CHANGE_THRESHOLD, 5);
495 
496     bool res;
497     Status status = ecoSession->addInfoListener(fakeListener, listenerConfig, &res);
498 
499     // Create listener.
500     sp<FakeECOServiceInfoListener> fakeListener2 =
501             new FakeECOServiceInfoListener(kTestWidth, kTestHeight, kIsCameraRecording, ecoSession);
502 
503     status = ecoSession->removeInfoListener(fakeListener2, &res);
504     EXPECT_FALSE(res);
505     EXPECT_FALSE(status.isOk());
506 }
507 
508 // Test the listener connects to the ECOSession after provider sends the session info. Listener
509 // should recieve the session info right after adding itself to the ECOSession.
TEST_F(EcoSessionTest,TestAddListenerAferProviderStarts)510 TEST_F(EcoSessionTest, TestAddListenerAferProviderStarts) {
511     // The time that listener needs to wait for the info from ECOService.
512     static constexpr int kServiceWaitTimeMs = 10;
513 
514     // Create the session.
515     sp<ECOSession> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
516 
517     // Add provider.
518     sp<FakeECOServiceStatsProvider> fakeProvider = new FakeECOServiceStatsProvider(
519             kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
520     ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG,
521                            systemTime(SYSTEM_TIME_BOOTTIME));
522     providerConfig.setString(KEY_PROVIDER_NAME, "FakeECOServiceStatsProvider");
523     providerConfig.setInt32(KEY_PROVIDER_TYPE,
524                             ECOServiceStatsProvider::STATS_PROVIDER_TYPE_VIDEO_ENCODER);
525     bool res;
526     Status status = ecoSession->addStatsProvider(fakeProvider, providerConfig, &res);
527 
528     // Inject the session stats into the ECOSession through fakeProvider.
529     SimpleEncoderConfig sessionEncoderConfig("google-avc", CodecTypeAVC, AVCProfileHigh, AVCLevel52,
530                                              kTargetBitrateBps, kKeyFrameIntervalFrames,
531                                              kFrameRate);
532     fakeProvider->injectSessionStats(sessionEncoderConfig.toEcoData(ECOData::DATA_TYPE_STATS));
533 
534     // Wait as ECOService may take some time to process.
535     std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
536 
537     // =======================================================================================
538     // Inject the frame stats with qp = 30. Expect receiving notification for the first frame.
539     SimpleEncodedFrameData frameStats(1 /* seq number */, FrameTypeI, 0 /* framePtsUs */,
540                                       30 /* avg-qp */, 56 /* frameSize */);
541 
542     fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS));
543     std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
544 
545     // =======================================================================================
546     // Create and add the listener to the ECOSession. Expect to receive the session infor right
547     // after addInfoListener.
548     sp<FakeECOServiceInfoListener> fakeListener =
549             new FakeECOServiceInfoListener(kTestWidth, kTestHeight, kIsCameraRecording, ecoSession);
550 
551     // Create the listener config.
552     ECOData listenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG,
553                            systemTime(SYSTEM_TIME_BOOTTIME));
554     listenerConfig.setString(KEY_LISTENER_NAME, "FakeECOServiceInfoListener");
555     listenerConfig.setInt32(KEY_LISTENER_TYPE, ECOServiceInfoListener::INFO_LISTENER_TYPE_CAMERA);
556 
557     // Specify the qp thresholds for receiving notification.
558     listenerConfig.setInt32(KEY_LISTENER_QP_BLOCKINESS_THRESHOLD, 40);
559     listenerConfig.setInt32(KEY_LISTENER_QP_CHANGE_THRESHOLD, 5);
560 
561     ECOData info;
562     bool getInfo = false;
563 
564     // Set the getInfo flag to true and copy the info from fakeListener.
565     fakeListener->setInfoAvailableCallback(
566             [&info, &getInfo](const ::android::media::eco::ECOData& newInfo) {
567                 getInfo = true;
568                 info = newInfo;
569             });
570 
571     status = ecoSession->addInfoListener(fakeListener, listenerConfig, &res);
572 
573     // Wait as ECOService may take some time to process.
574     std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
575 
576     // Check the Session info matches with the session stats sent by provider.
577     EXPECT_TRUE(getInfo);
578     EXPECT_TRUE(info.getDataType() == ECOData::DATA_TYPE_INFO);
579 
580     std::string infoType;
581     EXPECT_TRUE(info.findString(KEY_INFO_TYPE, &infoType) == ECODataStatus::OK);
582     EXPECT_EQ(infoType, VALUE_INFO_TYPE_SESSION);
583 
584     // Check the session info matches the session stats provided by FakeECOServiceStatsProvider.
585     int32_t codecType;
586     EXPECT_TRUE(info.findInt32(ENCODER_TYPE, &codecType) == ECODataStatus::OK);
587     EXPECT_EQ(codecType, CodecTypeAVC);
588 
589     int32_t profile;
590     EXPECT_TRUE(info.findInt32(ENCODER_PROFILE, &profile) == ECODataStatus::OK);
591     EXPECT_EQ(profile, AVCProfileHigh);
592 
593     int32_t level;
594     EXPECT_TRUE(info.findInt32(ENCODER_LEVEL, &level) == ECODataStatus::OK);
595     EXPECT_EQ(level, AVCLevel52);
596 
597     int32_t bitrate;
598     EXPECT_TRUE(info.findInt32(ENCODER_TARGET_BITRATE_BPS, &bitrate) == ECODataStatus::OK);
599     EXPECT_EQ(bitrate, kTargetBitrateBps);
600 
601     int32_t kfi;
602     EXPECT_TRUE(info.findInt32(ENCODER_KFI_FRAMES, &kfi) == ECODataStatus::OK);
603     EXPECT_EQ(kfi, kKeyFrameIntervalFrames);
604 }
605 
606 }  // namespace eco
607 }  // namespace media
608 }  // namespace android
609