Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/config/gfxFeature.cpp
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
#include "gfxFeature.h"
8
9
#include "mozilla/Preferences.h"
10
#include "mozilla/Sprintf.h"
11
#include "nsString.h"
12
13
namespace mozilla {
14
namespace gfx {
15
16
bool
17
FeatureState::IsEnabled() const
18
0
{
19
0
  return IsInitialized() && IsFeatureStatusSuccess(GetValue());
20
0
}
21
22
FeatureStatus
23
FeatureState::GetValue() const
24
0
{
25
0
  if (!IsInitialized()) {
26
0
    return FeatureStatus::Unused;
27
0
  }
28
0
29
0
  if (mRuntime.mStatus != FeatureStatus::Unused) {
30
0
    return mRuntime.mStatus;
31
0
  }
32
0
  if (mUser.mStatus == FeatureStatus::ForceEnabled) {
33
0
    return FeatureStatus::ForceEnabled;
34
0
  }
35
0
  if (mEnvironment.mStatus != FeatureStatus::Unused) {
36
0
    return mEnvironment.mStatus;
37
0
  }
38
0
  if (mUser.mStatus != FeatureStatus::Unused) {
39
0
    return mUser.mStatus;
40
0
  }
41
0
  return mDefault.mStatus;
42
0
}
43
44
bool
45
FeatureState::SetDefault(bool aEnable,
46
                         FeatureStatus aDisableStatus,
47
                         const char* aDisableMessage)
48
0
{
49
0
  if (!aEnable) {
50
0
    DisableByDefault(aDisableStatus, aDisableMessage,
51
0
                     NS_LITERAL_CSTRING("FEATURE_FAILURE_DISABLED"));
52
0
    return false;
53
0
  }
54
0
  EnableByDefault();
55
0
  return true;
56
0
}
57
58
void
59
FeatureState::SetDefaultFromPref(const char* aPrefName,
60
                                 bool aIsEnablePref,
61
                                 bool aDefaultValue)
62
0
{
63
0
  bool baseValue =
64
0
    Preferences::GetBool(aPrefName, aDefaultValue, PrefValueKind::Default);
65
0
  SetDefault(baseValue == aIsEnablePref, FeatureStatus::Disabled, "Disabled by default");
66
0
67
0
  if (Preferences::HasUserValue(aPrefName)) {
68
0
    bool userValue = Preferences::GetBool(aPrefName, aDefaultValue);
69
0
    if (userValue == aIsEnablePref) {
70
0
      nsCString message("Enabled via ");
71
0
      message.AppendASCII(aPrefName);
72
0
      UserEnable(message.get());
73
0
    } else {
74
0
      nsCString message("Disabled via ");
75
0
      message.AppendASCII(aPrefName);
76
0
      UserDisable(message.get(), NS_LITERAL_CSTRING("FEATURE_FAILURE_PREF_OFF"));
77
0
    }
78
0
  }
79
0
}
80
81
bool
82
FeatureState::InitOrUpdate(bool aEnable,
83
                           FeatureStatus aDisableStatus,
84
                           const char* aDisableMessage)
85
0
{
86
0
  if (!IsInitialized()) {
87
0
    return SetDefault(aEnable, aDisableStatus, aDisableMessage);
88
0
  }
89
0
  return MaybeSetFailed(aEnable, aDisableStatus, aDisableMessage, nsCString());
90
0
}
91
92
void
93
FeatureState::UserEnable(const char* aMessage)
94
0
{
95
0
  AssertInitialized();
96
0
  SetUser(FeatureStatus::Available, aMessage);
97
0
}
98
99
void
100
FeatureState::UserForceEnable(const char* aMessage)
101
0
{
102
0
  AssertInitialized();
103
0
  SetUser(FeatureStatus::ForceEnabled, aMessage);
104
0
}
105
106
void
107
FeatureState::UserDisable(const char* aMessage, const nsACString& aFailureId)
108
0
{
109
0
  AssertInitialized();
110
0
  SetUser(FeatureStatus::Disabled, aMessage);
111
0
  SetFailureId(aFailureId);
112
0
}
113
114
void
115
FeatureState::Disable(FeatureStatus aStatus, const char* aMessage,
116
                      const nsACString& aFailureId)
117
0
{
118
0
  AssertInitialized();
119
0
120
0
  // We should never bother setting an environment status to "enabled," since
121
0
  // it could override an explicit user decision to disable it.
122
0
  MOZ_ASSERT(IsFeatureStatusFailure(aStatus));
123
0
124
0
  SetEnvironment(aStatus, aMessage);
125
0
  SetFailureId(aFailureId);
126
0
}
127
128
void
129
FeatureState::SetFailed(FeatureStatus aStatus, const char* aMessage,
130
                        const nsACString& aFailureId)
131
0
{
132
0
  AssertInitialized();
133
0
134
0
  // We should never bother setting a runtime status to "enabled," since it could
135
0
  // override an explicit user decision to disable it.
136
0
  MOZ_ASSERT(IsFeatureStatusFailure(aStatus));
137
0
138
0
  SetRuntime(aStatus, aMessage);
139
0
  SetFailureId(aFailureId);
140
0
}
141
142
bool
143
FeatureState::MaybeSetFailed(bool aEnable, FeatureStatus aStatus, const char* aMessage,
144
                             const nsACString& aFailureId)
145
0
{
146
0
  if (!aEnable) {
147
0
    SetFailed(aStatus, aMessage, aFailureId);
148
0
    return false;
149
0
  }
150
0
  return true;
151
0
}
152
153
bool
154
FeatureState::MaybeSetFailed(FeatureStatus aStatus, const char* aMessage,
155
                             const nsACString& aFailureId)
156
0
{
157
0
  return MaybeSetFailed(IsFeatureStatusSuccess(aStatus), aStatus, aMessage,
158
0
                        aFailureId);
159
0
}
160
161
bool
162
FeatureState::DisabledByDefault() const
163
0
{
164
0
  return mDefault.mStatus != FeatureStatus::Available;
165
0
}
166
167
bool
168
FeatureState::IsForcedOnByUser() const
169
0
{
170
0
  AssertInitialized();
171
0
  return mUser.mStatus == FeatureStatus::ForceEnabled;
172
0
}
173
174
void
175
FeatureState::EnableByDefault()
176
0
{
177
0
  // User/runtime decisions should not have been made yet.
178
0
  MOZ_ASSERT(!mUser.IsInitialized());
179
0
  MOZ_ASSERT(!mEnvironment.IsInitialized());
180
0
  MOZ_ASSERT(!mRuntime.IsInitialized());
181
0
182
0
  mDefault.Set(FeatureStatus::Available);
183
0
}
184
185
void
186
FeatureState::DisableByDefault(FeatureStatus aStatus, const char* aMessage,
187
                               const nsACString& aFailureId)
188
0
{
189
0
  // User/runtime decisions should not have been made yet.
190
0
  MOZ_ASSERT(!mUser.IsInitialized());
191
0
  MOZ_ASSERT(!mEnvironment.IsInitialized());
192
0
  MOZ_ASSERT(!mRuntime.IsInitialized());
193
0
194
0
  // Make sure that when disabling we actually use a failure status.
195
0
  MOZ_ASSERT(IsFeatureStatusFailure(aStatus));
196
0
197
0
  mDefault.Set(aStatus, aMessage);
198
0
  SetFailureId(aFailureId);
199
0
}
200
201
void
202
FeatureState::SetUser(FeatureStatus aStatus, const char* aMessage)
203
0
{
204
0
  // Default decision must have been made, but not runtime or environment.
205
0
  MOZ_ASSERT(mDefault.IsInitialized());
206
0
  MOZ_ASSERT(!mEnvironment.IsInitialized());
207
0
  MOZ_ASSERT(!mRuntime.IsInitialized());
208
0
209
0
  mUser.Set(aStatus, aMessage);
210
0
}
211
212
void
213
FeatureState::SetEnvironment(FeatureStatus aStatus, const char* aMessage)
214
0
{
215
0
  // Default decision must have been made, but not runtime.
216
0
  MOZ_ASSERT(mDefault.IsInitialized());
217
0
  MOZ_ASSERT(!mRuntime.IsInitialized());
218
0
219
0
  mEnvironment.Set(aStatus, aMessage);
220
0
}
221
222
void
223
FeatureState::SetRuntime(FeatureStatus aStatus, const char* aMessage)
224
0
{
225
0
  AssertInitialized();
226
0
227
0
  mRuntime.Set(aStatus, aMessage);
228
0
}
229
230
const char*
231
FeatureState::GetRuntimeMessage() const
232
0
{
233
0
  MOZ_ASSERT(IsFeatureStatusFailure(mRuntime.mStatus));
234
0
  return mRuntime.mMessage;
235
0
}
236
237
void
238
FeatureState::ForEachStatusChange(const StatusIterCallback& aCallback) const
239
0
{
240
0
  AssertInitialized();
241
0
242
0
  aCallback("default", mDefault.mStatus, mDefault.MessageOrNull());
243
0
  if (mUser.IsInitialized()) {
244
0
    aCallback("user", mUser.mStatus, mUser.Message());
245
0
  }
246
0
  if (mEnvironment.IsInitialized()) {
247
0
    aCallback("env", mEnvironment.mStatus, mEnvironment.Message());
248
0
  }
249
0
  if (mRuntime.IsInitialized()) {
250
0
    aCallback("runtime", mRuntime.mStatus, mRuntime.Message());
251
0
  }
252
0
}
253
254
void
255
FeatureState::SetFailureId(const nsACString& aFailureId)
256
0
{
257
0
  if (mFailureId.IsEmpty()) {
258
0
    mFailureId = aFailureId;
259
0
  }
260
0
}
261
262
const char*
263
FeatureState::GetFailureMessage() const
264
0
{
265
0
  AssertInitialized();
266
0
  MOZ_ASSERT(!IsEnabled());
267
0
268
0
  if (mRuntime.mStatus != FeatureStatus::Unused &&
269
0
      IsFeatureStatusFailure(mRuntime.mStatus))
270
0
  {
271
0
    return mRuntime.mMessage;
272
0
  }
273
0
  if (mEnvironment.mStatus != FeatureStatus::Unused &&
274
0
      IsFeatureStatusFailure(mEnvironment.mStatus))
275
0
  {
276
0
    return mEnvironment.mMessage;
277
0
  }
278
0
  if (mUser.mStatus != FeatureStatus::Unused &&
279
0
      IsFeatureStatusFailure(mUser.mStatus))
280
0
  {
281
0
    return mUser.mMessage;
282
0
  }
283
0
284
0
  MOZ_ASSERT(IsFeatureStatusFailure(mDefault.mStatus));
285
0
  return mDefault.mMessage;
286
0
}
287
288
const nsCString&
289
FeatureState::GetFailureId() const
290
0
{
291
0
  MOZ_ASSERT(!IsEnabled());
292
0
  return mFailureId;
293
0
}
294
295
void
296
FeatureState::Reset()
297
0
{
298
0
  mDefault.Set(FeatureStatus::Unused);
299
0
  mUser.Set(FeatureStatus::Unused);
300
0
  mEnvironment.Set(FeatureStatus::Unused);
301
0
  mRuntime.Set(FeatureStatus::Unused);
302
0
  mFailureId = nsCString();
303
0
}
304
305
void
306
FeatureState::Instance::Set(FeatureStatus aStatus, const char* aMessage /* = nullptr */)
307
0
{
308
0
  mStatus = aStatus;
309
0
  if (aMessage) {
310
0
    SprintfLiteral(mMessage, "%s", aMessage);
311
0
  } else {
312
0
    mMessage[0] = '\0';
313
0
  }
314
0
}
315
316
} // namespace gfx
317
} // namespace mozilla