1 /*
2  * Copyright 2020 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 #undef LOG_TAG
18 #define LOG_TAG "LibSurfaceFlingerUnittests"
19 
20 #include "DisplayTransactionTestHelpers.h"
21 
22 namespace android {
23 namespace {
24 
25 class HotplugTest : public DisplayTransactionTest {};
26 
TEST_F(HotplugTest,enqueuesEventsForDisplayTransaction)27 TEST_F(HotplugTest, enqueuesEventsForDisplayTransaction) {
28     constexpr HWDisplayId hwcDisplayId1 = 456;
29     constexpr HWDisplayId hwcDisplayId2 = 654;
30 
31     // --------------------------------------------------------------------
32     // Preconditions
33 
34     // Set the main thread id so that the current thread does not appear to be
35     // the main thread.
36     mFlinger.mutableMainThreadId() = std::thread::id();
37 
38     // --------------------------------------------------------------------
39     // Call Expectations
40 
41     // We expect invalidate() to be invoked once to trigger display transaction
42     // processing.
43     EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
44 
45     // --------------------------------------------------------------------
46     // Invocation
47 
48     // Simulate two hotplug events (a connect and a disconnect)
49     mFlinger.onComposerHalHotplug(hwcDisplayId1, Connection::CONNECTED);
50     mFlinger.onComposerHalHotplug(hwcDisplayId2, Connection::DISCONNECTED);
51 
52     // --------------------------------------------------------------------
53     // Postconditions
54 
55     // The display transaction needed flag should be set.
56     EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
57 
58     // All events should be in the pending event queue.
59     const auto& pendingEvents = mFlinger.mutablePendingHotplugEvents();
60     ASSERT_EQ(2u, pendingEvents.size());
61     EXPECT_EQ(hwcDisplayId1, pendingEvents[0].hwcDisplayId);
62     EXPECT_EQ(Connection::CONNECTED, pendingEvents[0].connection);
63     EXPECT_EQ(hwcDisplayId2, pendingEvents[1].hwcDisplayId);
64     EXPECT_EQ(Connection::DISCONNECTED, pendingEvents[1].connection);
65 }
66 
TEST_F(HotplugTest,processesEnqueuedEventsIfCalledOnMainThread)67 TEST_F(HotplugTest, processesEnqueuedEventsIfCalledOnMainThread) {
68     constexpr HWDisplayId displayId1 = 456;
69 
70     // --------------------------------------------------------------------
71     // Note:
72     // --------------------------------------------------------------------
73     // This test case is a bit tricky. We want to verify that
74     // onComposerHalHotplug() calls processDisplayHotplugEventsLocked(), but we
75     // don't really want to provide coverage for everything the later function
76     // does as there are specific tests for it.
77     // --------------------------------------------------------------------
78 
79     // --------------------------------------------------------------------
80     // Preconditions
81 
82     // Set the main thread id so that the current thread does appear to be the
83     // main thread.
84     mFlinger.mutableMainThreadId() = std::this_thread::get_id();
85 
86     // --------------------------------------------------------------------
87     // Call Expectations
88 
89     // We expect invalidate() to be invoked once to trigger display transaction
90     // processing.
91     EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
92 
93     // --------------------------------------------------------------------
94     // Invocation
95 
96     // Simulate a disconnect on a display id that is not connected. This should
97     // be enqueued by onComposerHalHotplug(), and dequeued by
98     // processDisplayHotplugEventsLocked(), but then ignored as invalid.
99     mFlinger.onComposerHalHotplug(displayId1, Connection::DISCONNECTED);
100 
101     // --------------------------------------------------------------------
102     // Postconditions
103 
104     // The display transaction needed flag should be set.
105     EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
106 
107     // There should be no event queued on return, as it should have been
108     // processed.
109     EXPECT_TRUE(mFlinger.mutablePendingHotplugEvents().empty());
110 }
111 
112 } // namespace
113 } // namespace android
114