1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
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 mozilla.org code.
20 * The Initial Developer of the Original Code is Sun Microsystems, Inc.
21 * Portions created by Sun Microsystems are Copyright (C) 2003 Sun
22 * Microsystems, Inc. All Rights Reserved.
24 * Original Author: Bolian Yin (bolian.yin@sun.com)
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 "nsSystemPref.h"
43 #include "nsIObserverService.h"
45 #include "nsSystemPrefLog.h"
46 #include "nsSystemPrefService.h"
49 const char sSysPrefString
[] = "config.use_system_prefs";
57 const char *prefName
; // mozilla pref string name
58 MozPrefValue defaultValue
; // store the mozilla default value
59 PRBool isLocked
; // store the mozilla lock status
62 defaultValue
.intVal
= 0;
63 defaultValue
.stringVal
= nsnull
;
64 defaultValue
.boolVal
= PR_FALSE
;
67 void SetPrefName(const char *aPrefName
) {
72 // all prefs that mozilla need to read from host system if they are available
73 static const char *sSysPrefList
[] = {
75 "network.proxy.http_port",
77 "network.proxy.ftp_port",
79 "network.proxy.ssl_port",
80 "network.proxy.socks",
81 "network.proxy.socks_port",
82 "network.proxy.no_proxies_on",
83 "network.proxy.autoconfig_url",
85 "config.use_system_prefs.accessibility",
88 PRLogModuleInfo
*gSysPrefLog
= NULL
;
90 NS_IMPL_ISUPPORTS2(nsSystemPref
, nsIObserver
, nsISupportsWeakReference
)
92 nsSystemPref::nsSystemPref():
93 mSysPrefService(nsnull
),
99 nsSystemPref::~nsSystemPref()
101 mSysPrefService
= nsnull
;
106 ///////////////////////////////////////////////////////////////////////////////
107 // nsSystemPref::Init
108 // Setup log and listen on NS_PREFSERVICE_READ_TOPIC_ID from pref service
109 ///////////////////////////////////////////////////////////////////////////////
111 nsSystemPref::Init(void)
116 gSysPrefLog
= PR_NewLogModule("Syspref");
118 return NS_ERROR_OUT_OF_MEMORY
;
121 nsCOMPtr
<nsIObserverService
> observerService
=
122 do_GetService("@mozilla.org/observer-service;1", &rv
);
124 if (observerService
) {
125 rv
= observerService
->AddObserver(this, NS_PREFSERVICE_READ_TOPIC_ID
,
127 rv
= observerService
->AddObserver(this, "profile-before-change",
129 SYSPREF_LOG(("Add Observer for %s\n", NS_PREFSERVICE_READ_TOPIC_ID
));
134 ///////////////////////////////////////////////////////////////////////////////
135 // nsSystemPref::Observe
136 // Observe notifications from mozilla pref system and system prefs (if enabled)
137 ///////////////////////////////////////////////////////////////////////////////
139 nsSystemPref::Observe(nsISupports
*aSubject
,
141 const PRUnichar
*aData
)
148 // if we are notified by pref service
149 // check the system pref settings
150 if (!nsCRT::strcmp(aTopic
, NS_PREFSERVICE_READ_TOPIC_ID
)) {
151 SYSPREF_LOG(("Observed: %s\n", aTopic
));
153 nsCOMPtr
<nsIPrefBranch2
> prefBranch
=
154 do_GetService(NS_PREFSERVICE_CONTRACTID
, &rv
);
158 rv
= prefBranch
->GetBoolPref(sSysPrefString
, &mEnabled
);
160 SYSPREF_LOG(("...FAil to Get %s\n", sSysPrefString
));
164 // if there is no system pref service, assume nothing happen to us
165 mSysPrefService
= do_GetService(NS_SYSTEMPREF_SERVICE_CONTRACTID
, &rv
);
166 if (NS_FAILED(rv
) || !mSysPrefService
) {
167 SYSPREF_LOG(("...No System Pref Service\n"));
171 // listen on its changes
172 rv
= prefBranch
->AddObserver(sSysPrefString
, this, PR_TRUE
);
174 SYSPREF_LOG(("...FAil to add observer for %s\n", sSysPrefString
));
179 SYSPREF_LOG(("%s is disabled\n", sSysPrefString
));
182 SYSPREF_LOG(("%s is enabled\n", sSysPrefString
));
183 rv
= UseSystemPrefs();
186 // sSysPrefString value was changed, update ...
187 else if (!nsCRT::strcmp(aTopic
, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID
) &&
188 NS_ConvertUTF8toUTF16(sSysPrefString
).Equals(aData
)) {
189 SYSPREF_LOG(("++++++ Notify: topic=%s data=%s\n",
190 aTopic
, NS_ConvertUTF16toUTF8(aData
).get()));
192 nsCOMPtr
<nsIPrefBranch
> prefBranch
=
193 do_GetService(NS_PREFSERVICE_CONTRACTID
, &rv
);
197 PRBool enabled
= mEnabled
;
198 rv
= prefBranch
->GetBoolPref(sSysPrefString
, &mEnabled
);
199 if (enabled
!= mEnabled
) {
201 //read prefs from system
202 rv
= UseSystemPrefs();
204 //roll back to mozilla prefs
205 rv
= UseMozillaPrefs();
209 // if the system pref notify us that some pref has been changed by user
210 // outside mozilla. We need to read it again.
211 else if (!nsCRT::strcmp(aTopic
, NS_SYSTEMPREF_PREFCHANGE_TOPIC_ID
) &&
213 NS_ASSERTION(mEnabled
== PR_TRUE
, "Should not listen when disabled");
214 SYSPREF_LOG(("====== System Pref Notify topic=%s data=%s\n",
215 aTopic
, (char*)aData
));
216 rv
= ReadSystemPref(NS_LossyConvertUTF16toASCII(aData
).get());
218 } else if (!nsCRT::strcmp(aTopic
,"profile-before-change")) {
219 //roll back to mozilla prefs
223 mSysPrefService
= nsnull
;
227 SYSPREF_LOG(("Not needed topic Received %s\n", aTopic
));
233 ////////////////////////////////////////////////////////////////
234 // nsSystemPref::UseSystemPrefs
235 // Read all the prefs in the table from system, listen for their
236 // changes in system pref service.
237 ////////////////////////////////////////////////////////////////
239 nsSystemPref::UseSystemPrefs()
241 SYSPREF_LOG(("\n====Now Use system prefs==\n"));
243 if (!mSysPrefService
) {
244 return NS_ERROR_FAILURE
;
247 PRIntn sysPrefCount
= sizeof(sSysPrefList
) / sizeof(sSysPrefList
[0]);
250 mSysPrefs
= new SysPrefItem
[sysPrefCount
];
252 return NS_ERROR_OUT_OF_MEMORY
;
253 for (PRIntn index
= 0; index
< sysPrefCount
; ++index
)
254 mSysPrefs
[index
].SetPrefName(sSysPrefList
[index
]);
257 for (PRIntn index
= 0; index
< sysPrefCount
; ++index
) {
258 // save mozilla prefs
259 SaveMozDefaultPref(mSysPrefs
[index
].prefName
,
260 &mSysPrefs
[index
].defaultValue
,
261 &mSysPrefs
[index
].isLocked
);
263 // get the system prefs
264 ReadSystemPref(mSysPrefs
[index
].prefName
);
265 SYSPREF_LOG(("Add Listener on %s\n", mSysPrefs
[index
].prefName
));
266 mSysPrefService
->AddObserver(mSysPrefs
[index
].prefName
,
272 //////////////////////////////////////////////////////////////////////
273 // nsSystemPref::ReadSystemPref
274 // Read a pref value from system pref service, and lock it in mozilla.
275 //////////////////////////////////////////////////////////////////////
277 nsSystemPref::ReadSystemPref(const char *aPrefName
)
279 if (!mSysPrefService
)
280 return NS_ERROR_FAILURE
;
283 nsCOMPtr
<nsIPrefBranch
> prefBranch
284 (do_GetService(NS_PREFSERVICE_CONTRACTID
, &rv
));
288 SYSPREF_LOG(("about to read aPrefName %s\n", aPrefName
));
290 prefBranch
->UnlockPref(aPrefName
);
292 PRInt32 prefType
= nsIPrefBranch::PREF_INVALID
;
293 nsXPIDLCString strValue
;
294 PRInt32 intValue
= 0;
295 PRBool boolValue
= PR_FALSE
;
297 rv
= prefBranch
->GetPrefType(aPrefName
, &prefType
);
301 case nsIPrefBranch::PREF_STRING
:
302 mSysPrefService
->GetCharPref(aPrefName
, getter_Copies(strValue
));
303 SYSPREF_LOG(("system value is %s\n", strValue
.get()));
305 prefBranch
->SetCharPref(aPrefName
, strValue
.get());
307 case nsIPrefBranch::PREF_INT
:
308 mSysPrefService
->GetIntPref(aPrefName
, &intValue
);
309 SYSPREF_LOG(("system value is %d\n", intValue
));
311 prefBranch
->SetIntPref(aPrefName
, intValue
);
313 case nsIPrefBranch::PREF_BOOL
:
314 mSysPrefService
->GetBoolPref(aPrefName
, &boolValue
);
315 SYSPREF_LOG(("system value is %s\n", boolValue
? "TRUE" : "FALSE"));
317 prefBranch
->SetBoolPref(aPrefName
, boolValue
);
320 SYSPREF_LOG(("Fail to system value for it\n"));
321 return NS_ERROR_FAILURE
;
323 prefBranch
->LockPref(aPrefName
);
327 //////////////////////////////////////////////////////////////////////
328 // nsSystemPref::UseMozillaPrefs
329 // Restore mozilla default prefs, remove system pref listeners
330 /////////////////////////////////////////////////////////////////////
332 nsSystemPref::UseMozillaPrefs()
335 SYSPREF_LOG(("\n====Now rollback to Mozilla prefs==\n"));
337 // if we did not use system prefs, do nothing
338 if (!mSysPrefService
)
341 PRIntn sysPrefCount
= sizeof(sSysPrefList
) / sizeof(sSysPrefList
[0]);
342 for (PRIntn index
= 0; index
< sysPrefCount
; ++index
) {
343 // restore mozilla default value and free string memory if needed
344 RestoreMozDefaultPref(mSysPrefs
[index
].prefName
,
345 &mSysPrefs
[index
].defaultValue
,
346 mSysPrefs
[index
].isLocked
);
347 SYSPREF_LOG(("stop listening on %s\n", mSysPrefs
[index
].prefName
));
348 mSysPrefService
->RemoveObserver(mSysPrefs
[index
].prefName
,
354 ////////////////////////////////////////////////////////////////////////////
355 // nsSystemPref::RestoreMozDefaultPref
356 // Save the saved mozilla default value.
357 // It is also responsible for allocate the string memory when needed, because
358 // this method know what type of value is stored.
359 /////////////////////////////////////////////////////////////////////////////
361 nsSystemPref::SaveMozDefaultPref(const char *aPrefName
,
362 MozPrefValue
*aPrefValue
,
365 NS_ENSURE_ARG_POINTER(aPrefName
);
366 NS_ENSURE_ARG_POINTER(aPrefValue
);
367 NS_ENSURE_ARG_POINTER(aLocked
);
371 nsCOMPtr
<nsIPrefBranch
> prefBranch
=
372 do_GetService(NS_PREFSERVICE_CONTRACTID
, &rv
);
376 SYSPREF_LOG(("Save Mozilla value for %s\n", aPrefName
));
378 PRInt32 prefType
= nsIPrefBranch::PREF_INVALID
;
379 nsXPIDLCString strValue
;
381 rv
= prefBranch
->GetPrefType(aPrefName
, &prefType
);
385 case nsIPrefBranch::PREF_STRING
:
386 prefBranch
->GetCharPref(aPrefName
,
387 getter_Copies(strValue
));
388 SYSPREF_LOG(("Mozilla value is %s", strValue
.get()));
390 if (aPrefValue
->stringVal
)
391 PL_strfree(aPrefValue
->stringVal
);
392 aPrefValue
->stringVal
= PL_strdup(strValue
.get());
394 case nsIPrefBranch::PREF_INT
:
395 prefBranch
->GetIntPref(aPrefName
, &aPrefValue
->intVal
);
396 SYSPREF_LOG(("Mozilla value is %d\n", aPrefValue
->intVal
));
399 case nsIPrefBranch::PREF_BOOL
:
400 prefBranch
->GetBoolPref(aPrefName
, &aPrefValue
->boolVal
);
401 SYSPREF_LOG(("Mozilla value is %s\n",
402 aPrefValue
->boolVal
? "TRUE" : "FALSE"));
406 SYSPREF_LOG(("Fail to Read Mozilla value for it\n"));
407 return NS_ERROR_FAILURE
;
409 rv
= prefBranch
->PrefIsLocked(aPrefName
, aLocked
);
410 SYSPREF_LOG((" (%s).\n", aLocked
? "Locked" : "NOT Locked"));
414 ////////////////////////////////////////////////////////////////////////////
415 // nsSystemPref::RestoreMozDefaultPref
416 // Restore the saved mozilla default value to pref service.
417 // It is also responsible for free the string memory when needed, because
418 // this method know what type of value is stored.
419 /////////////////////////////////////////////////////////////////////////////
421 nsSystemPref::RestoreMozDefaultPref(const char *aPrefName
,
422 MozPrefValue
*aPrefValue
,
425 NS_ENSURE_ARG_POINTER(aPrefName
);
429 nsCOMPtr
<nsIPrefBranch
> prefBranch
=
430 do_GetService(NS_PREFSERVICE_CONTRACTID
, &rv
);
434 SYSPREF_LOG(("Restore Mozilla value for %s\n", aPrefName
));
436 PRInt32 prefType
= nsIPrefBranch::PREF_INVALID
;
437 rv
= prefBranch
->GetPrefType(aPrefName
, &prefType
);
441 // unlock, if it is locked
442 prefBranch
->UnlockPref(aPrefName
);
445 case nsIPrefBranch::PREF_STRING
:
446 prefBranch
->SetCharPref(aPrefName
,
447 aPrefValue
->stringVal
);
448 SYSPREF_LOG(("Mozilla value is %s\n", aPrefValue
->stringVal
));
450 PL_strfree(aPrefValue
->stringVal
);
451 aPrefValue
->stringVal
= nsnull
;
454 case nsIPrefBranch::PREF_INT
:
455 prefBranch
->SetIntPref(aPrefName
, aPrefValue
->intVal
);
456 SYSPREF_LOG(("Mozilla value is %d\n", aPrefValue
->intVal
));
459 case nsIPrefBranch::PREF_BOOL
:
460 prefBranch
->SetBoolPref(aPrefName
, aPrefValue
->boolVal
);
461 SYSPREF_LOG(("Mozilla value is %s\n",
462 aPrefValue
->boolVal
? "TRUE" : "FALSE"));
466 SYSPREF_LOG(("Fail to Restore Mozilla value for it\n"));
467 return NS_ERROR_FAILURE
;
470 // restore its old lock status
472 prefBranch
->LockPref(aPrefName
);