Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / toolkit / system / dbus / nsNetworkManagerListener.cpp
blob42e2d8edf2d3f22d03071e74e84097576d7dbcec
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
3 */
4 /* ***** BEGIN LICENSE BLOCK *****
5 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
8 * The contents of this file are subject to the Mozilla Public
9 * License Version 1.1 (the "License"); you may not use this file
10 * except in compliance with the License. You may obtain a copy of
11 * the License at http://www.mozilla.org/MPL/
13 * Software distributed under the License is distributed on an "AS
14 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
15 * implied. See the License for the specific language governing
16 * rights and limitations under the License.
18 * The Original Code is Novell code.
20 * The Initial Developer of the Original Code is Novell, Inc.
21 * Portions created by the Initial Developer are Copyright (C) 2006
22 * the Initial Developer. All Rights Reserved.
24 * Original Author: Robert O'Callahan (rocallahan@novell.com)
26 * Contributor(s):
28 * Alternatively, the contents of this file may be used under the terms of
29 * either the GNU General Public License Version 2 or later (the "GPL"), or
30 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31 * in which case the provisions of the GPL or the LGPL are applicable instead
32 * of those above. If you wish to allow use of your version of this file only
33 * under the terms of either the GPL or the LGPL, and not to allow others to
34 * use your version of this file under the terms of the NPL, indicate your
35 * decision by deleting the provisions above and replace them with the notice
36 * and other provisions required by the GPL or the LGPL. If you do not delete
37 * the provisions above, a recipient may use your version of this file under
38 * the terms of any one of the NPL, the GPL or the LGPL.
40 * ***** END LICENSE BLOCK ***** */
42 #include "nsNetworkManagerListener.h"
44 #include "nsNetCID.h"
45 #include "nsServiceManagerUtils.h"
46 #include "nsIObserverService.h"
47 #include "nsStringAPI.h"
48 #include "nsIPrefBranch2.h"
49 #include "nsIPrefService.h"
51 // Define NetworkManager API constants. This avoids a dependency on
52 // NetworkManager-devel.
53 #define NM_DBUS_SERVICE "org.freedesktop.NetworkManager"
54 #define NM_DBUS_PATH "/org/freedesktop/NetworkManager"
55 #define NM_DBUS_INTERFACE "org.freedesktop.NetworkManager"
56 #define NM_DBUS_SIGNAL_STATE_CHANGE "StateChange"
57 typedef enum NMState
59 NM_STATE_UNKNOWN = 0,
60 NM_STATE_ASLEEP,
61 NM_STATE_CONNECTING,
62 NM_STATE_CONNECTED,
63 NM_STATE_DISCONNECTED
64 } NMState;
66 nsNetworkManagerListener::nsNetworkManagerListener() :
67 mLinkUp(PR_TRUE), mNetworkManagerActive(PR_FALSE),
68 mOK(PR_TRUE), mManageIOService(PR_TRUE)
72 nsNetworkManagerListener::~nsNetworkManagerListener() {
73 if (mDBUS) {
74 mDBUS->RemoveClient(this);
78 NS_IMPL_ISUPPORTS1(nsNetworkManagerListener, nsINetworkLinkService)
80 nsresult
81 nsNetworkManagerListener::GetIsLinkUp(PRBool* aIsUp) {
82 *aIsUp = mLinkUp;
83 return NS_OK;
86 nsresult
87 nsNetworkManagerListener::GetLinkStatusKnown(PRBool* aKnown) {
88 *aKnown = mNetworkManagerActive;
89 return NS_OK;
92 nsresult
93 nsNetworkManagerListener::Init() {
94 mDBUS = nsDBusService::Get();
95 if (!mDBUS)
96 return NS_ERROR_OUT_OF_MEMORY;
97 nsresult rv = mDBUS->AddClient(this);
98 if (NS_FAILED(rv)) {
99 mDBUS = nsnull;
100 return rv;
102 if (!mOK)
103 return NS_ERROR_FAILURE;
104 return NS_OK;
107 static void
108 NetworkStatusNotify(DBusPendingCall *pending, void* user_data) {
109 DBusMessage* msg = dbus_pending_call_steal_reply(pending);
110 if (!msg)
111 return;
112 if (dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_METHOD_RETURN) {
113 static_cast<nsNetworkManagerListener*>(user_data)->UpdateNetworkStatus(msg);
115 dbus_message_unref(msg);
118 void
119 nsNetworkManagerListener::RegisterWithConnection(DBusConnection* connection) {
120 DBusError error;
121 dbus_error_init(&error);
123 dbus_bus_add_match(connection,
124 "type='signal',"
125 "interface='" NM_DBUS_INTERFACE "',"
126 "sender='" NM_DBUS_SERVICE "',"
127 "path='" NM_DBUS_PATH "'", &error);
128 mOK = !dbus_error_is_set(&error);
129 dbus_error_free(&error);
130 if (!mOK)
131 return;
133 DBusMessage* msg =
134 dbus_message_new_method_call(NM_DBUS_SERVICE, NM_DBUS_PATH,
135 NM_DBUS_INTERFACE, "state");
136 if (!msg) {
137 mOK = PR_FALSE;
138 return;
141 DBusPendingCall* reply = mDBUS->SendWithReply(this, msg);
142 if (!reply) {
143 mOK = PR_FALSE;
144 return;
147 dbus_pending_call_set_notify(reply, NetworkStatusNotify, this, NULL);
148 dbus_pending_call_unref(reply);
151 void
152 nsNetworkManagerListener::NotifyNetworkStatusObservers() {
153 nsCOMPtr<nsIObserverService> observerService =
154 do_GetService("@mozilla.org/observer-service;1");
155 if (!observerService)
156 return;
158 const PRUnichar* status;
159 if (mNetworkManagerActive) {
160 status = mLinkUp ? NS_LITERAL_STRING(NS_NETWORK_LINK_DATA_UP).get()
161 : NS_LITERAL_STRING(NS_NETWORK_LINK_DATA_DOWN).get();
162 } else {
163 status = NS_LITERAL_STRING(NS_NETWORK_LINK_DATA_UNKNOWN).get();
166 observerService->NotifyObservers(static_cast<nsISupports*>(this),
167 NS_NETWORK_LINK_TOPIC, status);
170 void
171 nsNetworkManagerListener::UnregisterWithConnection(DBusConnection* connection) {
172 mNetworkManagerActive = PR_FALSE;
173 NotifyNetworkStatusObservers();
176 PRBool
177 nsNetworkManagerListener::HandleMessage(DBusMessage* message) {
178 if (dbus_message_is_signal(message, NM_DBUS_INTERFACE,
179 NM_DBUS_SIGNAL_STATE_CHANGE)) {
180 UpdateNetworkStatus(message);
181 return PR_TRUE;
183 return PR_FALSE;
186 void
187 nsNetworkManagerListener::UpdateNetworkStatus(DBusMessage* msg) {
188 PRInt32 result;
189 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &result,
190 DBUS_TYPE_INVALID))
191 return;
193 // Don't update status if disabled by pref
194 nsCOMPtr<nsIPrefBranch2> prefs =
195 do_GetService(NS_PREFSERVICE_CONTRACTID);
196 if (prefs) {
197 PRBool ignore = PR_FALSE;
198 prefs->GetBoolPref("toolkit.networkmanager.disable", &ignore);
199 if (ignore)
200 return;
203 mNetworkManagerActive = PR_TRUE;
205 PRBool wasUp = mLinkUp;
206 mLinkUp = result == NM_STATE_CONNECTED;
207 if (wasUp == mLinkUp)
208 return;
210 NotifyNetworkStatusObservers();