michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsISupports.h" michael@0: #include "nsIComponentManager.h" michael@0: #include "nsIObserverService.h" michael@0: #include "nsIObserver.h" michael@0: #include "nsISimpleEnumerator.h" michael@0: #include "nsStringGlue.h" michael@0: #include "nsWeakReference.h" michael@0: #include "nsComponentManagerUtils.h" michael@0: #include "mozilla/Attributes.h" michael@0: michael@0: #include michael@0: michael@0: static nsIObserverService *anObserverService = nullptr; michael@0: michael@0: static void testResult( nsresult rv ) { michael@0: if ( NS_SUCCEEDED( rv ) ) { michael@0: printf("...ok\n"); michael@0: } else { michael@0: printf("...failed, rv=0x%x\n", (int)rv); michael@0: } michael@0: return; michael@0: } michael@0: michael@0: void printString(nsString &str) { michael@0: printf("%s", NS_ConvertUTF16toUTF8(str).get()); michael@0: } michael@0: michael@0: class TestObserver MOZ_FINAL : public nsIObserver, michael@0: public nsSupportsWeakReference michael@0: { michael@0: public: michael@0: TestObserver( const nsAString &name ) michael@0: : mName( name ) { michael@0: } michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSIOBSERVER michael@0: michael@0: nsString mName; michael@0: michael@0: private: michael@0: ~TestObserver() {} michael@0: }; michael@0: michael@0: NS_IMPL_ISUPPORTS( TestObserver, nsIObserver, nsISupportsWeakReference ) michael@0: michael@0: NS_IMETHODIMP michael@0: TestObserver::Observe( nsISupports *aSubject, michael@0: const char *aTopic, michael@0: const char16_t *someData ) { michael@0: nsCString topic( aTopic ); michael@0: nsString data( someData ); michael@0: /* michael@0: The annoying double-cast below is to work around an annoying bug in michael@0: the compiler currently used on wensleydale. This is a test. michael@0: */ michael@0: printString(mName); michael@0: printf(" has observed something: subject@%p", (void*)aSubject); michael@0: printf(" name="); michael@0: printString(reinterpret_cast(reinterpret_cast(aSubject))->mName); michael@0: printf(" aTopic=%s", topic.get()); michael@0: printf(" someData="); michael@0: printString(data); michael@0: printf("\n"); michael@0: return NS_OK; michael@0: } michael@0: michael@0: int main(int argc, char *argv[]) michael@0: { michael@0: nsCString topicA; topicA.Assign( "topic-A" ); michael@0: nsCString topicB; topicB.Assign( "topic-B" ); michael@0: nsresult rv; michael@0: michael@0: nsresult res = CallCreateInstance("@mozilla.org/observer-service;1", &anObserverService); michael@0: michael@0: if (res == NS_OK) { michael@0: michael@0: nsIObserver *aObserver = new TestObserver(NS_LITERAL_STRING("Observer-A")); michael@0: aObserver->AddRef(); michael@0: nsIObserver *bObserver = new TestObserver(NS_LITERAL_STRING("Observer-B")); michael@0: bObserver->AddRef(); michael@0: michael@0: printf("Adding Observer-A as observer of topic-A...\n"); michael@0: rv = anObserverService->AddObserver(aObserver, topicA.get(), false); michael@0: testResult(rv); michael@0: michael@0: printf("Adding Observer-B as observer of topic-A...\n"); michael@0: rv = anObserverService->AddObserver(bObserver, topicA.get(), false); michael@0: testResult(rv); michael@0: michael@0: printf("Adding Observer-B as observer of topic-B...\n"); michael@0: rv = anObserverService->AddObserver(bObserver, topicB.get(), false); michael@0: testResult(rv); michael@0: michael@0: printf("Testing Notify(observer-A, topic-A)...\n"); michael@0: rv = anObserverService->NotifyObservers( aObserver, michael@0: topicA.get(), michael@0: MOZ_UTF16("Testing Notify(observer-A, topic-A)") ); michael@0: testResult(rv); michael@0: michael@0: printf("Testing Notify(observer-B, topic-B)...\n"); michael@0: rv = anObserverService->NotifyObservers( bObserver, michael@0: topicB.get(), michael@0: MOZ_UTF16("Testing Notify(observer-B, topic-B)") ); michael@0: testResult(rv); michael@0: michael@0: printf("Testing EnumerateObserverList (for topic-A)...\n"); michael@0: nsCOMPtr e; michael@0: rv = anObserverService->EnumerateObservers(topicA.get(), getter_AddRefs(e)); michael@0: michael@0: testResult(rv); michael@0: michael@0: printf("Enumerating observers of topic-A...\n"); michael@0: if ( e ) { michael@0: nsCOMPtr observer; michael@0: bool loop = true; michael@0: while( NS_SUCCEEDED(e->HasMoreElements(&loop)) && loop) michael@0: { michael@0: nsCOMPtr supports; michael@0: e->GetNext(getter_AddRefs(supports)); michael@0: observer = do_QueryInterface(supports); michael@0: printf("Calling observe on enumerated observer "); michael@0: printString(reinterpret_cast michael@0: (reinterpret_cast(observer.get()))->mName); michael@0: printf("...\n"); michael@0: rv = observer->Observe( observer, michael@0: topicA.get(), michael@0: MOZ_UTF16("during enumeration") ); michael@0: testResult(rv); michael@0: } michael@0: } michael@0: printf("...done enumerating observers of topic-A\n"); michael@0: michael@0: printf("Removing Observer-A...\n"); michael@0: rv = anObserverService->RemoveObserver(aObserver, topicA.get()); michael@0: testResult(rv); michael@0: michael@0: michael@0: printf("Removing Observer-B (topic-A)...\n"); michael@0: rv = anObserverService->RemoveObserver(bObserver, topicB.get()); michael@0: testResult(rv); michael@0: printf("Removing Observer-B (topic-B)...\n"); michael@0: rv = anObserverService->RemoveObserver(bObserver, topicA.get()); michael@0: testResult(rv); michael@0: michael@0: } michael@0: return 0; michael@0: }