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 <thread>
18 
19 #include <gtest/gtest.h>
20 
21 #include <gui/SurfaceComposerClient.h>
22 #include <private/gui/ComposerService.h>
23 #include <chrono>
24 
25 using ::std::literals::chrono_literals::operator""ms;
26 using ::std::literals::chrono_literals::operator""s;
27 
28 static constexpr int kRefreshRateOverlayCode = 1034;
29 static constexpr int kRefreshRateOverlayEnable = 1;
30 static constexpr int kRefreshRateOverlayDisable = 0;
31 static constexpr int kRefreshRateOverlayQuery = 2;
32 
33 // These values must match the ones we used for developer options in
34 // com.android.settings.development.ShowRefreshRatePreferenceController
35 static_assert(kRefreshRateOverlayCode == 1034);
36 static_assert(kRefreshRateOverlayEnable == 1);
37 static_assert(kRefreshRateOverlayDisable == 0);
38 static_assert(kRefreshRateOverlayQuery == 2);
39 
40 namespace android {
41 
42 namespace {
sendCommandToSf(int command,Parcel & reply)43 void sendCommandToSf(int command, Parcel& reply) {
44     sp<ISurfaceComposer> sf(ComposerService::getComposerService());
45     Parcel request;
46     request.writeInterfaceToken(String16("android.ui.ISurfaceComposer"));
47     request.writeInt32(command);
48     ASSERT_EQ(NO_ERROR,
49               IInterface::asBinder(sf)->transact(kRefreshRateOverlayCode, request, &reply));
50 }
51 
isOverlayEnabled()52 bool isOverlayEnabled() {
53     Parcel reply;
54     sendCommandToSf(kRefreshRateOverlayQuery, reply);
55     return reply.readBool();
56 }
57 
waitForOverlay(bool enabled)58 void waitForOverlay(bool enabled) {
59     static constexpr auto kTimeout = std::chrono::nanoseconds(1s);
60     static constexpr auto kIterations = 10;
61     for (int i = 0; i < kIterations; i++) {
62         if (enabled == isOverlayEnabled()) {
63             return;
64         }
65         std::this_thread::sleep_for(kTimeout / kIterations);
66     }
67 }
68 
toggleOverlay(bool enabled)69 void toggleOverlay(bool enabled) {
70     if (enabled == isOverlayEnabled()) {
71         return;
72     }
73 
74     Parcel reply;
75     const auto command = enabled ? kRefreshRateOverlayEnable : kRefreshRateOverlayDisable;
76     sendCommandToSf(command, reply);
77     waitForOverlay(enabled);
78     ASSERT_EQ(enabled, isOverlayEnabled());
79 }
80 
81 } // namespace
82 
TEST(RefreshRateOverlayTest,enableAndDisableOverlay)83 TEST(RefreshRateOverlayTest, enableAndDisableOverlay) {
84     toggleOverlay(true);
85     toggleOverlay(false);
86 
87     toggleOverlay(true);
88     toggleOverlay(false);
89 }
90 
91 } // namespace android