summaryrefslogtreecommitdiffstats
path: root/toolkit/components/glean/bindings/private/Event.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/glean/bindings/private/Event.cpp')
-rw-r--r--toolkit/components/glean/bindings/private/Event.cpp110
1 files changed, 110 insertions, 0 deletions
diff --git a/toolkit/components/glean/bindings/private/Event.cpp b/toolkit/components/glean/bindings/private/Event.cpp
new file mode 100644
index 0000000000..6d4065947d
--- /dev/null
+++ b/toolkit/components/glean/bindings/private/Event.cpp
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/glean/bindings/Event.h"
+
+#include "nsString.h"
+#include "mozilla/dom/GleanMetricsBinding.h"
+#include "mozilla/dom/ToJSValue.h"
+#include "mozilla/glean/bindings/Common.h"
+#include "jsapi.h"
+#include "js/PropertyAndElement.h" // JS_DefineElement, JS_DefineProperty, JS_Enumerate, JS_GetProperty, JS_GetPropertyById
+
+namespace mozilla::glean {
+
+/* virtual */
+JSObject* GleanEvent::WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) {
+ return dom::GleanEvent_Binding::Wrap(aCx, this, aGivenProto);
+}
+
+// Convert all capital letters to "_x" where "x" is the corresponding lowercase.
+nsCString camelToSnake(const nsACString& aCamel) {
+ nsCString snake;
+ const auto* start = aCamel.BeginReading();
+ const auto* end = aCamel.EndReading();
+ for (; start != end; ++start) {
+ if ('A' <= *start && *start <= 'Z') {
+ snake.AppendLiteral("_");
+ snake.Append(static_cast<char>(std::tolower(*start)));
+ } else {
+ snake.Append(*start);
+ }
+ }
+ return snake;
+}
+
+void GleanEvent::Record(
+ const dom::Optional<dom::Record<nsCString, nsCString>>& aExtra) {
+ if (!aExtra.WasPassed()) {
+ mEvent.Record();
+ return;
+ }
+
+ nsTArray<nsCString> extraKeys;
+ nsTArray<nsCString> extraValues;
+ CopyableTArray<Telemetry::EventExtraEntry> telExtras;
+ for (const auto& entry : aExtra.Value().Entries()) {
+ if (entry.mValue.IsVoid()) {
+ // Someone passed undefined/null for this value.
+ // Pretend it wasn't here.
+ continue;
+ }
+ // We accept camelCase extra keys, but Glean requires snake_case.
+ auto snakeKey = camelToSnake(entry.mKey);
+
+ extraKeys.AppendElement(snakeKey);
+ extraValues.AppendElement(entry.mValue);
+ telExtras.EmplaceBack(Telemetry::EventExtraEntry{entry.mKey, entry.mValue});
+ }
+
+ // Since this calls the implementation directly, we need to implement GIFFT
+ // here as well as in EventMetric::Record.
+ auto id = EventIdForMetric(mEvent.mId);
+ if (id) {
+ Telemetry::RecordEvent(id.extract(), Nothing(),
+ telExtras.IsEmpty() ? Nothing() : Some(telExtras));
+ }
+
+ // Calling the implementation directly, because we have a `string->string`
+ // map, not a `T->string` map the C++ API expects.
+ impl::fog_event_record(mEvent.mId, &extraKeys, &extraValues);
+}
+
+void GleanEvent::TestGetValue(
+ const nsACString& aPingName,
+ dom::Nullable<nsTArray<dom::GleanEventRecord>>& aResult, ErrorResult& aRv) {
+ auto resEvents = mEvent.TestGetValue(aPingName);
+ if (resEvents.isErr()) {
+ aRv.ThrowDataError(resEvents.unwrapErr());
+ return;
+ }
+ auto optEvents = resEvents.unwrap();
+ if (optEvents.isNothing()) {
+ return;
+ }
+
+ nsTArray<dom::GleanEventRecord> ret;
+ for (auto& event : optEvents.extract()) {
+ dom::GleanEventRecord record;
+ if (!event.mExtra.IsEmpty()) {
+ record.mExtra.Construct();
+ for (auto& extraEntry : event.mExtra) {
+ dom::binding_detail::RecordEntry<nsCString, nsCString> extra;
+ extra.mKey = std::get<0>(extraEntry);
+ extra.mValue = std::get<1>(extraEntry);
+ record.mExtra.Value().Entries().EmplaceBack(std::move(extra));
+ }
+ }
+ record.mCategory = event.mCategory;
+ record.mName = event.mName;
+ record.mTimestamp = event.mTimestamp;
+ ret.EmplaceBack(std::move(record));
+ }
+ aResult.SetValue(std::move(ret));
+}
+
+} // namespace mozilla::glean