mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 715927 - addon telemetry, C++ side; r=taras
--HG-- extra : rebase_source : 21fc9e5dd98e4aa2ed09023a512df9e42bd1c4c9
This commit is contained in:
parent
77160ffd5a
commit
15a992cd01
@ -146,6 +146,27 @@ private:
|
|||||||
bool ShouldReflectHistogram(Histogram *h);
|
bool ShouldReflectHistogram(Histogram *h);
|
||||||
void IdentifyCorruptHistograms(StatisticsRecorder::Histograms &hs);
|
void IdentifyCorruptHistograms(StatisticsRecorder::Histograms &hs);
|
||||||
typedef StatisticsRecorder::Histograms::iterator HistogramIterator;
|
typedef StatisticsRecorder::Histograms::iterator HistogramIterator;
|
||||||
|
|
||||||
|
struct AddonHistogramInfo {
|
||||||
|
PRUint32 min;
|
||||||
|
PRUint32 max;
|
||||||
|
PRUint32 bucketCount;
|
||||||
|
PRUint32 histogramType;
|
||||||
|
Histogram *h;
|
||||||
|
};
|
||||||
|
typedef nsBaseHashtableET<nsCStringHashKey, AddonHistogramInfo> AddonHistogramEntryType;
|
||||||
|
typedef AutoHashtable<AddonHistogramEntryType> AddonHistogramMapType;
|
||||||
|
typedef nsBaseHashtableET<nsCStringHashKey, AddonHistogramMapType *> AddonEntryType;
|
||||||
|
typedef AutoHashtable<AddonEntryType> AddonMapType;
|
||||||
|
struct AddonEnumeratorArgs {
|
||||||
|
JSContext *cx;
|
||||||
|
JSObject *obj;
|
||||||
|
};
|
||||||
|
static bool AddonHistogramReflector(AddonHistogramEntryType *entry,
|
||||||
|
JSContext *cx, JSObject *obj);
|
||||||
|
static bool AddonReflector(AddonEntryType *entry, JSContext *cx, JSObject *obj);
|
||||||
|
AddonMapType mAddonMap;
|
||||||
|
|
||||||
// This is used for speedy string->Telemetry::ID conversions
|
// This is used for speedy string->Telemetry::ID conversions
|
||||||
typedef nsBaseHashtableET<nsCharPtrHashKey, Telemetry::ID> CharPtrEntryType;
|
typedef nsBaseHashtableET<nsCharPtrHashKey, Telemetry::ID> CharPtrEntryType;
|
||||||
typedef AutoHashtable<CharPtrEntryType> HistogramMapType;
|
typedef AutoHashtable<CharPtrEntryType> HistogramMapType;
|
||||||
@ -612,6 +633,111 @@ TelemetryImpl::ShouldReflectHistogram(Histogram *h)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute the name to pass into Histogram for the addon histogram
|
||||||
|
// 'name' from the addon 'id'. We can't use 'name' directly because it
|
||||||
|
// might conflict with other histograms in other addons or even with our
|
||||||
|
// own.
|
||||||
|
void
|
||||||
|
AddonHistogramName(const nsACString &id, const nsACString &name,
|
||||||
|
nsACString &ret)
|
||||||
|
{
|
||||||
|
ret.Append(id);
|
||||||
|
ret.Append(NS_LITERAL_CSTRING(":"));
|
||||||
|
ret.Append(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
TelemetryImpl::RegisterAddonHistogram(const nsACString &id,
|
||||||
|
const nsACString &name,
|
||||||
|
PRUint32 min, PRUint32 max,
|
||||||
|
PRUint32 bucketCount,
|
||||||
|
PRUint32 histogramType)
|
||||||
|
{
|
||||||
|
AddonEntryType *addonEntry = mAddonMap.GetEntry(id);
|
||||||
|
if (!addonEntry) {
|
||||||
|
addonEntry = mAddonMap.PutEntry(id);
|
||||||
|
if (NS_UNLIKELY(!addonEntry)) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
addonEntry->mData = new AddonHistogramMapType();
|
||||||
|
}
|
||||||
|
|
||||||
|
AddonHistogramMapType *histogramMap = addonEntry->mData;
|
||||||
|
AddonHistogramEntryType *histogramEntry = histogramMap->GetEntry(name);
|
||||||
|
// Can't re-register the same histogram.
|
||||||
|
if (histogramEntry) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
histogramEntry = histogramMap->PutEntry(name);
|
||||||
|
if (NS_UNLIKELY(!histogramEntry)) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddonHistogramInfo &info = histogramEntry->mData;
|
||||||
|
info.min = min;
|
||||||
|
info.max = max;
|
||||||
|
info.bucketCount = bucketCount;
|
||||||
|
info.histogramType = histogramType;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
TelemetryImpl::GetAddonHistogram(const nsACString &id, const nsACString &name,
|
||||||
|
JSContext *cx, jsval *ret)
|
||||||
|
{
|
||||||
|
AddonEntryType *addonEntry = mAddonMap.GetEntry(id);
|
||||||
|
// The given id has not been registered.
|
||||||
|
if (!addonEntry) {
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddonHistogramMapType *histogramMap = addonEntry->mData;
|
||||||
|
AddonHistogramEntryType *histogramEntry = histogramMap->GetEntry(name);
|
||||||
|
// The given histogram name has not been registered.
|
||||||
|
if (!histogramEntry) {
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddonHistogramInfo &info = histogramEntry->mData;
|
||||||
|
Histogram *h;
|
||||||
|
if (info.h) {
|
||||||
|
h = info.h;
|
||||||
|
} else {
|
||||||
|
nsCAutoString actualName;
|
||||||
|
AddonHistogramName(id, name, actualName);
|
||||||
|
nsresult rv = HistogramGet(PromiseFlatCString(actualName).get(),
|
||||||
|
info.min, info.max, info.bucketCount,
|
||||||
|
info.histogramType, &h);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
// Don't let this histogram be reported via the normal means
|
||||||
|
// (e.g. Telemetry.registeredHistograms); we'll make it available in
|
||||||
|
// other ways.
|
||||||
|
h->ClearFlags(Histogram::kUmaTargetedHistogramFlag);
|
||||||
|
info.h = h;
|
||||||
|
}
|
||||||
|
return WrapAndReturnHistogram(h, cx, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
TelemetryImpl::UnregisterAddonHistograms(const nsACString &id)
|
||||||
|
{
|
||||||
|
AddonEntryType *addonEntry = mAddonMap.GetEntry(id);
|
||||||
|
if (addonEntry) {
|
||||||
|
// Histogram's destructor is private, so this is the best we can do.
|
||||||
|
// The histograms the addon created *will* stick around, but they
|
||||||
|
// will be deleted if and when the addon registers histograms with
|
||||||
|
// the same names.
|
||||||
|
delete addonEntry->mData;
|
||||||
|
mAddonMap.RemoveEntry(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
TelemetryImpl::GetHistogramSnapshots(JSContext *cx, jsval *ret)
|
TelemetryImpl::GetHistogramSnapshots(JSContext *cx, jsval *ret)
|
||||||
{
|
{
|
||||||
@ -660,6 +786,73 @@ TelemetryImpl::GetHistogramSnapshots(JSContext *cx, jsval *ret)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TelemetryImpl::AddonHistogramReflector(AddonHistogramEntryType *entry,
|
||||||
|
JSContext *cx, JSObject *obj)
|
||||||
|
{
|
||||||
|
// Never even accessed the histogram.
|
||||||
|
if (!entry->mData.h) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject *snapshot = JS_NewObject(cx, NULL, NULL, NULL);
|
||||||
|
js::AutoObjectRooter r(cx, snapshot);
|
||||||
|
switch (ReflectHistogramSnapshot(cx, snapshot, entry->mData.h)) {
|
||||||
|
case REFLECT_FAILURE:
|
||||||
|
case REFLECT_CORRUPT:
|
||||||
|
return false;
|
||||||
|
case REFLECT_OK:
|
||||||
|
const nsACString &histogramName = entry->GetKey();
|
||||||
|
if (!JS_DefineProperty(cx, obj,
|
||||||
|
PromiseFlatCString(histogramName).get(),
|
||||||
|
OBJECT_TO_JSVAL(snapshot), NULL, NULL,
|
||||||
|
JSPROP_ENUMERATE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TelemetryImpl::AddonReflector(AddonEntryType *entry,
|
||||||
|
JSContext *cx, JSObject *obj)
|
||||||
|
{
|
||||||
|
const nsACString &addonId = entry->GetKey();
|
||||||
|
JSObject *subobj = JS_NewObject(cx, NULL, NULL, NULL);
|
||||||
|
if (!subobj) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
js::AutoObjectRooter r(cx, subobj);
|
||||||
|
|
||||||
|
AddonHistogramMapType *map = entry->mData;
|
||||||
|
if (!(map->ReflectHashtable(AddonHistogramReflector, cx, subobj)
|
||||||
|
&& JS_DefineProperty(cx, obj,
|
||||||
|
PromiseFlatCString(addonId).get(),
|
||||||
|
OBJECT_TO_JSVAL(subobj), NULL, NULL,
|
||||||
|
JSPROP_ENUMERATE))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
TelemetryImpl::GetAddonHistogramSnapshots(JSContext *cx, jsval *ret)
|
||||||
|
{
|
||||||
|
*ret = JSVAL_VOID;
|
||||||
|
JSObject *obj = JS_NewObject(cx, NULL, NULL, NULL);
|
||||||
|
if (!obj) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
js::AutoObjectRooter r(cx, obj);
|
||||||
|
|
||||||
|
if (!mAddonMap.ReflectHashtable(AddonReflector, cx, obj)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
*ret = OBJECT_TO_JSVAL(obj);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
TelemetryImpl::GetSlowSQL(JSContext *cx, jsval *ret)
|
TelemetryImpl::GetSlowSQL(JSContext *cx, jsval *ret)
|
||||||
{
|
{
|
||||||
|
@ -58,7 +58,7 @@ interface nsITelemetry : nsISupports
|
|||||||
* where data is consists of the following properties:
|
* where data is consists of the following properties:
|
||||||
* min - Minimal bucket size
|
* min - Minimal bucket size
|
||||||
* max - Maximum bucket size
|
* max - Maximum bucket size
|
||||||
* histogram_type - HISTOGRAM_EXPONENTIAL or HISTOGRAM_LINEAR
|
* histogram_type - HISTOGRAM_EXPONENTIAL, HISTOGRAM_LINEAR, or HISTOGRAM_BOOLEAN
|
||||||
* counts - array representing contents of the buckets in the histogram
|
* counts - array representing contents of the buckets in the histogram
|
||||||
* ranges - an array with calculated bucket sizes
|
* ranges - an array with calculated bucket sizes
|
||||||
* sum - sum of the bucket contents
|
* sum - sum of the bucket contents
|
||||||
@ -94,13 +94,13 @@ interface nsITelemetry : nsISupports
|
|||||||
readonly attribute jsval registeredHistograms;
|
readonly attribute jsval registeredHistograms;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and return a histogram where bucket sizes increase exponentially. Parameters:
|
* Create and return a histogram. Parameters:
|
||||||
*
|
*
|
||||||
* @param name Unique histogram name
|
* @param name Unique histogram name
|
||||||
* @param min - Minimal bucket size
|
* @param min - Minimal bucket size
|
||||||
* @param max - Maximum bucket size
|
* @param max - Maximum bucket size
|
||||||
* @param bucket_count - number of buckets in the histogram.
|
* @param bucket_count - number of buckets in the histogram.
|
||||||
* @param type - HISTOGRAM_EXPONENTIAL or HISTOGRAM_LINEAR
|
* @param type - HISTOGRAM_EXPONENTIAL, HISTOGRAM_LINEAR or HISTOGRAM_BOOLEAN
|
||||||
* The returned object has the following functions:
|
* The returned object has the following functions:
|
||||||
* add(int) - Adds an int value to the appropriate bucket
|
* add(int) - Adds an int value to the appropriate bucket
|
||||||
* snapshot() - Returns a snapshot of the histogram with the same data fields as in histogramSnapshots()
|
* snapshot() - Returns a snapshot of the histogram with the same data fields as in histogramSnapshots()
|
||||||
@ -136,4 +136,56 @@ interface nsITelemetry : nsISupports
|
|||||||
* A flag indicating whether Telemetry can submit official results.
|
* A flag indicating whether Telemetry can submit official results.
|
||||||
*/
|
*/
|
||||||
readonly attribute boolean canSend;
|
readonly attribute boolean canSend;
|
||||||
|
|
||||||
|
/** Addon telemetry hooks */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a histogram for an addon. Throws an error if the
|
||||||
|
* histogram name has been registered previously.
|
||||||
|
*
|
||||||
|
* @param addon_id - Unique ID of the addon
|
||||||
|
* @param name - Unique histogram name
|
||||||
|
* @param min - Minimal bucket size
|
||||||
|
* @param max - Maximum bucket size
|
||||||
|
* @param bucket_count - number of buckets in the histogram
|
||||||
|
* @param histogram_type - HISTOGRAM_EXPONENTIAL, HISTOGRAM_LINEAR, or
|
||||||
|
* HISTOGRAM_BOOLEAN
|
||||||
|
*/
|
||||||
|
void registerAddonHistogram(in ACString addon_id, in ACString name,
|
||||||
|
in PRUint32 min, in PRUint32 max,
|
||||||
|
in PRUint32 bucket_count,
|
||||||
|
in unsigned long histogram_type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a histogram previously registered via
|
||||||
|
* registerAddonHistogram. Throws an error if the id/name combo has
|
||||||
|
* not been registered via registerAddonHistogram.
|
||||||
|
*
|
||||||
|
* @param addon_id - Unique ID of the addon
|
||||||
|
* @param name - Registered histogram name
|
||||||
|
*
|
||||||
|
* The returned object has the same functions as a histogram returned
|
||||||
|
* from newHistogram.
|
||||||
|
*/
|
||||||
|
[implicit_jscontext]
|
||||||
|
jsval getAddonHistogram(in ACString addon_id, in ACString name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all histograms associated with the given addon id.
|
||||||
|
*
|
||||||
|
* @param addon_id - Unique ID of the addon
|
||||||
|
*/
|
||||||
|
void unregisterAddonHistograms(in ACString addon_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object containing a snapshot from all of the currently
|
||||||
|
* registered addon histograms.
|
||||||
|
* { addon-id1 : data1, ... }
|
||||||
|
*
|
||||||
|
* where data is an object whose properties are the names of the
|
||||||
|
* addon's histograms and whose corresponding values are as in
|
||||||
|
* histogramSnapshots.
|
||||||
|
*/
|
||||||
|
[implicit_jscontext]
|
||||||
|
readonly attribute jsval addonHistogramSnapshots;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user