• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 #define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
18 
19 #include "Composer.h"
20 
21 #include <android-base/logging.h>
22 #include <android/binder_ibinder_platform.h>
23 
24 #include "Util.h"
25 
26 namespace aidl::android::hardware::graphics::composer3::impl {
27 
createClient(std::shared_ptr<IComposerClient> * outClient)28 ndk::ScopedAStatus Composer::createClient(std::shared_ptr<IComposerClient>* outClient) {
29     DEBUG_FUNC();
30     std::unique_lock<std::mutex> lock(mClientMutex);
31     if (!waitForClientDestroyedLocked(lock)) {
32         *outClient = nullptr;
33         return TO_BINDER_STATUS(EX_NO_RESOURCES);
34     }
35 
36     auto client = ndk::SharedRefBase::make<ComposerClient>(mHal.get());
37     if (!client || !client->init()) {
38         *outClient = nullptr;
39         return TO_BINDER_STATUS(EX_NO_RESOURCES);
40     }
41 
42     auto clientDestroyed = [this]() { onClientDestroyed(); };
43     client->setOnClientDestroyed(clientDestroyed);
44 
45     mClientAlive = true;
46     *outClient = client;
47 
48     return ndk::ScopedAStatus::ok();
49 }
50 
dump(int fd,const char **,uint32_t)51 binder_status_t Composer::dump(int fd, const char** /*args*/, uint32_t /*numArgs*/) {
52     std::string output;
53     mHal->dumpDebugInfo(&output);
54     write(fd, output.c_str(), output.size());
55     return STATUS_OK;
56 }
57 
getCapabilities(std::vector<Capability> * caps)58 ndk::ScopedAStatus Composer::getCapabilities(std::vector<Capability>* caps) {
59     DEBUG_FUNC();
60     mHal->getCapabilities(caps);
61     return ndk::ScopedAStatus::ok();
62 }
63 
waitForClientDestroyedLocked(std::unique_lock<std::mutex> & lock)64 bool Composer::waitForClientDestroyedLocked(std::unique_lock<std::mutex>& lock) {
65     if (mClientAlive) {
66         using namespace std::chrono_literals;
67 
68         // In surface flinger we delete a composer client on one thread and
69         // then create a new client on another thread. Although surface
70         // flinger ensures the calls are made in that sequence (destroy and
71         // then create), sometimes the calls land in the composer service
72         // inverted (create and then destroy). Wait for a brief period to
73         // see if the existing client is destroyed.
74         LOG(DEBUG) << "waiting for previous client to be destroyed";
75         mClientDestroyedCondition.wait_for(lock, 1s,
76                                            [this]() -> bool { return !mClientAlive; });
77         if (mClientAlive) {
78             LOG(DEBUG) << "previous client was not destroyed";
79         }
80     }
81 
82     return !mClientAlive;
83 }
84 
onClientDestroyed()85 void Composer::onClientDestroyed() {
86     std::lock_guard<std::mutex> lock(mClientMutex);
87     mClientAlive = false;
88     mClientDestroyedCondition.notify_all();
89 }
90 
createBinder()91 ::ndk::SpAIBinder Composer::createBinder() {
92     auto binder = BnComposer::createBinder();
93     AIBinder_setInheritRt(binder.get(), true);
94     return binder;
95 }
96 
97 } // namespace aidl::android::hardware::graphics::composer3::impl
98 
99