1 /*
2  * Copyright 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 #include <gui/ISurfaceComposer.h>
18 #include <gui/WindowInfosListenerReporter.h>
19 
20 namespace android {
21 
22 using gui::IWindowInfosReportedListener;
23 using gui::WindowInfo;
24 using gui::WindowInfosListener;
25 
getInstance()26 sp<WindowInfosListenerReporter> WindowInfosListenerReporter::getInstance() {
27     static sp<WindowInfosListenerReporter> sInstance = new WindowInfosListenerReporter;
28     return sInstance;
29 }
30 
addWindowInfosListener(const sp<WindowInfosListener> & windowInfosListener,const sp<ISurfaceComposer> & surfaceComposer)31 status_t WindowInfosListenerReporter::addWindowInfosListener(
32         const sp<WindowInfosListener>& windowInfosListener,
33         const sp<ISurfaceComposer>& surfaceComposer) {
34     status_t status = OK;
35     {
36         std::scoped_lock lock(mListenersMutex);
37         if (mWindowInfosListeners.empty()) {
38             status = surfaceComposer->addWindowInfosListener(this);
39         }
40 
41         if (status == OK) {
42             mWindowInfosListeners.insert(windowInfosListener);
43         }
44     }
45 
46     return status;
47 }
48 
removeWindowInfosListener(const sp<WindowInfosListener> & windowInfosListener,const sp<ISurfaceComposer> & surfaceComposer)49 status_t WindowInfosListenerReporter::removeWindowInfosListener(
50         const sp<WindowInfosListener>& windowInfosListener,
51         const sp<ISurfaceComposer>& surfaceComposer) {
52     status_t status = OK;
53     {
54         std::scoped_lock lock(mListenersMutex);
55         if (mWindowInfosListeners.size() == 1) {
56             status = surfaceComposer->removeWindowInfosListener(this);
57         }
58 
59         if (status == OK) {
60             mWindowInfosListeners.erase(windowInfosListener);
61         }
62     }
63 
64     return status;
65 }
66 
onWindowInfosChanged(const std::vector<WindowInfo> & windowInfos,const sp<IWindowInfosReportedListener> & windowInfosReportedListener)67 binder::Status WindowInfosListenerReporter::onWindowInfosChanged(
68         const std::vector<WindowInfo>& windowInfos,
69         const sp<IWindowInfosReportedListener>& windowInfosReportedListener) {
70     std::unordered_set<sp<WindowInfosListener>, ISurfaceComposer::SpHash<WindowInfosListener>>
71             windowInfosListeners;
72 
73     {
74         std::scoped_lock lock(mListenersMutex);
75         for (auto listener : mWindowInfosListeners) {
76             windowInfosListeners.insert(listener);
77         }
78     }
79 
80     for (auto listener : windowInfosListeners) {
81         listener->onWindowInfosChanged(windowInfos);
82     }
83 
84     if (windowInfosReportedListener) {
85         windowInfosReportedListener->onWindowInfosReported();
86     }
87 
88     return binder::Status::ok();
89 }
90 
reconnect(const sp<ISurfaceComposer> & composerService)91 void WindowInfosListenerReporter::reconnect(const sp<ISurfaceComposer>& composerService) {
92     std::scoped_lock lock(mListenersMutex);
93     if (!mWindowInfosListeners.empty()) {
94         composerService->addWindowInfosListener(this);
95     }
96 }
97 
98 } // namespace android