• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2025 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 <chrono>
18 #include <cstdlib>
19 #include <memory>
20 #include <string>
21 #include <string_view>
22 #include <thread>
23 #include <utility>
24 
25 #include <android-base/expected.h>
26 #include <android-base/logging.h>
27 #include <android-base/properties.h>
28 #include <android/gui/ISurfaceComposer.h>
29 #include <binder/IBinder.h>
30 #include <binder/IInterface.h>
31 #include <binder/IServiceManager.h>
32 #include <binder/Status.h>
33 #include <ftl/finalizer.h>
34 #include <ftl/ignore.h>
35 #include <gui/Surface.h>
36 #include <gui/SurfaceComposerClient.h>
37 #include <utils/String16.h>
38 #include <utils/String8.h>
39 #include <utils/StrongPointer.h>
40 
41 #include "test_framework/surfaceflinger/SFController.h"
42 
43 namespace android::surfaceflinger::tests::end2end::test_framework::surfaceflinger {
44 
45 namespace {
46 
waitForSurfaceFlingerAIDL()47 auto waitForSurfaceFlingerAIDL() -> sp<gui::ISurfaceComposer> {
48     constexpr auto kTimeout = std::chrono::seconds(30);
49     constexpr auto kSurfaceFlingerServiceName = "SurfaceFlingerAIDL";
50     const sp<android::IServiceManager> serviceManager(android::defaultServiceManager());
51     const auto kTimeoutAfter = std::chrono::steady_clock::now() + kTimeout;
52 
53     LOG(INFO) << "Waiting " << kTimeout << " for service manager registration....";
54     sp<android::IBinder> flingerService;
55     while (flingerService == nullptr) {
56         if (std::chrono::steady_clock::now() > kTimeoutAfter) {
57             LOG(INFO) << "... Timeout!";
58             return nullptr;
59         }
60 
61         constexpr auto sleepTime = std::chrono::milliseconds(10);
62         std::this_thread::sleep_for(sleepTime);
63         flingerService = serviceManager->checkService(String16(kSurfaceFlingerServiceName));
64     }
65     LOG(INFO) << "Obtained surfaceflinger interface from service manager.";
66 
67     return interface_cast<gui::ISurfaceComposer>(flingerService);
68 }
69 
70 }  // namespace
71 
72 struct SFController::Passkey final {};
73 
useHwcService(std::string_view fqn)74 void SFController::useHwcService(std::string_view fqn) {
75     base::SetProperty("debug.sf.hwc_service_name", std::string(fqn));
76 }
77 
make()78 auto SFController::make() -> base::expected<std::shared_ptr<SFController>, std::string> {
79     using namespace std::string_literals;
80 
81     auto controller = std::make_unique<SFController>(Passkey{});
82     if (controller == nullptr) {
83         return base::unexpected("Failed to construct the SFController instance."s);
84     }
85 
86     if (auto result = controller->init(); !result) {
87         return base::unexpected("Failed to init the SFController instance: "s + result.error());
88     }
89 
90     return controller;
91 }
92 
SFController(Passkey passkey)93 SFController::SFController(Passkey passkey) {
94     ftl::ignore(passkey);
95 }
96 
init()97 auto SFController::init() -> base::expected<void, std::string> {
98     LOG(INFO) << "Stopping everything to prepare for tests";
99     // NOLINTBEGIN(cert-env33-c)
100     system("stop");
101     // NOLINTEND(cert-env33-c)
102 
103     mCleanup = ftl::Finalizer([this]() { stop(); });
104 
105     return {};
106 }
107 
startAndConnect()108 auto SFController::startAndConnect() -> base::expected<void, std::string> {
109     using namespace std::string_literals;
110 
111     start();
112 
113     LOG(VERBOSE) << "Getting ISurfaceComposer....";
114     auto surfaceComposerAidl = waitForSurfaceFlingerAIDL();
115     if (surfaceComposerAidl == nullptr) {
116         return base::unexpected("Failed to obtain the surfaceComposerAidl interface."s);
117     }
118     LOG(VERBOSE) << "Getting ISurfaceComposerClient....";
119     sp<gui::ISurfaceComposerClient> surfaceComposerClientAidl;
120     if (!surfaceComposerAidl->createConnection(&surfaceComposerClientAidl).isOk()) {
121         return base::unexpected("Failed to obtain the surfaceComposerClientAidl interface."s);
122     }
123     if (surfaceComposerClientAidl == nullptr) {
124         return base::unexpected("Failed to obtain a valid surfaceComposerClientAidl interface."s);
125     }
126     auto surfaceComposerClient = sp<SurfaceComposerClient>::make(surfaceComposerClientAidl);
127     if (surfaceComposerClient == nullptr) {
128         return base::unexpected(
129                 "Failed to construct a surfaceComposerClient around the aidl interface."s);
130     }
131 
132     mSurfaceComposerAidl = std::move(surfaceComposerAidl);
133     mSurfaceComposerClientAidl = std::move(surfaceComposerClientAidl);
134     mSurfaceComposerClient = std::move(surfaceComposerClient);
135 
136     LOG(INFO) << "Connected to surfaceflinger";
137     return {};
138 }
139 
start()140 void SFController::start() {
141     LOG(INFO) << "Starting surfaceflinger";
142     // NOLINTBEGIN(cert-env33-c)
143     system("start surfaceflinger");
144     // NOLINTEND(cert-env33-c)
145 }
146 
stop()147 void SFController::stop() {
148     LOG(INFO) << "Stopping surfaceflinger";
149     // NOLINTBEGIN(cert-env33-c)
150     system("stop surfaceflinger");
151     // NOLINTEND(cert-env33-c)
152 
153     if (mSurfaceComposerAidl != nullptr) {
154         LOG(INFO) << "Waiting for SF AIDL interface to die";
155 
156         constexpr auto kTimeout = std::chrono::seconds(30);
157         const auto binder = android::gui::ISurfaceComposer::asBinder(mSurfaceComposerAidl);
158         const auto kTimeoutAfter = std::chrono::steady_clock::now() + kTimeout;
159 
160         while (binder->isBinderAlive()) {
161             if (std::chrono::steady_clock::now() > kTimeoutAfter) {
162                 LOG(INFO) << "... Timeout!";
163                 break;
164             }
165 
166             ftl::ignore = binder->pingBinder();
167 
168             constexpr auto kPollInterval = std::chrono::milliseconds(10);
169             std::this_thread::sleep_for(kPollInterval);
170         }
171 
172         constexpr auto kShutdownWait = std::chrono::milliseconds(500);
173         std::this_thread::sleep_for(kShutdownWait);
174     }
175 
176     mSurfaceComposerClient = nullptr;
177     mSurfaceComposerClientAidl = nullptr;
178     mSurfaceComposerAidl = nullptr;
179 }
180 
181 }  // namespace android::surfaceflinger::tests::end2end::test_framework::surfaceflinger
182