• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <ftl/small_vector.h>
18 #include <gui/ISurfaceComposer.h>
19 
20 #include "SurfaceFlinger.h"
21 #include "WindowInfosListenerInvoker.h"
22 
23 namespace android {
24 
25 using gui::DisplayInfo;
26 using gui::IWindowInfosListener;
27 using gui::WindowInfo;
28 
29 struct WindowInfosListenerInvoker::WindowInfosReportedListener
30       : gui::BnWindowInfosReportedListener {
WindowInfosReportedListenerandroid::WindowInfosListenerInvoker::WindowInfosReportedListener31     explicit WindowInfosReportedListener(WindowInfosListenerInvoker& invoker) : mInvoker(invoker) {}
32 
onWindowInfosReportedandroid::WindowInfosListenerInvoker::WindowInfosReportedListener33     binder::Status onWindowInfosReported() override {
34         mInvoker.windowInfosReported();
35         return binder::Status::ok();
36     }
37 
38     WindowInfosListenerInvoker& mInvoker;
39 };
40 
WindowInfosListenerInvoker(SurfaceFlinger & flinger)41 WindowInfosListenerInvoker::WindowInfosListenerInvoker(SurfaceFlinger& flinger)
42       : mFlinger(flinger),
43         mWindowInfosReportedListener(sp<WindowInfosReportedListener>::make(*this)) {}
44 
addWindowInfosListener(sp<IWindowInfosListener> listener)45 void WindowInfosListenerInvoker::addWindowInfosListener(sp<IWindowInfosListener> listener) {
46     sp<IBinder> asBinder = IInterface::asBinder(listener);
47     asBinder->linkToDeath(this);
48 
49     std::scoped_lock lock(mListenersMutex);
50     mWindowInfosListeners.try_emplace(asBinder, std::move(listener));
51 }
52 
removeWindowInfosListener(const sp<IWindowInfosListener> & listener)53 void WindowInfosListenerInvoker::removeWindowInfosListener(
54         const sp<IWindowInfosListener>& listener) {
55     sp<IBinder> asBinder = IInterface::asBinder(listener);
56 
57     std::scoped_lock lock(mListenersMutex);
58     asBinder->unlinkToDeath(this);
59     mWindowInfosListeners.erase(asBinder);
60 }
61 
binderDied(const wp<IBinder> & who)62 void WindowInfosListenerInvoker::binderDied(const wp<IBinder>& who) {
63     std::scoped_lock lock(mListenersMutex);
64     mWindowInfosListeners.erase(who);
65 }
66 
windowInfosChanged(const std::vector<WindowInfo> & windowInfos,const std::vector<DisplayInfo> & displayInfos,bool shouldSync)67 void WindowInfosListenerInvoker::windowInfosChanged(const std::vector<WindowInfo>& windowInfos,
68                                                     const std::vector<DisplayInfo>& displayInfos,
69                                                     bool shouldSync) {
70     ftl::SmallVector<const sp<IWindowInfosListener>, kStaticCapacity> windowInfosListeners;
71     {
72         std::scoped_lock lock(mListenersMutex);
73         for (const auto& [_, listener] : mWindowInfosListeners) {
74             windowInfosListeners.push_back(listener);
75         }
76     }
77 
78     mCallbacksPending = windowInfosListeners.size();
79 
80     for (const auto& listener : windowInfosListeners) {
81         listener->onWindowInfosChanged(windowInfos, displayInfos,
82                                        shouldSync ? mWindowInfosReportedListener : nullptr);
83     }
84 }
85 
windowInfosReported()86 void WindowInfosListenerInvoker::windowInfosReported() {
87     mCallbacksPending--;
88     if (mCallbacksPending == 0) {
89         mFlinger.windowInfosReported();
90     }
91 }
92 
93 } // namespace android
94