• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 "Composer.h"
18 
19 #include <android-base/logging.h>
20 #include <android/binder_ibinder_platform.h>
21 
22 #include "Common.h"
23 
24 namespace aidl::android::hardware::graphics::composer3::impl {
25 
createClient(std::shared_ptr<IComposerClient> * outClient)26 ndk::ScopedAStatus Composer::createClient(
27     std::shared_ptr<IComposerClient>* outClient) {
28   DEBUG_LOG("%s", __FUNCTION__);
29 
30   std::unique_lock<std::mutex> lock(mClientMutex);
31 
32   const bool previousClientDestroyed = waitForClientDestroyedLocked(lock);
33   if (!previousClientDestroyed) {
34     ALOGE("%s: failed as composer client already exists", __FUNCTION__);
35     *outClient = nullptr;
36     return ToBinderStatus(HWC3::Error::NoResources);
37   }
38 
39   auto client = ndk::SharedRefBase::make<ComposerClient>();
40   if (!client) {
41     ALOGE("%s: failed to init composer client", __FUNCTION__);
42     *outClient = nullptr;
43     return ToBinderStatus(HWC3::Error::NoResources);
44   }
45 
46   auto error = client->init();
47   if (error != HWC3::Error::None) {
48     *outClient = nullptr;
49     return ToBinderStatus(error);
50   }
51 
52   auto clientDestroyed = [this]() { onClientDestroyed(); };
53   client->setOnClientDestroyed(clientDestroyed);
54 
55   mClient = client;
56   *outClient = client;
57 
58   return ndk::ScopedAStatus::ok();
59 }
60 
waitForClientDestroyedLocked(std::unique_lock<std::mutex> & lock)61 bool Composer::waitForClientDestroyedLocked(
62     std::unique_lock<std::mutex>& lock) {
63   if (!mClient.expired()) {
64     // In surface flinger we delete a composer client on one thread and
65     // then create a new client on another thread. Although surface
66     // flinger ensures the calls are made in that sequence (destroy and
67     // then create), sometimes the calls land in the composer service
68     // inverted (create and then destroy). Wait for a brief period to
69     // see if the existing client is destroyed.
70     constexpr const auto kTimeout = std::chrono::seconds(5);
71     mClientDestroyedCondition.wait_for(
72         lock, kTimeout, [this]() -> bool { return mClient.expired(); });
73     if (!mClient.expired()) {
74       ALOGW("%s: previous client was not destroyed", __FUNCTION__);
75     }
76   }
77 
78   return mClient.expired();
79 }
80 
onClientDestroyed()81 void Composer::onClientDestroyed() {
82   std::lock_guard<std::mutex> lock(mClientMutex);
83 
84   mClientDestroyedCondition.notify_all();
85 }
86 
dump(int fd,const char **,uint32_t)87 binder_status_t Composer::dump(int fd, const char** /*args*/,
88                                uint32_t /*numArgs*/) {
89   DEBUG_LOG("%s", __FUNCTION__);
90 
91   std::string output("TODO");
92 
93   write(fd, output.c_str(), output.size());
94   return STATUS_OK;
95 }
96 
getCapabilities(std::vector<Capability> * caps)97 ndk::ScopedAStatus Composer::getCapabilities(std::vector<Capability>* caps) {
98   DEBUG_LOG("%s", __FUNCTION__);
99 
100   caps->clear();
101   caps->emplace_back(Capability::PRESENT_FENCE_IS_NOT_RELIABLE);
102   caps->emplace_back(Capability::BOOT_DISPLAY_CONFIG);
103 
104   return ndk::ScopedAStatus::ok();
105 }
106 
createBinder()107 ::ndk::SpAIBinder Composer::createBinder() {
108   DEBUG_LOG("%s", __FUNCTION__);
109 
110   auto binder = BnComposer::createBinder();
111   AIBinder_setInheritRt(binder.get(), true);
112   return binder;
113 }
114 
115 }  // namespace aidl::android::hardware::graphics::composer3::impl