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()47auto 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)74void SFController::useHwcService(std::string_view fqn) { 75 base::SetProperty("debug.sf.hwc_service_name", std::string(fqn)); 76 } 77 make()78auto 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)93SFController::SFController(Passkey passkey) { 94 ftl::ignore(passkey); 95 } 96 init()97auto 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()108auto 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()140void SFController::start() { 141 LOG(INFO) << "Starting surfaceflinger"; 142 // NOLINTBEGIN(cert-env33-c) 143 system("start surfaceflinger"); 144 // NOLINTEND(cert-env33-c) 145 } 146 stop()147void 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