Bug 1848708 - Convert all Glean Metric types to webidl. r=nika,janerik,perry.mcmanis,application-update-reviewers,nalexander

Though these are in essence plain objects that need no refcounting,
the presence of a NamedGetter on GleanLabeled means we need to register
everything with the wrappercache.

Paths not taken:
* Making a common utility for Maybe<T> -> dom::Nullable<T>
* GleanEvent::Record taking a dictionary instead of object
* TimerId as opaque Web IDL
* GleanDatetime accept JS Date as well as return it

(( Should make decent follow-ups ))

Differential Revision: https://phabricator.services.mozilla.com/D186267
This commit is contained in:
Chris H-C 2023-09-19 17:39:09 +00:00
Родитель ce9f11eb18
Коммит c492480f20
67 изменённых файлов: 1284 добавлений и 1312 удалений

Просмотреть файл

@ -2934,7 +2934,7 @@ bool nsGlobalWindowInner::HasActiveSpeechSynthesis() {
mozilla::glean::Glean* nsGlobalWindowInner::Glean() {
if (!mGlean) {
mGlean = new mozilla::glean::Glean();
mGlean = new mozilla::glean::Glean(this);
}
return mGlean;

Просмотреть файл

@ -1568,6 +1568,78 @@ DOMInterfaces = {
'nativeType': 'mozilla::glean::GleanLabeled',
'headerFile': 'mozilla/glean/bindings/Labeled.h',
},
'GleanMetric': {
'nativeType': 'mozilla::glean::GleanMetric',
'headerFile': 'mozilla/glean/bindings/GleanMetric.h',
},
'GleanBoolean': {
'nativeType': 'mozilla::glean::GleanBoolean',
'headerFile': 'mozilla/glean/bindings/Boolean.h',
},
'GleanCounter': {
'nativeType': 'mozilla::glean::GleanCounter',
'headerFile': 'mozilla/glean/bindings/Counter.h',
},
'GleanCustomDistribution': {
'nativeType': 'mozilla::glean::GleanCustomDistribution',
'headerFile': 'mozilla/glean/bindings/CustomDistribution.h',
},
'GleanDatetime': {
'nativeType': 'mozilla::glean::GleanDatetime',
'headerFile': 'mozilla/glean/bindings/Datetime.h',
},
'GleanString': {
'nativeType': 'mozilla::glean::GleanString',
'headerFile': 'mozilla/glean/bindings/String.h',
},
'GleanStringList': {
'nativeType': 'mozilla::glean::GleanStringList',
'headerFile': 'mozilla/glean/bindings/StringList.h',
},
'GleanTimespan': {
'nativeType': 'mozilla::glean::GleanTimespan',
'headerFile': 'mozilla/glean/bindings/Timespan.h',
},
'GleanUuid': {
'nativeType': 'mozilla::glean::GleanUuid',
'headerFile': 'mozilla/glean/bindings/Uuid.h',
},
'GleanEvent': {
'nativeType': 'mozilla::glean::GleanEvent',
'headerFile': 'mozilla/glean/bindings/Event.h',
},
'GleanQuantity': {
'nativeType': 'mozilla::glean::GleanQuantity',
'headerFile': 'mozilla/glean/bindings/Quantity.h',
},
'GleanUrl': {
'nativeType': 'mozilla::glean::GleanUrl',
'headerFile': 'mozilla/glean/bindings/Url.h',
},
'GleanTimingDistribution': {
'nativeType': 'mozilla::glean::GleanTimingDistribution',
'headerFile': 'mozilla/glean/bindings/TimingDistribution.h',
},
'GleanMemoryDistribution': {
'nativeType': 'mozilla::glean::GleanMemoryDistribution',
'headerFile': 'mozilla/glean/bindings/MemoryDistribution.h',
},
'GleanNumerator': {
'nativeType': 'mozilla::glean::GleanNumerator',
'headerFile': 'mozilla/glean/bindings/Numerator.h',
},
'GleanDenominator': {
'nativeType': 'mozilla::glean::GleanDenominator',
'headerFile': 'mozilla/glean/bindings/Denominator.h',
},
'GleanRate': {
'nativeType': 'mozilla::glean::GleanRate',
'headerFile': 'mozilla/glean/bindings/Rate.h',
},
'GleanText': {
'nativeType': 'mozilla::glean::GleanText',
'headerFile': 'mozilla/glean/bindings/Text.h',
},
# WebRTC

Просмотреть файл

@ -4,8 +4,6 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
interface nsISupports;
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanCategory {
/**
@ -14,7 +12,7 @@ interface GleanCategory {
* Returns an object of the corresponding metric type,
* with only the allowed functions available.
*/
getter nsISupports (DOMString identifier);
getter GleanMetric (DOMString identifier);
};
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
@ -41,5 +39,5 @@ interface GleanLabeled {
* After that, any additional labels will be recorded under the special
* `OTHER_LABEL` label.
*/
getter nsISupports (DOMString identifier);
getter GleanMetric (DOMString identifier);
};

Просмотреть файл

@ -1,19 +1,26 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
* 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 "nsISupports.idl"
// The definitions in this file are not sorted.
// Please add new ones to the bottom.
[scriptable, uuid(d3180fe0-19fa-11eb-8b6f-0800200c9a66)]
interface nsIGleanBoolean : nsISupports
{
/**
* Base interface for all metric types to make typing more expressive.
*/
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanMetric {};
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanBoolean : GleanMetric {
/**
* Set to the specified boolean value.
*
* @param value the value to set.
*/
void set(in bool value);
undefined set(boolean value);
/**
* **Test-only API**
@ -30,14 +37,14 @@ interface nsIGleanBoolean : nsISupports
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or undefined if there is no value.
* @return value of the stored metric, or null if there is no value.
*/
jsval testGetValue([optional] in AUTF8String aPingName);
[Throws, ChromeOnly]
boolean? testGetValue(optional UTF8String aPingName = "");
};
[scriptable, uuid(aa15fd20-1e8a-11eb-9bec-0800200c9a66)]
interface nsIGleanDatetime : nsISupports
{
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanDatetime : GleanMetric {
/**
* Set the datetime to the provided value, or the local now.
* The internal value will store the local timezone.
@ -48,13 +55,12 @@ interface nsIGleanDatetime : nsISupports
* @param aValue The (optional) time value as PRTime (nanoseconds since epoch).
* Defaults to local now.
*/
[optional_argc]
void set([optional] in PRTime aValue);
undefined set(optional long long aValue);
/**
* **Test-only API**
*
* Gets the currently stored value as an integer.
* Gets the currently stored value as a Date.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
@ -67,21 +73,20 @@ interface nsIGleanDatetime : nsISupports
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric as a JS Date with timezone,
* or undefined if there is no value.
* or null if there is no value.
*/
[implicit_jscontext]
jsval testGetValue([optional] in AUTF8String aPingName);
[Throws, ChromeOnly]
any testGetValue(optional UTF8String aPingName = "");
};
[scriptable, uuid(05b89d2a-d57c-11ea-82da-3f63399a6f5a)]
interface nsIGleanCounter : nsISupports
{
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanCounter : GleanMetric {
/*
* Increases the counter by `amount`.
*
* @param amount The amount to increase by. Should be positive.
*/
void add(in int32_t amount);
* Increases the counter by `amount`.
*
* @param aAmount The (optional) amount to increase by. Should be positive. Defaults to 1.
*/
undefined add(optional long aAmount = 1);
/**
* **Test-only API**
@ -98,21 +103,25 @@ interface nsIGleanCounter : nsISupports
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or undefined if there is no value.
* @return value of the stored metric, or null if there is no value.
*/
jsval testGetValue([optional] in AUTF8String aPingName);
[Throws, ChromeOnly]
long? testGetValue(optional UTF8String aPingName = "");
};
[scriptable, uuid(92e14730-9b5f-45a1-b018-f588d0b964d8)]
interface nsIGleanTimingDistribution : nsISupports
{
dictionary GleanDistributionData {
required unsigned long long sum;
required record<UTF8String, unsigned long long> values;
};
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanTimingDistribution : GleanMetric {
/**
* Starts tracking time for the provided metric.
*
* @returns A unique timer id for the new timer
*/
[implicit_jscontext]
jsval start();
unsigned long long start();
/**
* Stops tracking time for the provided metric and timer id.
@ -124,7 +133,7 @@ interface nsIGleanTimingDistribution : nsISupports
* @param aId The TimerId associated with this timing. This allows for
* concurrent timing of events associated with different ids.
*/
void stopAndAccumulate(in uint64_t aId);
undefined stopAndAccumulate(unsigned long long aId);
/**
* Aborts a previous `start` call. No error is recorded if no `start` was
@ -132,206 +141,7 @@ interface nsIGleanTimingDistribution : nsISupports
*
* @param aId The TimerID whose `start` you wish to abort.
*/
void cancel(in uint64_t aId);
/**
* **Test-only API**
*
* Gets the currently stored value as a DistributionData.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* This doesn't clear the stored value.
* Parent process only. Panics in child processes.
*
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or undefined if there is no value.
*/
[implicit_jscontext]
jsval testGetValue([optional] in ACString aPingName);
/**
* **Test-only API**
*
* Accumulates a raw numeric sample of milliseconds.
*
* Test-only until we find a use-case and decent JS Time Duration type.
*
* @param aSample The sample, in milliseconds, to add.
*/
void testAccumulateRawMillis(in uint64_t aSample);
};
[scriptable, uuid(eea5ed46-16ba-46cd-bb1f-504581987fe1)]
interface nsIGleanMemoryDistribution : nsISupports
{
/*
* Accumulates the provided sample in the metric.
*
* @param aSample The sample to be recorded by the metric. The sample is
* assumed to be in the confgured memory unit of the metric.
*
* Notes: Values bigger than 1 Terabyte (2^40 bytes) are truncated and an
* InvalidValue error is recorded.
*/
void accumulate(in uint64_t aSample);
/**
* **Test-only API**
*
* Gets the currently stored value as a DistributionData.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* This doesn't clear the stored value.
* Parent process only. Panics in child processes.
*
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or undefined if there is no value.
*/
[implicit_jscontext]
jsval testGetValue([optional] in ACString aPingName);
};
[scriptable, uuid(45cc016f-c1d5-4d54-aaa5-a802cf65f23b)]
interface nsIGleanCustomDistribution : nsISupports
{
/*
* Accumulates the provided signed samples in the metric.
*
* @param aSamples - The vector holding the samples to be recorded by the metric.
*
* Notes: Discards any negative value in `samples`
* and report an `ErrorType::InvalidValue` for each of them.
*/
void accumulateSamples(in Array<int64_t> aSamples);
/**
* **Test-only API**
*
* Gets the currently stored value as a DistributionData.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* This doesn't clear the stored value.
* Parent process only. Panics in child processes.
*
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or undefined if there is no value.
*/
[implicit_jscontext]
jsval testGetValue([optional] in ACString aPingName);
};
[scriptable, function, uuid(e5447f62-4b03-497c-81e9-6ab683d20380)]
interface nsIGleanPingTestCallback : nsISupports
{
void call(in ACString aReason);
};
[scriptable, uuid(5223a48b-687d-47ff-a629-fd4a72d1ecfa)]
interface nsIGleanPing : nsISupports
{
/**
* Collect and submit the ping for eventual upload.
*
* This will collect all stored data to be included in the ping.
* Data with lifetime `ping` will then be reset.
*
* If the ping is configured with `send_if_empty = false`
* and the ping currently contains no content,
* it will not be queued for upload.
* If the ping is configured with `send_if_empty = true`
* it will be queued for upload even if empty.
*
* Pings always contain the `ping_info` and `client_info` sections.
* See [ping sections](https://mozilla.github.io/glean/book/user/pings/index.html#ping-sections)
* for details.
*
* @param aReason - Optional. The reason the ping is being submitted.
* Must match one of the configured `reason_codes`.
*/
void submit([optional] in ACString aReason);
/**
* **Test-only API**
*
* Register a callback to be called right before this ping is next submitted.
* The provided function is called exactly once before submitting.
*
* Note: The callback will be called on any call to submit.
* A ping might not be sent afterwards, e.g. if the ping is empty and
* `send_if_empty` is `false`.
*
* @param aCallback - The callback to call on the next submit.
*/
void testBeforeNextSubmit(in nsIGleanPingTestCallback aCallback);
};
[scriptable, uuid(d84a3555-46f1-48c1-9122-e8e88b069d2b)]
interface nsIGleanString : nsISupports
{
/*
* Set to the specified value.
*
* @param value The string to set the metric to.
*/
void set(in AUTF8String value);
/**
* **Test-only API**
*
* Gets the currently stored value as a string.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* This doesn't clear the stored value.
* Parent process only. Panics in child processes.
*
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or undefined if there is no value.
*/
[implicit_jscontext]
jsval testGetValue([optional] in AUTF8String aPingName);
};
[scriptable, uuid(46751205-2ac7-47dc-91d2-ef4a95ef2af9)]
interface nsIGleanStringList : nsISupports
{
/**
* Adds a new string to the list.
*
* Truncates the value and logs an error if it is longer than 50 bytes.
*
* @param value The string to add.
*/
void add(in AUTF8String value);
/**
* Sets to a specific list of strings.
*
* Truncates the list and logs an error if longer than 20 items.
* Truncates any item longer than 50 bytes and logs an error.
*
* @param value The list of strings to set.
*/
void set(in Array<AUTF8String> value);
undefined cancel(unsigned long long aId);
/**
* **Test-only API**
@ -348,15 +158,163 @@ interface nsIGleanStringList : nsISupports
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or undefined if there is no value.
* @return value of the stored metric, or null if there is no value.
*/
[implicit_jscontext]
jsval testGetValue([optional] in AUTF8String aPingName);
[Throws, ChromeOnly]
GleanDistributionData? testGetValue(optional UTF8String aPingName = "");
/**
* **Test-only API**
*
* Accumulates a raw numeric sample of milliseconds.
*
* @param aSample The sample, in milliseconds, to add.
*/
[ChromeOnly]
undefined testAccumulateRawMillis(unsigned long long aSample);
};
[scriptable, uuid(2586530c-030f-11eb-93cb-cbf30d25225a)]
interface nsIGleanTimespan : nsISupports
{
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanMemoryDistribution : GleanMetric {
/**
* Accumulates the provided signed sample in the metric.
*
* @param aSample The sample to be recorded by the metric. The sample is
* assumed to be in the confgured memory unit of the metric.
*
* Notes: Values bigger than 1 Terabyte (2^40 bytes) are truncated and an
* InvalidValue error is recorded.
*/
undefined accumulate(unsigned long long aSample);
/**
* **Test-only API**
*
* Gets the currently stored value as a DistributionData.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* This doesn't clear the stored value.
* Parent process only. Panics in child processes.
*
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or null if there is no value.
*/
[Throws, ChromeOnly]
GleanDistributionData? testGetValue(optional UTF8String aPingName = "");
};
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanCustomDistribution : GleanMetric {
/**
* Accumulates the provided signed samples in the metric.
*
* @param aSamples - The vector holding the samples to be recorded by the metric.
*
* Notes: Discards any negative value in `samples`
* and report an `ErrorType::InvalidValue` for each of them.
*/
undefined accumulateSamples(sequence<long long> aSamples);
/**
* **Test-only API**
*
* Gets the currently stored value as a DistributionData.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* This doesn't clear the stored value.
* Parent process only. Panics in child processes.
*
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or null if there is no value.
*/
[Throws, ChromeOnly]
GleanDistributionData? testGetValue(optional UTF8String aPingName = "");
};
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanString : GleanMetric {
/**
* Set the string to the provided value.
*
* @param aValue The string to set the metric to.
*/
undefined set(UTF8String? aValue);
/**
* **Test-only API**
*
* Gets the currently stored value as a string.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* This doesn't clear the stored value.
* Parent process only. Panics in child processes.
*
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or null if there is no value.
*/
[Throws, ChromeOnly]
UTF8String? testGetValue(optional UTF8String aPingName = "");
};
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanStringList : GleanMetric {
/**
* Adds a new string to the list.
*
* Truncates the value and logs an error if it is longer than 100 bytes.
*
* @param value The string to add.
*/
undefined add(UTF8String value);
/**
* Sets the string_list to the provided list of strings.
*
* Truncates the list and logs an error if longer than 100 items.
* Truncates any item longer than 100 bytes and logs an error.
*
* @param aValue The list of strings to set the metric to.
*/
undefined set(sequence<UTF8String> aValue);
/**
* **Test-only API**
*
* Gets the currently stored value.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* This doesn't clear the stored value.
* Parent process only. Panics in child processes.
*
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or null if there is no value.
*/
[Throws, ChromeOnly]
sequence<UTF8String>? testGetValue(optional UTF8String aPingName = "");
};
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanTimespan : GleanMetric {
/**
* Start tracking time for the provided metric.
*
@ -364,7 +322,7 @@ interface nsIGleanTimespan : nsISupports
* called with no corresponding [stop]): in that case the original
* start time will be preserved.
*/
void start();
undefined start();
/**
* Stop tracking time for the provided metric.
@ -374,14 +332,14 @@ interface nsIGleanTimespan : nsISupports
* This will record an error if no [start] was called or there is an already
* existing value.
*/
void stop();
undefined stop();
/**
* Aborts a previous start.
*
* Does not record an error if there was no previous call to start.
*/
void cancel();
undefined cancel();
/**
* Explicitly sets the timespan value.
@ -392,127 +350,7 @@ interface nsIGleanTimespan : nsISupports
* @param aDuration The duration of this timespan, in units matching the
* `time_unit` of this metric's definition.
*/
void setRaw(in uint32_t aDuration);
/**
* **Test-only API**
*
* Gets the currently stored value as an integer.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* This doesn't clear the stored value.
* Parent process only. Panics in child processes.
*
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or undefined if there is no value.
*/
jsval testGetValue([optional] in AUTF8String aPingName);
};
[scriptable, uuid(395700e7-06f6-46be-adcc-ea58977fda6d)]
interface nsIGleanUuid : nsISupports
{
/**
* Set to the specified value.
*
* @param aValue The UUID to set the metric to.
*/
void set(in AUTF8String aValue);
/**
* Generate a new random UUID and set the metric to it.
*/
void generateAndSet();
/**
* **Test-only API**
*
* Gets the currently stored value as an integer.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* This doesn't clear the stored value.
* Parent process only. Panics in child processes.
*
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or undefined if there is no value.
*/
[implicit_jscontext]
jsval testGetValue([optional] in AUTF8String aPingName);
};
[scriptable, uuid(1b01424a-1f55-11eb-92a5-0754f6c3f240)]
interface nsIGleanEvent : nsISupports
{
/*
* Record an event.
*
* @param aExtra An (optional) map of extra values.
*/
[implicit_jscontext]
void record([optional] in jsval aExtra);
/**
* **Test-only API**
*
* Get a list of currently stored events for this event metric.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* This doesn't clear the stored value.
* Parent process only. Panics in child processes.
*
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or undefined if there is no value.
*
* The data is an array of objects:
*
* ```
* [
* {
* timestamp: Integer,
* category: String,
* name: String,
* extra: {
* String: String
* ...
* }
* },
* ...
* ]
* ```
*
* The difference between event timestamps is in milliseconds
* See https://mozilla.github.io/glean/book/user/metrics/event.html for further details.
* Due to limitations of numbers in JavaScript, the timestamp will only be accurate up until 2^53.
* (This is probably not an issue with the current clock implementation. Probably.)
*/
[implicit_jscontext]
jsval testGetValue([optional] in AUTF8String aPingName);
};
[scriptable, uuid(0558c1b2-2cb1-4e21-a0a0-6a91a35ef219)]
interface nsIGleanQuantity : nsISupports
{
/**
* Set to the specified value.
*
* @param value the value to set.
*/
void set(in int64_t value);
undefined setRaw(unsigned long aDuration);
/**
* **Test-only API**
@ -529,20 +367,128 @@ interface nsIGleanQuantity : nsISupports
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or undefined if there is no value.
* @return value of the stored metric, or null if there is no value.
*/
jsval testGetValue([optional] in AUTF8String aPingName);
[Throws, ChromeOnly]
unsigned long long? testGetValue(optional UTF8String aPingName = "");
};
[scriptable, uuid(394d9d3b-9e7e-48cc-b76c-a89a51830da3)]
interface nsIGleanDenominator : nsISupports
{
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanUuid : GleanMetric {
/**
* Set to the specified value.
*
* @param aValue The UUID to set the metric to.
*/
undefined set(UTF8String aValue);
/**
* Generate a new random UUID and set the metric to it.
*/
undefined generateAndSet();
/**
* **Test-only API**
*
* Gets the currently stored value.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* This doesn't clear the stored value.
* Parent process only. Panics in child processes.
*
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or null if there is no value.
*/
[Throws, ChromeOnly]
UTF8String? testGetValue(optional UTF8String aPingName = "");
};
dictionary GleanEventRecord {
required unsigned long long timestamp;
required UTF8String category;
required UTF8String name;
record<UTF8String, UTF8String> extra;
};
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanEvent : GleanMetric {
/*
* Increases the counter by `amount`.
*
* @param amount The amount to increase by. Should be positive.
*/
void add(in int32_t amount);
* Record an event.
*
* @param aExtra An (optional) map of extra values.
*/
undefined _record(optional record<UTF8String, UTF8String> aExtra);
/**
* **Test-only API**
*
* Gets the currently stored value.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* This doesn't clear the stored value.
* Parent process only. Panics in child processes.
*
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or null if there is no value.
*
* The difference between event timestamps is in milliseconds
* See https://mozilla.github.io/glean/book/user/metrics/event.html for further details.
* Due to limitations of numbers in JavaScript, the timestamp will only be accurate up until 2^53.
* (This is probably not an issue with the current clock implementation. Probably.)
*/
[Throws, ChromeOnly]
sequence<GleanEventRecord>? testGetValue(optional UTF8String aPingName = "");
};
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanQuantity : GleanMetric {
/**
* Set to the specified value.
*
* @param aValue The value to set the metric to.
*/
undefined set(long long aValue);
/**
* **Test-only API**
*
* Gets the currently stored value.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* This doesn't clear the stored value.
* Parent process only. Panics in child processes.
*
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or null if there is no value.
*/
[Throws, ChromeOnly]
long long? testGetValue(optional UTF8String aPingName = "");
};
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanDenominator : GleanMetric {
/*
* Increases the counter by `aAmount`.
*
* @param aAmount The (optional) amount to increase by. Should be positive. Defaults to 1.
*/
undefined add(optional long aAmount = 1);
/**
* **Test-only API**
@ -559,20 +505,25 @@ interface nsIGleanDenominator : nsISupports
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or undefined if there is no value.
* @return value of the stored metric, or null if there is no value.
*/
jsval testGetValue([optional] in AUTF8String aPingName);
[Throws, ChromeOnly]
long? testGetValue(optional UTF8String aPingName = "");
};
[scriptable, uuid(153fff71-7edd-49b4-a166-4697aa89c7a1)]
interface nsIGleanNumerator : nsISupports
{
dictionary GleanRateData {
required long numerator;
required long denominator;
};
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanNumerator : GleanMetric {
/*
* Increases the numerator by `amount`.
*
* @param amount The amount to increase by. Should be positive.
*/
void addToNumerator(in int32_t amount);
* Increases the numerator by `aAmount`.
*
* @param aAmount The (optional) amount to increase by. Should be positive. Defaults to 1.
*/
undefined addToNumerator(optional long aAmount = 1);
/**
* **Test-only API**
@ -589,28 +540,27 @@ interface nsIGleanNumerator : nsISupports
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or undefined if there is no value.
* @return value of the stored metric, or null if there is no value.
*/
[implicit_jscontext]
jsval testGetValue([optional] in AUTF8String aPingName);
[Throws, ChromeOnly]
GleanRateData? testGetValue(optional UTF8String aPingName = "");
};
[scriptable, uuid(920cf631-2b1e-4efe-ae2e-f03277c3112a)]
interface nsIGleanRate : nsISupports
{
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanRate : GleanMetric {
/*
* Increases the numerator by `amount`.
*
* @param amount The amount to increase by. Should be positive.
*/
void addToNumerator(in int32_t amount);
* Increases the numerator by `amount`.
*
* @param aAmount The (optional) amount to increase by. Should be positive. Defaults to 1.
*/
undefined addToNumerator(optional long aAmount = 1);
/*
* Increases the denominator by `amount`.
*
* @param amount The amount to increase by. Should be positive.
*/
void addToDenominator(in int32_t amount);
* Increases the denominator by `amount`.
*
* @param aAmount The (optional) amount to increase by. Should be positive. Defaults to 1.
*/
undefined addToDenominator(optional long aAmount = 1);
/**
* **Test-only API**
@ -627,21 +577,50 @@ interface nsIGleanRate : nsISupports
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or undefined if there is no value.
* @return value of the stored metric, or null if there is no value.
*/
[implicit_jscontext]
jsval testGetValue([optional] in AUTF8String aPingName);
[Throws, ChromeOnly]
GleanRateData? testGetValue(optional UTF8String aPingName = "");
};
[scriptable, uuid(a59672c4-bc48-4bfe-8f9c-6f408a59d819)]
interface nsIGleanUrl : nsISupports
{
/*
* Sets to the specified stringified URL.
*
* @param value The stringified URL to set the metric to.
*/
void set(in AUTF8String value);
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanUrl : GleanMetric {
/**
* Set to the specified value.
*
* @param aValue The stringified URL to set the metric to.
*/
undefined set(UTF8String aValue);
/**
* **Test-only API**
*
* Gets the currently stored value.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* This doesn't clear the stored value.
* Parent process only. Panics in child processes.
*
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or null if there is no value.
*/
[Throws, ChromeOnly]
UTF8String? testGetValue(optional UTF8String aPingName = "");
};
[Func="nsGlobalWindowInner::IsGleanNeeded", Exposed=Window]
interface GleanText : GleanMetric {
/**
* Set to the provided value.
*
* @param aValue The text to set the metric to.
*/
undefined set(UTF8String aValue);
/**
* **Test-only API**
@ -658,39 +637,8 @@ interface nsIGleanUrl : nsISupports
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or undefined if there is no value.
* @return value of the stored metric, or null if there is no value.
*/
[implicit_jscontext]
jsval testGetValue([optional] in AUTF8String aPingName);
};
[scriptable, uuid(fafceafb-c3a0-4424-b3b9-b7bd487f6bb4)]
interface nsIGleanText : nsISupports
{
/*
* Set to the specified value.
*
* @param value The text to set the metric to.
*/
void set(in AUTF8String value);
/**
* **Test-only API**
*
* Gets the currently stored value as a string.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* This doesn't clear the stored value.
* Parent process only. Panics in child processes.
*
* @param aPingName The (optional) name of the ping to retrieve the metric
* for. Defaults to the first value in `send_in_pings`.
*
* @return value of the stored metric, or undefined if there is no value.
*/
[implicit_jscontext]
jsval testGetValue([optional] in AUTF8String aPingName);
[Throws, ChromeOnly]
UTF8String? testGetValue(optional UTF8String aPingName = "");
};

Просмотреть файл

@ -587,6 +587,7 @@ WEBIDL_FILES = [
"GeometryUtils.webidl",
"GetUserMediaRequest.webidl",
"Glean.webidl",
"GleanMetrics.webidl",
"GleanPings.webidl",
"Grid.webidl",
"Headers.webidl",

Просмотреть файл

@ -12,7 +12,7 @@
namespace mozilla::glean {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(Category)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Category, mParent)
NS_IMPL_CYCLE_COLLECTING_ADDREF(Category)
NS_IMPL_CYCLE_COLLECTING_RELEASE(Category)
@ -26,7 +26,7 @@ JSObject* Category::WrapObject(JSContext* aCx,
return dom::GleanCategory_Binding::Wrap(aCx, this, aGivenProto);
}
already_AddRefed<nsISupports> Category::NamedGetter(const nsAString& aName,
already_AddRefed<GleanMetric> Category::NamedGetter(const nsAString& aName,
bool& aFound) {
aFound = false;
@ -45,8 +45,8 @@ already_AddRefed<nsISupports> Category::NamedGetter(const nsAString& aName,
return nullptr;
}
aFound = true;
return NewMetricFromId(metricIdx.value());
aFound = true; // Should always be true (MOZ_ASSERT_UNREACHABLE-guarded).
return NewMetricFromId(metricIdx.value(), mParent);
}
bool Category::NameIsEnumerable(const nsAString& aName) { return false; }

Просмотреть файл

@ -8,6 +8,7 @@
#define mozilla_glean_Category_h
#include "js/TypeDecls.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "nsISupports.h"
#include "nsTArrayForwardDeclare.h"
#include "nsWrapperCache.h"
@ -21,17 +22,19 @@ class Category final : public nsISupports, public nsWrapperCache {
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
nsISupports* GetParentObject() { return nullptr; }
nsISupports* GetParentObject() { return mParent; };
explicit Category(nsCString&& aName) : mName(aName) {}
explicit Category(nsCString&& aName, nsISupports* aParent)
: mName(aName), mParent(aParent) {}
already_AddRefed<nsISupports> NamedGetter(const nsAString& aName,
already_AddRefed<GleanMetric> NamedGetter(const nsAString& aName,
bool& aFound);
bool NameIsEnumerable(const nsAString& aName);
void GetSupportedNames(nsTArray<nsString>& aNames);
private:
nsCString mName;
nsCOMPtr<nsISupports> mParent;
protected:
virtual ~Category() = default;

Просмотреть файл

@ -25,7 +25,7 @@ namespace mozilla::glean {
// Threading: Must only be read or written to on the main thread.
static bool gRuntimeMetricsComprehensive = false;
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(Glean)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Glean, mParent)
NS_IMPL_CYCLE_COLLECTING_ADDREF(Glean)
NS_IMPL_CYCLE_COLLECTING_RELEASE(Glean)
@ -52,7 +52,7 @@ bool Glean::DefineGlean(JSContext* aCx, JS::Handle<JSObject*> aGlobal) {
JS::Rooted<JS::Value> glean(aCx);
js::AssertSameCompartment(aCx, aGlobal);
auto impl = MakeRefPtr<Glean>();
auto impl = MakeRefPtr<Glean>(global);
if (!dom::GetOrCreateDOMReflector(aCx, impl.get(), &glean)) {
return false;
}
@ -69,7 +69,7 @@ already_AddRefed<Category> Glean::NamedGetter(const nsAString& aName,
NS_ConvertUTF16toUTF8 categoryName(aName);
if (JOG::HasCategory(categoryName)) {
aFound = true;
return MakeAndAddRef<Category>(std::move(categoryName));
return MakeAndAddRef<Category>(std::move(categoryName), mParent);
}
if (gRuntimeMetricsComprehensive) {
@ -87,7 +87,7 @@ already_AddRefed<Category> Glean::NamedGetter(const nsAString& aName,
aFound = true;
nsDependentCString name(GetCategoryName(categoryIdx.value()));
return MakeAndAddRef<Category>(std::move(name));
return MakeAndAddRef<Category>(std::move(name), mParent);
}
bool Glean::NameIsEnumerable(const nsAString& aName) { return false; }

Просмотреть файл

@ -22,9 +22,11 @@ class Glean final : public nsISupports, public nsWrapperCache {
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(Glean)
explicit Glean(nsIGlobalObject* aGlobal) : mParent(aGlobal) {}
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
nsISupports* GetParentObject() { return nullptr; }
nsISupports* GetParentObject() { return mParent; }
static bool DefineGlean(JSContext* aCx, JS::Handle<JSObject*> aGlobal);
@ -43,6 +45,9 @@ class Glean final : public nsISupports, public nsWrapperCache {
*/
static void TestSetRuntimeMetricsComprehensive(bool aIsComprehensive);
private:
nsCOMPtr<nsISupports> mParent;
protected:
virtual ~Glean() = default;
};

Просмотреть файл

@ -0,0 +1,22 @@
/* -*- 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/GleanMetric.h"
#include "nsWrapperCache.h"
namespace mozilla::glean {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(GleanMetric, mParent)
NS_IMPL_CYCLE_COLLECTING_ADDREF(GleanMetric)
NS_IMPL_CYCLE_COLLECTING_RELEASE(GleanMetric)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GleanMetric)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
} // namespace mozilla::glean

Просмотреть файл

@ -0,0 +1,31 @@
/* -*- 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/. */
#ifndef mozilla_glean_GleanMetric_h
#define mozilla_glean_GleanMetric_h
#include "js/TypeDecls.h"
#include "nsIGlobalObject.h"
#include "nsWrapperCache.h"
namespace mozilla::glean {
class GleanMetric : public nsISupports, public nsWrapperCache {
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS;
NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(GleanMetric);
nsISupports* GetParentObject() const { return mParent; }
protected:
GleanMetric(nsISupports* aParent) : mParent(aParent) {}
virtual ~GleanMetric() = default;
nsCOMPtr<nsISupports> mParent;
};
} // namespace mozilla::glean
#endif /* mozilla_glean_GleanMetric_h */

Просмотреть файл

@ -7,12 +7,10 @@
#include "mozilla/glean/bindings/Boolean.h"
#include "nsString.h"
#include "mozilla/Components.h"
#include "mozilla/ResultVariant.h"
#include "mozilla/dom/GleanMetricsBinding.h"
#include "mozilla/glean/bindings/ScalarGIFFTMap.h"
#include "mozilla/glean/fog_ffi_generated.h"
#include "nsIClassInfoImpl.h"
#include "Common.h"
namespace mozilla::glean {
@ -48,32 +46,26 @@ Result<Maybe<bool>, nsCString> BooleanMetric::TestGetValue(
} // namespace impl
NS_IMPL_CLASSINFO(GleanBoolean, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(GleanBoolean, nsIGleanBoolean)
NS_IMETHODIMP
GleanBoolean::Set(bool aValue) {
mBoolean.Set(aValue);
return NS_OK;
JSObject* GleanBoolean::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return dom::GleanBoolean_Binding::Wrap(aCx, this, aGivenProto);
}
NS_IMETHODIMP
GleanBoolean::TestGetValue(const nsACString& aStorageName,
JS::MutableHandle<JS::Value> aResult) {
auto result = mBoolean.TestGetValue(aStorageName);
void GleanBoolean::Set(bool aValue) { mBoolean.Set(aValue); }
dom::Nullable<bool> GleanBoolean::TestGetValue(const nsACString& aPingName,
ErrorResult& aRv) {
dom::Nullable<bool> ret;
auto result = mBoolean.TestGetValue(aPingName);
if (result.isErr()) {
aResult.set(JS::UndefinedValue());
LogToBrowserConsole(nsIScriptError::errorFlag,
NS_ConvertUTF8toUTF16(result.unwrapErr()));
return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
aRv.ThrowDataError(result.unwrapErr());
return ret;
}
auto optresult = result.unwrap();
if (optresult.isNothing()) {
aResult.set(JS::UndefinedValue());
} else {
aResult.set(JS::BooleanValue(optresult.value()));
if (!optresult.isNothing()) {
ret.SetValue(optresult.value());
}
return NS_OK;
return ret;
}
} // namespace mozilla::glean

Просмотреть файл

@ -7,9 +7,11 @@
#ifndef mozilla_glean_GleanBoolean_h
#define mozilla_glean_GleanBoolean_h
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "mozilla/Result.h"
#include "nsIGleanMetrics.h"
#include "nsString.h"
#include "nsWrapperCache.h"
namespace mozilla {
namespace glean {
@ -53,12 +55,18 @@ class BooleanMetric {
} // namespace impl
class GleanBoolean final : public nsIGleanBoolean {
class GleanBoolean final : public GleanMetric {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGLEANBOOLEAN
explicit GleanBoolean(uint32_t id, nsISupports* aParent)
: GleanMetric(aParent), mBoolean(id) {}
explicit GleanBoolean(uint32_t id) : mBoolean(id){};
virtual JSObject* WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
void Set(bool aValue);
dom::Nullable<bool> TestGetValue(const nsACString& aPingName,
ErrorResult& aRv);
private:
virtual ~GleanBoolean() = default;

Просмотреть файл

@ -7,13 +7,10 @@
#include "mozilla/glean/bindings/Counter.h"
#include "nsString.h"
#include "mozilla/Components.h"
#include "mozilla/ResultVariant.h"
#include "mozilla/dom/GleanMetricsBinding.h"
#include "mozilla/glean/bindings/ScalarGIFFTMap.h"
#include "mozilla/glean/fog_ffi_generated.h"
#include "Common.h"
#include "nsIClassInfoImpl.h"
#include "nsIScriptError.h"
namespace mozilla::glean {
@ -51,32 +48,27 @@ Result<Maybe<int32_t>, nsCString> CounterMetric::TestGetValue(
} // namespace impl
NS_IMPL_CLASSINFO(GleanCounter, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(GleanCounter, nsIGleanCounter)
NS_IMETHODIMP
GleanCounter::Add(int32_t aAmount) {
mCounter.Add(aAmount);
return NS_OK;
/* virtual */
JSObject* GleanCounter::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return dom::GleanCounter_Binding::Wrap(aCx, this, aGivenProto);
}
NS_IMETHODIMP
GleanCounter::TestGetValue(const nsACString& aStorageName,
JS::MutableHandle<JS::Value> aResult) {
auto result = mCounter.TestGetValue(aStorageName);
void GleanCounter::Add(int32_t aAmount) { mCounter.Add(aAmount); }
dom::Nullable<int32_t> GleanCounter::TestGetValue(const nsACString& aPingName,
ErrorResult& aRv) {
dom::Nullable<int32_t> ret;
auto result = mCounter.TestGetValue(aPingName);
if (result.isErr()) {
aResult.set(JS::UndefinedValue());
LogToBrowserConsole(nsIScriptError::errorFlag,
NS_ConvertUTF8toUTF16(result.unwrapErr()));
return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
aRv.ThrowDataError(result.unwrapErr());
return ret;
}
auto optresult = result.unwrap();
if (optresult.isNothing()) {
aResult.set(JS::UndefinedValue());
} else {
aResult.set(JS::Int32Value(optresult.value()));
if (!optresult.isNothing()) {
ret.SetValue(optresult.value());
}
return NS_OK;
return ret;
}
} // namespace mozilla::glean

Просмотреть файл

@ -7,9 +7,10 @@
#ifndef mozilla_glean_GleanCounter_h
#define mozilla_glean_GleanCounter_h
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "mozilla/Maybe.h"
#include "mozilla/Result.h"
#include "nsIGleanMetrics.h"
#include "nsString.h"
namespace mozilla::glean {
@ -52,12 +53,18 @@ class CounterMetric {
};
} // namespace impl
class GleanCounter final : public nsIGleanCounter {
class GleanCounter final : public GleanMetric {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGLEANCOUNTER
explicit GleanCounter(uint32_t id, nsISupports* aParent)
: GleanMetric(aParent), mCounter(id) {}
explicit GleanCounter(uint32_t id) : mCounter(id){};
virtual JSObject* WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
void Add(int32_t aAmount);
dom::Nullable<int32_t> TestGetValue(const nsACString& aPingName,
ErrorResult& aRv);
private:
virtual ~GleanCounter() = default;

Просмотреть файл

@ -6,12 +6,10 @@
#include "mozilla/glean/bindings/CustomDistribution.h"
#include "Common.h"
#include "mozilla/Components.h"
#include "mozilla/ResultVariant.h"
#include "mozilla/dom/GleanMetricsBinding.h"
#include "mozilla/glean/bindings/HistogramGIFFTMap.h"
#include "mozilla/glean/fog_ffi_generated.h"
#include "nsIClassInfoImpl.h"
#include "nsJSUtils.h"
#include "nsPrintfCString.h"
#include "nsString.h"
@ -68,58 +66,40 @@ CustomDistributionMetric::TestGetValue(const nsACString& aPingName) const {
} // namespace impl
NS_IMPL_CLASSINFO(GleanCustomDistribution, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(GleanCustomDistribution, nsIGleanCustomDistribution)
NS_IMETHODIMP
GleanCustomDistribution::AccumulateSamples(const nsTArray<int64_t>& aSamples) {
mCustomDist.AccumulateSamplesSigned(aSamples);
return NS_OK;
/* virtual */
JSObject* GleanCustomDistribution::WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
return dom::GleanCustomDistribution_Binding::Wrap(aCx, this, aGivenProto);
}
NS_IMETHODIMP
GleanCustomDistribution::TestGetValue(const nsACString& aPingName,
JSContext* aCx,
JS::MutableHandle<JS::Value> aResult) {
void GleanCustomDistribution::AccumulateSamples(
const dom::Sequence<int64_t>& aSamples) {
mCustomDist.AccumulateSamplesSigned(aSamples);
}
void GleanCustomDistribution::TestGetValue(
const nsACString& aPingName,
dom::Nullable<dom::GleanDistributionData>& aRetval, ErrorResult& aRv) {
auto result = mCustomDist.TestGetValue(aPingName);
if (result.isErr()) {
aResult.set(JS::UndefinedValue());
LogToBrowserConsole(nsIScriptError::errorFlag,
NS_ConvertUTF8toUTF16(result.unwrapErr()));
return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
aRv.ThrowDataError(result.unwrapErr());
return;
}
auto optresult = result.unwrap();
if (optresult.isNothing()) {
aResult.set(JS::UndefinedValue());
} else {
// Build return value of the form: { sum: #, values: {bucket1: count1, ...}
JS::Rooted<JSObject*> root(aCx, JS_NewPlainObject(aCx));
if (!root) {
return NS_ERROR_FAILURE;
}
uint64_t sum = optresult.ref().sum;
if (!JS_DefineProperty(aCx, root, "sum", static_cast<double>(sum),
JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
JS::Rooted<JSObject*> valuesObj(aCx, JS_NewPlainObject(aCx));
if (!valuesObj ||
!JS_DefineProperty(aCx, root, "values", valuesObj, JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
auto& data = optresult.ref().values;
for (const auto& entry : data) {
const uint64_t bucket = entry.GetKey();
const uint64_t count = entry.GetData();
if (!JS_DefineProperty(aCx, valuesObj,
nsPrintfCString("%" PRIu64, bucket).get(),
static_cast<double>(count), JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
}
aResult.setObject(*root);
return;
}
return NS_OK;
dom::GleanDistributionData ret;
ret.mSum = optresult.ref().sum;
auto& data = optresult.ref().values;
for (const auto& entry : data) {
dom::binding_detail::RecordEntry<nsCString, uint64_t> bucket;
bucket.mKey = nsPrintfCString("%" PRIu64, entry.GetKey());
bucket.mValue = entry.GetData();
ret.mValues.Entries().EmplaceBack(std::move(bucket));
}
aRetval.SetValue(std::move(ret));
}
} // namespace mozilla::glean

Просмотреть файл

@ -7,12 +7,17 @@
#ifndef mozilla_glean_GleanCustomDistribution_h
#define mozilla_glean_GleanCustomDistribution_h
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "mozilla/glean/bindings/DistributionData.h"
#include "mozilla/Maybe.h"
#include "mozilla/Result.h"
#include "nsIGleanMetrics.h"
#include "nsTArray.h"
namespace mozilla::dom {
struct GleanDistributionData;
} // namespace mozilla::dom
namespace mozilla::glean {
namespace impl {
@ -65,12 +70,19 @@ class CustomDistributionMetric {
};
} // namespace impl
class GleanCustomDistribution final : public nsIGleanCustomDistribution {
class GleanCustomDistribution final : public GleanMetric {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGLEANCUSTOMDISTRIBUTION
explicit GleanCustomDistribution(uint64_t aId, nsISupports* aParent)
: GleanMetric(aParent), mCustomDist(aId) {}
explicit GleanCustomDistribution(uint64_t aId) : mCustomDist(aId){};
virtual JSObject* WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
void AccumulateSamples(const dom::Sequence<int64_t>& aSamples);
void TestGetValue(const nsACString& aPingName,
dom::Nullable<dom::GleanDistributionData>& aRetval,
ErrorResult& aRv);
private:
virtual ~GleanCustomDistribution() = default;

Просмотреть файл

@ -9,13 +9,10 @@
#include "jsapi.h"
#include "js/Date.h"
#include "nsString.h"
#include "nsIScriptError.h"
#include "mozilla/Components.h"
#include "mozilla/ResultVariant.h"
#include "mozilla/dom/GleanMetricsBinding.h"
#include "mozilla/glean/bindings/ScalarGIFFTMap.h"
#include "mozilla/glean/fog_ffi_generated.h"
#include "nsIClassInfoImpl.h"
#include "Common.h"
#include "prtime.h"
namespace mozilla::glean {
@ -84,31 +81,30 @@ Result<Maybe<PRExplodedTime>, nsCString> DatetimeMetric::TestGetValue(
} // namespace impl
NS_IMPL_CLASSINFO(GleanDatetime, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(GleanDatetime, nsIGleanDatetime)
NS_IMETHODIMP
GleanDatetime::Set(PRTime aValue, uint8_t aOptionalArgc) {
if (aOptionalArgc == 0) {
mDatetime.Set();
} else {
PRExplodedTime exploded;
PR_ExplodeTime(aValue, PR_LocalTimeParameters, &exploded);
mDatetime.Set(&exploded);
}
return NS_OK;
/* virtual */
JSObject* GleanDatetime::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return dom::GleanDatetime_Binding::Wrap(aCx, this, aGivenProto);
}
NS_IMETHODIMP
GleanDatetime::TestGetValue(const nsACString& aStorageName, JSContext* aCx,
JS::MutableHandle<JS::Value> aResult) {
auto result = mDatetime.TestGetValue(aStorageName);
void GleanDatetime::Set(const dom::Optional<int64_t>& aValue) {
if (aValue.WasPassed()) {
PRExplodedTime exploded;
PR_ExplodeTime(aValue.Value(), PR_LocalTimeParameters, &exploded);
mDatetime.Set(&exploded);
} else {
mDatetime.Set();
}
}
void GleanDatetime::TestGetValue(JSContext* aCx, const nsACString& aPingName,
JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv) {
auto result = mDatetime.TestGetValue(aPingName);
if (result.isErr()) {
aResult.set(JS::UndefinedValue());
LogToBrowserConsole(nsIScriptError::errorFlag,
NS_ConvertUTF8toUTF16(result.unwrapErr()));
return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
aRv.ThrowDataError(result.unwrapErr());
return;
}
auto optresult = result.unwrap();
if (optresult.isNothing()) {
@ -120,7 +116,6 @@ GleanDatetime::TestGetValue(const nsACString& aStorageName, JSContext* aCx,
JS::NewDateObject(aCx, JS::TimeClip(millis)));
aResult.setObject(*root);
}
return NS_OK;
}
} // namespace mozilla::glean

Просмотреть файл

@ -7,10 +7,12 @@
#ifndef mozilla_glean_GleanDatetime_h
#define mozilla_glean_GleanDatetime_h
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "mozilla/Maybe.h"
#include "mozilla/Result.h"
#include "nsIGleanMetrics.h"
#include "nsString.h"
#include "nsWrapperCache.h"
#include "prtime.h"
namespace mozilla::glean {
@ -53,12 +55,18 @@ class DatetimeMetric {
};
} // namespace impl
class GleanDatetime final : public nsIGleanDatetime {
class GleanDatetime final : public GleanMetric {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGLEANDATETIME
explicit GleanDatetime(uint32_t aId, nsISupports* aParent)
: GleanMetric(aParent), mDatetime(aId) {}
explicit GleanDatetime(uint32_t aId) : mDatetime(aId){};
virtual JSObject* WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
void Set(const dom::Optional<int64_t>& aValue);
void TestGetValue(JSContext* aCx, const nsACString& aPingName,
JS::MutableHandle<JS::Value> aResult, ErrorResult& aRv);
private:
virtual ~GleanDatetime() = default;

Просмотреть файл

@ -7,13 +7,10 @@
#include "mozilla/glean/bindings/Denominator.h"
#include "nsString.h"
#include "mozilla/Components.h"
#include "mozilla/ResultVariant.h"
#include "mozilla/dom/GleanMetricsBinding.h"
#include "mozilla/glean/bindings/ScalarGIFFTMap.h"
#include "mozilla/glean/fog_ffi_generated.h"
#include "nsIClassInfoImpl.h"
#include "nsIScriptError.h"
#include "Common.h"
namespace mozilla::glean {
@ -41,32 +38,27 @@ Result<Maybe<int32_t>, nsCString> DenominatorMetric::TestGetValue(
} // namespace impl
NS_IMPL_CLASSINFO(GleanDenominator, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(GleanDenominator, nsIGleanDenominator)
NS_IMETHODIMP
GleanDenominator::Add(int32_t aAmount) {
mDenominator.Add(aAmount);
return NS_OK;
/* virtual */
JSObject* GleanDenominator::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return dom::GleanDenominator_Binding::Wrap(aCx, this, aGivenProto);
}
NS_IMETHODIMP
GleanDenominator::TestGetValue(const nsACString& aStorageName,
JS::MutableHandle<JS::Value> aResult) {
auto result = mDenominator.TestGetValue(aStorageName);
void GleanDenominator::Add(int32_t aAmount) { mDenominator.Add(aAmount); }
dom::Nullable<int32_t> GleanDenominator::TestGetValue(
const nsACString& aPingName, ErrorResult& aRv) {
dom::Nullable<int32_t> ret;
auto result = mDenominator.TestGetValue(aPingName);
if (result.isErr()) {
aResult.set(JS::UndefinedValue());
LogToBrowserConsole(nsIScriptError::errorFlag,
NS_ConvertUTF8toUTF16(result.unwrapErr()));
return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
aRv.ThrowDataError(result.unwrapErr());
return ret;
}
auto optresult = result.unwrap();
if (optresult.isNothing()) {
aResult.set(JS::UndefinedValue());
} else {
aResult.set(JS::Int32Value(optresult.value()));
if (!optresult.isNothing()) {
ret.SetValue(optresult.value());
}
return NS_OK;
return ret;
}
} // namespace mozilla::glean

Просмотреть файл

@ -7,9 +7,10 @@
#ifndef mozilla_glean_GleanDenominator_h
#define mozilla_glean_GleanDenominator_h
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "mozilla/Maybe.h"
#include "mozilla/Result.h"
#include "nsIGleanMetrics.h"
#include "nsString.h"
namespace mozilla::glean {
@ -52,12 +53,18 @@ class DenominatorMetric {
};
} // namespace impl
class GleanDenominator final : public nsIGleanDenominator {
class GleanDenominator final : public GleanMetric {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGLEANDENOMINATOR
explicit GleanDenominator(uint32_t id, nsISupports* aParent)
: GleanMetric(aParent), mDenominator(id) {}
explicit GleanDenominator(uint32_t id) : mDenominator(id){};
virtual JSObject* WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
void Add(int32_t aAmount);
dom::Nullable<int32_t> TestGetValue(const nsACString& aPingName,
ErrorResult& aRv);
private:
virtual ~GleanDenominator() = default;

Просмотреть файл

@ -6,19 +6,20 @@
#include "mozilla/glean/bindings/Event.h"
#include "Common.h"
#include "nsString.h"
#include "mozilla/Components.h"
#include "mozilla/dom/GleanMetricsBinding.h"
#include "mozilla/dom/ToJSValue.h"
#include "nsIClassInfoImpl.h"
#include "mozilla/glean/bindings/Common.h"
#include "jsapi.h"
#include "js/PropertyAndElement.h" // JS_DefineElement, JS_DefineProperty, JS_Enumerate, JS_GetProperty, JS_GetPropertyById
#include "nsIScriptError.h"
namespace mozilla::glean {
NS_IMPL_CLASSINFO(GleanEvent, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(GleanEvent, nsIGleanEvent)
/* 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) {
@ -36,76 +37,23 @@ nsCString camelToSnake(const nsACString& aCamel) {
return snake;
}
NS_IMETHODIMP
GleanEvent::Record(JS::Handle<JS::Value> aExtra, JSContext* aCx) {
if (aExtra.isNullOrUndefined()) {
void GleanEvent::Record(
const dom::Optional<dom::Record<nsCString, nsCString>>& aExtra) {
if (!aExtra.WasPassed()) {
mEvent.Record();
return NS_OK;
}
if (!aExtra.isObject()) {
LogToBrowserConsole(
nsIScriptError::warningFlag,
u"Extras need to be an object. Event will not be recorded."_ns);
return NS_OK;
return;
}
nsTArray<nsCString> extraKeys;
nsTArray<nsCString> extraValues;
CopyableTArray<Telemetry::EventExtraEntry> telExtras;
JS::Rooted<JSObject*> obj(aCx, &aExtra.toObject());
JS::Rooted<JS::IdVector> ids(aCx, JS::IdVector(aCx));
if (!JS_Enumerate(aCx, obj, &ids)) {
LogToBrowserConsole(
nsIScriptError::warningFlag,
u"Failed to enumerate object. Event will not be recorded."_ns);
return NS_OK;
}
for (size_t i = 0, n = ids.length(); i < n; i++) {
nsAutoJSCString jsKey;
if (!jsKey.init(aCx, ids[i])) {
LogToBrowserConsole(
nsIScriptError::warningFlag,
u"Extra dictionary should only contain string keys. Event will not be recorded."_ns);
return NS_OK;
}
for (const auto& entry : aExtra.Value().Entries()) {
// We accept camelCase extra keys, but Glean requires snake_case.
auto snakeKey = camelToSnake(jsKey);
JS::Rooted<JS::Value> value(aCx);
if (!JS_GetPropertyById(aCx, obj, ids[i], &value)) {
LogToBrowserConsole(
nsIScriptError::warningFlag,
u"Failed to get extra property. Event will not be recorded."_ns);
return NS_OK;
}
nsAutoJSCString jsValue;
if (value.isString() || (value.isInt32() && value.toInt32() >= 0) ||
value.isBoolean()) {
if (!jsValue.init(aCx, value)) {
LogToBrowserConsole(
nsIScriptError::warningFlag,
u"Can't extract extra property. Event will not be recorded."_ns);
return NS_OK;
}
} else if (value.isNullOrUndefined()) {
// The extra key is present, but has an empty value.
// Treat as though it weren't here at all.
continue;
} else {
LogToBrowserConsole(
nsIScriptError::warningFlag,
u"Extra properties should have string, bool or non-negative integer values. Event will not be recorded."_ns);
return NS_OK;
}
auto snakeKey = camelToSnake(entry.mKey);
extraKeys.AppendElement(snakeKey);
extraValues.AppendElement(jsValue);
telExtras.EmplaceBack(Telemetry::EventExtraEntry{jsKey, jsValue});
extraValues.AppendElement(entry.mValue);
telExtras.EmplaceBack(Telemetry::EventExtraEntry{entry.mKey, entry.mValue});
}
// Since this calls the implementation directly, we need to implement GIFFT
@ -119,88 +67,39 @@ GleanEvent::Record(JS::Handle<JS::Value> aExtra, JSContext* aCx) {
// 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);
return NS_OK;
}
NS_IMETHODIMP
GleanEvent::TestGetValue(const nsACString& aStorageName, JSContext* aCx,
JS::MutableHandle<JS::Value> aResult) {
auto resEvents = mEvent.TestGetValue(aStorageName);
void GleanEvent::TestGetValue(
const nsACString& aPingName,
dom::Nullable<nsTArray<dom::GleanEventRecord>>& aResult, ErrorResult& aRv) {
auto resEvents = mEvent.TestGetValue(aPingName);
if (resEvents.isErr()) {
aResult.set(JS::UndefinedValue());
LogToBrowserConsole(nsIScriptError::errorFlag,
NS_ConvertUTF8toUTF16(resEvents.unwrapErr()));
return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
aRv.ThrowDataError(resEvents.unwrapErr());
return;
}
auto optEvents = resEvents.unwrap();
if (optEvents.isNothing()) {
aResult.set(JS::UndefinedValue());
return NS_OK;
return;
}
auto events = optEvents.extract();
auto count = events.Length();
JS::Rooted<JSObject*> eventArray(aCx, JS::NewArrayObject(aCx, count));
if (NS_WARN_IF(!eventArray)) {
return NS_ERROR_FAILURE;
}
for (size_t i = 0; i < count; i++) {
auto* value = &events[i];
JS::Rooted<JSObject*> eventObj(aCx, JS_NewPlainObject(aCx));
if (NS_WARN_IF(!eventObj)) {
return NS_ERROR_FAILURE;
}
if (!JS_DefineProperty(aCx, eventObj, "timestamp",
(double)value->mTimestamp, JSPROP_ENUMERATE)) {
NS_WARNING("Failed to define timestamp for event object.");
return NS_ERROR_FAILURE;
}
JS::Rooted<JS::Value> catStr(aCx);
if (!dom::ToJSValue(aCx, value->mCategory, &catStr) ||
!JS_DefineProperty(aCx, eventObj, "category", catStr,
JSPROP_ENUMERATE)) {
NS_WARNING("Failed to define category for event object.");
return NS_ERROR_FAILURE;
}
JS::Rooted<JS::Value> nameStr(aCx);
if (!dom::ToJSValue(aCx, value->mName, &nameStr) ||
!JS_DefineProperty(aCx, eventObj, "name", nameStr, JSPROP_ENUMERATE)) {
NS_WARNING("Failed to define name for event object.");
return NS_ERROR_FAILURE;
}
JS::Rooted<JSObject*> extraObj(aCx, JS_NewPlainObject(aCx));
if (!JS_DefineProperty(aCx, eventObj, "extra", extraObj,
JSPROP_ENUMERATE)) {
NS_WARNING("Failed to define extra for event object.");
return NS_ERROR_FAILURE;
}
for (auto pair : value->mExtra) {
auto key = std::get<0>(pair);
auto val = std::get<1>(pair);
JS::Rooted<JS::Value> valStr(aCx);
if (!dom::ToJSValue(aCx, val, &valStr) ||
!JS_DefineProperty(aCx, extraObj, key.Data(), valStr,
JSPROP_ENUMERATE)) {
NS_WARNING("Failed to define extra property for event object.");
return NS_ERROR_FAILURE;
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));
}
}
if (!JS_DefineElement(aCx, eventArray, i, eventObj, JSPROP_ENUMERATE)) {
NS_WARNING("Failed to define item in events array.");
return NS_ERROR_FAILURE;
}
record.mCategory = event.mCategory;
record.mName = event.mName;
record.mTimestamp = event.mTimestamp;
ret.EmplaceBack(std::move(record));
}
aResult.setObject(*eventArray);
return NS_OK;
aResult.SetValue(std::move(ret));
}
} // namespace mozilla::glean

Просмотреть файл

@ -7,14 +7,21 @@
#ifndef mozilla_glean_GleanEvent_h
#define mozilla_glean_GleanEvent_h
#include "nsIGleanMetrics.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/Record.h"
#include "mozilla/glean/bindings/EventGIFFTMap.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "mozilla/glean/fog_ffi_generated.h"
#include "mozilla/ResultVariant.h"
#include "nsString.h"
#include "nsTArray.h"
namespace mozilla::dom {
// forward declaration
struct GleanEventRecord;
} // namespace mozilla::dom
namespace mozilla::glean {
// forward declaration
@ -145,12 +152,19 @@ struct NoExtraKeys {
}
};
class GleanEvent final : public nsIGleanEvent {
class GleanEvent final : public GleanMetric {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGLEANEVENT
explicit GleanEvent(uint32_t id, nsISupports* aParent)
: GleanMetric(aParent), mEvent(id) {}
explicit GleanEvent(uint32_t id) : mEvent(id){};
virtual JSObject* WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
void Record(const dom::Optional<dom::Record<nsCString, nsCString>>& aExtra);
void TestGetValue(const nsACString& aPingName,
dom::Nullable<nsTArray<dom::GleanEventRecord>>& aResult,
ErrorResult& aRv);
private:
virtual ~GleanEvent() = default;

Просмотреть файл

@ -10,33 +10,24 @@
#include "mozilla/glean/fog_ffi_generated.h"
#include "mozilla/glean/bindings/GleanJSMetricsLookup.h"
#include "mozilla/glean/bindings/MetricTypes.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/glean/bindings/ScalarGIFFTMap.h"
#include "nsString.h"
namespace mozilla::glean {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(GleanLabeled)
NS_IMPL_CYCLE_COLLECTING_ADDREF(GleanLabeled)
NS_IMPL_CYCLE_COLLECTING_RELEASE(GleanLabeled)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GleanLabeled)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
JSObject* GleanLabeled::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return dom::GleanLabeled_Binding::Wrap(aCx, this, aGivenProto);
}
already_AddRefed<nsISupports> GleanLabeled::NamedGetter(const nsAString& aName,
already_AddRefed<GleanMetric> GleanLabeled::NamedGetter(const nsAString& aName,
bool& aFound) {
auto label = NS_ConvertUTF16toUTF8(aName);
// All strings will map to a label. Either a valid one or `__other__`.
aFound = true;
uint32_t submetricId = 0;
already_AddRefed<nsISupports> submetric =
NewSubMetricFromIds(mTypeId, mId, label, &submetricId);
already_AddRefed<GleanMetric> submetric =
NewSubMetricFromIds(mTypeId, mId, label, &submetricId, mParent);
auto mirrorId = ScalarIdForMetric(mId);
if (mirrorId) {

Просмотреть файл

@ -7,12 +7,12 @@
#ifndef mozilla_glean_Labeled_h
#define mozilla_glean_Labeled_h
#include "nsIGleanMetrics.h"
#include "nsISupports.h"
#include "nsWrapperCache.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/glean/bindings/Boolean.h"
#include "mozilla/glean/bindings/Counter.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "mozilla/glean/bindings/ScalarGIFFTMap.h"
#include "mozilla/glean/bindings/String.h"
#include "mozilla/glean/fog_ffi_generated.h"
@ -231,19 +231,15 @@ class Labeled<StringMetric, DynamicLabel> {
} // namespace impl
class GleanLabeled final : public nsISupports, public nsWrapperCache {
class GleanLabeled final : public GleanMetric {
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(GleanLabeled)
explicit GleanLabeled(uint32_t aId, uint32_t aTypeId, nsISupports* aParent)
: GleanMetric(aParent), mId(aId), mTypeId(aTypeId) {}
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
nsISupports* GetParentObject() { return nullptr; }
JS::Handle<JSObject*> aGivenProto) override final;
explicit GleanLabeled(uint32_t aId, uint32_t aTypeId)
: mId(aId), mTypeId(aTypeId){};
already_AddRefed<nsISupports> NamedGetter(const nsAString& aName,
already_AddRefed<GleanMetric> NamedGetter(const nsAString& aName,
bool& aFound);
bool NameIsEnumerable(const nsAString& aName);
void GetSupportedNames(nsTArray<nsString>& aNames);

Просмотреть файл

@ -9,6 +9,7 @@
#include "mozilla/Components.h"
#include "mozilla/Maybe.h"
#include "mozilla/ResultVariant.h"
#include "mozilla/dom/GleanMetricsBinding.h"
#include "mozilla/glean/bindings/HistogramGIFFTMap.h"
#include "mozilla/glean/fog_ffi_generated.h"
#include "nsIClassInfoImpl.h"
@ -50,57 +51,39 @@ MemoryDistributionMetric::TestGetValue(const nsACString& aPingName) const {
} // namespace impl
NS_IMPL_CLASSINFO(GleanMemoryDistribution, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(GleanMemoryDistribution, nsIGleanMemoryDistribution)
NS_IMETHODIMP
GleanMemoryDistribution::Accumulate(uint64_t aSample) {
mMemoryDist.Accumulate(aSample);
return NS_OK;
/* virtual */
JSObject* GleanMemoryDistribution::WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
return dom::GleanMemoryDistribution_Binding::Wrap(aCx, this, aGivenProto);
}
NS_IMETHODIMP
GleanMemoryDistribution::TestGetValue(const nsACString& aPingName,
JSContext* aCx,
JS::MutableHandle<JS::Value> aResult) {
void GleanMemoryDistribution::Accumulate(uint64_t aSample) {
mMemoryDist.Accumulate(aSample);
}
void GleanMemoryDistribution::TestGetValue(
const nsACString& aPingName,
dom::Nullable<dom::GleanDistributionData>& aRetval, ErrorResult& aRv) {
auto result = mMemoryDist.TestGetValue(aPingName);
if (result.isErr()) {
aResult.set(JS::UndefinedValue());
return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
aRv.ThrowDataError(result.unwrapErr());
return;
}
auto optresult = result.unwrap();
if (optresult.isNothing()) {
aResult.set(JS::UndefinedValue());
} else {
// Build return value of the form:
// { sum: #, values: {bucket1: count1, ...} }
JS::Rooted<JSObject*> root(aCx, JS_NewPlainObject(aCx));
if (!root) {
return NS_ERROR_FAILURE;
}
uint64_t sum = optresult.ref().sum;
if (!JS_DefineProperty(aCx, root, "sum", static_cast<double>(sum),
JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
JS::Rooted<JSObject*> valuesObj(aCx, JS_NewPlainObject(aCx));
if (!valuesObj ||
!JS_DefineProperty(aCx, root, "values", valuesObj, JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
auto& data = optresult.ref().values;
for (const auto& entry : data) {
const uint64_t bucket = entry.GetKey();
const uint64_t count = entry.GetData();
if (!JS_DefineProperty(aCx, valuesObj,
nsPrintfCString("%" PRIu64, bucket).get(),
static_cast<double>(count), JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
}
aResult.setObject(*root);
return;
}
return NS_OK;
dom::GleanDistributionData ret;
ret.mSum = optresult.ref().sum;
auto& data = optresult.ref().values;
for (const auto& entry : data) {
dom::binding_detail::RecordEntry<nsCString, uint64_t> bucket;
bucket.mKey = nsPrintfCString("%" PRIu64, entry.GetKey());
bucket.mValue = entry.GetData();
ret.mValues.Entries().EmplaceBack(std::move(bucket));
}
aRetval.SetValue(std::move(ret));
}
} // namespace mozilla::glean

Просмотреть файл

@ -7,11 +7,16 @@
#ifndef mozilla_glean_GleanMemoryDistribution_h
#define mozilla_glean_GleanMemoryDistribution_h
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/glean/bindings/DistributionData.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "mozilla/Maybe.h"
#include "nsIGleanMetrics.h"
#include "nsTArray.h"
namespace mozilla::dom {
struct GleanDistributionData;
} // namespace mozilla::dom
namespace mozilla::glean {
namespace impl {
@ -56,12 +61,19 @@ class MemoryDistributionMetric {
};
} // namespace impl
class GleanMemoryDistribution final : public nsIGleanMemoryDistribution {
class GleanMemoryDistribution final : public GleanMetric {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGLEANMEMORYDISTRIBUTION
explicit GleanMemoryDistribution(uint64_t aId, nsISupports* aParent)
: GleanMetric(aParent), mMemoryDist(aId) {}
explicit GleanMemoryDistribution(uint64_t aId) : mMemoryDist(aId){};
virtual JSObject* WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
void Accumulate(uint64_t aSample);
void TestGetValue(const nsACString& aPingName,
dom::Nullable<dom::GleanDistributionData>& aRetval,
ErrorResult& aRv);
private:
virtual ~GleanMemoryDistribution() = default;

Просмотреть файл

@ -7,13 +7,10 @@
#include "mozilla/glean/bindings/Numerator.h"
#include "nsString.h"
#include "mozilla/Components.h"
#include "mozilla/ResultVariant.h"
#include "mozilla/dom/GleanMetricsBinding.h"
#include "mozilla/glean/bindings/ScalarGIFFTMap.h"
#include "mozilla/glean/fog_ffi_generated.h"
#include "nsIClassInfoImpl.h"
#include "nsIScriptError.h"
#include "Common.h"
#include "jsapi.h"
namespace mozilla::glean {
@ -45,48 +42,32 @@ NumeratorMetric::TestGetValue(const nsACString& aPingName) const {
} // namespace impl
NS_IMPL_CLASSINFO(GleanNumerator, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(GleanNumerator, nsIGleanNumerator)
NS_IMETHODIMP
GleanNumerator::AddToNumerator(int32_t aAmount) {
mNumerator.AddToNumerator(aAmount);
return NS_OK;
/* virtual */
JSObject* GleanNumerator::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return dom::GleanNumerator_Binding::Wrap(aCx, this, aGivenProto);
}
NS_IMETHODIMP
GleanNumerator::TestGetValue(const nsACString& aPingName, JSContext* aCx,
JS::MutableHandle<JS::Value> aResult) {
void GleanNumerator::AddToNumerator(int32_t aAmount) {
mNumerator.AddToNumerator(aAmount);
}
void GleanNumerator::TestGetValue(const nsACString& aPingName,
dom::Nullable<dom::GleanRateData>& aResult,
ErrorResult& aRv) {
auto result = mNumerator.TestGetValue(aPingName);
if (result.isErr()) {
aResult.set(JS::UndefinedValue());
LogToBrowserConsole(nsIScriptError::errorFlag,
NS_ConvertUTF8toUTF16(result.unwrapErr()));
return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
aRv.ThrowDataError(result.unwrapErr());
return;
}
auto optresult = result.unwrap();
if (optresult.isNothing()) {
aResult.set(JS::UndefinedValue());
} else {
// Build return value of the form: { numerator: n, denominator: d }
JS::Rooted<JSObject*> root(aCx, JS_NewPlainObject(aCx));
if (!root) {
return NS_ERROR_FAILURE;
}
if (!optresult.isNothing()) {
dom::GleanRateData ret;
auto pair = optresult.extract();
int32_t num = pair.first;
int32_t den = pair.second;
if (!JS_DefineProperty(aCx, root, "numerator", static_cast<double>(num),
JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
if (!JS_DefineProperty(aCx, root, "denominator", static_cast<double>(den),
JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
aResult.setObject(*root);
ret.mNumerator = pair.first;
ret.mDenominator = pair.second;
aResult.SetValue(std::move(ret));
}
return NS_OK;
}
} // namespace mozilla::glean

Просмотреть файл

@ -7,11 +7,16 @@
#ifndef mozilla_glean_GleanNumerator_h
#define mozilla_glean_GleanNumerator_h
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "mozilla/Maybe.h"
#include "mozilla/Result.h"
#include "nsIGleanMetrics.h"
#include "nsString.h"
namespace mozilla::dom {
struct GleanRateData;
} // namespace mozilla::dom
namespace mozilla::glean {
namespace impl {
@ -54,12 +59,19 @@ class NumeratorMetric {
};
} // namespace impl
class GleanNumerator final : public nsIGleanNumerator {
class GleanNumerator final : public GleanMetric {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGLEANNUMERATOR
explicit GleanNumerator(uint32_t id, nsISupports* aParent)
: GleanMetric(aParent), mNumerator(id) {}
explicit GleanNumerator(uint32_t id) : mNumerator(id){};
virtual JSObject* WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
void AddToNumerator(int32_t aAmount);
void TestGetValue(const nsACString& aPingName,
dom::Nullable<dom::GleanRateData>& aResult,
ErrorResult& aRv);
private:
virtual ~GleanNumerator() = default;

Просмотреть файл

@ -10,7 +10,7 @@
#include "mozilla/DataMutex.h"
#include "mozilla/glean/fog_ffi_generated.h"
#include "mozilla/Maybe.h"
#include "nsIGleanMetrics.h"
#include "nsIGleanPing.h"
#include "nsString.h"
namespace mozilla::glean {

Просмотреть файл

@ -6,13 +6,11 @@
#include "mozilla/glean/bindings/Quantity.h"
#include "mozilla/Components.h"
#include "mozilla/ResultVariant.h"
#include "mozilla/dom/GleanMetricsBinding.h"
#include "mozilla/glean/bindings/ScalarGIFFTMap.h"
#include "mozilla/glean/fog_ffi_generated.h"
#include "nsIClassInfoImpl.h"
#include "nsString.h"
#include "Common.h"
namespace mozilla::glean {
@ -44,32 +42,27 @@ Result<Maybe<int64_t>, nsCString> QuantityMetric::TestGetValue(
} // namespace impl
NS_IMPL_CLASSINFO(GleanQuantity, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(GleanQuantity, nsIGleanQuantity)
NS_IMETHODIMP
GleanQuantity::Set(int64_t aValue) {
mQuantity.Set(aValue);
return NS_OK;
/* virtual */
JSObject* GleanQuantity::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return dom::GleanQuantity_Binding::Wrap(aCx, this, aGivenProto);
}
NS_IMETHODIMP
GleanQuantity::TestGetValue(const nsACString& aPingName,
JS::MutableHandle<JS::Value> aResult) {
void GleanQuantity::Set(int64_t aValue) { mQuantity.Set(aValue); }
dom::Nullable<int64_t> GleanQuantity::TestGetValue(const nsACString& aPingName,
ErrorResult& aRv) {
dom::Nullable<int64_t> ret;
auto result = mQuantity.TestGetValue(aPingName);
if (result.isErr()) {
aResult.set(JS::UndefinedValue());
LogToBrowserConsole(nsIScriptError::errorFlag,
NS_ConvertUTF8toUTF16(result.unwrapErr()));
return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
aRv.ThrowDataError(result.unwrapErr());
return ret;
}
auto optresult = result.unwrap();
if (optresult.isNothing()) {
aResult.set(JS::UndefinedValue());
} else {
aResult.set(JS::DoubleValue(static_cast<double>(optresult.value())));
if (!optresult.isNothing()) {
ret.SetValue(optresult.value());
}
return NS_OK;
return ret;
}
} // namespace mozilla::glean

Просмотреть файл

@ -7,7 +7,8 @@
#ifndef mozilla_glean_GleanQuantity_h
#define mozilla_glean_GleanQuantity_h
#include "nsIGleanMetrics.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "nsTString.h"
#include "nsIScriptError.h"
@ -52,12 +53,18 @@ class QuantityMetric {
} // namespace impl
class GleanQuantity final : public nsIGleanQuantity {
class GleanQuantity final : public GleanMetric {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGLEANQUANTITY
explicit GleanQuantity(uint32_t id, nsISupports* aParent)
: GleanMetric(aParent), mQuantity(id) {}
explicit GleanQuantity(uint32_t id) : mQuantity(id){};
virtual JSObject* WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
void Set(int64_t aValue);
dom::Nullable<int64_t> TestGetValue(const nsACString& aPingName,
ErrorResult& aRv);
private:
virtual ~GleanQuantity() = default;

Просмотреть файл

@ -8,12 +8,11 @@
#include "jsapi.h"
#include "nsString.h"
#include "mozilla/Components.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/ResultVariant.h"
#include "mozilla/glean/bindings/Common.h"
#include "mozilla/dom/GleanMetricsBinding.h"
#include "mozilla/glean/bindings/ScalarGIFFTMap.h"
#include "mozilla/glean/fog_ffi_generated.h"
#include "nsIClassInfoImpl.h"
namespace mozilla::glean {
@ -52,54 +51,36 @@ Result<Maybe<std::pair<int32_t, int32_t>>, nsCString> RateMetric::TestGetValue(
} // namespace impl
NS_IMPL_CLASSINFO(GleanRate, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(GleanRate, nsIGleanRate)
/* virtual */
JSObject* GleanRate::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return dom::GleanRate_Binding::Wrap(aCx, this, aGivenProto);
}
NS_IMETHODIMP
GleanRate::AddToNumerator(int32_t aAmount) {
void GleanRate::AddToNumerator(int32_t aAmount) {
mRate.AddToNumerator(aAmount);
return NS_OK;
}
NS_IMETHODIMP
GleanRate::AddToDenominator(int32_t aAmount) {
void GleanRate::AddToDenominator(int32_t aAmount) {
mRate.AddToDenominator(aAmount);
return NS_OK;
}
NS_IMETHODIMP
GleanRate::TestGetValue(const nsACString& aPingName, JSContext* aCx,
JS::MutableHandle<JS::Value> aResult) {
void GleanRate::TestGetValue(const nsACString& aPingName,
dom::Nullable<dom::GleanRateData>& aResult,
ErrorResult& aRv) {
auto result = mRate.TestGetValue(aPingName);
if (result.isErr()) {
aResult.set(JS::UndefinedValue());
LogToBrowserConsole(nsIScriptError::errorFlag,
NS_ConvertUTF8toUTF16(result.unwrapErr()));
return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
aRv.ThrowDataError(result.unwrapErr());
return;
}
auto optresult = result.unwrap();
if (optresult.isNothing()) {
aResult.set(JS::UndefinedValue());
} else {
// Build return value of the form: { numerator: n, denominator: d }
JS::Rooted<JSObject*> root(aCx, JS_NewPlainObject(aCx));
if (!root) {
return NS_ERROR_FAILURE;
}
if (!optresult.isNothing()) {
dom::GleanRateData ret;
auto pair = optresult.extract();
int32_t num = pair.first;
int32_t den = pair.second;
if (!JS_DefineProperty(aCx, root, "numerator", static_cast<double>(num),
JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
if (!JS_DefineProperty(aCx, root, "denominator", static_cast<double>(den),
JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
aResult.setObject(*root);
ret.mNumerator = pair.first;
ret.mDenominator = pair.second;
aResult.SetValue(std::move(ret));
}
return NS_OK;
}
} // namespace mozilla::glean

Просмотреть файл

@ -7,11 +7,16 @@
#ifndef mozilla_glean_GleanRate_h
#define mozilla_glean_GleanRate_h
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "mozilla/Maybe.h"
#include "mozilla/Result.h"
#include "nsIGleanMetrics.h"
#include "nsString.h"
namespace mozilla::dom {
struct GleanRateData;
} // namespace mozilla::dom
namespace mozilla::glean {
namespace impl {
@ -59,12 +64,20 @@ class RateMetric {
};
} // namespace impl
class GleanRate final : public nsIGleanRate {
class GleanRate final : public GleanMetric {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGLEANRATE
explicit GleanRate(uint32_t id, nsISupports* aParent)
: GleanMetric(aParent), mRate(id) {}
explicit GleanRate(uint32_t id) : mRate(id){};
virtual JSObject* WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
void AddToNumerator(int32_t aAmount);
void AddToDenominator(int32_t aAmount);
void TestGetValue(const nsACString& aPingName,
dom::Nullable<dom::GleanRateData>& aResult,
ErrorResult& aRv);
private:
virtual ~GleanRate() = default;

Просмотреть файл

@ -6,15 +6,14 @@
#include "mozilla/glean/bindings/String.h"
#include "Common.h"
#include "jsapi.h"
#include "js/String.h"
#include "nsString.h"
#include "mozilla/Components.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/ResultVariant.h"
#include "mozilla/dom/GleanMetricsBinding.h"
#include "mozilla/glean/bindings/ScalarGIFFTMap.h"
#include "mozilla/glean/fog_ffi_generated.h"
#include "nsIClassInfoImpl.h"
namespace mozilla::glean {
@ -44,34 +43,33 @@ Result<Maybe<nsCString>, nsCString> StringMetric::TestGetValue(
} // namespace impl
NS_IMPL_CLASSINFO(GleanString, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(GleanString, nsIGleanString)
NS_IMETHODIMP
GleanString::Set(const nsACString& aValue) {
mString.Set(aValue);
return NS_OK;
/* virtual */
JSObject* GleanString::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return dom::GleanString_Binding::Wrap(aCx, this, aGivenProto);
}
NS_IMETHODIMP
GleanString::TestGetValue(const nsACString& aStorageName, JSContext* aCx,
JS::MutableHandle<JS::Value> aResult) {
auto result = mString.TestGetValue(aStorageName);
void GleanString::Set(const nsACString& aValue) {
if (aValue.IsVoid()) {
// TODO: Instrument this error (bug 1691073)
return;
}
mString.Set(aValue);
}
void GleanString::TestGetValue(const nsACString& aPingName, nsCString& aResult,
ErrorResult& aRv) {
auto result = mString.TestGetValue(aPingName);
if (result.isErr()) {
aResult.set(JS::UndefinedValue());
LogToBrowserConsole(nsIScriptError::errorFlag,
NS_ConvertUTF8toUTF16(result.unwrapErr()));
return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
aRv.ThrowDataError(result.unwrapErr());
return;
}
auto optresult = result.unwrap();
if (optresult.isNothing()) {
aResult.set(JS::UndefinedValue());
if (!optresult.isNothing()) {
aResult.Assign(optresult.extract());
} else {
const NS_ConvertUTF8toUTF16 str(optresult.ref());
aResult.set(
JS::StringValue(JS_NewUCStringCopyN(aCx, str.Data(), str.Length())));
aResult.SetIsVoid(true);
}
return NS_OK;
}
} // namespace mozilla::glean

Просмотреть файл

@ -7,9 +7,10 @@
#ifndef mozilla_glean_GleanString_h
#define mozilla_glean_GleanString_h
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "mozilla/Maybe.h"
#include "mozilla/Result.h"
#include "nsIGleanMetrics.h"
#include "nsString.h"
namespace mozilla::glean {
@ -55,16 +56,22 @@ class StringMetric {
};
} // namespace impl
class GleanString final : public nsIGleanString {
class GleanString final : public GleanMetric {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGLEANSTRING
explicit GleanString(uint32_t aId, nsISupports* aParent)
: GleanMetric(aParent), mString(aId) {}
explicit GleanString(uint32_t aId) : mString(aId){};
virtual JSObject* WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
void Set(const nsACString& aValue);
void TestGetValue(const nsACString& aPingName, nsCString& aResult,
ErrorResult& aRv);
private:
virtual ~GleanString() = default;
private:
const impl::StringMetric mString;
};

Просмотреть файл

@ -6,13 +6,11 @@
#include "mozilla/glean/bindings/StringList.h"
#include "Common.h"
#include "mozilla/Components.h"
#include "mozilla/ResultVariant.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/GleanMetricsBinding.h"
#include "mozilla/glean/bindings/ScalarGIFFTMap.h"
#include "mozilla/glean/fog_ffi_generated.h"
#include "nsIClassInfoImpl.h"
#include "nsString.h"
#include "nsTArray.h"
@ -53,40 +51,30 @@ Result<Maybe<nsTArray<nsCString>>, nsCString> StringListMetric::TestGetValue(
} // namespace impl
NS_IMPL_CLASSINFO(GleanStringList, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(GleanStringList, nsIGleanStringList)
NS_IMETHODIMP
GleanStringList::Add(const nsACString& aValue) {
mStringList.Add(aValue);
return NS_OK;
/* virtual */
JSObject* GleanStringList::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return dom::GleanStringList_Binding::Wrap(aCx, this, aGivenProto);
}
NS_IMETHODIMP
GleanStringList::Set(const nsTArray<nsCString>& aValue) {
void GleanStringList::Add(const nsACString& aValue) { mStringList.Add(aValue); }
void GleanStringList::Set(const dom::Sequence<nsCString>& aValue) {
mStringList.Set(aValue);
return NS_OK;
}
NS_IMETHODIMP
GleanStringList::TestGetValue(const nsACString& aStorageName, JSContext* aCx,
JS::MutableHandle<JS::Value> aResult) {
auto result = mStringList.TestGetValue(aStorageName);
void GleanStringList::TestGetValue(const nsACString& aPingName,
dom::Nullable<nsTArray<nsCString>>& aResult,
ErrorResult& aRv) {
auto result = mStringList.TestGetValue(aPingName);
if (result.isErr()) {
aResult.set(JS::UndefinedValue());
LogToBrowserConsole(nsIScriptError::errorFlag,
NS_ConvertUTF8toUTF16(result.unwrapErr()));
return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
aRv.ThrowDataError(result.unwrapErr());
return;
}
auto optresult = result.unwrap();
if (optresult.isNothing()) {
aResult.set(JS::UndefinedValue());
} else {
if (!dom::ToJSValue(aCx, optresult.ref(), aResult)) {
return NS_ERROR_FAILURE;
}
if (!optresult.isNothing()) {
aResult.SetValue(optresult.extract());
}
return NS_OK;
}
} // namespace mozilla::glean

Просмотреть файл

@ -8,7 +8,8 @@
#define mozilla_glean_GleanStringList_h
#include "mozilla/Maybe.h"
#include "nsIGleanMetrics.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "nsString.h"
#include "nsTArray.h"
@ -66,12 +67,20 @@ class StringListMetric {
};
} // namespace impl
class GleanStringList final : public nsIGleanStringList {
class GleanStringList final : public GleanMetric {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGLEANSTRINGLIST
explicit GleanStringList(uint32_t aId, nsISupports* aParent)
: GleanMetric(aParent), mStringList(aId) {}
explicit GleanStringList(uint32_t aId) : mStringList(aId){};
virtual JSObject* WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
void Add(const nsACString& aValue);
void Set(const dom::Sequence<nsCString>& aValue);
void TestGetValue(const nsACString& aPingName,
dom::Nullable<nsTArray<nsCString>>& aResult,
ErrorResult& aRv);
private:
virtual ~GleanStringList() = default;

Просмотреть файл

@ -6,15 +6,13 @@
#include "mozilla/glean/bindings/Text.h"
#include "Common.h"
#include "jsapi.h"
#include "js/String.h"
#include "nsString.h"
#include "mozilla/Components.h"
#include "mozilla/ResultVariant.h"
#include "mozilla/dom/GleanMetricsBinding.h"
#include "mozilla/glean/bindings/ScalarGIFFTMap.h"
#include "mozilla/glean/fog_ffi_generated.h"
#include "nsIClassInfoImpl.h"
namespace mozilla::glean {
@ -40,33 +38,27 @@ Result<Maybe<nsCString>, nsCString> TextMetric::TestGetValue(
} // namespace impl
NS_IMPL_CLASSINFO(GleanText, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(GleanText, nsIGleanText)
NS_IMETHODIMP
GleanText::Set(const nsACString& aValue) {
mText.Set(aValue);
return NS_OK;
/* virtual */
JSObject* GleanText::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return dom::GleanText_Binding::Wrap(aCx, this, aGivenProto);
}
NS_IMETHODIMP
GleanText::TestGetValue(const nsACString& aStorageName, JSContext* aCx,
JS::MutableHandle<JS::Value> aResult) {
auto result = mText.TestGetValue(aStorageName);
void GleanText::Set(const nsACString& aValue) { mText.Set(aValue); }
void GleanText::TestGetValue(const nsACString& aPingName, nsCString& aResult,
ErrorResult& aRv) {
auto result = mText.TestGetValue(aPingName);
if (result.isErr()) {
aResult.set(JS::UndefinedValue());
LogToBrowserConsole(nsIScriptError::errorFlag,
NS_ConvertUTF8toUTF16(result.unwrapErr()));
return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
aRv.ThrowDataError(result.unwrapErr());
return;
}
auto optresult = result.unwrap();
if (optresult.isNothing()) {
aResult.set(JS::UndefinedValue());
if (!optresult.isNothing()) {
aResult.Assign(optresult.extract());
} else {
const NS_ConvertUTF8toUTF16 str(optresult.ref());
aResult.set(
JS::StringValue(JS_NewUCStringCopyN(aCx, str.Data(), str.Length())));
aResult.SetIsVoid(true);
}
return NS_OK;
}
} // namespace mozilla::glean

Просмотреть файл

@ -7,9 +7,10 @@
#ifndef mozilla_glean_GleanText_h
#define mozilla_glean_GleanText_h
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "mozilla/Maybe.h"
#include "mozilla/Result.h"
#include "nsIGleanMetrics.h"
#include "nsString.h"
namespace mozilla::glean {
@ -31,12 +32,18 @@ class TextMetric {
} // namespace impl
class GleanText final : public nsIGleanText {
class GleanText final : public GleanMetric {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGLEANTEXT
explicit GleanText(uint32_t aId, nsISupports* aParent)
: GleanMetric(aParent), mText(aId) {}
explicit GleanText(uint32_t aId) : mText(aId){};
virtual JSObject* WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
void Set(const nsACString& aValue);
void TestGetValue(const nsACString& aPingName, nsCString& aResult,
ErrorResult& aRv);
private:
virtual ~GleanText() = default;

Просмотреть файл

@ -6,13 +6,12 @@
#include "mozilla/glean/bindings/Timespan.h"
#include "Common.h"
#include "nsString.h"
#include "mozilla/Components.h"
#include "mozilla/ResultVariant.h"
#include "mozilla/dom/GleanMetricsBinding.h"
#include "mozilla/glean/bindings/ScalarGIFFTMap.h"
#include "mozilla/glean/fog_ffi_generated.h"
#include "nsIClassInfoImpl.h"
namespace mozilla::glean {
@ -84,50 +83,33 @@ Result<Maybe<uint64_t>, nsCString> TimespanMetric::TestGetValue(
} // namespace impl
NS_IMPL_CLASSINFO(GleanTimespan, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(GleanTimespan, nsIGleanTimespan)
NS_IMETHODIMP
GleanTimespan::Start() {
mTimespan.Start();
return NS_OK;
/* virtual */
JSObject* GleanTimespan::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return dom::GleanTimespan_Binding::Wrap(aCx, this, aGivenProto);
}
NS_IMETHODIMP
GleanTimespan::Stop() {
mTimespan.Stop();
return NS_OK;
}
void GleanTimespan::Start() { mTimespan.Start(); }
NS_IMETHODIMP
GleanTimespan::Cancel() {
mTimespan.Cancel();
return NS_OK;
}
void GleanTimespan::Stop() { mTimespan.Stop(); }
NS_IMETHODIMP
GleanTimespan::SetRaw(uint32_t aDuration) {
mTimespan.SetRaw(aDuration);
return NS_OK;
}
void GleanTimespan::Cancel() { mTimespan.Cancel(); }
NS_IMETHODIMP
GleanTimespan::TestGetValue(const nsACString& aStorageName,
JS::MutableHandle<JS::Value> aResult) {
auto result = mTimespan.TestGetValue(aStorageName);
void GleanTimespan::SetRaw(uint32_t aDuration) { mTimespan.SetRaw(aDuration); }
dom::Nullable<uint64_t> GleanTimespan::TestGetValue(const nsACString& aPingName,
ErrorResult& aRv) {
dom::Nullable<uint64_t> ret;
auto result = mTimespan.TestGetValue(aPingName);
if (result.isErr()) {
aResult.set(JS::UndefinedValue());
LogToBrowserConsole(nsIScriptError::errorFlag,
NS_ConvertUTF8toUTF16(result.unwrapErr()));
return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
aRv.ThrowDataError(result.unwrapErr());
return ret;
}
auto optresult = result.unwrap();
if (optresult.isNothing()) {
aResult.set(JS::UndefinedValue());
} else {
aResult.set(JS::DoubleValue(static_cast<double>(optresult.value())));
if (!optresult.isNothing()) {
ret.SetValue(optresult.value());
}
return NS_OK;
return ret;
}
} // namespace mozilla::glean

Просмотреть файл

@ -9,7 +9,8 @@
#include "mozilla/Maybe.h"
#include "mozilla/Result.h"
#include "nsIGleanMetrics.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "nsTString.h"
namespace mozilla::glean {
@ -82,12 +83,21 @@ class TimespanMetric {
};
} // namespace impl
class GleanTimespan final : public nsIGleanTimespan {
class GleanTimespan final : public GleanMetric {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGLEANTIMESPAN
explicit GleanTimespan(uint32_t aId, nsISupports* aParent)
: GleanMetric(aParent), mTimespan(aId) {}
explicit GleanTimespan(uint32_t aId) : mTimespan(aId){};
virtual JSObject* WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
void Start();
void Stop();
void Cancel();
void SetRaw(uint32_t aDuration);
dom::Nullable<uint64_t> TestGetValue(const nsACString& aPingName,
ErrorResult& aRv);
private:
virtual ~GleanTimespan() = default;

Просмотреть файл

@ -6,14 +6,11 @@
#include "mozilla/glean/bindings/TimingDistribution.h"
#include "Common.h"
#include "mozilla/Components.h"
#include "mozilla/ResultVariant.h"
#include "mozilla/dom/GleanMetricsBinding.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/glean/bindings/HistogramGIFFTMap.h"
#include "mozilla/glean/fog_ffi_generated.h"
#include "nsIClassInfoImpl.h"
#include "nsJSUtils.h"
#include "nsPrintfCString.h"
#include "nsString.h"
@ -116,80 +113,49 @@ TimingDistributionMetric::TestGetValue(const nsACString& aPingName) const {
} // namespace impl
NS_IMPL_CLASSINFO(GleanTimingDistribution, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(GleanTimingDistribution, nsIGleanTimingDistribution)
NS_IMETHODIMP
GleanTimingDistribution::Start(JSContext* aCx,
JS::MutableHandle<JS::Value> aResult) {
if (!dom::ToJSValue(aCx, mTimingDist.Start(), aResult)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
/* virtual */
JSObject* GleanTimingDistribution::WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
return dom::GleanTimingDistribution_Binding::Wrap(aCx, this, aGivenProto);
}
NS_IMETHODIMP
GleanTimingDistribution::StopAndAccumulate(uint64_t aId) {
uint64_t GleanTimingDistribution::Start() { return mTimingDist.Start(); }
void GleanTimingDistribution::StopAndAccumulate(uint64_t aId) {
mTimingDist.StopAndAccumulate(std::move(aId));
return NS_OK;
}
NS_IMETHODIMP
GleanTimingDistribution::Cancel(uint64_t aId) {
void GleanTimingDistribution::Cancel(uint64_t aId) {
mTimingDist.Cancel(std::move(aId));
return NS_OK;
}
NS_IMETHODIMP
GleanTimingDistribution::TestGetValue(const nsACString& aPingName,
JSContext* aCx,
JS::MutableHandle<JS::Value> aResult) {
void GleanTimingDistribution::TestGetValue(
const nsACString& aPingName,
dom::Nullable<dom::GleanDistributionData>& aRetval, ErrorResult& aRv) {
auto result = mTimingDist.TestGetValue(aPingName);
if (result.isErr()) {
aResult.set(JS::UndefinedValue());
LogToBrowserConsole(nsIScriptError::errorFlag,
NS_ConvertUTF8toUTF16(result.unwrapErr()));
return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
aRv.ThrowDataError(result.unwrapErr());
return;
}
auto optresult = result.unwrap();
if (optresult.isNothing()) {
aResult.set(JS::UndefinedValue());
} else {
// Build return value of the form: { sum: #, values: {bucket1: count1,
// ...}
JS::Rooted<JSObject*> root(aCx, JS_NewPlainObject(aCx));
if (!root) {
return NS_ERROR_FAILURE;
}
uint64_t sum = optresult.ref().sum;
if (!JS_DefineProperty(aCx, root, "sum", static_cast<double>(sum),
JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
JS::Rooted<JSObject*> valuesObj(aCx, JS_NewPlainObject(aCx));
if (!valuesObj ||
!JS_DefineProperty(aCx, root, "values", valuesObj, JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
auto& data = optresult.ref().values;
for (const auto& entry : data) {
const uint64_t bucket = entry.GetKey();
const uint64_t count = entry.GetData();
if (!JS_DefineProperty(aCx, valuesObj,
nsPrintfCString("%" PRIu64, bucket).get(),
static_cast<double>(count), JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
}
aResult.setObject(*root);
return;
}
return NS_OK;
dom::GleanDistributionData ret;
ret.mSum = optresult.ref().sum;
auto& data = optresult.ref().values;
for (const auto& entry : data) {
dom::binding_detail::RecordEntry<nsCString, uint64_t> bucket;
bucket.mKey = nsPrintfCString("%" PRIu64, entry.GetKey());
bucket.mValue = entry.GetData();
ret.mValues.Entries().EmplaceBack(std::move(bucket));
}
aRetval.SetValue(std::move(ret));
}
NS_IMETHODIMP
GleanTimingDistribution::TestAccumulateRawMillis(uint64_t aSample) {
void GleanTimingDistribution::TestAccumulateRawMillis(uint64_t aSample) {
mTimingDist.AccumulateRawDuration(TimeDuration::FromMilliseconds(aSample));
return NS_OK;
}
} // namespace mozilla::glean

Просмотреть файл

@ -7,13 +7,18 @@
#ifndef mozilla_glean_GleanTimingDistribution_h
#define mozilla_glean_GleanTimingDistribution_h
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/glean/bindings/DistributionData.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "mozilla/Maybe.h"
#include "mozilla/Result.h"
#include "mozilla/TimeStamp.h"
#include "nsIGleanMetrics.h"
#include "nsTArray.h"
namespace mozilla::dom {
struct GleanDistributionData;
} // namespace mozilla::dom
namespace mozilla::glean {
typedef uint64_t TimerId;
@ -91,12 +96,23 @@ class TimingDistributionMetric {
};
} // namespace impl
class GleanTimingDistribution final : public nsIGleanTimingDistribution {
class GleanTimingDistribution final : public GleanMetric {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGLEANTIMINGDISTRIBUTION
explicit GleanTimingDistribution(uint64_t aId, nsISupports* aParent)
: GleanMetric(aParent), mTimingDist(aId) {}
explicit GleanTimingDistribution(uint64_t aId) : mTimingDist(aId){};
virtual JSObject* WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
uint64_t Start();
void StopAndAccumulate(uint64_t aId);
void Cancel(uint64_t aId);
void TestGetValue(const nsACString& aPingName,
dom::Nullable<dom::GleanDistributionData>& aRetval,
ErrorResult& aRv);
void TestAccumulateRawMillis(uint64_t aSample);
private:
virtual ~GleanTimingDistribution() = default;

Просмотреть файл

@ -6,15 +6,13 @@
#include "mozilla/glean/bindings/Url.h"
#include "Common.h"
#include "jsapi.h"
#include "js/String.h"
#include "nsString.h"
#include "mozilla/Components.h"
#include "mozilla/ResultVariant.h"
#include "mozilla/dom/GleanMetricsBinding.h"
#include "mozilla/glean/bindings/ScalarGIFFTMap.h"
#include "mozilla/glean/fog_ffi_generated.h"
#include "nsIClassInfoImpl.h"
namespace mozilla::glean {
@ -44,34 +42,27 @@ Result<Maybe<nsCString>, nsCString> UrlMetric::TestGetValue(
} // namespace impl
NS_IMPL_CLASSINFO(GleanUrl, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(GleanUrl, nsIGleanUrl)
NS_IMETHODIMP
GleanUrl::Set(const nsACString& aValue) {
mUrl.Set(aValue);
return NS_OK;
/* virtual */
JSObject* GleanUrl::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return dom::GleanUrl_Binding::Wrap(aCx, this, aGivenProto);
}
NS_IMETHODIMP
GleanUrl::TestGetValue(const nsACString& aStorageName, JSContext* aCx,
JS::MutableHandle<JS::Value> aResult) {
auto result = mUrl.TestGetValue(aStorageName);
void GleanUrl::Set(const nsACString& aValue) { mUrl.Set(aValue); }
void GleanUrl::TestGetValue(const nsACString& aPingName, nsCString& aResult,
ErrorResult& aRv) {
auto result = mUrl.TestGetValue(aPingName);
if (result.isErr()) {
aResult.set(JS::UndefinedValue());
LogToBrowserConsole(nsIScriptError::errorFlag,
NS_ConvertUTF8toUTF16(result.unwrapErr()));
return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
aRv.ThrowDataError(result.unwrapErr());
return;
}
auto optresult = result.unwrap();
if (optresult.isNothing()) {
aResult.set(JS::UndefinedValue());
if (!optresult.isNothing()) {
aResult.Assign(optresult.extract());
} else {
const NS_ConvertUTF8toUTF16 str(optresult.ref());
aResult.set(
JS::StringValue(JS_NewUCStringCopyN(aCx, str.Data(), str.Length())));
aResult.SetIsVoid(true);
}
return NS_OK;
}
} // namespace mozilla::glean

Просмотреть файл

@ -7,9 +7,10 @@
#ifndef mozilla_glean_GleanUrl_h
#define mozilla_glean_GleanUrl_h
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "mozilla/Maybe.h"
#include "mozilla/Result.h"
#include "nsIGleanMetrics.h"
#include "nsString.h"
namespace mozilla::glean {
@ -52,12 +53,18 @@ class UrlMetric {
};
} // namespace impl
class GleanUrl final : public nsIGleanUrl {
class GleanUrl final : public GleanMetric {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGLEANURL
explicit GleanUrl(uint32_t aId, nsISupports* aParent)
: GleanMetric(aParent), mUrl(aId) {}
explicit GleanUrl(uint32_t aId) : mUrl(aId){};
virtual JSObject* WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
void Set(const nsACString& aValue);
void TestGetValue(const nsACString& aPingName, nsCString& aResult,
ErrorResult& aRv);
private:
virtual ~GleanUrl() = default;

Просмотреть файл

@ -6,13 +6,11 @@
#include "mozilla/glean/bindings/Uuid.h"
#include "Common.h"
#include "jsapi.h"
#include "mozilla/Components.h"
#include "mozilla/ResultVariant.h"
#include "mozilla/dom/GleanMetricsBinding.h"
#include "mozilla/glean/bindings/ScalarGIFFTMap.h"
#include "mozilla/glean/fog_ffi_generated.h"
#include "nsIClassInfoImpl.h"
#include "nsString.h"
namespace mozilla::glean {
@ -50,40 +48,29 @@ Result<Maybe<nsCString>, nsCString> UuidMetric::TestGetValue(
} // namespace impl
NS_IMPL_CLASSINFO(GleanUuid, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(GleanUuid, nsIGleanUuid)
NS_IMETHODIMP
GleanUuid::Set(const nsACString& aValue) {
mUuid.Set(aValue);
return NS_OK;
/* virtual */
JSObject* GleanUuid::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return dom::GleanUuid_Binding::Wrap(aCx, this, aGivenProto);
}
NS_IMETHODIMP
GleanUuid::GenerateAndSet() {
mUuid.GenerateAndSet();
return NS_OK;
}
void GleanUuid::Set(const nsACString& aValue) { mUuid.Set(aValue); }
NS_IMETHODIMP
GleanUuid::TestGetValue(const nsACString& aStorageName, JSContext* aCx,
JS::MutableHandle<JS::Value> aResult) {
auto result = mUuid.TestGetValue(aStorageName);
void GleanUuid::GenerateAndSet() { mUuid.GenerateAndSet(); }
void GleanUuid::TestGetValue(const nsACString& aPingName, nsCString& aResult,
ErrorResult& aRv) {
auto result = mUuid.TestGetValue(aPingName);
if (result.isErr()) {
aResult.set(JS::UndefinedValue());
LogToBrowserConsole(nsIScriptError::errorFlag,
NS_ConvertUTF8toUTF16(result.unwrapErr()));
return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
aRv.ThrowDataError(result.unwrapErr());
return;
}
auto optresult = result.unwrap();
if (optresult.isNothing()) {
aResult.set(JS::UndefinedValue());
if (!optresult.isNothing()) {
aResult.Assign(optresult.extract());
} else {
const NS_ConvertUTF8toUTF16 str(optresult.value());
aResult.set(
JS::StringValue(JS_NewUCStringCopyN(aCx, str.Data(), str.Length())));
aResult.SetIsVoid(true);
}
return NS_OK;
}
} // namespace mozilla::glean

Просмотреть файл

@ -9,7 +9,8 @@
#include "mozilla/Maybe.h"
#include "mozilla/Result.h"
#include "nsIGleanMetrics.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "nsString.h"
namespace mozilla::glean {
@ -57,12 +58,19 @@ class UuidMetric {
};
} // namespace impl
class GleanUuid final : public nsIGleanUuid {
class GleanUuid final : public GleanMetric {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGLEANUUID
explicit GleanUuid(uint32_t aId, nsISupports* aParent)
: GleanMetric(aParent), mUuid(aId) {}
explicit GleanUuid(uint32_t aId) : mUuid(aId){};
virtual JSObject* WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
void Set(const nsACString& aValue);
void GenerateAndSet();
void TestGetValue(const nsACString& aPingName, nsCString& aResult,
ErrorResult& aRv);
private:
virtual ~GleanUuid() = default;

Просмотреть файл

@ -44,7 +44,7 @@ static_assert({{ categories|length }} < UINT32_MAX, "Too many metric categories
static_assert({{ metric_id_mapping|length }} < {{2 ** (id_bits - id_signal_bits)}}, "Too many metrics generated. Need room for {{id_signal_bits}} signal bits.");
static_assert({{ metric_type_ids|length }} < {{2 ** type_bits}}, "Too many different metric types.");
already_AddRefed<nsISupports> NewMetricFromId(uint32_t id) {
already_AddRefed<GleanMetric> NewMetricFromId(uint32_t id, nsISupports* aParent) {
uint32_t typeId = GLEAN_TYPE_ID(id);
uint32_t metricId = GLEAN_METRIC_ID(id);
@ -52,7 +52,7 @@ already_AddRefed<nsISupports> NewMetricFromId(uint32_t id) {
{% for (type_name, subtype_name), (type_id, original_type) in metric_type_ids.items() %}
case {{ type_id }}: /* {{ original_type }} */
{
return MakeAndAddRef<{{type_name}}>(metricId{% if subtype_name|length > 0 %}, {{ type_id }}{% endif %});
return MakeAndAddRef<{{type_name}}>(metricId{% if subtype_name|length > 0 %}, {{ type_id }}{% endif %}, aParent);
}
{% endfor %}
default:
@ -72,14 +72,19 @@ already_AddRefed<nsISupports> NewMetricFromId(uint32_t id) {
* @param aSubmetricId - an outparam which is assigned the submetric's SDK-generated submetric id.
* Used only by GIFFT.
*/
already_AddRefed<nsISupports> NewSubMetricFromIds(uint32_t aParentTypeId, uint32_t aParentMetricId, const nsACString& aLabel, uint32_t* aSubmetricId) {
already_AddRefed<GleanMetric> NewSubMetricFromIds(uint32_t aParentTypeId,
uint32_t aParentMetricId,
const nsACString& aLabel,
uint32_t* aSubmetricId,
nsISupports* aParent) {
switch (aParentTypeId) {
{% for (type_name, subtype_name), (type_id, original_type) in metric_type_ids.items() %}
{% if subtype_name|length > 0 %}
{# TODO: Remove the subtype inclusion clause when we suport the rest of labeled_* #}
{% if subtype_name|length > 0 and original_type in ['labeled_boolean', 'labeled_counter', 'labeled_string'] %}
case {{ type_id }}: { /* {{ original_type }} */
auto id = impl::fog_{{original_type}}_get(aParentMetricId, &aLabel);
*aSubmetricId = id;
return MakeAndAddRef<{{subtype_name}}>(id);
return MakeAndAddRef<{{subtype_name}}>(id, aParent);
}
{% endif %}
{% endfor %}

Просмотреть файл

@ -15,6 +15,7 @@ Jinja2 template is not. Please file bugs! #}
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/Maybe.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "nsStringFwd.h"
class nsISupports;
@ -34,7 +35,7 @@ using category_entry_t = uint32_t;
// characteristics (which hopefully will prove to be enough).
using metric_entry_t = uint64_t;
already_AddRefed<nsISupports> NewMetricFromId(uint32_t id);
already_AddRefed<GleanMetric> NewMetricFromId(uint32_t id, nsISupports* aParent);
/**
* Create a submetric instance for a labeled metric of the provided type and id for the given label.
@ -47,7 +48,7 @@ already_AddRefed<nsISupports> NewMetricFromId(uint32_t id);
* @param aSubmetricId - an outparam which is assigned the submetric's SDK-generated submetric id.
* Used only by GIFFT.
*/
already_AddRefed<nsISupports> NewSubMetricFromIds(uint32_t aParentTypeId, uint32_t aParentMetricId, const nsACString& aLabel, uint32_t* aSubmetricId);
already_AddRefed<GleanMetric> NewSubMetricFromIds(uint32_t aParentTypeId, uint32_t aParentMetricId, const nsACString& aLabel, uint32_t* aSubmetricId, nsISupports* aParent);
/**
* Get a category's name from the string table.

Просмотреть файл

@ -28,6 +28,7 @@ EXPORTS.mozilla.glean.bindings += [
"!ScalarGIFFTMap.h",
"bindings/Category.h",
"bindings/Glean.h",
"bindings/GleanMetric.h",
"bindings/GleanPings.h",
"bindings/MetricTypes.h",
"bindings/private/Boolean.h",
@ -74,6 +75,7 @@ if CONFIG["COMPILE_ENVIRONMENT"]:
UNIFIED_SOURCES += [
"bindings/Category.cpp",
"bindings/Glean.cpp",
"bindings/GleanMetric.cpp",
"bindings/GleanPings.cpp",
"bindings/jog/JOG.cpp",
"bindings/private/Boolean.cpp",

Просмотреть файл

@ -55,7 +55,7 @@ add_task(async () => {
Services.fog.testResetFOG();
is(
undefined,
null,
Glean.testOnlyIpc.aCounter.testGetValue(),
"Ensure we begin without value."
);

Просмотреть файл

@ -37,7 +37,7 @@ add_task(async () => {
Services.fog.testResetFOG();
is(
undefined,
null,
Glean.testOnlyIpc.aCounter.testGetValue(),
"Ensure we begin without value."
);

Просмотреть файл

@ -17,7 +17,7 @@ add_task(async () => {
Services.fog.testResetFOG();
is(
undefined,
null,
Glean.testOnlyIpc.aCounter.testGetValue(),
"Ensure we begin without value."
);

Просмотреть файл

@ -13,7 +13,7 @@ add_task(async () => {
Services.fog.testResetFOG();
is(
undefined,
null,
Glean.testOnlyIpc.aCounter.testGetValue(),
"Ensure we begin without value."
);

Просмотреть файл

@ -33,7 +33,7 @@ add_task(async () => {
Glean.testOnlyIpc.aLabeledCounter["1".repeat(72)].add(3);
Assert.throws(
() => Glean.testOnlyIpc.aLabeledCounter.__other__.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Can't get the value when you're error'd"
);

Просмотреть файл

@ -42,86 +42,86 @@ static_assert(2 < UINT32_MAX, "Too many metric categories generated.");
static_assert(23 < 33554432, "Too many metrics generated. Need room for 2 signal bits.");
static_assert(19 < 32, "Too many different metric types.");
already_AddRefed<nsISupports> NewMetricFromId(uint32_t id) {
already_AddRefed<GleanMetric> NewMetricFromId(uint32_t id, nsISupports* aParent) {
uint32_t typeId = GLEAN_TYPE_ID(id);
uint32_t metricId = GLEAN_METRIC_ID(id);
switch (typeId) {
case 1: /* boolean */
{
return MakeAndAddRef<GleanBoolean>(metricId);
return MakeAndAddRef<GleanBoolean>(metricId, aParent);
}
case 2: /* counter */
{
return MakeAndAddRef<GleanCounter>(metricId);
return MakeAndAddRef<GleanCounter>(metricId, aParent);
}
case 3: /* custom_distribution */
{
return MakeAndAddRef<GleanCustomDistribution>(metricId);
return MakeAndAddRef<GleanCustomDistribution>(metricId, aParent);
}
case 4: /* labeled_boolean */
{
return MakeAndAddRef<GleanLabeled>(metricId, 4);
return MakeAndAddRef<GleanLabeled>(metricId, 4, aParent);
}
case 5: /* labeled_counter */
{
return MakeAndAddRef<GleanLabeled>(metricId, 5);
return MakeAndAddRef<GleanLabeled>(metricId, 5, aParent);
}
case 6: /* labeled_string */
{
return MakeAndAddRef<GleanLabeled>(metricId, 6);
return MakeAndAddRef<GleanLabeled>(metricId, 6, aParent);
}
case 7: /* memory_distribution */
{
return MakeAndAddRef<GleanMemoryDistribution>(metricId);
return MakeAndAddRef<GleanMemoryDistribution>(metricId, aParent);
}
case 8: /* string_list */
{
return MakeAndAddRef<GleanStringList>(metricId);
return MakeAndAddRef<GleanStringList>(metricId, aParent);
}
case 9: /* string */
{
return MakeAndAddRef<GleanString>(metricId);
return MakeAndAddRef<GleanString>(metricId, aParent);
}
case 10: /* text */
{
return MakeAndAddRef<GleanText>(metricId);
return MakeAndAddRef<GleanText>(metricId, aParent);
}
case 11: /* timespan */
{
return MakeAndAddRef<GleanTimespan>(metricId);
return MakeAndAddRef<GleanTimespan>(metricId, aParent);
}
case 12: /* timing_distribution */
{
return MakeAndAddRef<GleanTimingDistribution>(metricId);
return MakeAndAddRef<GleanTimingDistribution>(metricId, aParent);
}
case 13: /* datetime */
{
return MakeAndAddRef<GleanDatetime>(metricId);
return MakeAndAddRef<GleanDatetime>(metricId, aParent);
}
case 14: /* event */
{
return MakeAndAddRef<GleanEvent>(metricId);
return MakeAndAddRef<GleanEvent>(metricId, aParent);
}
case 15: /* denominator */
{
return MakeAndAddRef<GleanDenominator>(metricId);
return MakeAndAddRef<GleanDenominator>(metricId, aParent);
}
case 16: /* quantity */
{
return MakeAndAddRef<GleanQuantity>(metricId);
return MakeAndAddRef<GleanQuantity>(metricId, aParent);
}
case 17: /* rate */
{
return MakeAndAddRef<GleanRate>(metricId);
return MakeAndAddRef<GleanRate>(metricId, aParent);
}
case 18: /* numerator */
{
return MakeAndAddRef<GleanNumerator>(metricId);
return MakeAndAddRef<GleanNumerator>(metricId, aParent);
}
case 19: /* uuid */
{
return MakeAndAddRef<GleanUuid>(metricId);
return MakeAndAddRef<GleanUuid>(metricId, aParent);
}
default:
MOZ_ASSERT_UNREACHABLE("Invalid type ID reached when trying to instantiate a new metric");
@ -140,22 +140,26 @@ already_AddRefed<nsISupports> NewMetricFromId(uint32_t id) {
* @param aSubmetricId - an outparam which is assigned the submetric's SDK-generated submetric id.
* Used only by GIFFT.
*/
already_AddRefed<nsISupports> NewSubMetricFromIds(uint32_t aParentTypeId, uint32_t aParentMetricId, const nsACString& aLabel, uint32_t* aSubmetricId) {
already_AddRefed<GleanMetric> NewSubMetricFromIds(uint32_t aParentTypeId,
uint32_t aParentMetricId,
const nsACString& aLabel,
uint32_t* aSubmetricId,
nsISupports* aParent) {
switch (aParentTypeId) {
case 4: { /* labeled_boolean */
auto id = impl::fog_labeled_boolean_get(aParentMetricId, &aLabel);
*aSubmetricId = id;
return MakeAndAddRef<GleanBoolean>(id);
return MakeAndAddRef<GleanBoolean>(id, aParent);
}
case 5: { /* labeled_counter */
auto id = impl::fog_labeled_counter_get(aParentMetricId, &aLabel);
*aSubmetricId = id;
return MakeAndAddRef<GleanCounter>(id);
return MakeAndAddRef<GleanCounter>(id, aParent);
}
case 6: { /* labeled_string */
auto id = impl::fog_labeled_string_get(aParentMetricId, &aLabel);
*aSubmetricId = id;
return MakeAndAddRef<GleanString>(id);
return MakeAndAddRef<GleanString>(id, aParent);
}
default: {
MOZ_ASSERT_UNREACHABLE("Invalid type ID for submetric.");

Просмотреть файл

@ -13,6 +13,7 @@
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/Maybe.h"
#include "mozilla/glean/bindings/GleanMetric.h"
#include "nsStringFwd.h"
class nsISupports;
@ -32,7 +33,7 @@ using category_entry_t = uint32_t;
// characteristics (which hopefully will prove to be enough).
using metric_entry_t = uint64_t;
already_AddRefed<nsISupports> NewMetricFromId(uint32_t id);
already_AddRefed<GleanMetric> NewMetricFromId(uint32_t id, nsISupports* aParent);
/**
* Create a submetric instance for a labeled metric of the provided type and id for the given label.
@ -45,7 +46,7 @@ already_AddRefed<nsISupports> NewMetricFromId(uint32_t id);
* @param aSubmetricId - an outparam which is assigned the submetric's SDK-generated submetric id.
* Used only by GIFFT.
*/
already_AddRefed<nsISupports> NewSubMetricFromIds(uint32_t aParentTypeId, uint32_t aParentMetricId, const nsACString& aLabel, uint32_t* aSubmetricId);
already_AddRefed<GleanMetric> NewSubMetricFromIds(uint32_t aParentTypeId, uint32_t aParentMetricId, const nsACString& aLabel, uint32_t* aSubmetricId, nsISupports* aParent);
/**
* Get a category's name from the string table.

Просмотреть файл

@ -117,7 +117,7 @@ add_task(function test_gifft_memory_dist() {
Glean.testOnlyIpc.aMemoryDist.accumulate(Math.pow(2, 31));
Assert.throws(
() => Glean.testOnlyIpc.aMemoryDist.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Did not accumulate correctly"
);
});
@ -278,7 +278,7 @@ add_task(function test_gifft_labeled_counter() {
Glean.testOnlyIpc.aLabeledCounter["1".repeat(72)].add(3);
Assert.throws(
() => Glean.testOnlyIpc.aLabeledCounter.__other__.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Can't get the value when you're error'd"
);
@ -345,7 +345,7 @@ add_task(async function test_gifft_labeled_boolean() {
Glean.testOnly.mirrorsForLabeledBools["1".repeat(72)].set(true);
Assert.throws(
() => Glean.testOnly.mirrorsForLabeledBools.__other__.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Should throw because of a recording error."
);
@ -397,7 +397,7 @@ add_task(function test_gifft_numeric_limits() {
// (chutten blames chutten for his shortsightedness)
Assert.throws(
() => Glean.testOnlyIpc.aCounter.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Can't get the value when you're error'd"
);
Assert.equal(undefined, scalarValue("telemetry.test.mirror_for_counter"));
@ -422,7 +422,7 @@ add_task(function test_gifft_numeric_limits() {
// Glean will error on this.
Assert.throws(
() => Glean.testOnly.meaningOfLife.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Can't get the value when you're error'd"
);
// GIFFT doesn't tell Telemetry about the weird value at all.
@ -445,7 +445,7 @@ add_task(function test_gifft_numeric_limits() {
Glean.testOnlyIpc.irate.addToDenominator(7);
Assert.throws(
() => Glean.testOnlyIpc.irate.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Can't get the value when you're error'd"
);
Assert.deepEqual(
@ -462,7 +462,7 @@ add_task(function test_gifft_numeric_limits() {
Glean.testOnlyIpc.irate.addToDenominator(-7);
Assert.throws(
() => Glean.testOnlyIpc.irate.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Can't get the value when you're error'd"
);
Assert.deepEqual(
@ -488,7 +488,7 @@ add_task(function test_gifft_numeric_limits() {
Glean.testOnlyIpc.aTimingDist.testAccumulateRawMillis(Math.pow(2, 32) + 1);
Assert.throws(
() => Glean.testOnlyIpc.aTimingDist.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Can't get the value when you're error'd"
);
let snapshot = Telemetry.getHistogramById(

Просмотреть файл

@ -200,7 +200,7 @@ add_task(
Assert.throws(
() => Glean.testOnlyIpc.anotherLabeledCounter.__other__.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Invalid labels record errors, which throw"
);

Просмотреть файл

@ -33,6 +33,12 @@ add_task(function test_fog_counter_works() {
});
add_task(async function test_fog_string_works() {
Assert.equal(null, Glean.testOnly.cheesyString.testGetValue());
// Setting `undefined` will be ignored.
Glean.testOnly.cheesyString.set(undefined);
Assert.equal(null, Glean.testOnly.cheesyString.testGetValue());
const value = "a cheesy string!";
Glean.testOnly.cheesyString.set(value);
@ -74,7 +80,7 @@ add_task(async function test_fog_timespan_throws_on_stop_wout_start() {
Glean.testOnly.canWeTimeIt.stop();
Assert.throws(
() => Glean.testOnly.canWeTimeIt.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Should throw because stop was called without start."
);
});
@ -138,16 +144,6 @@ add_task(async function test_fog_event_works() {
};
Assert.deepEqual(expectedExtra, events[0].extra);
// Quantities need to be non-negative.
// This does not record a Glean error.
let extra4 = {
extra2: -1,
};
Glean.testOnlyIpc.eventWithExtra.record(extra4);
events = Glean.testOnlyIpc.eventWithExtra.testGetValue();
// Unchanged number of events
Assert.equal(1, events.length, "Recorded one event too many.");
// camelCase extras work.
let extra5 = {
extra3LongerName: false,
@ -168,7 +164,7 @@ add_task(async function test_fog_event_works() {
Glean.testOnlyIpc.eventWithExtra.record(extra3);
Assert.throws(
() => Glean.testOnlyIpc.eventWithExtra.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Should throw because of a recording error."
);
});
@ -204,7 +200,7 @@ add_task(async function test_fog_custom_distribution_works() {
Glean.testOnlyIpc.aCustomDist.accumulateSamples([-7]);
Assert.throws(
() => Glean.testOnlyIpc.aCustomDist.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/
/DataError/
);
});
@ -300,14 +296,14 @@ add_task(async function test_fog_labels_conform() {
Glean.testOnly.mabelsLabelMaker[veryLong].set("seventy-two");
Assert.throws(
() => Glean.testOnly.mabelsLabelMaker[veryLong].testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Should throw because of an invalid label."
);
// This test should _now_ throw because we are calling data after an invalid
// label has been set.
Assert.throws(
() => Glean.testOnly.mabelsLabelMaker["dot.separated"].testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Should throw because of an invalid label."
);
});
@ -336,7 +332,7 @@ add_task(async function test_fog_labeled_boolean_works() {
Glean.testOnly.mabelsLikeBalloons["1".repeat(72)].set(true);
Assert.throws(
() => Glean.testOnly.mabelsLikeBalloons.__other__.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Should throw because of a recording error."
);
});
@ -365,7 +361,7 @@ add_task(async function test_fog_labeled_counter_works() {
Glean.testOnly.mabelsKitchenCounters["1".repeat(72)].add(1);
Assert.throws(
() => Glean.testOnly.mabelsKitchenCounters.__other__.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Should throw because of a recording error."
);
});
@ -394,7 +390,7 @@ add_task(async function test_fog_labeled_string_works() {
Glean.testOnly.mabelsBalloonStrings["1".repeat(72)].set("valid");
Assert.throws(
() => Glean.testOnly.mabelsBalloonStrings.__other__.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/
/DataError/
);
});

Просмотреть файл

@ -145,7 +145,7 @@ add_task(
Assert.throws(
() => Glean.testOnly.mabelsBathroomCounters.__other__.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Invalid labels record errors, which throw"
);

Просмотреть файл

@ -213,14 +213,6 @@ add_task(async function test_jog_event_works() {
};
Assert.deepEqual(expectedExtra, events[0].extra);
// Quantities need to be non-negative.
let extra4 = {
extra2: -1,
};
Glean.jogCat.jogEventWithExtra.record(extra4);
events = Glean.jogCat.jogEventWithExtra.testGetValue();
Assert.equal(1, events.length, "Recorded one event too many.");
// Invalid extra keys don't crash, the event is not recorded.
let extra3 = {
extra1_nonexistent_extra: "this does not crash",
@ -229,7 +221,7 @@ add_task(async function test_jog_event_works() {
// And test methods throw appropriately
Assert.throws(
() => Glean.jogCat.jogEventWithExtra.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/
/DataError/
);
});
@ -285,10 +277,7 @@ add_task(async function test_jog_custom_distribution_works() {
// Negative values will not be recorded, instead an error is recorded.
Glean.jogCat.jogCustomDist.accumulateSamples([-7]);
Assert.throws(
() => Glean.jogCat.jogCustomDist.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/
);
Assert.throws(() => Glean.jogCat.jogCustomDist.testGetValue(), /DataError/);
});
add_task(async function test_jog_custom_pings() {
@ -382,7 +371,7 @@ add_task(async function test_jog_labeled_boolean_works() {
Glean.jogCat.jogLabeledBool["1".repeat(72)].set(true);
Assert.throws(
() => Glean.jogCat.jogLabeledBool.__other__.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Should throw because of a recording error."
);
});
@ -451,7 +440,7 @@ add_task(async function test_jog_labeled_counter_works() {
Glean.jogCat.jogLabeledCounter["1".repeat(72)].add(1);
Assert.throws(
() => Glean.jogCat.jogLabeledCounter.__other__.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Should throw because of a recording error."
);
});
@ -490,7 +479,7 @@ add_task(async function test_jog_labeled_counter_with_static_labels_works() {
// TODO:(bug 1766515) - This should throw.
/*Assert.throws(
() => Glean.jogCat.jogLabeledCounterWithLabels.__other__.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Should throw because of a recording error."
);*/
Assert.equal(
@ -525,7 +514,7 @@ add_task(async function test_jog_labeled_string_works() {
Glean.jogCat.jogLabeledString["1".repeat(72)].set("valid");
Assert.throws(
() => Glean.jogCat.jogLabeledString.__other__.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/
/DataError/
);
});
@ -563,7 +552,7 @@ add_task(async function test_jog_labeled_string_with_labels_works() {
// TODO:(bug 1766515) - This should throw.
/*Assert.throws(
() => Glean.jogCat.jogLabeledStringWithLabels.__other__.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/
/DataError/
);*/
Assert.equal(
"valid",

Просмотреть файл

@ -238,7 +238,7 @@ add_task(
Assert.throws(
() => Glean.jogIpc.jogLabeledCounterErr.__other__.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Invalid labels record errors, which throw"
);
@ -250,7 +250,7 @@ add_task(
/*Assert.throws(
() =>
Glean.jogIpc.jogLabeledCounterWithLabelsErr.__other__.testGetValue(),
/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA/,
/DataError/,
"Invalid labels record errors, which throw"
);*/
Assert.equal(

Просмотреть файл

@ -20,7 +20,7 @@ XPIDL_MODULE = "fog"
XPIDL_SOURCES += [
"nsIFOG.idl",
"nsIGleanMetrics.idl",
"nsIGleanPing.idl",
]
with Files("**"):

Просмотреть файл

@ -0,0 +1,51 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* 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 "nsISupports.idl"
[scriptable, function, uuid(e5447f62-4b03-497c-81e9-6ab683d20380)]
interface nsIGleanPingTestCallback : nsISupports
{
void call(in ACString aReason);
};
[scriptable, uuid(5223a48b-687d-47ff-a629-fd4a72d1ecfa)]
interface nsIGleanPing : nsISupports
{
/**
* Collect and submit the ping for eventual upload.
*
* This will collect all stored data to be included in the ping.
* Data with lifetime `ping` will then be reset.
*
* If the ping is configured with `send_if_empty = false`
* and the ping currently contains no content,
* it will not be queued for upload.
* If the ping is configured with `send_if_empty = true`
* it will be queued for upload even if empty.
*
* Pings always contain the `ping_info` and `client_info` sections.
* See [ping sections](https://mozilla.github.io/glean/book/user/pings/index.html#ping-sections)
* for details.
*
* @param aReason - Optional. The reason the ping is being submitted.
* Must match one of the configured `reason_codes`.
*/
void submit([optional] in ACString aReason);
/**
* **Test-only API**
*
* Register a callback to be called right before this ping is next submitted.
* The provided function is called exactly once before submitting.
*
* Note: The callback will be called on any call to submit.
* A ping might not be sent afterwards, e.g. if the ping is empty and
* `send_if_empty` is `false`.
*
* @param aCallback - The callback to call on the next submit.
*/
void testBeforeNextSubmit(in nsIGleanPingTestCallback aCallback);
};

Просмотреть файл

@ -902,7 +902,7 @@ export var BackgroundUpdate = {
for (const [key, value] of Object.entries(this.REASON)) {
if (reasons.includes(value)) {
try {
// `testGetValue` throws `NS_ERROR_LOSS_OF_SIGNIFICANT_DATA` in case
// `testGetValue` throws a `DataError` in case
// of `InvalidOverflow` and other outstanding errors.
Glean.backgroundUpdate.reasonsToNotUpdate.testGetValue();
Glean.backgroundUpdate.reasonsToNotUpdate.add(key);