# HG changeset patch
# Parent 31879b88cc82c1f44e6a6c25a05aa2c70af22d7e
# User Martin Stransky <stransky@redhat.com>
Bug 627672 - XPCOM component (libdbusservice.so) is not registered although it should be; r=cbiesinger



diff --git a/netwerk/base/src/nsIOService.cpp b/netwerk/base/src/nsIOService.cpp
--- a/netwerk/base/src/nsIOService.cpp
+++ b/netwerk/base/src/nsIOService.cpp
@@ -160,31 +160,33 @@ PRInt16 gBadPortList[] = {
   2049, // nfs
   4045, // lockd
   6000, // x11        
   0,    // This MUST be zero so that we can populating the array
 };
 
 static const char kProfileChangeNetTeardownTopic[] = "profile-change-net-teardown";
 static const char kProfileChangeNetRestoreTopic[] = "profile-change-net-restore";
+static const char kStartupTopic[] = "profile-after-change";
 
 // Necko buffer cache
 nsIMemory* nsIOService::gBufferCache = nsnull;
 PRUint32   nsIOService::gDefaultSegmentSize = 4096;
 PRUint32   nsIOService::gDefaultSegmentCount = 24;
 
 ////////////////////////////////////////////////////////////////////////////////
 
 nsIOService::nsIOService()
     : mOffline(PR_TRUE)
     , mOfflineForProfileChange(PR_FALSE)
     , mManageOfflineStatus(PR_TRUE)
     , mSettingOffline(PR_FALSE)
     , mSetOfflineValue(PR_FALSE)
     , mShutdown(PR_FALSE)
+    , mNetworkLinkServiceInitialized(PR_FALSE)
     , mChannelEventSinks(NS_CHANNEL_EVENT_SINK_CATEGORY)
     , mContentSniffers(NS_CONTENT_SNIFFER_CATEGORY)
     , mAutoDialEnabled(PR_FALSE)
 {
 }
 
 nsresult
 nsIOService::Init()
@@ -230,16 +232,17 @@ nsIOService::Init()
     }
     
     // Register for profile change notifications
     nsCOMPtr<nsIObserverService> observerService =
         mozilla::services::GetObserverService();
     if (observerService) {
         observerService->AddObserver(this, kProfileChangeNetTeardownTopic, PR_TRUE);
         observerService->AddObserver(this, kProfileChangeNetRestoreTopic, PR_TRUE);
+        observerService->AddObserver(this, kStartupTopic, PR_TRUE);
         observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE);
         observerService->AddObserver(this, NS_NETWORK_LINK_TOPIC, PR_TRUE);
     }
     else
         NS_WARNING("failed to get observer service");
         
     NS_TIME_FUNCTION_MARK("Registered observers");
 
@@ -258,29 +261,19 @@ nsIOService::Init()
         NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Was unable to allocate.  No gBufferCache.");
         CallQueryInterface(recyclingAllocator, &gBufferCache);
     }
 
     NS_TIME_FUNCTION_MARK("Set up the recycling allocator");
 
     gIOService = this;
 
-    // go into managed mode if we can, and chrome process
-    if (XRE_GetProcessType() == GeckoProcessType_Default)
-        mNetworkLinkService = do_GetService(NS_NETWORK_LINK_SERVICE_CONTRACTID);
-
-    if (!mNetworkLinkService)
-        // We can't really determine if the machine has a usable network connection,
-        // so let's cross our fingers!
-        mManageOfflineStatus = PR_FALSE;
-
-    if (mManageOfflineStatus)
-        TrackNetworkLinkStatusForOffline();
-    else
-        SetOffline(PR_FALSE);
+    // We can't really determine if the machine has a usable network connection,
+    // (mNetworkLinkService will be initialized later) so let's cross our fingers!
+    SetOffline(PR_FALSE);
     
     NS_TIME_FUNCTION_MARK("Set up network link service");
 
     return NS_OK;
 }
 
 
 nsIOService::~nsIOService()
@@ -306,16 +299,57 @@ nsIOService::InitializeSocketTransportSe
         rv = mSocketTransportService->Init();
         NS_ASSERTION(NS_SUCCEEDED(rv), "socket transport service init failed");
         mSocketTransportService->SetAutodialEnabled(mAutoDialEnabled);
     }
 
     return rv;
 }
 
+nsresult
+nsIOService::InitializeNetworkLinkService()
+{
+    NS_TIME_FUNCTION;
+
+    nsresult rv = NS_OK;
+
+    if (mNetworkLinkServiceInitialized)
+      return rv;
+
+#if defined(MOZ_PLATFORM_MAEMO)
+    // libdbusservice fails to initialize on Maemo platform, see Bug 627672
+    mNetworkLinkService = NULL;
+#else
+    // go into managed mode if we can, and chrome process
+    if (XRE_GetProcessType() == GeckoProcessType_Default)
+    {
+        mNetworkLinkService = do_GetService(NS_NETWORK_LINK_SERVICE_CONTRACTID, &rv);
+        if (NS_FAILED(rv)) {
+            NS_WARNING("failed to get network link service");
+            return rv;
+        }
+    }
+#endif
+
+    mNetworkLinkServiceInitialized = PR_TRUE;
+
+    if (!mNetworkLinkService) {
+        // We can't really determine if the machine has a usable network connection,
+        // so let's cross our fingers!
+        mManageOfflineStatus = PR_FALSE;
+    }
+
+    if (mManageOfflineStatus)
+        TrackNetworkLinkStatusForOffline();
+    else
+        SetOffline(PR_FALSE);
+    
+    return rv;
+}
+
 nsIOService*
 nsIOService::GetInstance() {
     if (!gIOService) {
         gIOService = new nsIOService();
         if (!gIOService)
             return nsnull;
         NS_ADDREF(gIOService);
 
@@ -689,16 +723,19 @@ nsIOService::NewChannel(const nsACString
     if (NS_FAILED(rv)) return rv;
 
     return NewChannelFromURI(uri, result);
 }
 
 PRBool
 nsIOService::IsLinkUp()
 {
+    NS_ASSERTION(mNetworkLinkServiceInitialized, 
+                 "network link service should be initialized");
+
     if (!mNetworkLinkService) {
         // We cannot decide, assume the link is up
         return PR_TRUE;
     }
 
     PRBool isLinkUp;
     nsresult rv;
     rv = mNetworkLinkService->GetIsLinkUp(&isLinkUp);
@@ -968,16 +1005,20 @@ nsIOService::Observe(nsISupports *subjec
         if (mOfflineForProfileChange) {
             mOfflineForProfileChange = PR_FALSE;
             if (!mManageOfflineStatus ||
                 NS_FAILED(TrackNetworkLinkStatusForOffline())) {
                 SetOffline(PR_FALSE);
             }
         } 
     }
+    else if (!strcmp(topic, kStartupTopic)) {
+        // Lazy initialization of network link service (see bug 620472)
+        InitializeNetworkLinkService();
+    }
     else if (!strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
         // Remember we passed XPCOM shutdown notification to prevent any
         // changes of the offline status from now. We must not allow going
         // online after this point.
         mShutdown = PR_TRUE;
 
         SetOffline(PR_TRUE);
 
@@ -1085,32 +1126,40 @@ nsIOService::NewSimpleNestedURI(nsIURI* 
     NS_IF_ADDREF(*aResult = new nsSimpleNestedURI(safeURI));
     return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 NS_IMETHODIMP
 nsIOService::SetManageOfflineStatus(PRBool aManage) {
     PRBool wasManaged = mManageOfflineStatus;
     mManageOfflineStatus = aManage;
+
+    if (!mNetworkLinkServiceInitialized) {
+        InitializeNetworkLinkService();
+    }
+
     if (mManageOfflineStatus && !wasManaged)
         return TrackNetworkLinkStatusForOffline();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsIOService::GetManageOfflineStatus(PRBool* aManage) {
     *aManage = mManageOfflineStatus;
     return NS_OK;
 }
 
 nsresult
 nsIOService::TrackNetworkLinkStatusForOffline()
 {
     NS_ASSERTION(mManageOfflineStatus,
                  "Don't call this unless we're managing the offline status");
+    NS_ASSERTION(mNetworkLinkServiceInitialized, 
+                "network link service should be set up");
+
     if (!mNetworkLinkService)
         return NS_ERROR_FAILURE;
 
     if (mShutdown)
         return NS_ERROR_NOT_AVAILABLE;
   
     // check to make sure this won't collide with Autodial
     if (mSocketTransportService) {
diff --git a/netwerk/base/src/nsIOService.h b/netwerk/base/src/nsIOService.h
--- a/netwerk/base/src/nsIOService.h
+++ b/netwerk/base/src/nsIOService.h
@@ -129,16 +129,17 @@ private:
                                               nsIProtocolHandler* hdlr);
 
     // Prefs wrangling
     NS_HIDDEN_(void) PrefsChanged(nsIPrefBranch *prefs, const char *pref = nsnull);
     NS_HIDDEN_(void) GetPrefBranch(nsIPrefBranch2 **);
     NS_HIDDEN_(void) ParsePortList(nsIPrefBranch *prefBranch, const char *pref, PRBool remove);
 
     nsresult InitializeSocketTransportService();
+    nsresult InitializeNetworkLinkService();
 
 private:
     PRPackedBool                         mOffline;
     PRPackedBool                         mOfflineForProfileChange;
     PRPackedBool                         mManageOfflineStatus;
 
     // Used to handle SetOffline() reentrancy.  See the comment in
     // SetOffline() for more details.
@@ -146,16 +147,17 @@ private:
     PRPackedBool                         mSetOfflineValue;
 
     PRPackedBool                         mShutdown;
 
     nsCOMPtr<nsPISocketTransportService> mSocketTransportService;
     nsCOMPtr<nsPIDNSService>             mDNSService;
     nsCOMPtr<nsIProtocolProxyService2>   mProxyService;
     nsCOMPtr<nsINetworkLinkService>      mNetworkLinkService;
+    PRPackedBool                         mNetworkLinkServiceInitialized;
     
     // Cached protocol handlers
     nsWeakPtr                            mWeakHandler[NS_N(gScheme)];
 
     // cached categories
     nsCategoryCache<nsIChannelEventSink> mChannelEventSinks;
     nsCategoryCache<nsIContentSniffer>   mContentSniffers;
 
