Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/modules/libpref/Preferences.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef mozilla_Preferences_h
8
#define mozilla_Preferences_h
9
10
#ifndef MOZILLA_INTERNAL_API
11
#error "This header is only usable from within libxul (MOZILLA_INTERNAL_API)."
12
#endif
13
14
#include "mozilla/Atomics.h"
15
#include "mozilla/MemoryReporting.h"
16
#include "mozilla/Result.h"
17
#include "mozilla/StaticPtr.h"
18
#include "nsCOMPtr.h"
19
#include "nsIObserver.h"
20
#include "nsIPrefBranch.h"
21
#include "nsIPrefService.h"
22
#include "nsPrintfCString.h"
23
#include "nsString.h"
24
#include "nsTArray.h"
25
#include "nsWeakReference.h"
26
27
class nsIFile;
28
29
// The callback function will get passed the pref name which triggered the call
30
// and the void* data which was passed to the registered callback function.
31
typedef void (*PrefChangedFunc)(const char* aPref, void* aData);
32
33
class nsPrefBranch;
34
35
namespace mozilla {
36
37
// A typesafe version of PrefChangeFunc, with its data argument type deduced
38
// from the type of the argument passed to RegisterCallback.
39
//
40
// Note: We specify this as a dependent type TypedPrefChangeFunc<T>::SelfType so
41
// that it does not participate in argument type deduction. This allows us to
42
// use its implicit conversion constructor, and also allows our Register and
43
// Unregister methods to accept non-capturing lambdas (which will not match
44
// void(*)(const char*, T*) when used in type deduction) as callback functions.
45
template<typename T>
46
struct TypedPrefChangeFunc
47
{
48
  using Type = TypedPrefChangeFunc<T>;
49
  using CallbackType = void (*)(const char*, T*);
50
51
  MOZ_IMPLICIT TypedPrefChangeFunc(CallbackType aCallback)
52
    : mCallback(aCallback)
53
0
  {
54
0
  }
Unexecuted instantiation: mozilla::TypedPrefChangeFunc<mozilla::Closure<bool, bool> >::TypedPrefChangeFunc(void (*)(char const*, mozilla::Closure<bool, bool>*))
Unexecuted instantiation: mozilla::TypedPrefChangeFunc<mozilla::Closure<bool, mozilla::Atomic<bool, (mozilla::MemoryOrdering)0, (mozilla::recordreplay::Behavior)1, void> > >::TypedPrefChangeFunc(void (*)(char const*, mozilla::Closure<bool, mozilla::Atomic<bool, (mozilla::MemoryOrdering)0, (mozilla::recordreplay::Behavior)1, void> >*))
Unexecuted instantiation: mozilla::TypedPrefChangeFunc<mozilla::Closure<bool, mozilla::Atomic<bool, (mozilla::MemoryOrdering)1, (mozilla::recordreplay::Behavior)1, void> > >::TypedPrefChangeFunc(void (*)(char const*, mozilla::Closure<bool, mozilla::Atomic<bool, (mozilla::MemoryOrdering)1, (mozilla::recordreplay::Behavior)1, void> >*))
Unexecuted instantiation: mozilla::TypedPrefChangeFunc<mozilla::Closure<int, int> >::TypedPrefChangeFunc(void (*)(char const*, mozilla::Closure<int, int>*))
Unexecuted instantiation: mozilla::TypedPrefChangeFunc<mozilla::Closure<int, mozilla::Atomic<int, (mozilla::MemoryOrdering)0, (mozilla::recordreplay::Behavior)1, void> > >::TypedPrefChangeFunc(void (*)(char const*, mozilla::Closure<int, mozilla::Atomic<int, (mozilla::MemoryOrdering)0, (mozilla::recordreplay::Behavior)1, void> >*))
Unexecuted instantiation: mozilla::TypedPrefChangeFunc<mozilla::Closure<unsigned int, unsigned int> >::TypedPrefChangeFunc(void (*)(char const*, mozilla::Closure<unsigned int, unsigned int>*))
Unexecuted instantiation: mozilla::TypedPrefChangeFunc<mozilla::Closure<unsigned int, mozilla::Atomic<unsigned int, (mozilla::MemoryOrdering)0, (mozilla::recordreplay::Behavior)1, void> > >::TypedPrefChangeFunc(void (*)(char const*, mozilla::Closure<unsigned int, mozilla::Atomic<unsigned int, (mozilla::MemoryOrdering)0, (mozilla::recordreplay::Behavior)1, void> >*))
Unexecuted instantiation: mozilla::TypedPrefChangeFunc<mozilla::Closure<unsigned int, mozilla::Atomic<unsigned int, (mozilla::MemoryOrdering)1, (mozilla::recordreplay::Behavior)1, void> > >::TypedPrefChangeFunc(void (*)(char const*, mozilla::Closure<unsigned int, mozilla::Atomic<unsigned int, (mozilla::MemoryOrdering)1, (mozilla::recordreplay::Behavior)1, void> >*))
Unexecuted instantiation: mozilla::TypedPrefChangeFunc<mozilla::Closure<float, float> >::TypedPrefChangeFunc(void (*)(char const*, mozilla::Closure<float, float>*))
55
56
  template<typename F>
57
  MOZ_IMPLICIT TypedPrefChangeFunc(F&& aLambda)
58
    : mCallback(aLambda)
59
  {
60
  }
61
62
  operator PrefChangedFunc() const
63
0
  {
64
0
    return reinterpret_cast<PrefChangedFunc>(mCallback);
65
0
  }
Unexecuted instantiation: mozilla::TypedPrefChangeFunc<mozilla::Closure<bool, bool> >::operator void (*)(char const*, void*)() const
Unexecuted instantiation: mozilla::TypedPrefChangeFunc<mozilla::Closure<bool, mozilla::Atomic<bool, (mozilla::MemoryOrdering)0, (mozilla::recordreplay::Behavior)1, void> > >::operator void (*)(char const*, void*)() const
Unexecuted instantiation: mozilla::TypedPrefChangeFunc<mozilla::Closure<bool, mozilla::Atomic<bool, (mozilla::MemoryOrdering)1, (mozilla::recordreplay::Behavior)1, void> > >::operator void (*)(char const*, void*)() const
Unexecuted instantiation: mozilla::TypedPrefChangeFunc<mozilla::Closure<int, int> >::operator void (*)(char const*, void*)() const
Unexecuted instantiation: mozilla::TypedPrefChangeFunc<mozilla::Closure<int, mozilla::Atomic<int, (mozilla::MemoryOrdering)0, (mozilla::recordreplay::Behavior)1, void> > >::operator void (*)(char const*, void*)() const
Unexecuted instantiation: mozilla::TypedPrefChangeFunc<mozilla::Closure<unsigned int, unsigned int> >::operator void (*)(char const*, void*)() const
Unexecuted instantiation: mozilla::TypedPrefChangeFunc<mozilla::Closure<unsigned int, mozilla::Atomic<unsigned int, (mozilla::MemoryOrdering)0, (mozilla::recordreplay::Behavior)1, void> > >::operator void (*)(char const*, void*)() const
Unexecuted instantiation: mozilla::TypedPrefChangeFunc<mozilla::Closure<unsigned int, mozilla::Atomic<unsigned int, (mozilla::MemoryOrdering)1, (mozilla::recordreplay::Behavior)1, void> > >::operator void (*)(char const*, void*)() const
Unexecuted instantiation: mozilla::TypedPrefChangeFunc<mozilla::Closure<float, float> >::operator void (*)(char const*, void*)() const
66
67
  CallbackType mCallback;
68
};
69
70
// Similar to PrefChangedFunc, but for use with instance methods.
71
//
72
// Any instance method with this signature may be passed to the
73
// PREF_CHANGE_METHOD macro, which will wrap it into a typesafe preference
74
// callback function, which accepts a preference name as its first argument, and
75
// an instance of the appropriate class as the second.
76
//
77
// When called, the wrapper will forward the call to the wrapped method on the
78
// given instance, with the notified preference as its only argument.
79
typedef void(PrefChangedMethod)(const char* aPref);
80
81
namespace detail {
82
// Helper to extract the instance type from any instance method. For an instance
83
// method `Method = U T::*`, InstanceType<Method>::Type returns T.
84
template<typename T>
85
struct InstanceType;
86
87
template<typename T, typename U>
88
struct InstanceType<U T::*>
89
{
90
  using Type = T;
91
};
92
93
// A wrapper for a PrefChangeMethod instance method which forwards calls to the
94
// wrapped method on the given instance.
95
template<typename T, PrefChangedMethod T::*Method>
96
void
97
PrefChangeMethod(const char* aPref, T* aInst)
98
{
99
  ((*aInst).*Method)(aPref);
100
}
101
} // namespace detail
102
103
// Creates a wrapper around an instance method, with the signature of
104
// PrefChangedMethod, from an arbitrary class, so that it can be used as a
105
// preference callback. The closure data passed to RegisterCallback must be an
106
// instance of this class.
107
//
108
// Note: This is implemented as a macro rather than a pure template function
109
// because, prior to C++17, value template arguments must have their types
110
// fully-specified. Once all of our supported compilers have C++17 support, we
111
// can give PrefChangeMethod a single <auto Method> argument, and use
112
// PrefChangeMethod<&meth> directly.
113
#define PREF_CHANGE_METHOD(meth)                                               \
114
  (&::mozilla::detail::PrefChangeMethod<                                       \
115
    ::mozilla::detail::InstanceType<decltype(&meth)>::Type,                    \
116
    &meth>)
117
118
class PreferenceServiceReporter;
119
120
namespace dom {
121
class Pref;
122
class PrefValue;
123
} // namespace dom
124
125
namespace ipc {
126
class FileDescriptor;
127
} // namespace ipc
128
129
struct PrefsSizes;
130
131
// Xlib.h defines Bool as a macro constant. Don't try to define this enum if
132
// it's already been included.
133
#ifndef Bool
134
135
// Keep this in sync with PrefType in parser/src/lib.rs.
136
enum class PrefType : uint8_t
137
{
138
  None = 0, // only used when neither the default nor user value is set
139
  String = 1,
140
  Int = 2,
141
  Bool = 3,
142
};
143
144
#endif
145
146
#ifdef XP_UNIX
147
// We need to send two shared memory descriptors to every child process:
148
//
149
// 1) A read-only/write-protected snapshot of the initial state of the
150
//    preference database. This memory is shared between all processes, and
151
//    therefore cannot be modified once it has been created.
152
//
153
// 2) A set of changes on top of the snapshot, containing the current values of
154
//    all preferences which have changed since it was created.
155
//
156
// Since the second set will be different for every process, and the first set
157
// cannot be modified, it is unfortunately not possible to combine them into a
158
// single file descriptor.
159
//
160
// XXX: bug 1440207 is about improving how fixed fds such as this are used.
161
static const int kPrefsFileDescriptor = 8;
162
static const int kPrefMapFileDescriptor = 9;
163
#endif
164
165
// Keep this in sync with PrefType in parser/src/lib.rs.
166
enum class PrefValueKind : uint8_t
167
{
168
  Default,
169
  User
170
};
171
172
class Preferences final
173
  : public nsIPrefService
174
  , public nsIObserver
175
  , public nsIPrefBranch
176
  , public nsSupportsWeakReference
177
{
178
  friend class ::nsPrefBranch;
179
180
public:
181
  NS_DECL_THREADSAFE_ISUPPORTS
182
  NS_DECL_NSIPREFSERVICE
183
  NS_FORWARD_NSIPREFBRANCH(mRootBranch->)
184
  NS_DECL_NSIOBSERVER
185
186
  Preferences();
187
188
  // Returns true if the Preferences service is available, false otherwise.
189
  static bool IsServiceAvailable();
190
191
  // Initialize user prefs from prefs.js/user.js
192
  static void InitializeUserPrefs();
193
194
  // Returns the singleton instance which is addreffed.
195
  static already_AddRefed<Preferences> GetInstanceForService();
196
197
  // Finallizes global members.
198
  static void Shutdown();
199
200
  // Returns shared pref service instance NOTE: not addreffed.
201
  static nsIPrefService* GetService()
202
  {
203
    NS_ENSURE_TRUE(InitStaticMembers(), nullptr);
204
    return sPreferences;
205
  }
206
207
  // Returns shared pref branch instance. NOTE: not addreffed.
208
  static nsIPrefBranch* GetRootBranch(PrefValueKind aKind = PrefValueKind::User)
209
  {
210
    NS_ENSURE_TRUE(InitStaticMembers(), nullptr);
211
    return (aKind == PrefValueKind::Default) ? sPreferences->mDefaultRootBranch
212
                                             : sPreferences->mRootBranch;
213
  }
214
215
  // Gets the type of the pref.
216
  static int32_t GetType(const char* aPrefName);
217
218
  // Fallible value getters. When `aKind` is `User` they will get the user
219
  // value if possible, and fall back to the default value otherwise.
220
  static nsresult GetBool(const char* aPrefName,
221
                          bool* aResult,
222
                          PrefValueKind aKind = PrefValueKind::User);
223
  static nsresult GetInt(const char* aPrefName,
224
                         int32_t* aResult,
225
                         PrefValueKind aKind = PrefValueKind::User);
226
  static nsresult GetUint(const char* aPrefName,
227
                          uint32_t* aResult,
228
                          PrefValueKind aKind = PrefValueKind::User)
229
  {
230
    return GetInt(aPrefName, reinterpret_cast<int32_t*>(aResult), aKind);
231
  }
232
  static nsresult GetFloat(const char* aPrefName,
233
                           float* aResult,
234
                           PrefValueKind aKind = PrefValueKind::User);
235
  static nsresult GetCString(const char* aPrefName,
236
                             nsACString& aResult,
237
                             PrefValueKind aKind = PrefValueKind::User);
238
  static nsresult GetString(const char* aPrefName,
239
                            nsAString& aResult,
240
                            PrefValueKind aKind = PrefValueKind::User);
241
  static nsresult GetLocalizedCString(
242
    const char* aPrefName,
243
    nsACString& aResult,
244
    PrefValueKind aKind = PrefValueKind::User);
245
  static nsresult GetLocalizedString(const char* aPrefName,
246
                                     nsAString& aResult,
247
                                     PrefValueKind aKind = PrefValueKind::User);
248
  static nsresult GetComplex(const char* aPrefName,
249
                             const nsIID& aType,
250
                             void** aResult,
251
                             PrefValueKind aKind = PrefValueKind::User);
252
253
  // Infallible getters of user or default values, with fallback results on
254
  // failure. When `aKind` is `User` they will get the user value if possible,
255
  // and fall back to the default value otherwise.
256
  static bool GetBool(const char* aPrefName,
257
                      bool aFallback = false,
258
                      PrefValueKind aKind = PrefValueKind::User)
259
  {
260
    bool result = aFallback;
261
    GetBool(aPrefName, &result, aKind);
262
    return result;
263
  }
264
  static int32_t GetInt(const char* aPrefName,
265
                        int32_t aFallback = 0,
266
                        PrefValueKind aKind = PrefValueKind::User)
267
  {
268
    int32_t result = aFallback;
269
    GetInt(aPrefName, &result, aKind);
270
    return result;
271
  }
272
  static uint32_t GetUint(const char* aPrefName,
273
                          uint32_t aFallback = 0,
274
                          PrefValueKind aKind = PrefValueKind::User)
275
  {
276
    uint32_t result = aFallback;
277
    GetUint(aPrefName, &result, aKind);
278
    return result;
279
  }
280
  static float GetFloat(const char* aPrefName,
281
                        float aFallback = 0.0f,
282
                        PrefValueKind aKind = PrefValueKind::User)
283
  {
284
    float result = aFallback;
285
    GetFloat(aPrefName, &result, aKind);
286
    return result;
287
  }
288
289
  // Value setters. These fail if run outside the parent process.
290
291
  static nsresult SetBool(const char* aPrefName,
292
                          bool aValue,
293
                          PrefValueKind aKind = PrefValueKind::User);
294
  static nsresult SetInt(const char* aPrefName,
295
                         int32_t aValue,
296
                         PrefValueKind aKind = PrefValueKind::User);
297
  static nsresult SetCString(const char* aPrefName,
298
                             const nsACString& aValue,
299
                             PrefValueKind aKind = PrefValueKind::User);
300
301
  static nsresult SetUint(const char* aPrefName,
302
                          uint32_t aValue,
303
                          PrefValueKind aKind = PrefValueKind::User)
304
  {
305
    return SetInt(aPrefName, static_cast<int32_t>(aValue), aKind);
306
  }
307
308
  static nsresult SetFloat(const char* aPrefName,
309
                           float aValue,
310
                           PrefValueKind aKind = PrefValueKind::User)
311
  {
312
    return SetCString(aPrefName, nsPrintfCString("%f", aValue), aKind);
313
  }
314
315
  static nsresult SetCString(const char* aPrefName,
316
                             const char* aValue,
317
                             PrefValueKind aKind = PrefValueKind::User)
318
  {
319
    return Preferences::SetCString(
320
      aPrefName, nsDependentCString(aValue), aKind);
321
  }
322
323
  static nsresult SetString(const char* aPrefName,
324
                            const char16ptr_t aValue,
325
                            PrefValueKind aKind = PrefValueKind::User)
326
  {
327
    return Preferences::SetCString(
328
      aPrefName, NS_ConvertUTF16toUTF8(aValue), aKind);
329
  }
330
331
  static nsresult SetString(const char* aPrefName,
332
                            const nsAString& aValue,
333
                            PrefValueKind aKind = PrefValueKind::User)
334
  {
335
    return Preferences::SetCString(
336
      aPrefName, NS_ConvertUTF16toUTF8(aValue), aKind);
337
  }
338
339
  static nsresult SetComplex(const char* aPrefName,
340
                             const nsIID& aType,
341
                             nsISupports* aValue,
342
                             PrefValueKind aKind = PrefValueKind::User);
343
344
  static nsresult Lock(const char* aPrefName);
345
  static nsresult Unlock(const char* aPrefName);
346
  static bool IsLocked(const char* aPrefName);
347
348
  // Clears user set pref. Fails if run outside the parent process.
349
  static nsresult ClearUser(const char* aPrefName);
350
351
  // Whether the pref has a user value or not.
352
  static bool HasUserValue(const char* aPref);
353
354
  // Adds/Removes the observer for the root pref branch. See nsIPrefBranch.idl
355
  // for details.
356
  static nsresult AddStrongObserver(nsIObserver* aObserver,
357
                                    const nsACString& aPref);
358
  static nsresult AddWeakObserver(nsIObserver* aObserver,
359
                                  const nsACString& aPref);
360
  static nsresult RemoveObserver(nsIObserver* aObserver,
361
                                 const nsACString& aPref);
362
363
  template<int N>
364
  static nsresult AddStrongObserver(nsIObserver* aObserver,
365
                                    const char (&aPref)[N])
366
  {
367
    return AddStrongObserver(aObserver, nsLiteralCString(aPref));
368
  }
369
  template<int N>
370
  static nsresult AddWeakObserver(nsIObserver* aObserver,
371
                                  const char (&aPref)[N])
372
  {
373
    return AddWeakObserver(aObserver, nsLiteralCString(aPref));
374
  }
375
  template<int N>
376
  static nsresult RemoveObserver(nsIObserver* aObserver, const char (&aPref)[N])
377
  {
378
    return RemoveObserver(aObserver, nsLiteralCString(aPref));
379
  }
380
381
  // Adds/Removes two or more observers for the root pref branch. Pass to
382
  // aPrefs an array of const char* whose last item is nullptr.
383
  // Note: All preference strings *must* be statically-allocated string
384
  // literals.
385
  static nsresult AddStrongObservers(nsIObserver* aObserver,
386
                                     const char** aPrefs);
387
  static nsresult AddWeakObservers(nsIObserver* aObserver, const char** aPrefs);
388
  static nsresult RemoveObservers(nsIObserver* aObserver, const char** aPrefs);
389
390
  // Registers/Unregisters the callback function for the aPref.
391
  template<typename T = void>
392
  static nsresult RegisterCallback(
393
    typename TypedPrefChangeFunc<T>::Type aCallback,
394
    const nsACString& aPref,
395
    T* aClosure = nullptr)
396
0
  {
397
0
    return RegisterCallback(aCallback, aPref, aClosure, ExactMatch);
398
0
  }
Unexecuted instantiation: nsresult mozilla::Preferences::RegisterCallback<mozilla::Closure<bool, bool> >(mozilla::TypedPrefChangeFunc<mozilla::Closure<bool, bool> >::Type, nsTSubstring<char> const&, mozilla::Closure<bool, bool>*)
Unexecuted instantiation: nsresult mozilla::Preferences::RegisterCallback<mozilla::Closure<bool, mozilla::Atomic<bool, (mozilla::MemoryOrdering)0, (mozilla::recordreplay::Behavior)1, void> > >(mozilla::TypedPrefChangeFunc<mozilla::Closure<bool, mozilla::Atomic<bool, (mozilla::MemoryOrdering)0, (mozilla::recordreplay::Behavior)1, void> > >::Type, nsTSubstring<char> const&, mozilla::Closure<bool, mozilla::Atomic<bool, (mozilla::MemoryOrdering)0, (mozilla::recordreplay::Behavior)1, void> >*)
Unexecuted instantiation: nsresult mozilla::Preferences::RegisterCallback<mozilla::Closure<bool, mozilla::Atomic<bool, (mozilla::MemoryOrdering)1, (mozilla::recordreplay::Behavior)1, void> > >(mozilla::TypedPrefChangeFunc<mozilla::Closure<bool, mozilla::Atomic<bool, (mozilla::MemoryOrdering)1, (mozilla::recordreplay::Behavior)1, void> > >::Type, nsTSubstring<char> const&, mozilla::Closure<bool, mozilla::Atomic<bool, (mozilla::MemoryOrdering)1, (mozilla::recordreplay::Behavior)1, void> >*)
Unexecuted instantiation: nsresult mozilla::Preferences::RegisterCallback<mozilla::Closure<int, int> >(mozilla::TypedPrefChangeFunc<mozilla::Closure<int, int> >::Type, nsTSubstring<char> const&, mozilla::Closure<int, int>*)
Unexecuted instantiation: nsresult mozilla::Preferences::RegisterCallback<mozilla::Closure<int, mozilla::Atomic<int, (mozilla::MemoryOrdering)0, (mozilla::recordreplay::Behavior)1, void> > >(mozilla::TypedPrefChangeFunc<mozilla::Closure<int, mozilla::Atomic<int, (mozilla::MemoryOrdering)0, (mozilla::recordreplay::Behavior)1, void> > >::Type, nsTSubstring<char> const&, mozilla::Closure<int, mozilla::Atomic<int, (mozilla::MemoryOrdering)0, (mozilla::recordreplay::Behavior)1, void> >*)
Unexecuted instantiation: nsresult mozilla::Preferences::RegisterCallback<mozilla::Closure<unsigned int, unsigned int> >(mozilla::TypedPrefChangeFunc<mozilla::Closure<unsigned int, unsigned int> >::Type, nsTSubstring<char> const&, mozilla::Closure<unsigned int, unsigned int>*)
Unexecuted instantiation: nsresult mozilla::Preferences::RegisterCallback<mozilla::Closure<unsigned int, mozilla::Atomic<unsigned int, (mozilla::MemoryOrdering)0, (mozilla::recordreplay::Behavior)1, void> > >(mozilla::TypedPrefChangeFunc<mozilla::Closure<unsigned int, mozilla::Atomic<unsigned int, (mozilla::MemoryOrdering)0, (mozilla::recordreplay::Behavior)1, void> > >::Type, nsTSubstring<char> const&, mozilla::Closure<unsigned int, mozilla::Atomic<unsigned int, (mozilla::MemoryOrdering)0, (mozilla::recordreplay::Behavior)1, void> >*)
Unexecuted instantiation: nsresult mozilla::Preferences::RegisterCallback<mozilla::Closure<unsigned int, mozilla::Atomic<unsigned int, (mozilla::MemoryOrdering)1, (mozilla::recordreplay::Behavior)1, void> > >(mozilla::TypedPrefChangeFunc<mozilla::Closure<unsigned int, mozilla::Atomic<unsigned int, (mozilla::MemoryOrdering)1, (mozilla::recordreplay::Behavior)1, void> > >::Type, nsTSubstring<char> const&, mozilla::Closure<unsigned int, mozilla::Atomic<unsigned int, (mozilla::MemoryOrdering)1, (mozilla::recordreplay::Behavior)1, void> >*)
Unexecuted instantiation: nsresult mozilla::Preferences::RegisterCallback<mozilla::Closure<float, float> >(mozilla::TypedPrefChangeFunc<mozilla::Closure<float, float> >::Type, nsTSubstring<char> const&, mozilla::Closure<float, float>*)
399
400
  template<typename T = void>
401
  static nsresult UnregisterCallback(
402
    typename TypedPrefChangeFunc<T>::Type aCallback,
403
    const nsACString& aPref,
404
    T* aClosure = nullptr)
405
  {
406
    return UnregisterCallback(aCallback, aPref, aClosure, ExactMatch);
407
  }
408
409
  // Like RegisterCallback, but also calls the callback immediately for
410
  // initialization.
411
  template<typename T = void>
412
  static nsresult RegisterCallbackAndCall(
413
    typename TypedPrefChangeFunc<T>::Type aCallback,
414
    const nsACString& aPref,
415
    T* aClosure = nullptr)
416
  {
417
    return RegisterCallbackAndCall(aCallback, aPref, aClosure, ExactMatch);
418
  }
419
420
  // Like RegisterCallback, but registers a callback for a prefix of multiple
421
  // pref names, not a single pref name.
422
  template<typename T = void>
423
  static nsresult RegisterPrefixCallback(
424
    typename TypedPrefChangeFunc<T>::Type aCallback,
425
    const nsACString& aPref,
426
    T* aClosure = nullptr)
427
  {
428
    return RegisterCallback(aCallback, aPref, aClosure, PrefixMatch);
429
  }
430
431
  // Like RegisterPrefixCallback, but also calls the callback immediately for
432
  // initialization.
433
  template<typename T = void>
434
  static nsresult RegisterPrefixCallbackAndCall(
435
    typename TypedPrefChangeFunc<T>::Type aCallback,
436
    const nsACString& aPref,
437
    T* aClosure = nullptr)
438
  {
439
    return RegisterCallbackAndCall(aCallback, aPref, aClosure, PrefixMatch);
440
  }
441
442
  // Unregister a callback registered with RegisterPrefixCallback or
443
  // RegisterPrefixCallbackAndCall.
444
  template<typename T = void>
445
  static nsresult UnregisterPrefixCallback(
446
    typename TypedPrefChangeFunc<T>::Type aCallback,
447
    const nsACString& aPref,
448
    T* aClosure = nullptr)
449
  {
450
    return UnregisterCallback(aCallback, aPref, aClosure, PrefixMatch);
451
  }
452
453
  // Variants of the above which register a single callback to handle multiple
454
  // preferences.
455
  //
456
  // The array of preference names must be null terminated. It may be
457
  // dynamically allocated, but the caller is responsible for keeping it alive
458
  // until the callback is unregistered.
459
  //
460
  // Also note that the exact same aPrefs pointer must be passed to the
461
  // Unregister call as was passed to the Register call.
462
  template<typename T = void>
463
  static nsresult RegisterCallbacks(
464
    typename TypedPrefChangeFunc<T>::Type aCallback,
465
    const char** aPrefs,
466
    T* aClosure = nullptr)
467
  {
468
    return RegisterCallbacks(aCallback, aPrefs, aClosure, ExactMatch);
469
  }
470
  static nsresult RegisterCallbacksAndCall(PrefChangedFunc aCallback,
471
                                           const char** aPrefs,
472
                                           void* aClosure = nullptr);
473
  template<typename T = void>
474
  static nsresult UnregisterCallbacks(
475
    typename TypedPrefChangeFunc<T>::Type aCallback,
476
    const char** aPrefs,
477
    T* aClosure = nullptr)
478
  {
479
    return UnregisterCallbacks(aCallback, aPrefs, aClosure, ExactMatch);
480
  }
481
  template<typename T = void>
482
  static nsresult RegisterPrefixCallbacks(
483
    typename TypedPrefChangeFunc<T>::Type aCallback,
484
    const char** aPrefs,
485
    T* aClosure = nullptr)
486
  {
487
    return RegisterCallbacks(aCallback, aPrefs, aClosure, PrefixMatch);
488
  }
489
  template<typename T = void>
490
  static nsresult UnregisterPrefixCallbacks(
491
    typename TypedPrefChangeFunc<T>::Type aCallback,
492
    const char** aPrefs,
493
    T* aClosure = nullptr)
494
  {
495
    return UnregisterCallbacks(aCallback, aPrefs, aClosure, PrefixMatch);
496
  }
497
498
  template<int N, typename T = void>
499
  static nsresult RegisterCallback(
500
    typename TypedPrefChangeFunc<T>::Type aCallback,
501
    const char (&aPref)[N],
502
    T* aClosure = nullptr)
503
  {
504
    return RegisterCallback(
505
      aCallback, nsLiteralCString(aPref), aClosure, ExactMatch);
506
  }
507
508
  template<int N, typename T = void>
509
  static nsresult UnregisterCallback(
510
    typename TypedPrefChangeFunc<T>::Type aCallback,
511
    const char (&aPref)[N],
512
    T* aClosure = nullptr)
513
  {
514
    return UnregisterCallback(
515
      aCallback, nsLiteralCString(aPref), aClosure, ExactMatch);
516
  }
517
518
  template<int N, typename T = void>
519
  static nsresult RegisterCallbackAndCall(
520
    typename TypedPrefChangeFunc<T>::Type aCallback,
521
    const char (&aPref)[N],
522
    T* aClosure = nullptr)
523
  {
524
    return RegisterCallbackAndCall(
525
      aCallback, nsLiteralCString(aPref), aClosure, ExactMatch);
526
  }
527
528
  template<int N, typename T = void>
529
  static nsresult RegisterPrefixCallback(
530
    typename TypedPrefChangeFunc<T>::Type aCallback,
531
    const char (&aPref)[N],
532
    T* aClosure = nullptr)
533
  {
534
    return RegisterCallback(
535
      aCallback, nsLiteralCString(aPref), aClosure, PrefixMatch);
536
  }
537
538
  template<int N, typename T = void>
539
  static nsresult RegisterPrefixCallbackAndCall(
540
    typename TypedPrefChangeFunc<T>::Type aCallback,
541
    const char (&aPref)[N],
542
    T* aClosure = nullptr)
543
  {
544
    return RegisterCallbackAndCall(
545
      aCallback, nsLiteralCString(aPref), aClosure, PrefixMatch);
546
  }
547
548
  template<int N, typename T = void>
549
  static nsresult UnregisterPrefixCallback(
550
    typename TypedPrefChangeFunc<T>::Type aCallback,
551
    const char (&aPref)[N],
552
    T* aClosure = nullptr)
553
  {
554
    return UnregisterCallback(
555
      aCallback, nsLiteralCString(aPref), aClosure, PrefixMatch);
556
  }
557
558
  // Adds the aVariable to cache table. |aVariable| must be a pointer for a
559
  // static variable. The value will be modified when the pref value is changed
560
  // but note that even if you modified it, the value isn't assigned to the
561
  // pref.
562
  static nsresult AddBoolVarCache(bool* aVariable,
563
                                  const nsACString& aPref,
564
                                  bool aDefault = false,
565
                                  bool aSkipAssignment = false);
566
  template<MemoryOrdering Order>
567
  static nsresult AddAtomicBoolVarCache(Atomic<bool, Order>* aVariable,
568
                                        const nsACString& aPref,
569
                                        bool aDefault = false,
570
                                        bool aSkipAssignment = false);
571
  static nsresult AddIntVarCache(int32_t* aVariable,
572
                                 const nsACString& aPref,
573
                                 int32_t aDefault = 0,
574
                                 bool aSkipAssignment = false);
575
  template<MemoryOrdering Order>
576
  static nsresult AddAtomicIntVarCache(Atomic<int32_t, Order>* aVariable,
577
                                       const nsACString& aPref,
578
                                       int32_t aDefault = 0,
579
                                       bool aSkipAssignment = false);
580
  static nsresult AddUintVarCache(uint32_t* aVariable,
581
                                  const nsACString& aPref,
582
                                  uint32_t aDefault = 0,
583
                                  bool aSkipAssignment = false);
584
  template<MemoryOrdering Order>
585
  static nsresult AddAtomicUintVarCache(Atomic<uint32_t, Order>* aVariable,
586
                                        const nsACString& aPref,
587
                                        uint32_t aDefault = 0,
588
                                        bool aSkipAssignment = false);
589
  static nsresult AddFloatVarCache(float* aVariable,
590
                                   const nsACString& aPref,
591
                                   float aDefault = 0.0f,
592
                                   bool aSkipAssignment = false);
593
594
  template<int N>
595
  static nsresult AddBoolVarCache(bool* aVariable,
596
                                  const char (&aPref)[N],
597
                                  bool aDefault = false,
598
                                  bool aSkipAssignment = false)
599
  {
600
    return AddBoolVarCache(
601
      aVariable, nsLiteralCString(aPref), aDefault, aSkipAssignment);
602
  }
603
  template<MemoryOrdering Order, int N>
604
  static nsresult AddAtomicBoolVarCache(Atomic<bool, Order>* aVariable,
605
                                        const char (&aPref)[N],
606
                                        bool aDefault = false,
607
                                        bool aSkipAssignment = false)
608
  {
609
    return AddAtomicBoolVarCache<Order>(
610
      aVariable, nsLiteralCString(aPref), aDefault, aSkipAssignment);
611
  }
612
  template<int N>
613
  static nsresult AddIntVarCache(int32_t* aVariable,
614
                                 const char (&aPref)[N],
615
                                 int32_t aDefault = 0,
616
                                 bool aSkipAssignment = false)
617
  {
618
    return AddIntVarCache(
619
      aVariable, nsLiteralCString(aPref), aDefault, aSkipAssignment);
620
  }
621
  template<MemoryOrdering Order, int N>
622
  static nsresult AddAtomicIntVarCache(Atomic<int32_t, Order>* aVariable,
623
                                       const char (&aPref)[N],
624
                                       int32_t aDefault = 0,
625
                                       bool aSkipAssignment = false)
626
  {
627
    return AddAtomicIntVarCache<Order>(
628
      aVariable, nsLiteralCString(aPref), aDefault, aSkipAssignment);
629
  }
630
  template<int N>
631
  static nsresult AddUintVarCache(uint32_t* aVariable,
632
                                  const char (&aPref)[N],
633
                                  uint32_t aDefault = 0,
634
                                  bool aSkipAssignment = false)
635
  {
636
    return AddUintVarCache(
637
      aVariable, nsLiteralCString(aPref), aDefault, aSkipAssignment);
638
  }
639
  template<MemoryOrdering Order, int N>
640
  static nsresult AddAtomicUintVarCache(Atomic<uint32_t, Order>* aVariable,
641
                                        const char (&aPref)[N],
642
                                        uint32_t aDefault = 0,
643
                                        bool aSkipAssignment = false)
644
  {
645
    return AddAtomicUintVarCache<Order>(
646
      aVariable, nsLiteralCString(aPref), aDefault, aSkipAssignment);
647
  }
648
  template<int N>
649
  static nsresult AddFloatVarCache(float* aVariable,
650
                                   const char (&aPref)[N],
651
                                   float aDefault = 0.0f,
652
                                   bool aSkipAssignment = false)
653
  {
654
    return AddFloatVarCache(
655
      aVariable, nsLiteralCString(aPref), aDefault, aSkipAssignment);
656
  }
657
658
  // When a content process is created these methods are used to pass changed
659
  // prefs in bulk from the parent process, via shared memory.
660
  static void SerializePreferences(nsCString& aStr);
661
  static void DeserializePreferences(char* aStr, size_t aPrefsLen);
662
663
  static mozilla::ipc::FileDescriptor EnsureSnapshot(size_t* aSize);
664
  static void InitSnapshot(const mozilla::ipc::FileDescriptor&, size_t aSize);
665
666
  // When a single pref is changed in the parent process, these methods are
667
  // used to pass the update to content processes.
668
  static void GetPreference(dom::Pref* aPref);
669
  static void SetPreference(const dom::Pref& aPref);
670
671
#ifdef DEBUG
672
  static bool ArePrefsInitedInContentProcess();
673
#endif
674
675
  static void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
676
                                     PrefsSizes& aSizes);
677
678
  static void HandleDirty();
679
680
  // Explicitly choosing synchronous or asynchronous (if allowed) preferences
681
  // file write. Only for the default file.  The guarantee for the "blocking"
682
  // is that when it returns, the file on disk reflect the current state of
683
  // preferences.
684
  nsresult SavePrefFileBlocking();
685
  nsresult SavePrefFileAsynchronous();
686
687
private:
688
  virtual ~Preferences();
689
690
  nsresult NotifyServiceObservers(const char* aSubject);
691
692
  // Loads the prefs.js file from the profile, or creates a new one. Returns
693
  // the prefs file if successful, or nullptr on failure.
694
  already_AddRefed<nsIFile> ReadSavedPrefs();
695
696
  // Loads the user.js file from the profile if present.
697
  void ReadUserOverridePrefs();
698
699
  nsresult MakeBackupPrefFile(nsIFile* aFile);
700
701
  // Default pref file save can be blocking or not.
702
  enum class SaveMethod
703
  {
704
    Blocking,
705
    Asynchronous
706
  };
707
708
  // Off main thread is only respected for the default aFile value (nullptr).
709
  nsresult SavePrefFileInternal(nsIFile* aFile, SaveMethod aSaveMethod);
710
  nsresult WritePrefFile(nsIFile* aFile, SaveMethod aSaveMethod);
711
712
  // If this is false, only blocking writes, on main thread are allowed.
713
  bool AllowOffMainThreadSave();
714
715
  // Helpers for implementing
716
  // Register(Prefix)Callback/Unregister(Prefix)Callback.
717
public:
718
  // Public so the ValueObserver classes can use it.
719
  enum MatchKind
720
  {
721
    PrefixMatch,
722
    ExactMatch,
723
  };
724
725
private:
726
  static void SetupTelemetryPref();
727
  static mozilla::Result<mozilla::Ok, const char*> InitInitialObjects(
728
    bool aIsStartup);
729
730
  static nsresult RegisterCallback(PrefChangedFunc aCallback,
731
                                   const nsACString& aPref,
732
                                   void* aClosure,
733
                                   MatchKind aMatchKind,
734
                                   bool aIsPriority = false);
735
  static nsresult UnregisterCallback(PrefChangedFunc aCallback,
736
                                     const nsACString& aPref,
737
                                     void* aClosure,
738
                                     MatchKind aMatchKind);
739
  static nsresult RegisterCallbackAndCall(PrefChangedFunc aCallback,
740
                                          const nsACString& aPref,
741
                                          void* aClosure,
742
                                          MatchKind aMatchKind);
743
744
  static nsresult RegisterCallbacks(PrefChangedFunc aCallback,
745
                                    const char** aPrefs,
746
                                    void* aClosure,
747
                                    MatchKind aMatchKind);
748
  static nsresult UnregisterCallbacks(PrefChangedFunc aCallback,
749
                                      const char** aPrefs,
750
                                      void* aClosure,
751
                                      MatchKind aMatchKind);
752
753
  template<typename T>
754
  static nsresult RegisterCallbackImpl(PrefChangedFunc aCallback,
755
                                       T& aPref,
756
                                       void* aClosure,
757
                                       MatchKind aMatchKind,
758
                                       bool aIsPriority = false);
759
  template<typename T>
760
  static nsresult UnregisterCallbackImpl(PrefChangedFunc aCallback,
761
                                         T& aPref,
762
                                         void* aClosure,
763
                                         MatchKind aMatchKind);
764
765
  static nsresult RegisterCallback(PrefChangedFunc aCallback,
766
                                   const char* aPref,
767
                                   void* aClosure,
768
                                   MatchKind aMatchKind,
769
                                   bool aIsPriority = false)
770
  {
771
    return RegisterCallback(
772
      aCallback, nsDependentCString(aPref), aClosure, aMatchKind, aIsPriority);
773
  }
774
  static nsresult UnregisterCallback(PrefChangedFunc aCallback,
775
                                     const char* aPref,
776
                                     void* aClosure,
777
                                     MatchKind aMatchKind)
778
  {
779
    return UnregisterCallback(
780
      aCallback, nsDependentCString(aPref), aClosure, aMatchKind);
781
  }
782
  static nsresult RegisterCallbackAndCall(PrefChangedFunc aCallback,
783
                                          const char* aPref,
784
                                          void* aClosure,
785
                                          MatchKind aMatchKind)
786
  {
787
    return RegisterCallbackAndCall(
788
      aCallback, nsDependentCString(aPref), aClosure, aMatchKind);
789
  }
790
791
private:
792
  nsCOMPtr<nsIFile> mCurrentFile;
793
  bool mDirty = false;
794
  bool mProfileShutdown = false;
795
  // We wait a bit after prefs are dirty before writing them. In this period,
796
  // mDirty and mSavePending will both be true.
797
  bool mSavePending = false;
798
799
  nsCOMPtr<nsIPrefBranch> mRootBranch;
800
  nsCOMPtr<nsIPrefBranch> mDefaultRootBranch;
801
802
  static StaticRefPtr<Preferences> sPreferences;
803
  static bool sShutdown;
804
805
  // Init static members. Returns true on success.
806
  static bool InitStaticMembers();
807
};
808
809
} // namespace mozilla
810
811
#endif // mozilla_Preferences_h