|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "nsISupports.h" |
|
7 #include "nsIComponentManager.h" |
|
8 #include "nsIObserverService.h" |
|
9 #include "nsIObserver.h" |
|
10 #include "nsISimpleEnumerator.h" |
|
11 #include "nsStringGlue.h" |
|
12 #include "nsWeakReference.h" |
|
13 #include "nsComponentManagerUtils.h" |
|
14 #include "mozilla/Attributes.h" |
|
15 |
|
16 #include <stdio.h> |
|
17 |
|
18 static nsIObserverService *anObserverService = nullptr; |
|
19 |
|
20 static void testResult( nsresult rv ) { |
|
21 if ( NS_SUCCEEDED( rv ) ) { |
|
22 printf("...ok\n"); |
|
23 } else { |
|
24 printf("...failed, rv=0x%x\n", (int)rv); |
|
25 } |
|
26 return; |
|
27 } |
|
28 |
|
29 void printString(nsString &str) { |
|
30 printf("%s", NS_ConvertUTF16toUTF8(str).get()); |
|
31 } |
|
32 |
|
33 class TestObserver MOZ_FINAL : public nsIObserver, |
|
34 public nsSupportsWeakReference |
|
35 { |
|
36 public: |
|
37 TestObserver( const nsAString &name ) |
|
38 : mName( name ) { |
|
39 } |
|
40 NS_DECL_ISUPPORTS |
|
41 NS_DECL_NSIOBSERVER |
|
42 |
|
43 nsString mName; |
|
44 |
|
45 private: |
|
46 ~TestObserver() {} |
|
47 }; |
|
48 |
|
49 NS_IMPL_ISUPPORTS( TestObserver, nsIObserver, nsISupportsWeakReference ) |
|
50 |
|
51 NS_IMETHODIMP |
|
52 TestObserver::Observe( nsISupports *aSubject, |
|
53 const char *aTopic, |
|
54 const char16_t *someData ) { |
|
55 nsCString topic( aTopic ); |
|
56 nsString data( someData ); |
|
57 /* |
|
58 The annoying double-cast below is to work around an annoying bug in |
|
59 the compiler currently used on wensleydale. This is a test. |
|
60 */ |
|
61 printString(mName); |
|
62 printf(" has observed something: subject@%p", (void*)aSubject); |
|
63 printf(" name="); |
|
64 printString(reinterpret_cast<TestObserver*>(reinterpret_cast<void*>(aSubject))->mName); |
|
65 printf(" aTopic=%s", topic.get()); |
|
66 printf(" someData="); |
|
67 printString(data); |
|
68 printf("\n"); |
|
69 return NS_OK; |
|
70 } |
|
71 |
|
72 int main(int argc, char *argv[]) |
|
73 { |
|
74 nsCString topicA; topicA.Assign( "topic-A" ); |
|
75 nsCString topicB; topicB.Assign( "topic-B" ); |
|
76 nsresult rv; |
|
77 |
|
78 nsresult res = CallCreateInstance("@mozilla.org/observer-service;1", &anObserverService); |
|
79 |
|
80 if (res == NS_OK) { |
|
81 |
|
82 nsIObserver *aObserver = new TestObserver(NS_LITERAL_STRING("Observer-A")); |
|
83 aObserver->AddRef(); |
|
84 nsIObserver *bObserver = new TestObserver(NS_LITERAL_STRING("Observer-B")); |
|
85 bObserver->AddRef(); |
|
86 |
|
87 printf("Adding Observer-A as observer of topic-A...\n"); |
|
88 rv = anObserverService->AddObserver(aObserver, topicA.get(), false); |
|
89 testResult(rv); |
|
90 |
|
91 printf("Adding Observer-B as observer of topic-A...\n"); |
|
92 rv = anObserverService->AddObserver(bObserver, topicA.get(), false); |
|
93 testResult(rv); |
|
94 |
|
95 printf("Adding Observer-B as observer of topic-B...\n"); |
|
96 rv = anObserverService->AddObserver(bObserver, topicB.get(), false); |
|
97 testResult(rv); |
|
98 |
|
99 printf("Testing Notify(observer-A, topic-A)...\n"); |
|
100 rv = anObserverService->NotifyObservers( aObserver, |
|
101 topicA.get(), |
|
102 MOZ_UTF16("Testing Notify(observer-A, topic-A)") ); |
|
103 testResult(rv); |
|
104 |
|
105 printf("Testing Notify(observer-B, topic-B)...\n"); |
|
106 rv = anObserverService->NotifyObservers( bObserver, |
|
107 topicB.get(), |
|
108 MOZ_UTF16("Testing Notify(observer-B, topic-B)") ); |
|
109 testResult(rv); |
|
110 |
|
111 printf("Testing EnumerateObserverList (for topic-A)...\n"); |
|
112 nsCOMPtr<nsISimpleEnumerator> e; |
|
113 rv = anObserverService->EnumerateObservers(topicA.get(), getter_AddRefs(e)); |
|
114 |
|
115 testResult(rv); |
|
116 |
|
117 printf("Enumerating observers of topic-A...\n"); |
|
118 if ( e ) { |
|
119 nsCOMPtr<nsIObserver> observer; |
|
120 bool loop = true; |
|
121 while( NS_SUCCEEDED(e->HasMoreElements(&loop)) && loop) |
|
122 { |
|
123 nsCOMPtr<nsISupports> supports; |
|
124 e->GetNext(getter_AddRefs(supports)); |
|
125 observer = do_QueryInterface(supports); |
|
126 printf("Calling observe on enumerated observer "); |
|
127 printString(reinterpret_cast<TestObserver*> |
|
128 (reinterpret_cast<void*>(observer.get()))->mName); |
|
129 printf("...\n"); |
|
130 rv = observer->Observe( observer, |
|
131 topicA.get(), |
|
132 MOZ_UTF16("during enumeration") ); |
|
133 testResult(rv); |
|
134 } |
|
135 } |
|
136 printf("...done enumerating observers of topic-A\n"); |
|
137 |
|
138 printf("Removing Observer-A...\n"); |
|
139 rv = anObserverService->RemoveObserver(aObserver, topicA.get()); |
|
140 testResult(rv); |
|
141 |
|
142 |
|
143 printf("Removing Observer-B (topic-A)...\n"); |
|
144 rv = anObserverService->RemoveObserver(bObserver, topicB.get()); |
|
145 testResult(rv); |
|
146 printf("Removing Observer-B (topic-B)...\n"); |
|
147 rv = anObserverService->RemoveObserver(bObserver, topicA.get()); |
|
148 testResult(rv); |
|
149 |
|
150 } |
|
151 return 0; |
|
152 } |