OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All Rights Reserved. | 2 * Copyright (C) 2013 Google Inc. All Rights Reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 20 matching lines...) Expand all Loading... |
31 #include <gtest/gtest.h> | 31 #include <gtest/gtest.h> |
32 | 32 |
33 using namespace blink; | 33 using namespace blink; |
34 | 34 |
35 namespace blink { | 35 namespace blink { |
36 | 36 |
37 class TestingObserver; | 37 class TestingObserver; |
38 | 38 |
39 class DummyContext final : public NoBaseWillBeGarbageCollectedFinalized<DummyCon
text>, public LifecycleNotifier<DummyContext, TestingObserver> { | 39 class DummyContext final : public NoBaseWillBeGarbageCollectedFinalized<DummyCon
text>, public LifecycleNotifier<DummyContext, TestingObserver> { |
40 public: | 40 public: |
41 DummyContext() | 41 static PassOwnPtrWillBeRawPtr<DummyContext> create() |
42 : LifecycleNotifier<DummyContext, TestingObserver>(this) | |
43 { | 42 { |
| 43 return adoptPtrWillBeNoop(new DummyContext()); |
44 } | 44 } |
45 | 45 |
46 void addObserver(TestingObserver* observer) | 46 void addObserver(TestingObserver* observer) |
47 { | 47 { |
48 LifecycleNotifier<DummyContext, TestingObserver>::addObserver(observer); | 48 LifecycleNotifier<DummyContext, TestingObserver>::addObserver(observer); |
49 } | 49 } |
50 | 50 |
51 void removeObserver(TestingObserver* observer) | 51 void removeObserver(TestingObserver* observer) |
52 { | 52 { |
53 LifecycleNotifier<DummyContext, TestingObserver>::removeObserver(observe
r); | 53 LifecycleNotifier<DummyContext, TestingObserver>::removeObserver(observe
r); |
54 } | 54 } |
55 | 55 |
56 DEFINE_INLINE_TRACE() | 56 DEFINE_INLINE_TRACE() |
57 { | 57 { |
58 LifecycleNotifier<DummyContext, TestingObserver>::trace(visitor); | 58 LifecycleNotifier<DummyContext, TestingObserver>::trace(visitor); |
59 } | 59 } |
| 60 |
| 61 private: |
| 62 DummyContext() |
| 63 : LifecycleNotifier<DummyContext, TestingObserver>(this) |
| 64 { |
| 65 } |
60 }; | 66 }; |
61 | 67 |
62 class TestingObserver final : public NoBaseWillBeGarbageCollectedFinalized<Testi
ngObserver>, public LifecycleObserver<DummyContext, TestingObserver, DummyContex
t> { | 68 class TestingObserver final : public NoBaseWillBeGarbageCollectedFinalized<Testi
ngObserver>, public LifecycleObserver<DummyContext, TestingObserver, DummyContex
t> { |
63 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TestingObserver); | 69 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TestingObserver); |
64 public: | 70 public: |
| 71 static PassOwnPtrWillBeRawPtr<TestingObserver> create(DummyContext* context) |
| 72 { |
| 73 return adoptPtrWillBeNoop(new TestingObserver(context)); |
| 74 } |
| 75 |
| 76 virtual void contextDestroyed() override |
| 77 { |
| 78 LifecycleObserver<DummyContext, TestingObserver, DummyContext>::contextD
estroyed(); |
| 79 if (m_observerToRemoveOnDestruct) { |
| 80 lifecycleContext()->removeObserver(m_observerToRemoveOnDestruct.get(
)); |
| 81 m_observerToRemoveOnDestruct.clear(); |
| 82 } |
| 83 m_contextDestroyedCalled = true; |
| 84 } |
| 85 |
| 86 DEFINE_INLINE_TRACE() |
| 87 { |
| 88 visitor->trace(m_observerToRemoveOnDestruct); |
| 89 LifecycleObserver<DummyContext, TestingObserver, DummyContext>::trace(vi
sitor); |
| 90 } |
| 91 |
| 92 void unobserve() { setContext(nullptr); } |
| 93 |
| 94 void setObserverToRemoveAndDestroy(PassOwnPtrWillBeRawPtr<TestingObserver> o
bserverToRemoveOnDestruct) |
| 95 { |
| 96 ASSERT(!m_observerToRemoveOnDestruct); |
| 97 m_observerToRemoveOnDestruct = observerToRemoveOnDestruct; |
| 98 } |
| 99 |
| 100 TestingObserver* innerObserver() const { return m_observerToRemoveOnDestruct
.get(); } |
| 101 bool contextDestroyedCalled() const { return m_contextDestroyedCalled; } |
| 102 |
| 103 private: |
65 explicit TestingObserver(DummyContext* context) | 104 explicit TestingObserver(DummyContext* context) |
66 : LifecycleObserver<DummyContext, TestingObserver, DummyContext>(context
) | 105 : LifecycleObserver<DummyContext, TestingObserver, DummyContext>(context
) |
67 , m_contextDestroyedCalled(false) | 106 , m_contextDestroyedCalled(false) |
68 { | 107 { |
69 setContext(context); | 108 setContext(context); |
70 } | 109 } |
71 | 110 |
72 virtual void contextDestroyed() override | 111 OwnPtrWillBeMember<TestingObserver> m_observerToRemoveOnDestruct; |
73 { | |
74 LifecycleObserver<DummyContext, TestingObserver, DummyContext>::contextD
estroyed(); | |
75 m_contextDestroyedCalled = true; | |
76 } | |
77 | |
78 DEFINE_INLINE_TRACE() | |
79 { | |
80 LifecycleObserver<DummyContext, TestingObserver, DummyContext>::trace(vi
sitor); | |
81 } | |
82 | |
83 bool m_contextDestroyedCalled; | 112 bool m_contextDestroyedCalled; |
84 | |
85 void unobserve() { setContext(nullptr); } | |
86 }; | 113 }; |
87 | 114 |
88 TEST(LifecycleContextTest, shouldObserveContextDestroyed) | 115 TEST(LifecycleContextTest, shouldObserveContextDestroyed) |
89 { | 116 { |
90 OwnPtrWillBeRawPtr<DummyContext> context = adoptPtrWillBeNoop(new DummyConte
xt()); | 117 OwnPtrWillBeRawPtr<DummyContext> context = DummyContext::create(); |
91 OwnPtrWillBePersistent<TestingObserver> observer = adoptPtrWillBeNoop(new Te
stingObserver(context.get())); | 118 OwnPtrWillBePersistent<TestingObserver> observer = TestingObserver::create(c
ontext.get()); |
92 | 119 |
93 EXPECT_EQ(observer->lifecycleContext(), context.get()); | 120 EXPECT_EQ(observer->lifecycleContext(), context.get()); |
94 EXPECT_FALSE(observer->m_contextDestroyedCalled); | 121 EXPECT_FALSE(observer->contextDestroyedCalled()); |
95 context->notifyContextDestroyed(); | 122 context->notifyContextDestroyed(); |
96 context = nullptr; | 123 context = nullptr; |
97 Heap::collectAllGarbage(); | 124 Heap::collectAllGarbage(); |
98 EXPECT_EQ(observer->lifecycleContext(), static_cast<DummyContext*>(0)); | 125 EXPECT_EQ(observer->lifecycleContext(), static_cast<DummyContext*>(0)); |
99 EXPECT_TRUE(observer->m_contextDestroyedCalled); | 126 EXPECT_TRUE(observer->contextDestroyedCalled()); |
100 } | 127 } |
101 | 128 |
102 TEST(LifecycleContextTest, shouldNotObserveContextDestroyedIfUnobserve) | 129 TEST(LifecycleContextTest, shouldNotObserveContextDestroyedIfUnobserve) |
103 { | 130 { |
104 OwnPtrWillBeRawPtr<DummyContext> context = adoptPtrWillBeNoop(new DummyConte
xt()); | 131 OwnPtrWillBeRawPtr<DummyContext> context = DummyContext::create(); |
105 OwnPtrWillBePersistent<TestingObserver> observer = adoptPtrWillBeNoop(new Te
stingObserver(context.get())); | 132 OwnPtrWillBePersistent<TestingObserver> observer = TestingObserver::create(c
ontext.get()); |
106 observer->unobserve(); | 133 observer->unobserve(); |
107 context->notifyContextDestroyed(); | 134 context->notifyContextDestroyed(); |
108 context = nullptr; | 135 context = nullptr; |
109 Heap::collectAllGarbage(); | 136 Heap::collectAllGarbage(); |
110 EXPECT_EQ(observer->lifecycleContext(), static_cast<DummyContext*>(0)); | 137 EXPECT_EQ(observer->lifecycleContext(), static_cast<DummyContext*>(0)); |
111 EXPECT_FALSE(observer->m_contextDestroyedCalled); | 138 EXPECT_FALSE(observer->contextDestroyedCalled()); |
112 } | 139 } |
113 | 140 |
| 141 TEST(LifecycleContextTest, observerRemovedDuringNotifyDestroyed) |
| 142 { |
| 143 // FIXME: Oilpan: this test can be removed when the LifecycleNotifier<T>::m_
observers |
| 144 // hash set is on the heap and membership is handled implicitly by the garba
ge collector. |
| 145 OwnPtrWillBeRawPtr<DummyContext> context = DummyContext::create(); |
| 146 OwnPtrWillBePersistent<TestingObserver> observer = TestingObserver::create(c
ontext.get()); |
| 147 OwnPtrWillBeRawPtr<TestingObserver> innerObserver = TestingObserver::create(
context.get()); |
| 148 // Attach the observer to the other. When 'observer' is notified |
| 149 // of destruction, it will remove & destroy 'innerObserver'. |
| 150 observer->setObserverToRemoveAndDestroy(innerObserver.release()); |
| 151 |
| 152 EXPECT_EQ(observer->lifecycleContext(), context.get()); |
| 153 EXPECT_EQ(observer->innerObserver()->lifecycleContext(), context.get()); |
| 154 EXPECT_FALSE(observer->contextDestroyedCalled()); |
| 155 EXPECT_FALSE(observer->innerObserver()->contextDestroyedCalled()); |
| 156 |
| 157 context->notifyContextDestroyed(); |
| 158 EXPECT_EQ(observer->innerObserver(), nullptr); |
| 159 context = nullptr; |
| 160 Heap::collectAllGarbage(); |
| 161 EXPECT_EQ(observer->lifecycleContext(), static_cast<DummyContext*>(0)); |
| 162 EXPECT_TRUE(observer->contextDestroyedCalled()); |
114 } | 163 } |
| 164 |
| 165 } // namespace blink |
OLD | NEW |