Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/console/ConsoleUtils.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 "ConsoleUtils.h"
8
#include "ConsoleCommon.h"
9
10
#include "mozilla/ClearOnShutdown.h"
11
#include "mozilla/NullPrincipal.h"
12
13
namespace mozilla {
14
namespace dom {
15
16
namespace {
17
18
StaticRefPtr<ConsoleUtils> gConsoleUtilsService;
19
20
}
21
22
/* static */ ConsoleUtils*
23
ConsoleUtils::GetOrCreate()
24
0
{
25
0
  if (!gConsoleUtilsService) {
26
0
    MOZ_ASSERT(NS_IsMainThread());
27
0
28
0
    gConsoleUtilsService = new ConsoleUtils();
29
0
    ClearOnShutdown(&gConsoleUtilsService);
30
0
  }
31
0
32
0
  return gConsoleUtilsService;
33
0
}
34
35
0
ConsoleUtils::ConsoleUtils() = default;
36
0
ConsoleUtils::~ConsoleUtils() = default;
37
38
/* static */ void
39
ConsoleUtils::ReportForServiceWorkerScope(const nsAString& aScope,
40
                                          const nsAString& aMessage,
41
                                          const nsAString& aFilename,
42
                                          uint32_t aLineNumber,
43
                                          uint32_t aColumnNumber,
44
                                          Level aLevel)
45
0
{
46
0
  MOZ_ASSERT(NS_IsMainThread());
47
0
48
0
  RefPtr<ConsoleUtils> service = ConsoleUtils::GetOrCreate();
49
0
  if (NS_WARN_IF(!service)) {
50
0
    return;
51
0
  }
52
0
53
0
  service->ReportForServiceWorkerScopeInternal(aScope, aMessage, aFilename,
54
0
                                               aLineNumber, aColumnNumber,
55
0
                                               aLevel);
56
0
}
57
58
void
59
ConsoleUtils::ReportForServiceWorkerScopeInternal(const nsAString& aScope,
60
                                                  const nsAString& aMessage,
61
                                                  const nsAString& aFilename,
62
                                                  uint32_t aLineNumber,
63
                                                  uint32_t aColumnNumber,
64
                                                  Level aLevel)
65
0
{
66
0
  MOZ_ASSERT(NS_IsMainThread());
67
0
68
0
  AutoJSAPI jsapi;
69
0
  jsapi.Init();
70
0
71
0
  JSContext* cx = jsapi.cx();
72
0
73
0
  ConsoleCommon::ClearException ce(cx);
74
0
  JS::Rooted<JSObject*> global(cx, GetOrCreateSandbox(cx));
75
0
  if (NS_WARN_IF(!global)) {
76
0
    return;
77
0
  }
78
0
79
0
  // The GetOrCreateSandbox call returns a proxy to the actual sandbox object.
80
0
  // We don't need a proxy here.
81
0
  global = js::UncheckedUnwrap(global);
82
0
83
0
  JSAutoRealm ar(cx, global);
84
0
85
0
  RootedDictionary<ConsoleEvent> event(cx);
86
0
87
0
  event.mID.Construct();
88
0
  event.mID.Value().SetAsString() = aScope;
89
0
90
0
  event.mInnerID.Construct();
91
0
  event.mInnerID.Value().SetAsString() = NS_LITERAL_STRING("ServiceWorker");
92
0
93
0
  switch (aLevel) {
94
0
    case eLog:
95
0
      event.mLevel = NS_LITERAL_STRING("log");
96
0
      break;
97
0
98
0
    case eWarning:
99
0
      event.mLevel = NS_LITERAL_STRING("warn");
100
0
      break;
101
0
102
0
    case eError:
103
0
      event.mLevel = NS_LITERAL_STRING("error");
104
0
      break;
105
0
  }
106
0
107
0
  event.mFilename = aFilename;
108
0
  event.mLineNumber = aLineNumber;
109
0
  event.mColumnNumber = aColumnNumber;
110
0
  event.mTimeStamp = JS_Now() / PR_USEC_PER_MSEC;
111
0
112
0
  JS::Rooted<JS::Value> messageValue(cx);
113
0
  if (!dom::ToJSValue(cx, aMessage, &messageValue)) {
114
0
    return;
115
0
  }
116
0
117
0
  event.mArguments.Construct();
118
0
  if (!event.mArguments.Value().AppendElement(messageValue, fallible)) {
119
0
    return;
120
0
  }
121
0
122
0
  nsCOMPtr<nsIConsoleAPIStorage> storage =
123
0
    do_GetService("@mozilla.org/consoleAPI-storage;1");
124
0
125
0
  if (NS_WARN_IF(!storage)) {
126
0
    return;
127
0
  }
128
0
129
0
  JS::Rooted<JS::Value> eventValue(cx);
130
0
  if (!ToJSValue(cx, event, &eventValue)) {
131
0
    return;
132
0
  }
133
0
134
0
  // This is a legacy property.
135
0
  JS::Rooted<JSObject*> eventObj(cx, &eventValue.toObject());
136
0
  if (NS_WARN_IF(!JS_DefineProperty(cx, eventObj, "wrappedJSObject", eventObj,
137
0
                                    JSPROP_ENUMERATE))) {
138
0
    return;
139
0
  }
140
0
141
0
  storage->RecordEvent(NS_LITERAL_STRING("ServiceWorker"), aScope, eventValue);
142
0
}
143
144
JSObject*
145
ConsoleUtils::GetOrCreateSandbox(JSContext* aCx)
146
0
{
147
0
  AssertIsOnMainThread();
148
0
149
0
  if (!mSandbox) {
150
0
    nsIXPConnect* xpc = nsContentUtils::XPConnect();
151
0
    MOZ_ASSERT(xpc, "This should never be null!");
152
0
153
0
    RefPtr<NullPrincipal> nullPrincipal = NullPrincipal::CreateWithoutOriginAttributes();
154
0
155
0
    JS::Rooted<JSObject*> sandbox(aCx);
156
0
    nsresult rv = xpc->CreateSandbox(aCx, nullPrincipal, sandbox.address());
157
0
    if (NS_WARN_IF(NS_FAILED(rv))) {
158
0
      return nullptr;
159
0
    }
160
0
161
0
    mSandbox = new JSObjectHolder(aCx, sandbox);
162
0
  }
163
0
164
0
  return mSandbox->GetJSObject();
165
0
}
166
167
} // namespace dom
168
} // namespace mozilla