Bug 616761 - Remove deadcode extensions/metrics, r=Mossop, a=ted

This commit is contained in:
Phil Ringnalda 2010-12-05 11:26:45 -08:00
Родитель 843cb967df
Коммит 272cba2b78
42 изменённых файлов: 0 добавлений и 7818 удалений

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

@ -1,70 +0,0 @@
# vim:set ts=8 sw=8 sts=8 noet:
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is the Metrics extension.
#
# The Initial Developer of the Original Code is Google Inc.
# Portions created by the Initial Developer are Copyright (C) 2006
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Darin Fisher <darin@meer.net>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
METRICS_VERSION = 2a3
XPI_NAME = metrics
USE_EXTENSION_MANIFEST = 1
NO_JAR_AUTO_REG = 1
INSTALL_EXTENSION_ID = metrics@mozilla.org
XPI_PKGNAME = metrics-$(METRICS_VERSION)
DIRS = public src build
ifdef ENABLE_TESTS
DIRS += test
endif
PREF_JS_EXPORTS = $(srcdir)/metrics.js
DIST_FILES = install.rdf
# We should really pull FIREFOX_VERSION from browser/config/version.txt but we
# can't be assured that we've even pulled those files. So we hardcode them.
XULAPP_DEFINES = \
-DFIREFOX_VERSION=$(FIREFOX_VERSION) \
-DEXTENSION_VERSION=$(METRICS_VERSION) \
$(NULL)
include $(topsrcdir)/config/rules.mk

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

@ -1,78 +0,0 @@
# vim:set ts=8 sw=8 sts=8 noet:
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is the Metrics extension.
#
# The Initial Developer of the Original Code is Google Inc.
# Portions created by the Initial Developer are Copyright (C) 2006
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Brian Ryner <bryner@brianryner.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = metrics
IS_COMPONENT = 1
LIBRARY_NAME = metrics
SHORT_LIBNAME = metrics
XPI_NAME = metrics
CPPSRCS = \
nsMetricsModule.cpp \
$(NULL)
SHARED_LIBRARY_LIBS = \
../src/$(LIB_PREFIX)metrics_s.$(LIB_SUFFIX) \
$(NULL)
EXTRA_DSO_LDOPTS = $(XPCOM_GLUE_LDOPTS) \
$(NSPR_LIBS) \
$(BZ2_LIBS) \
$(NULL)
LOCAL_INCLUDES = \
-I$(srcdir)/../src \
-I$(DIST)/public/nss \
-I$(DIST)/private/nss \
$(NULL)
include $(topsrcdir)/config/rules.mk
ifeq ($(OS_ARCH)_$(GNU_CC), WINNT_)
LDFLAGS += -NODEFAULTLIB:MSVCRT
endif
CXXFLAGS += $(BZ2_CFLAGS)

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

@ -1,134 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsMetricsModule.h"
#include "nsMetricsService.h"
#include "nsLoadCollector.h"
#include "nsWindowCollector.h"
#include "nsProfileCollector.h"
#include "nsUICommandCollector.h"
#include "nsAutoCompleteCollector.h"
#include "nsIGenericFactory.h"
#include "nsICategoryManager.h"
#include "nsServiceManagerUtils.h"
#include "nsCOMPtr.h"
#include "nsXPCOMCID.h"
#include "nsIClassInfoImpl.h"
NS_DECL_CLASSINFO(nsMetricsService)
#define COLLECTOR_CONTRACTID(type) \
"@mozilla.org/extensions/metrics/collector;1?name=" type ":" NS_METRICS_NAMESPACE
static NS_METHOD
nsMetricsServiceRegisterSelf(nsIComponentManager *compMgr,
nsIFile *path,
const char *loaderStr,
const char *type,
const nsModuleComponentInfo *info)
{
nsCOMPtr<nsICategoryManager> cat =
do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
NS_ENSURE_STATE(cat);
cat->AddCategoryEntry("app-startup",
NS_METRICSSERVICE_CLASSNAME,
"service," NS_METRICSSERVICE_CONTRACTID,
PR_TRUE, PR_TRUE, nsnull);
return NS_OK;
}
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsLoadCollector, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindowCollector)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsProfileCollector)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsUICommandCollector)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAutoCompleteCollector)
static const nsModuleComponentInfo components[] = {
{
NS_METRICSSERVICE_CLASSNAME,
NS_METRICSSERVICE_CID,
NS_METRICSSERVICE_CONTRACTID,
nsMetricsService::Create,
nsMetricsServiceRegisterSelf,
NULL,
NULL,
NS_CI_INTERFACE_GETTER_NAME(nsMetricsService),
NULL,
&NS_CLASSINFO_NAME(nsMetricsService),
nsIClassInfo::MAIN_THREAD_ONLY | nsIClassInfo::SINGLETON
},
{
NS_METRICSSERVICE_CLASSNAME,
NS_METRICSSERVICE_CID,
NS_ABOUT_MODULE_CONTRACTID_PREFIX "metrics",
nsMetricsService::Create
},
{
NS_LOADCOLLECTOR_CLASSNAME,
NS_LOADCOLLECTOR_CID,
COLLECTOR_CONTRACTID("document"),
nsLoadCollectorConstructor
},
{
NS_WINDOWCOLLECTOR_CLASSNAME,
NS_WINDOWCOLLECTOR_CID,
COLLECTOR_CONTRACTID("window"),
nsWindowCollectorConstructor
},
{
NS_PROFILECOLLECTOR_CLASSNAME,
NS_PROFILECOLLECTOR_CID,
COLLECTOR_CONTRACTID("profile"),
nsProfileCollectorConstructor
},
{
NS_UICOMMANDCOLLECTOR_CLASSNAME,
NS_UICOMMANDCOLLECTOR_CID,
COLLECTOR_CONTRACTID("uielement"),
nsUICommandCollectorConstructor
},
{
NS_AUTOCOMPLETECOLLECTOR_CLASSNAME,
NS_AUTOCOMPLETECOLLECTOR_CID,
COLLECTOR_CONTRACTID("autocomplete"),
nsAutoCompleteCollectorConstructor
}
};
NS_IMPL_NSGETMODULE(metrics, components)

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

@ -1,28 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://metrics/skin/prefs.css" type="text/css"?>
<!DOCTYPE prefwindow SYSTEM "chrome://metrics/locale/prefs.dtd">
<prefwindow
id="metrics-options-window"
type="prefwindow"
windowtype="Metrics:Preferences"
title="&prefs.title;"
width="400" height="160"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<prefpane id="metricsPrefsPanel" flex="1">
<preferences id="metrics-prefs">
<preference id="metrics-pref-upload-enable" name="extensions.mozilla.metrics.upload.enable" type="bool" instantApply="true"/>
</preferences>
<vbox class="prefs" flex="1">
<description class="msg">&prefs.label.msg;</description>
<checkbox id="metrics-enable-checkbox" checked="true" label="&prefs.checkbox.enable;" preference="metrics-pref-upload-enable"
persist="checked" class="cb" />
</vbox>
<spacer flex="1" />
</prefpane>
</prefwindow>

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

@ -1,34 +0,0 @@
<?xml version="1.0"?>
#filter substitution
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>metrics@mozilla.org</em:id>
<em:version>@EXTENSION_VERSION@</em:version>
<em:targetApplication>
<!-- Firefox -->
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>3.0a1</em:minVersion>
<em:maxVersion>@FIREFOX_VERSION@</em:maxVersion>
</Description>
</em:targetApplication>
<!-- front-end metadata -->
<em:name>Spectator</em:name>
<em:description>Collects anonymous usage statistics from the browser</em:description>
<em:creator>mozilla.org</em:creator>
<em:optionsURL>chrome://metrics/content/prefs.xul</em:optionsURL>
<em:file>
<Description about="urn:mozilla:extension:file:metrics.jar">
<em:package>content/</em:package>
<em:skin>skin/</em:skin>
<em:locale>locale/en-US/</em:locale>
</Description>
</em:file>
</Description>
</RDF>

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

@ -1,7 +0,0 @@
metrics.jar:
% content metrics %content/
% skin metrics classic/1.0 %skin/
% locale metrics en-US %locale/en-US/
content/prefs.xul (content/prefs.xul)
skin/prefs.css (skin/prefs.css)
locale/en-US/prefs.dtd (locale/en-US/prefs.dtd)

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

@ -1,7 +0,0 @@
<!ENTITY prefs.title "Spectator Preferences">
<!ENTITY prefs.label.msg "Help us make Firefox better by sending anonymous usage statistics.">
<!ENTITY prefs.checkbox.enable "Enable Spectator">
<!ENTITY prefs.button.close "Close">

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

@ -1,45 +0,0 @@
#! /bin/sh
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Build System
#
# The Initial Developer of the Original Code is
# Ben Turner <mozilla@songbirdnest.com>
#
# Portions created by the Initial Developer are Copyright (C) 2007
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
add_makefiles "
extensions/metrics/Makefile
extensions/metrics/build/Makefile
extensions/metrics/public/Makefile
extensions/metrics/src/Makefile
extensions/metrics/test/Makefile
"

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

@ -1,3 +0,0 @@
pref("extensions.mozilla.metrics.upload.enable", false);
pref("extensions.mozilla.metrics.upload.uri", "");
pref("extensions.mozilla.metrics.event-count", 0);

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

@ -1,57 +0,0 @@
# vim:set ts=8 sw=8 sts=8 noet:
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is the Metrics extension.
#
# The Initial Developer of the Original Code is Google Inc.
# Portions created by the Initial Developer are Copyright (C) 2006
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Darin Fisher <darin@meer.net>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = metrics
XPI_NAME = metrics
XPIDLSRCS = \
nsIMetricsService.idl \
nsIMetricsCollector.idl \
$(NULL)
EXPORTS = \
nsMetricsModule.h \
$(NULL)
include $(topsrcdir)/config/rules.mk

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

@ -1,73 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
/**
* The nsIMetricsCollector interface is implemented by any object that collects
* data on behalf of the MetricsService. When the configuration file reequests
* collector "foo" in namespace "http://www.mozilla.org/metrics",
* the contract id
* "@mozilla.org/extensions/metrics/collector;1?name=http://www.mozilla.org/metrics:foo"
* is instantiated (using getSerivce). The collector is responsible for
* calling nsIMetricsService::logEvent() when it has something to log.
*/
[scriptable, uuid(be965c17-848a-43d1-a9f6-b3f1c1bd8faa)]
interface nsIMetricsCollector : nsISupports
{
/**
* Notification that this collector should be enabled. The collector
* should register itself for observer and event notifications as
* necessary.
*/
void onAttach();
/**
* Notification that this collector is no longer enabled. The collector
* should unregister itself from observer and event notifications so that
* the object can be freed.
*/
void onDetach();
/**
* Notification that the MetricsService is starting a new event log.
* This happens after any onDetach() notifications that result from parsing
* the new configuration.
*/
void onNewLog();
};

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

@ -1,214 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface nsIPropertyBag;
interface nsIDOMWindow;
/**
* This file defines the interfaces for the Metrics Service.
*
* This service allows arbitrary types of events to be logged and uploaded
* to a server, based on server-configured collection parameters.
* The nsIMetricsService API provides an abstraction for the underlying XML
* data format.
*
* For more information about the data format and the built-in
* event collectors, see http://wiki.mozilla.org/Browser_Metrics.
*/
/**
* nsIMetricsEventItem represents a particular node of data to record
* in an event. Each item has a namespaced item name, a list of properties
* (key/value pairs), and an ordered list of child items. The child items
* need not be unique; an item may be repeated.
*/
[scriptable, uuid(62f4528f-5c59-4e86-a7ee-f34b67d7d65f)]
interface nsIMetricsEventItem : nsISupports
{
/**
* The namespace for this item, which must be a valid XML namespace URI.
*/
readonly attribute DOMString itemNamespace;
/**
* The name of this item, which must be a valid XML tag name.
*/
readonly attribute DOMString itemName;
/**
* A PropertyBag containing the key/value pairs to be included in the item.
* JavaScript callers can simply set this to an object containing the
* key/value pairs as object properties.
*/
attribute nsIPropertyBag properties;
/**
* Returns the child event item at the given index.
*/
nsIMetricsEventItem childAt(in long index);
/**
* Returns the first occurrence of the given item in the child list,
* or -1 if the item is not in the child list.
*/
long indexOf(in nsIMetricsEventItem item);
/**
* Appends a child event item to this item.
*/
void appendChild(in nsIMetricsEventItem item);
/**
* Inserts a child event item at a given index, moving later items
* up by one position.
* @param item The new item to insert
* @param index The position in the array. If the index is equal to
* childCount, the new item will be appended.
* The index may not be greater than childCount.
*/
void insertChildAt(in nsIMetricsEventItem item, in long index);
/**
* Removes a child event item at the given index, moving all items
* stored at a higher position down one.
*/
void removeChildAt(in long index);
/**
* Replaces a child event item at the given index.
* @param newItem The new item
* @param index The position of the item to be replaced
*/
void replaceChildAt(in nsIMetricsEventItem newItem, in long index);
/**
* Clears all of the child items.
*/
void clearChildren();
/**
* The number of child event items
*/
readonly attribute long childCount;
};
[scriptable, uuid(0aad28fd-3478-4090-9730-0fff8c7683b5)]
interface nsIMetricsService : nsISupports
{
/**
* Creates a new EventItem object to hold event data.
* The event will not be logged until logEvent() is called.
* @param itemNamespace The new item's namespace
* @param itemName The new item's name
*
* @returns a new MetricsEventItem instance
*/
nsIMetricsEventItem createEventItem(in DOMString itemNamespace,
in DOMString itemName);
/**
* Logs an event using the given EventItem. The event is recorded with a
* timestamp generated at the time at which this method is called, and a
* session id for this instance of the application. The keys "time" and
* "sessionid" are reserved for this data.
*
* @param item
* The item to log. This item and its entire tree of child items
* will be logged as part of the event.
*/
void logEvent(in nsIMetricsEventItem item);
/**
* Constructs and logs an EventItem, using the given namespace, event name,
* and event properties. This is a more convenient version of logEvent() for
* the case where there are no child EventItems.
*
* @see nsIMetricsEventItem
*/
void logSimpleEvent(in DOMString eventNS, in DOMString event,
in nsIPropertyBag eventValues);
/**
* Flush data to disk.
*/
void flush();
/**
* Initiate the upload of the current event log. This causes the current
* event log to be truncated once the upload completes.
*/
void upload();
/**
* Suspend log collection. LogEvent calls will be silently ignored while log
* collection is suspended. For each call to suspend, resume must be called
* to re-enable log collection.
*/
void suspend();
/**
* Resume log collection. Call this method once per call to suspend to
* re-enable log collection.
*/
void resume();
/**
* Gets a numeric window id corresponding to the given DOMWindow.
* The id remains constant for as long as the window exists.
*/
unsigned long getWindowID(in nsIDOMWindow window);
};
%{C++
/**
* Observer notifications
*/
/**
* These work like NS[_CHROME]_WEBNAVIGATION_DESTROY, except that the
* MetricsService is guaranteed to still know about the window which is being
* destroyed (via getWindowID). Collectors should use these notifications
* instead of the docshell-provided ones.
*/
#define NS_METRICS_WEBNAVIGATION_DESTROY "metrics-webnavigation-destroy"
#define NS_METRICS_CHROME_WEBNAVIGATION_DESTROY \
"metrics-chrome-webnavigation-destroy"
%}

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

@ -1,52 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsMetricsModule_h__
#define nsMetricsModule_h__
#define NS_METRICSSERVICE_CLASSNAME "nsMetricsService"
#define NS_METRICSSERVICE_CID \
{ /* 45f190da-8e83-4389-8b42-6939417c3297 */ \
0x45f190da, \
0x8e83, \
0x4389, \
{0x8b, 0x42, 0x69, 0x39, 0x41, 0x7c, 0x32, 0x97} \
}
#define NS_METRICSSERVICE_CONTRACTID "@mozilla.org/extensions/metrics/service;1"
#endif // nsMetricsModule_h__

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

@ -1,18 +0,0 @@
.prefs
{
background : white;
margin : 5px 5px 0px 5px;
border : 1px inset ThreeDFace;
}
.msg
{
margin-left : 4px;
margin-bottom : 10px;
}
.cb
{
margin-left : 20px;
}

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

@ -1,91 +0,0 @@
# vim:set ts=8 sw=8 sts=8 noet:
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is the Metrics extension.
#
# The Initial Developer of the Original Code is Google Inc.
# Portions created by the Initial Developer are Copyright (C) 2006
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Darin Fisher <darin@meer.net>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = metrics
LIBRARY_NAME = metrics_s
SHORT_LIBNAME = metrics_s
XPI_NAME = metrics
CSRCS = \
md5.c \
nssstubs.c \
$(NULL)
CPPSRCS = \
nsLoadCollector.cpp \
nsMetricsConfig.cpp \
nsMetricsEventItem.cpp \
nsMetricsService.cpp \
nsProfileCollector.cpp \
nsWindowCollector.cpp \
nsUICommandCollector.cpp \
nsAutoCompleteCollector.cpp \
nsStringUtils.cpp \
$(NULL)
# Create a static library to link into the component library and unit tests
FORCE_STATIC_LIB = 1
# md5.c requires NSS headers
LOCAL_INCLUDES = -I$(topsrcdir)/security/nss/lib/freebl
# Link against the static CRT
ifeq ($(OS_ARCH)_$(GNU_CC), WINNT_)
USE_STATIC_LIBS = 1
EXTRA_DSO_LDOPTS += -NODEFAULTLIB:MSVCRT \
-NODEFAULTLIB:MSVCRTD \
$(NULL)
endif
# Enable logging in release builds
ifneq (,$(findstring -DMOZ_LOGGING=1, $(ACDEFINES)))
DEFINES += -DFORCE_PR_LOG
endif
include $(topsrcdir)/config/rules.mk
export:: $(topsrcdir)/security/nss/lib/freebl/md5.c
$(INSTALL) $^ .

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

@ -1,219 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsAutoCompleteCollector.h"
#include "nsMetricsService.h"
#include "nsIObserverService.h"
#include "nsIAutoCompleteController.h"
#include "nsIAutoCompleteInput.h"
#include "nsIAutoCompletePopup.h"
#include "nsIDOMElement.h"
#include "nsServiceManagerUtils.h"
static const char kAutoCompleteTopic[] = "autocomplete-will-enter-text";
nsAutoCompleteCollector::nsAutoCompleteCollector()
{
}
nsAutoCompleteCollector::~nsAutoCompleteCollector()
{
}
NS_IMPL_ISUPPORTS2(nsAutoCompleteCollector, nsIMetricsCollector, nsIObserver)
NS_IMETHODIMP
nsAutoCompleteCollector::OnAttach()
{
nsCOMPtr<nsIObserverService> obsSvc =
do_GetService("@mozilla.org/observer-service;1");
NS_ENSURE_STATE(obsSvc);
nsresult rv = obsSvc->AddObserver(this, kAutoCompleteTopic, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
nsAutoCompleteCollector::OnDetach()
{
nsCOMPtr<nsIObserverService> obsSvc =
do_GetService("@mozilla.org/observer-service;1");
NS_ENSURE_STATE(obsSvc);
nsresult rv = obsSvc->RemoveObserver(this, kAutoCompleteTopic);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
nsAutoCompleteCollector::OnNewLog()
{
return NS_OK;
}
NS_IMETHODIMP
nsAutoCompleteCollector::Observe(nsISupports *subject,
const char *topic,
const PRUnichar *data)
{
if (strcmp(topic, kAutoCompleteTopic) != 0) {
MS_LOG(("Unexpected observer notification received: %s", topic));
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIAutoCompleteInput> input = do_QueryInterface(subject);
if (!input) {
MS_LOG(("subject isn't an AutoCompleteInput"));
return NS_OK;
}
nsCOMPtr<nsIAutoCompletePopup> popup;
input->GetPopup(getter_AddRefs(popup));
if (!popup) {
MS_LOG(("AutoCompleteInput has no popup"));
return NS_OK;
}
PRBool open;
nsresult rv = popup->GetPopupOpen(&open);
NS_ENSURE_SUCCESS(rv, rv);
if (!open) {
MS_LOG(("AutoComplete popup is closed, not logging"));
return NS_OK;
}
PRInt32 selectedIndex;
rv = popup->GetSelectedIndex(&selectedIndex);
NS_ENSURE_SUCCESS(rv, rv);
if (selectedIndex == -1) {
MS_LOG(("popup has no selected index, not logging"));
return NS_OK;
}
nsString textValue;
rv = input->GetTextValue(textValue);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIAutoCompleteController> controller;
input->GetController(getter_AddRefs(controller));
NS_ENSURE_STATE(controller);
nsString completion;
rv = controller->GetValueAt(selectedIndex, completion);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(subject);
if (!element) {
MS_LOG(("subject isn't a DOMElement"));
return NS_OK;
}
nsString id;
element->GetAttribute(NS_LITERAL_STRING("id"), id);
if (id.IsEmpty()) {
MS_LOG(("Warning: skipping logging because of empty target ID"));
return NS_OK;
}
// Fill a property bag for the <uielement> item
nsCOMPtr<nsIWritablePropertyBag2> properties;
nsMetricsUtils::NewPropertyBag(getter_AddRefs(properties));
NS_ENSURE_STATE(properties);
PRInt32 window = nsMetricsUtils::FindWindowForNode(element);
rv = properties->SetPropertyAsUint32(NS_LITERAL_STRING("window"), window);
NS_ENSURE_SUCCESS(rv, rv);
rv = properties->SetPropertyAsAString(NS_LITERAL_STRING("action"),
NS_LITERAL_STRING("autocomplete"));
NS_ENSURE_SUCCESS(rv, rv);
nsMetricsService *ms = nsMetricsService::get();
NS_ENSURE_STATE(ms);
nsCString hashedId;
rv = ms->HashUTF16(id, hashedId);
NS_ENSURE_SUCCESS(rv, rv);
rv = properties->SetPropertyAsACString(NS_LITERAL_STRING("targetidhash"),
hashedId);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMetricsEventItem> item;
ms->CreateEventItem(NS_LITERAL_STRING("uielement"), getter_AddRefs(item));
NS_ENSURE_STATE(item);
item->SetProperties(properties);
// Now fill in the properties for the <autocomplete> child item
nsMetricsUtils::NewPropertyBag(getter_AddRefs(properties));
NS_ENSURE_STATE(properties);
rv = properties->SetPropertyAsUint32(NS_LITERAL_STRING("typedlength"),
textValue.Length());
NS_ENSURE_SUCCESS(rv, rv);
rv = properties->SetPropertyAsInt32(NS_LITERAL_STRING("selectedindex"),
selectedIndex);
NS_ENSURE_SUCCESS(rv, rv);
rv = properties->SetPropertyAsInt32(NS_LITERAL_STRING("completedlength"),
completion.Length());
NS_ENSURE_SUCCESS(rv, rv);
rv = nsMetricsUtils::AddChildItem(item, NS_LITERAL_STRING("autocomplete"),
properties);
NS_ENSURE_SUCCESS(rv, rv);
rv = ms->LogEvent(item);
NS_ENSURE_SUCCESS(rv, rv);
MS_LOG(("Logged autocomplete event:\n"
" window id: %d\n"
" target %s (hash=%s)\n"
" typedlength: %d\n"
" selectedindex: %d\n"
" completedlength: %d",
window, NS_ConvertUTF16toUTF8(id).get(), hashedId.get(),
textValue.Length(), selectedIndex, completion.Length()));
return NS_OK;
}

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

@ -1,70 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// nsAutoCompleteCollector listens for autocomplete events using the
// observer service notification "autocomplete-text-entered". The
// AutoCompleteInput is examined to determine the autocomplete index,
// and the length of typed and completed text. The text itself is not logged.
// This data, along with the hashed id of the AutoCompleteInput, is logged
// to the MetricsService in a <uielement action="autocomplete"> event.
#ifndef nsAutoCompleteCollector_h_
#define nsAutoCompleteCollector_h_
#include "nsIMetricsCollector.h"
#include "nsIObserver.h"
class nsAutoCompleteCollector : public nsIMetricsCollector,
public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIMETRICSCOLLECTOR
NS_DECL_NSIOBSERVER
nsAutoCompleteCollector();
private:
~nsAutoCompleteCollector();
};
#define NS_AUTOCOMPLETECOLLECTOR_CLASSNAME "AutoComplete Collector"
#define NS_AUTOCOMPLETECOLLECTOR_CID \
{ 0x62cb877d, 0x5c8a, 0x44ca, {0xab, 0xcd, 0x1c, 0xaa, 0x76, 0x7c, 0xf4, 0xd4}}
#endif // nsAutoCompleteCollector_h_

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

@ -1,547 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsLoadCollector.h"
#include "nsMetricsService.h"
#include "nsCOMPtr.h"
#include "nsCURILoader.h"
#include "nsIServiceManager.h"
#include "nsIWebProgress.h"
#include "nsIDocShell.h"
#include "nsIDocShellTreeItem.h"
#include "nsIChannel.h"
#include "nsIDOMWindow.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsServiceManagerUtils.h"
#include "nsIURI.h"
#include "nsIDOMDocument.h"
// Hack around internal string usage in nsIDocument.h on the branch
#include "nsIDocument.h"
// This is needed to gain access to the LOAD_ defines in this file.
#define MOZILLA_INTERNAL_API
#include "nsDocShellLoadTypes.h"
#undef MOZILLA_INTERNAL_API
//-----------------------------------------------------------------------------
#if defined(__linux)
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
static FILE *sProcFP;
static void GetMemUsage_Shutdown() {
if (sProcFP) {
fclose(sProcFP);
sProcFP = NULL;
}
}
#elif defined(XP_WIN)
#include <windows.h>
#if _MSC_VER > 1200
#include <psapi.h>
#else
typedef struct _PROCESS_MEMORY_COUNTERS {
DWORD cb;
DWORD PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
} PROCESS_MEMORY_COUNTERS;
typedef PROCESS_MEMORY_COUNTERS *PPROCESS_MEMORY_COUNTERS;
#endif
typedef BOOL (WINAPI * GETPROCESSMEMORYINFO_FUNC)(
HANDLE process, PPROCESS_MEMORY_COUNTERS counters, DWORD cb);
static HMODULE sPSModule;
static HANDLE sProcess;
static GETPROCESSMEMORYINFO_FUNC sGetMemInfo;
static void GetMemUsage_Shutdown() {
if (sProcess) {
CloseHandle(sProcess);
sProcess = NULL;
}
if (sPSModule) {
FreeLibrary(sPSModule);
sPSModule = NULL;
}
sGetMemInfo = NULL;
}
#elif defined(XP_MACOSX)
#include <mach/mach.h>
#include <mach/task.h>
static void GetMemUsage_Shutdown() {
}
#endif
struct MemUsage {
PRInt64 total;
PRInt64 resident;
};
// This method should be incorporated into NSPR
static PRBool GetMemUsage(MemUsage *result)
{
PRBool setResult = PR_FALSE;
#if defined(__linux)
// Read /proc/<pid>/statm, and look at the first and second fields, which
// report the program size and the number of resident pages for this process,
// respectively.
char buf[256];
if (!sProcFP) {
pid_t pid = getpid();
snprintf(buf, sizeof(buf), "/proc/%d/statm", pid);
sProcFP = fopen(buf, "rb");
}
if (sProcFP) {
int vmsize, vmrss;
int count = fscanf(sProcFP, "%d %d", &vmsize, &vmrss);
rewind(sProcFP);
if (count == 2) {
static int ps = getpagesize();
result->total = PRInt64(vmsize) * ps;
result->resident = PRInt64(vmrss) * ps;
setResult = PR_TRUE;
}
}
#elif defined(XP_WIN)
// Use GetProcessMemoryInfo, which only works on WinNT and later.
if (!sGetMemInfo) {
sPSModule = LoadLibrary("psapi.dll");
if (sPSModule) {
sGetMemInfo = (GETPROCESSMEMORYINFO_FUNC)
GetProcAddress(sPSModule, "GetProcessMemoryInfo");
if (sGetMemInfo)
sProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, GetCurrentProcessId());
// Don't leave ourselves partially initialized.
if (!sProcess)
GetMemUsage_Shutdown();
}
}
if (sGetMemInfo) {
PROCESS_MEMORY_COUNTERS pmc;
if (sGetMemInfo(sProcess, &pmc, sizeof(pmc))) {
result->total = PRInt64(pmc.PagefileUsage);
result->resident = PRInt64(pmc.WorkingSetSize);
setResult = PR_TRUE;
}
}
#elif defined(XP_MACOSX)
// Use task_info
task_basic_info_data_t ti;
mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;
kern_return_t error = task_info(mach_task_self(), TASK_BASIC_INFO,
(task_info_t) &ti, &count);
if (error == KERN_SUCCESS) {
result->total = PRInt64(ti.virtual_size);
result->resident = PRInt64(ti.resident_size);
setResult = PR_TRUE;
}
#endif
return setResult;
}
//-----------------------------------------------------------------------------
nsLoadCollector::nsLoadCollector()
: mNextDocID(0)
{
mDocumentMap.Init(16);
}
nsLoadCollector::~nsLoadCollector()
{
GetMemUsage_Shutdown();
}
NS_IMPL_ISUPPORTS5(nsLoadCollector, nsIMetricsCollector,
nsIWebProgressListener, nsISupportsWeakReference,
nsIDocumentObserver, nsIMutationObserver)
NS_IMETHODIMP
nsLoadCollector::OnStateChange(nsIWebProgress *webProgress,
nsIRequest *request,
PRUint32 flags,
nsresult status)
{
NS_ASSERTION(flags & STATE_IS_DOCUMENT,
"incorrect state change notification");
#ifdef PR_LOGGING
if (MS_LOG_ENABLED()) {
nsCString name;
request->GetName(name);
MS_LOG(("LoadCollector: progress = %p, request = %p [%s], flags = %x, status = %x",
webProgress, request, name.get(), flags, status));
}
#endif
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
if (!channel) {
// We don't care about non-channel requests
return NS_OK;
}
nsresult rv;
if (flags & STATE_START) {
RequestEntry entry;
NS_ASSERTION(!mRequestMap.Get(request, &entry), "duplicate STATE_START");
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(webProgress);
nsCOMPtr<nsIDOMWindow> window = do_GetInterface(docShell);
if (!window) {
// We don't really care about windowless loads
return NS_OK;
}
rv = nsMetricsUtils::NewPropertyBag(getter_AddRefs(entry.properties));
NS_ENSURE_SUCCESS(rv, rv);
nsIWritablePropertyBag2 *props = entry.properties;
rv = props->SetPropertyAsUint32(NS_LITERAL_STRING("window"),
nsMetricsService::GetWindowID(window));
NS_ENSURE_SUCCESS(rv, rv);
if (flags & STATE_RESTORING) {
rv = props->SetPropertyAsBool(NS_LITERAL_STRING("bfCacheHit"), PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
}
nsString origin;
PRUint32 loadType;
docShell->GetLoadType(&loadType);
switch (loadType) {
case LOAD_NORMAL:
case LOAD_NORMAL_REPLACE:
case LOAD_BYPASS_HISTORY:
origin = NS_LITERAL_STRING("typed");
break;
case LOAD_NORMAL_EXTERNAL:
origin = NS_LITERAL_STRING("external");
break;
case LOAD_HISTORY:
origin = NS_LITERAL_STRING("session-history");
break;
case LOAD_RELOAD_NORMAL:
case LOAD_RELOAD_BYPASS_CACHE:
case LOAD_RELOAD_BYPASS_PROXY:
case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:
case LOAD_RELOAD_CHARSET_CHANGE:
origin = NS_LITERAL_STRING("reload");
break;
case LOAD_LINK:
origin = NS_LITERAL_STRING("link");
break;
case LOAD_REFRESH:
origin = NS_LITERAL_STRING("refresh");
break;
default:
break;
}
if (!origin.IsEmpty()) {
rv = props->SetPropertyAsAString(NS_LITERAL_STRING("origin"), origin);
NS_ENSURE_SUCCESS(rv, rv);
}
entry.startTime = PR_Now();
NS_ENSURE_TRUE(mRequestMap.Put(request, entry), NS_ERROR_OUT_OF_MEMORY);
} else if (flags & STATE_STOP) {
RequestEntry entry;
if (mRequestMap.Get(request, &entry)) {
mRequestMap.Remove(request);
// Log a <document action="load"> event
nsIWritablePropertyBag2 *props = entry.properties;
rv = props->SetPropertyAsACString(NS_LITERAL_STRING("action"),
NS_LITERAL_CSTRING("load"));
NS_ENSURE_SUCCESS(rv, rv);
// Compute the load time now that we have the end time.
PRInt64 loadTime = (PR_Now() - entry.startTime) / PR_USEC_PER_MSEC;
rv = props->SetPropertyAsUint64(NS_LITERAL_STRING("loadtime"), loadTime);
NS_ENSURE_SUCCESS(rv, rv);
MemUsage mu;
if (GetMemUsage(&mu)) {
rv = props->SetPropertyAsUint64(NS_LITERAL_STRING("memtotal"), mu.total);
NS_ENSURE_SUCCESS(rv, rv);
rv = props->SetPropertyAsUint64(NS_LITERAL_STRING("memresident"), mu.resident);
NS_ENSURE_SUCCESS(rv, rv);
}
// Look up the document id, or assign a new one
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(webProgress);
nsCOMPtr<nsIDOMWindow> window = do_GetInterface(docShell);
if (!window) {
MS_LOG(("Couldn't get window"));
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIDOMDocument> domDoc;
window->GetDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
if (!doc) {
MS_LOG(("Couldn't get document"));
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIDocShellTreeItem> item = do_QueryInterface(docShell);
NS_ENSURE_STATE(item);
PRBool subframe = nsMetricsUtils::IsSubframe(item);
if (subframe) {
rv = props->SetPropertyAsBool(NS_LITERAL_STRING("subframe"), PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
}
nsMetricsService *ms = nsMetricsService::get();
DocumentEntry docEntry;
if (!mDocumentMap.Get(doc, &docEntry)) {
docEntry.docID = mNextDocID++;
docEntry.subframe = subframe;
if (!ms->WindowMap().Get(window, &docEntry.windowID)) {
MS_LOG(("Window not in the window map"));
return NS_ERROR_UNEXPECTED;
}
NS_ENSURE_TRUE(mDocumentMap.Put(doc, docEntry),
NS_ERROR_OUT_OF_MEMORY);
}
doc->AddObserver(this); // set up to log the document destroy
rv = props->SetPropertyAsUint32(NS_LITERAL_STRING("docid"),
docEntry.docID);
NS_ENSURE_SUCCESS(rv, rv);
// If this was a load of a chrome document, hash the URL of the document
// so it can be identified.
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
if (channel) {
nsCOMPtr<nsIURI> uri;
channel->GetURI(getter_AddRefs(uri));
if (uri) {
PRBool isChrome = PR_FALSE;
uri->SchemeIs("chrome", &isChrome);
if (isChrome) {
nsCString spec;
uri->GetSpec(spec);
nsCString hashedSpec;
rv = ms->HashUTF8(spec, hashedSpec);
NS_ENSURE_SUCCESS(rv, rv);
rv = props->SetPropertyAsACString(NS_LITERAL_STRING("urlhash"),
hashedSpec);
NS_ENSURE_SUCCESS(rv, rv);
}
}
}
rv = ms->LogEvent(NS_LITERAL_STRING("document"), props);
NS_ENSURE_SUCCESS(rv, rv);
} else {
NS_WARNING("STATE_STOP without STATE_START");
}
}
return NS_OK;
}
NS_IMETHODIMP
nsLoadCollector::OnProgressChange(nsIWebProgress *webProgress,
nsIRequest *request,
PRInt32 curSelfProgress,
PRInt32 maxSelfProgress,
PRInt32 curTotalProgress,
PRInt32 maxTotalProgress)
{
return NS_OK;
}
NS_IMETHODIMP
nsLoadCollector::OnLocationChange(nsIWebProgress *webProgress,
nsIRequest *request, nsIURI *location)
{
return NS_OK;
}
NS_IMETHODIMP
nsLoadCollector::OnStatusChange(nsIWebProgress *webProgress,
nsIRequest *request,
nsresult status, const PRUnichar *messaage)
{
return NS_OK;
}
NS_IMETHODIMP
nsLoadCollector::OnSecurityChange(nsIWebProgress *webProgress,
nsIRequest *request, PRUint32 state)
{
return NS_OK;
}
nsresult
nsLoadCollector::Init()
{
NS_ENSURE_TRUE(mRequestMap.Init(32), NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
NS_IMETHODIMP
nsLoadCollector::OnAttach()
{
// Attach the LoadCollector as a global web progress listener
nsCOMPtr<nsIWebProgress> progress =
do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID);
NS_ENSURE_STATE(progress);
nsresult rv = progress->AddProgressListener(
this, nsIWebProgress::NOTIFY_STATE_DOCUMENT);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
/* static */ PLDHashOperator
nsLoadCollector::RemoveDocumentFromMap(const nsIDocument *document,
DocumentEntry &entry, void *userData)
{
nsIDocument *mutable_doc = const_cast<nsIDocument*>(document);
mutable_doc->RemoveObserver(static_cast<nsLoadCollector*>(userData));
return PL_DHASH_REMOVE;
}
NS_IMETHODIMP
nsLoadCollector::OnDetach()
{
// Clear the request and document maps so we start fresh
// next time we're attached
mRequestMap.Clear();
mDocumentMap.Enumerate(RemoveDocumentFromMap, this);
// Remove the progress listener
nsCOMPtr<nsIWebProgress> progress =
do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID);
NS_ENSURE_STATE(progress);
nsresult rv = progress->RemoveProgressListener(this);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
nsLoadCollector::OnNewLog()
{
return NS_OK;
}
NS_IMPL_NSIDOCUMENTOBSERVER_LOAD_STUB(nsLoadCollector)
NS_IMPL_NSIDOCUMENTOBSERVER_STATE_STUB(nsLoadCollector)
NS_IMPL_NSIDOCUMENTOBSERVER_CONTENT(nsLoadCollector)
NS_IMPL_NSIDOCUMENTOBSERVER_STYLE_STUB(nsLoadCollector)
void
nsLoadCollector::BeginUpdate(nsIDocument *document, nsUpdateType updateType)
{
}
void
nsLoadCollector::EndUpdate(nsIDocument *document, nsUpdateType updateType)
{
}
void
nsLoadCollector::NodeWillBeDestroyed(const nsINode *node)
{
const nsIDocument* document = static_cast<const nsIDocument*>(node);
// Look up the document to get its id.
DocumentEntry entry;
if (!mDocumentMap.Get(document, &entry)) {
MS_LOG(("Document not in map!"));
return;
}
mDocumentMap.Remove(document);
nsCOMPtr<nsIWritablePropertyBag2> props;
nsMetricsUtils::NewPropertyBag(getter_AddRefs(props));
if (!props) {
return;
}
props->SetPropertyAsACString(NS_LITERAL_STRING("action"),
NS_LITERAL_CSTRING("destroy"));
props->SetPropertyAsUint32(NS_LITERAL_STRING("docid"), entry.docID);
props->SetPropertyAsUint32(NS_LITERAL_STRING("window"), entry.windowID);
if (entry.subframe) {
props->SetPropertyAsBool(NS_LITERAL_STRING("subframe"), PR_TRUE);
}
MemUsage mu;
if (GetMemUsage(&mu)) {
props->SetPropertyAsUint64(NS_LITERAL_STRING("memtotal"), mu.total);
props->SetPropertyAsUint64(NS_LITERAL_STRING("memresident"), mu.resident);
}
nsMetricsService *ms = nsMetricsService::get();
if (ms) {
ms->LogEvent(NS_LITERAL_STRING("document"), props);
#ifdef PR_LOGGING
nsIURI *uri = document->GetDocumentURI();
if (uri) {
nsCString spec;
uri->GetSpec(spec);
MS_LOG(("LoadCollector: Logged document destroy for %s\n", spec.get()));
}
#endif
}
}

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

@ -1,123 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsLoadCollector_h_
#define nsLoadCollector_h_
// This file defines the load collector class, which monitors requests using
// the document loader service and records the events into the metrics service.
//
// The load collector logs <document action="load"/> events.
// This event has the following attributes:
//
// origin: The action which initiated the load (string). Possible values are:
// "typed": The user typed or pasted the URI into the location bar.
// "link": The user followed a link to the URI.
// "reload": The user reloaded the URI.
// "refresh": A meta-refresh caused the URI to be loaded.
// "session-history": The user used back/forward to load the URI.
// "global-history": The user selected the URI from global history.
// "bookmark": The user selected the URI from bookmarks.
// "external": An external application passed in the URI to load.
// "other": Any origin not listed above.
//
// bfCacheHit: The document presentation was restored from the
// session history cache (boolean).
//
// window: The id of the window where the document loaded (uint16).
// loadtime: The elapsed time for the load, in milliseconds (uint32).
#include "nsIMetricsCollector.h"
#include "nsIWebProgressListener.h"
#include "nsIWritablePropertyBag2.h"
#include "nsWeakReference.h"
#include "nsDataHashtable.h"
#include "nsAutoPtr.h"
#include "nsIDocumentObserver.h"
#include "nsPtrHashKey.h"
class nsIDocument;
class nsLoadCollector : public nsIMetricsCollector,
public nsIWebProgressListener,
public nsIDocumentObserver,
public nsSupportsWeakReference
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIMETRICSCOLLECTOR
NS_DECL_NSIWEBPROGRESSLISTENER
NS_DECL_NSIDOCUMENTOBSERVER
nsLoadCollector();
nsresult Init();
private:
struct RequestEntry {
nsCOMPtr<nsIWritablePropertyBag2> properties;
PRTime startTime;
};
struct DocumentEntry {
PRUint32 docID;
PRUint32 windowID;
PRBool subframe;
};
~nsLoadCollector();
// Callback for removing a document observer and map entry
static PLDHashOperator
RemoveDocumentFromMap(const nsIDocument *document,
DocumentEntry &entry, void *userData);
// Hash table mapping nsIRequest objects to their event properties.
nsDataHashtable<nsISupportsHashKey, RequestEntry> mRequestMap;
// Documents we're currently listening to, and their associated ids
nsDataHashtable< nsPtrHashKey<nsIDocument>, DocumentEntry > mDocumentMap;
// The next document id we'll assign
PRUint32 mNextDocID;
};
#define NS_LOADCOLLECTOR_CLASSNAME "Load Collector"
#define NS_LOADCOLLECTOR_CID \
{ 0xa97357a0, 0xa2f3, 0x4b1f, {0x93, 0xd3, 0x36, 0xdc, 0xb7, 0xee, 0x24, 0x63}}
#endif // nsLoadCollector_h_

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

@ -1,428 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsMetricsService.h"
#include "nsStringUtils.h"
#include "nsIDOMDocument.h"
#include "nsIDOMParser.h"
#include "nsIDOMElement.h"
#include "nsIDOM3Node.h"
#include "nsIFileStreams.h"
#include "nsILocalFile.h"
#include "nsComponentManagerUtils.h"
#include "nsNetCID.h"
#include "prprf.h"
#include "nsTArray.h"
#include "nsIDOMSerializer.h"
#define NS_DEFAULT_UPLOAD_INTERVAL_SEC 60 * 5
//-----------------------------------------------------------------------------
static const nsString
MakeKey(const nsAString &eventNS, const nsAString &eventName)
{
// Since eventName must be a valid XML NCName, we can use ':' to separate
// eventName from eventNS when formulating our hash key.
NS_ASSERTION(FindChar(eventName, ':') == -1, "Not a valid NCName");
nsString key;
key.Append(eventName);
key.Append(':');
key.Append(eventNS);
return key;
}
static void
SplitKey(const nsString &key, nsString &eventNS, nsString &eventName)
{
PRInt32 colon = FindChar(key, ':');
if (colon == -1) {
NS_ERROR("keys from MakeKey should always have a colon");
return;
}
eventName = Substring(key, 0, colon);
eventNS = Substring(key, colon + 1, key.Length() - colon - 1);
}
// This method leaves the result value unchanged if a parsing error occurs.
static void
ReadIntegerAttr(nsIDOMElement *elem, const nsAString &attrName, PRInt32 *result)
{
nsString attrValue;
elem->GetAttribute(attrName, attrValue);
NS_ConvertUTF16toUTF8 attrValueUtf8(attrValue);
PR_sscanf(attrValueUtf8.get(), "%ld", result);
}
//-----------------------------------------------------------------------------
nsMetricsConfig::nsMetricsConfig()
{
}
PRBool
nsMetricsConfig::Init()
{
if (!mEventSet.Init() || !mNSURIToPrefixMap.Init()) {
return PR_FALSE;
}
Reset();
return PR_TRUE;
}
void
nsMetricsConfig::Reset()
{
// By default, we have no event limit, but all collectors are disabled
// until we're told by the server to enable them.
NS_ASSERTION(mEventSet.IsInitialized(), "nsMetricsConfig::Init not called");
mEventSet.Clear();
mNSURIToPrefixMap.Clear();
mEventLimit = PR_INT32_MAX;
mUploadInterval = NS_DEFAULT_UPLOAD_INTERVAL_SEC;
mHasConfig = PR_FALSE;
}
nsresult
nsMetricsConfig::Load(nsIFile *file)
{
// The given file references a XML file with the following structure:
//
// <response xmlns="http://www.mozilla.org/metrics">
// <config xmlns:foo="http://foo.com/metrics">
// <collectors>
// <collector type="ui"/>
// <collector type="document"/>
// <collector type="window"/>
// <collector type="foo:mystat"/>
// </collectors>
// <limit events="200"/>
// <upload interval="600"/>
// </config>
// </response>
NS_ASSERTION(mEventSet.IsInitialized(), "nsMetricsConfig::Init not called");
PRInt64 fileSize;
nsresult rv = file->GetFileSize(&fileSize);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_STATE(fileSize <= PR_INT32_MAX);
nsCOMPtr<nsIFileInputStream> stream =
do_CreateInstance(NS_LOCALFILEINPUTSTREAM_CONTRACTID);
NS_ENSURE_STATE(stream);
rv = stream->Init(file, -1, -1, 0);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMParser> parser = do_CreateInstance(NS_DOMPARSER_CONTRACTID);
NS_ENSURE_STATE(parser);
nsCOMPtr<nsIDOMDocument> doc;
parser->ParseFromStream(stream, nsnull, PRInt32(fileSize), "application/xml",
getter_AddRefs(doc));
NS_ENSURE_STATE(doc);
// Now, walk the DOM. Most elements are optional, but we check the root
// element to make sure it's a valid response document.
nsCOMPtr<nsIDOMElement> elem;
doc->GetDocumentElement(getter_AddRefs(elem));
NS_ENSURE_STATE(elem);
nsString nameSpace;
elem->GetNamespaceURI(nameSpace);
if (!nameSpace.Equals(NS_LITERAL_STRING(NS_METRICS_NAMESPACE))) {
// We have a root element, but it's the wrong namespace
return NS_ERROR_FAILURE;
}
nsString tag;
elem->GetLocalName(tag);
if (!tag.Equals(NS_LITERAL_STRING("response"))) {
// The root tag isn't what we're expecting
return NS_ERROR_FAILURE;
}
// At this point, we can clear our old configuration.
Reset();
ForEachChildElement(elem, &nsMetricsConfig::ProcessToplevelElement);
return NS_OK;
}
nsresult
nsMetricsConfig::Save(nsILocalFile *file)
{
nsCOMPtr<nsIDOMDocument> doc =
do_CreateInstance("@mozilla.org/xml/xml-document;1");
NS_ENSURE_STATE(doc);
nsCOMPtr<nsIDOMElement> response;
nsMetricsUtils::CreateElement(doc, NS_LITERAL_STRING("response"),
getter_AddRefs(response));
NS_ENSURE_STATE(response);
nsCOMPtr<nsIDOMElement> config;
nsMetricsUtils::CreateElement(doc, NS_LITERAL_STRING("config"),
getter_AddRefs(config));
NS_ENSURE_STATE(config);
nsCOMPtr<nsIDOMElement> collectors;
nsMetricsUtils::CreateElement(doc, NS_LITERAL_STRING("collectors"),
getter_AddRefs(collectors));
NS_ENSURE_STATE(collectors);
nsTArray<nsString> events;
GetEvents(events);
nsCOMPtr<nsIDOMNode> nodeOut;
nsresult rv;
for (PRUint32 i = 0; i < events.Length(); ++i) {
nsString eventNS, eventName;
SplitKey(events[i], eventNS, eventName);
nsString prefix;
if (!eventNS.Equals(NS_LITERAL_STRING(NS_METRICS_NAMESPACE))) {
if (!mNSURIToPrefixMap.Get(eventNS, &prefix)) {
MS_LOG(("uri %s not in prefix map",
NS_ConvertUTF16toUTF8(eventNS).get()));
continue;
}
// Declare the namespace prefix on the root element
nsString attrName(NS_LITERAL_STRING("xmlns:"));
attrName.Append(prefix);
response->SetAttribute(attrName, eventNS);
}
nsCOMPtr<nsIDOMElement> collector;
nsMetricsUtils::CreateElement(doc, NS_LITERAL_STRING("collector"),
getter_AddRefs(collector));
NS_ENSURE_STATE(collector);
nsString shortName;
if (!prefix.IsEmpty()) {
shortName = prefix;
shortName.Append(':');
}
shortName.Append(eventName);
collector->SetAttribute(NS_LITERAL_STRING("type"), eventName);
collectors->AppendChild(collector, getter_AddRefs(nodeOut));
}
config->AppendChild(collectors, getter_AddRefs(nodeOut));
if (mEventLimit != PR_INT32_MAX) {
nsCOMPtr<nsIDOMElement> limit;
nsMetricsUtils::CreateElement(doc, NS_LITERAL_STRING("limit"),
getter_AddRefs(limit));
NS_ENSURE_STATE(limit);
nsString limitStr;
AppendInt(limitStr, mEventLimit);
limit->SetAttribute(NS_LITERAL_STRING("events"), limitStr);
config->AppendChild(limit, getter_AddRefs(nodeOut));
}
nsCOMPtr<nsIDOMElement> upload;
nsMetricsUtils::CreateElement(doc, NS_LITERAL_STRING("upload"),
getter_AddRefs(upload));
NS_ENSURE_STATE(upload);
nsString intervalStr;
AppendInt(intervalStr, mUploadInterval);
upload->SetAttribute(NS_LITERAL_STRING("interval"), intervalStr);
config->AppendChild(upload, getter_AddRefs(nodeOut));
response->AppendChild(config, getter_AddRefs(nodeOut));
nsCOMPtr<nsIDOMSerializer> ds =
do_CreateInstance(NS_XMLSERIALIZER_CONTRACTID);
NS_ENSURE_STATE(ds);
nsString docText;
rv = ds->SerializeToString(response, docText);
NS_ENSURE_SUCCESS(rv, rv);
NS_ConvertUTF16toUTF8 utf8Doc(docText);
PRInt32 num = utf8Doc.Length();
PRFileDesc *fd;
rv = file->OpenNSPRFileDesc(
PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0600, &fd);
NS_ENSURE_SUCCESS(rv, rv);
PRBool success = (PR_Write(fd, utf8Doc.get(), num) == num);
PR_Close(fd);
return success ? NS_OK : NS_ERROR_FAILURE;
}
void
nsMetricsConfig::ForEachChildElement(nsIDOMElement *elem,
ForEachChildElementCallback callback)
{
nsCOMPtr<nsIDOMNode> node, next;
elem->GetFirstChild(getter_AddRefs(node));
while (node) {
nsCOMPtr<nsIDOMElement> childElem = do_QueryInterface(node);
if (childElem) {
// Skip elements that are not in our namespace
nsString namespaceURI;
childElem->GetNamespaceURI(namespaceURI);
if (namespaceURI.Equals(NS_LITERAL_STRING(NS_METRICS_NAMESPACE)))
(this->*callback)(childElem);
}
node->GetNextSibling(getter_AddRefs(next));
node.swap(next);
}
}
void
nsMetricsConfig::ProcessToplevelElement(nsIDOMElement *elem)
{
// Process a top-level element
nsString name;
elem->GetLocalName(name);
if (name.Equals(NS_LITERAL_STRING("config"))) {
mHasConfig = PR_TRUE;
ForEachChildElement(elem, &nsMetricsConfig::ProcessConfigChild);
}
}
void
nsMetricsConfig::ProcessConfigChild(nsIDOMElement *elem)
{
// Process a config element child
nsString name;
elem->GetLocalName(name);
if (name.Equals(NS_LITERAL_STRING("collectors"))) {
// Enumerate <collector> elements
ForEachChildElement(elem, &nsMetricsConfig::ProcessCollectorElement);
} else if (name.Equals(NS_LITERAL_STRING("limit"))) {
ReadIntegerAttr(elem, NS_LITERAL_STRING("events"), &mEventLimit);
} else if (name.Equals(NS_LITERAL_STRING("upload"))) {
ReadIntegerAttr(elem, NS_LITERAL_STRING("interval"), &mUploadInterval);
}
}
void
nsMetricsConfig::ProcessCollectorElement(nsIDOMElement *elem)
{
// Make sure we are dealing with a <collector> element.
nsString localName;
elem->GetLocalName(localName);
if (!localName.Equals(NS_LITERAL_STRING("collector")))
return;
nsString type;
elem->GetAttribute(NS_LITERAL_STRING("type"), type);
if (type.IsEmpty())
return;
// Get the namespace URI specified by any prefix of |type|.
nsCOMPtr<nsIDOM3Node> node = do_QueryInterface(elem);
if (!node)
return;
// Check to see if this type references a specific namespace.
PRInt32 colon = FindChar(type, ':');
nsString namespaceURI;
if (colon == -1) {
node->LookupNamespaceURI(EmptyString(), namespaceURI);
// value is the EventName
} else {
// value is NamespacePrefix + ":" + EventName
nsString prefix(StringHead(type, colon));
node->LookupNamespaceURI(prefix, namespaceURI);
type.Cut(0, colon + 1);
// Add this namespace -> prefix mapping to our lookup table
mNSURIToPrefixMap.Put(namespaceURI, prefix);
}
mEventSet.PutEntry(MakeKey(namespaceURI, type));
}
PRBool
nsMetricsConfig::IsEventEnabled(const nsAString &eventNS,
const nsAString &eventName) const
{
NS_ASSERTION(mEventSet.IsInitialized(), "nsMetricsConfig::Init not called");
return mEventSet.GetEntry(MakeKey(eventNS, eventName)) != nsnull;
}
void
nsMetricsConfig::SetEventEnabled(const nsAString &eventNS,
const nsAString &eventName, PRBool enabled)
{
NS_ASSERTION(mEventSet.IsInitialized(), "nsMetricsConfig::Init not called");
nsString key = MakeKey(eventNS, eventName);
if (enabled) {
mEventSet.PutEntry(key);
} else {
mEventSet.RemoveEntry(key);
}
}
void
nsMetricsConfig::ClearEvents()
{
NS_ASSERTION(mEventSet.IsInitialized(), "nsMetricsConfig::Init not called");
mEventSet.Clear();
}
/* static */ PLDHashOperator
nsMetricsConfig::CopyKey(nsStringHashKey *entry, void *userData)
{
static_cast<nsTArray<nsString> *>(userData)->
AppendElement(entry->GetKey());
return PL_DHASH_NEXT;
}
void
nsMetricsConfig::GetEvents(nsTArray<nsString> &events) {
mEventSet.EnumerateEntries(CopyKey, &events);
}

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

@ -1,164 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsMetricsConfig_h__
#define nsMetricsConfig_h__
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
class nsIDOMElement;
class nsIFile;
class nsILocalFile;
template<class E> class nsTArray;
class nsMetricsConfig
{
public:
nsMetricsConfig();
~nsMetricsConfig() {}
/**
* This method must be called before using an instance of this class.
*/
PRBool Init();
/**
* Restore the default configuration.
*/
void Reset();
/**
* Load the metrics configuration from disk.
*/
nsresult Load(nsIFile *file);
/**
* Writes the current metrics configuration to disk.
*/
nsresult Save(nsILocalFile *file);
/**
* Call this method to determine if the given event type is enabled for
* collection.
*/
PRBool IsEventEnabled(const nsAString &eventNS,
const nsAString &eventName) const;
/**
* Sets a particular event to be enabled or disabled.
*/
void SetEventEnabled(const nsAString &eventNS,
const nsAString &eventName, PRBool enabled);
/**
* Call this method to get a list of all events that are enabled.
* The event names are prefixed with the namespace, separated by a colon.
*/
void GetEvents(nsTArray<nsString> &events);
/**
* Clears the set of events in this config.
*/
void ClearEvents();
/**
* Get the limit on the number of events that should be collected.
*/
PRInt32 EventLimit() const {
NS_ASSERTION(mEventSet.IsInitialized(),
"nsMetricsConfig::Init not called");
return mEventLimit;
}
/**
* Sets the event limit.
*/
void SetEventLimit(PRInt32 limit) {
NS_ASSERTION(mEventSet.IsInitialized(),
"nsMetricsConfig::Init not called");
mEventLimit = limit;
}
/**
* Get the upload interval (measured in seconds).
*/
PRInt32 UploadInterval() const {
NS_ASSERTION(mEventSet.IsInitialized(),
"nsMetricsConfig::Init not called");
return mUploadInterval;
}
/**
* Set the upload interval (measured in seconds).
*/
void SetUploadInterval(PRInt32 uploadInterval) {
NS_ASSERTION(mEventSet.IsInitialized(),
"nsMetricsConfig::Init not called");
mUploadInterval = uploadInterval;
}
/**
* Returns true if there was a <config> present in the response.
*/
PRBool HasConfig() const {
NS_ASSERTION(mEventSet.IsInitialized(),
"nsMetricsConfig::Init not called");
return mHasConfig;
}
private:
typedef void (nsMetricsConfig::*ForEachChildElementCallback)(nsIDOMElement *);
// Run a callback method for each child element of the given element.
void ForEachChildElement(nsIDOMElement *elem, ForEachChildElementCallback cb);
void ProcessToplevelElement(nsIDOMElement *elem);
void ProcessConfigChild(nsIDOMElement *elem);
void ProcessCollectorElement(nsIDOMElement *elem);
static PLDHashOperator CopyKey(nsStringHashKey *key, void *userData);
nsTHashtable<nsStringHashKey> mEventSet;
nsDataHashtable<nsStringHashKey,nsString> mNSURIToPrefixMap;
PRInt32 mEventLimit;
PRInt32 mUploadInterval;
PRBool mHasConfig;
};
#endif // nsMetricsConfig_h__

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

@ -1,153 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsMetricsEventItem.h"
#include "nsIPropertyBag.h"
nsMetricsEventItem::nsMetricsEventItem(const nsAString &itemNamespace,
const nsAString &itemName)
: mNamespace(itemNamespace), mName(itemName)
{
}
nsMetricsEventItem::~nsMetricsEventItem()
{
}
NS_IMPL_ISUPPORTS1(nsMetricsEventItem, nsIMetricsEventItem)
NS_IMETHODIMP
nsMetricsEventItem::GetItemNamespace(nsAString &result)
{
result = mNamespace;
return NS_OK;
}
NS_IMETHODIMP
nsMetricsEventItem::GetItemName(nsAString &result)
{
result = mName;
return NS_OK;
}
NS_IMETHODIMP
nsMetricsEventItem::GetProperties(nsIPropertyBag **aProperties)
{
NS_IF_ADDREF(*aProperties = mProperties);
return NS_OK;
}
NS_IMETHODIMP
nsMetricsEventItem::SetProperties(nsIPropertyBag *aProperties)
{
// This do_QueryInterface() shouldn't be necessary, but is needed to avoid
// assertions from nsCOMPtr when an nsIWritablePropertyBag2 is passed in.
mProperties = do_QueryInterface(aProperties);
return NS_OK;
}
NS_IMETHODIMP
nsMetricsEventItem::ChildAt(PRInt32 index, nsIMetricsEventItem **result)
{
NS_ENSURE_ARG_RANGE(index, 0, PRInt32(mChildren.Length()) - 1);
NS_ADDREF(*result = mChildren[index]);
return NS_OK;
}
NS_IMETHODIMP
nsMetricsEventItem::IndexOf(nsIMetricsEventItem *item, PRInt32 *result)
{
*result = PRInt32(mChildren.IndexOf(item)); // NoIndex mapped to -1
return NS_OK;
}
NS_IMETHODIMP
nsMetricsEventItem::AppendChild(nsIMetricsEventItem *item)
{
NS_ENSURE_ARG_POINTER(item);
NS_ENSURE_TRUE(mChildren.AppendElement(item), NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
NS_IMETHODIMP
nsMetricsEventItem::InsertChildAt(nsIMetricsEventItem *item, PRInt32 index)
{
NS_ENSURE_ARG_POINTER(item);
// allow appending
NS_ENSURE_ARG_RANGE(index, 0, PRInt32(mChildren.Length()));
NS_ENSURE_TRUE(mChildren.InsertElementAt(index, item),
NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
NS_IMETHODIMP
nsMetricsEventItem::RemoveChildAt(PRInt32 index)
{
NS_ENSURE_ARG_RANGE(index, 0, PRInt32(mChildren.Length()) - 1);
mChildren.RemoveElementAt(index);
return NS_OK;
}
NS_IMETHODIMP
nsMetricsEventItem::ReplaceChildAt(nsIMetricsEventItem *newItem, PRInt32 index)
{
NS_ENSURE_ARG_POINTER(newItem);
NS_ENSURE_ARG_RANGE(index, 0, PRInt32(mChildren.Length()) - 1);
mChildren.ReplaceElementsAt(index, 1, newItem);
return NS_OK;
}
NS_IMETHODIMP
nsMetricsEventItem::ClearChildren()
{
mChildren.Clear();
return NS_OK;
}
NS_IMETHODIMP
nsMetricsEventItem::GetChildCount(PRInt32 *childCount)
{
*childCount = PRInt32(mChildren.Length());
return NS_OK;
}

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

@ -1,69 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsMetricsEventItem_h__
#define nsMetricsEventItem_h__
#include "nsIMetricsService.h"
#include "nsTArray.h"
#include "nsCOMPtr.h"
#include "nsStringAPI.h"
class nsIPropertyBag;
// nsMetricsEventItem implements a single event item that can store properties.
class nsMetricsEventItem : public nsIMetricsEventItem
{
public:
nsMetricsEventItem(const nsAString &itemNamespace,
const nsAString &itemName);
NS_DECL_ISUPPORTS
NS_DECL_NSIMETRICSEVENTITEM
private:
~nsMetricsEventItem();
nsString mNamespace;
nsString mName;
nsCOMPtr<nsIPropertyBag> mProperties;
nsTArray< nsCOMPtr<nsIMetricsEventItem> > mChildren;
};
#endif // nsMetricsEventItem_h__

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -1,325 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsMetricsService_h__
#define nsMetricsService_h__
#include "nsIMetricsService.h"
#include "nsMetricsModule.h"
#include "nsMetricsConfig.h"
#include "nsIAboutModule.h"
#include "nsIStreamListener.h"
#include "nsIOutputStream.h"
#include "nsIObserver.h"
#include "nsITimer.h"
#include "nsCOMPtr.h"
#include "prio.h"
#include "prlog.h"
#include "nsIWritablePropertyBag2.h"
#include "nsDataHashtable.h"
#include "nsInterfaceHashtable.h"
#include "nsPtrHashKey.h"
#include "blapit.h"
class nsILocalFile;
class nsIDOMWindow;
class nsIDOMDocument;
class nsIDOMNode;
class nsIMetricsCollector;
class nsIDocShellTreeItem;
#ifdef PR_LOGGING
// Shared log for the metrics service and collectors.
// (NSPR_LOG_MODULES=nsMetricsService:5)
extern PRLogModuleInfo *gMetricsLog;
#endif
#define MS_LOG(args) PR_LOG(gMetricsLog, PR_LOG_DEBUG, args)
#define MS_LOG_ENABLED() PR_LOG_TEST(gMetricsLog, PR_LOG_DEBUG)
// This is the namespace for the built-in metrics events.
#define NS_METRICS_NAMESPACE "http://www.mozilla.org/metrics"
// This class manages the metrics datastore. It is responsible for persisting
// the data when the browser closes and for uploading it to the metrics server
// periodically.
class nsMetricsService : public nsIMetricsService
, public nsIAboutModule
, public nsIStreamListener
, public nsIObserver
, public nsITimerCallback
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIMETRICSSERVICE
NS_DECL_NSIABOUTMODULE
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIOBSERVER
NS_DECL_NSITIMERCALLBACK
// Get the metrics service singleton. This method will call do_GetService if
// necessary to fetch the metrics service. It relies on the service manager
// to keep the singleton instance alive. This method may return null!
static nsMetricsService* get();
// Create the metrics service singleton, called only by the XPCOM factory for
// this class.
static NS_METHOD Create(nsISupports *outer, const nsIID &iid, void **result);
// Helper function for logging events in the default namespace
nsresult LogEvent(const nsAString &eventName,
nsIWritablePropertyBag2 *eventProperties)
{
nsCOMPtr<nsIPropertyBag> bag = do_QueryInterface(eventProperties);
NS_ENSURE_STATE(bag);
return LogSimpleEvent(NS_LITERAL_STRING(NS_METRICS_NAMESPACE), eventName,
bag);
}
// Creates an EventItem in the default metrics namespace.
nsresult CreateEventItem(const nsAString &name, nsIMetricsEventItem **item)
{
return CreateEventItem(NS_LITERAL_STRING(NS_METRICS_NAMESPACE),
name, item);
}
// More convenient non-scriptable version of GetWindowID().
static PRUint32 GetWindowID(nsIDOMWindow *window);
// VC6 needs this to be public :-(
nsresult Init();
// Returns the window id map (readonly)
const nsDataHashtable< nsPtrHashKey<nsIDOMWindow>, PRUint32 >&
WindowMap() const
{
return mWindowMap;
}
// Creates a one-way hash of the given string.
nsresult HashUTF8(const nsCString &str, nsCString &hashed);
// Convenience method for hashing UTF-16 strings.
// The string is converted to UTF-8, then HashUTF8() is called.
nsresult HashUTF16(const nsString &str, nsCString &hashed) {
return HashUTF8(NS_ConvertUTF16toUTF8(str), hashed);
}
private:
nsMetricsService();
~nsMetricsService();
// Post-profile-initialization startup code
nsresult ProfileStartup();
// Reads the config, starts a new session, and turns on collectors
nsresult StartCollection();
// Stops collectors and removes all metrics-related prefs and files
nsresult StopCollection();
// Starts and stops collectors based on the current configuration
void EnableCollectors();
// Creates a new root element to hold event nodes
nsresult CreateRoot();
nsresult UploadData();
nsresult GetDataFile(nsCOMPtr<nsILocalFile> *result);
nsresult OpenDataFile(PRUint32 flags, PRFileDesc **result);
nsresult GetDataFileForUpload(nsCOMPtr<nsILocalFile> *result);
// This method returns an input stream containing the complete XML for the
// data to upload.
nsresult OpenCompleteXMLStream(nsILocalFile *dataFile,
nsIInputStream **result);
// Initialize our timer for the next upload.
// If immediate is true, the timer will be fired as soon as possible,
// which is at the deferred-upload time if one exists, or immediately
// if not.
void InitUploadTimer(PRBool immediate);
// A reference to the local file containing our current configuration
void GetConfigFile(nsIFile **result);
// A reference to the local file where we'll download the server response.
// We don't replace the real config file until we know the new one is valid.
void GetConfigTempFile(nsIFile **result);
// Generate a new random client id string
nsresult GenerateClientID(nsCString &clientID);
// Check if a built-in event is enabled
PRBool IsEventEnabled(const nsAString &event) const
{
return mConfig.IsEventEnabled(NS_LITERAL_STRING(NS_METRICS_NAMESPACE),
event);
}
// Builds up a DOMElement tree from the given item and its children
nsresult BuildEventItem(nsIMetricsEventItem *item,
nsIDOMElement **itemElement);
// Called to persist mEventCount. Returns "true" if succeeded.
PRBool PersistEventCount();
// Hashes a byte buffer of the given length
nsresult HashBytes(const PRUint8 *bytes, PRUint32 length,
nsACString &result);
// Does the real work of GetWindowID().
PRUint32 GetWindowIDInternal(nsIDOMWindow *window);
// Tries to load a new config. If successful, the old config file is
// replaced with the new one. If the new config couldn't be loaded,
// a config file is written which disables collection and preserves the
// upload interval from the old config. Returns true if the new config
// file was loaded successfully.
PRBool LoadNewConfig(nsIFile *newConfig, nsIFile *oldConfig);
// Removes the existing data file (metrics.xml)
void RemoveDataFile();
// Generates a random interval, in seconds, between 12 and 36 hours.
PRInt32 GetRandomUploadInterval();
static PLDHashOperator
PruneDisabledCollectors(const nsAString &key,
nsCOMPtr<nsIMetricsCollector> &value,
void *userData);
static PLDHashOperator
DetachCollector(const nsAString &key,
nsIMetricsCollector *value, void *userData);
static PLDHashOperator
NotifyNewLog(const nsAString &key,
nsIMetricsCollector *value, void *userData);
// Helpers to set a pref and then flush the pref file to disk.
static nsresult FlushIntPref(const char *prefName, PRInt32 prefValue);
static nsresult FlushCharPref(const char *prefName, const char *prefValue);
static nsresult FlushClearPref(const char *prefName);
// Returns true if the pref to enable collection is set to true
static PRBool CollectionEnabled();
private:
class BadCertListener;
// Pointer to the metrics service singleton
static nsMetricsService* sMetricsService;
nsMetricsConfig mConfig;
// This output stream is non-null when we are downloading the config file.
nsCOMPtr<nsIOutputStream> mConfigOutputStream;
// XML document containing events to be flushed.
nsCOMPtr<nsIDOMDocument> mDocument;
// Root element of the XML document
nsCOMPtr<nsIDOMNode> mRoot;
// MD5 hashing object for collectors to use
MD5Context *mMD5Context;
// Window to incrementing-id map. The keys are nsIDOMWindow*.
nsDataHashtable< nsPtrHashKey<nsIDOMWindow>, PRUint32 > mWindowMap;
// All of the active observers, keyed by name.
nsInterfaceHashtable<nsStringHashKey, nsIMetricsCollector> mCollectorMap;
// Timer object used for uploads
nsCOMPtr<nsITimer> mUploadTimer;
// The max number of times we'll retry the upload before stopping
// for several hours.
static const PRUint32 kMaxRetries;
// This is the logging format version that is sent with each upload.
// The version should be incremented whenver a change is made that
// affects the log output, including but not limited to:
// - adding or removing a collector
// - adding or removing a property
// - changing the meaning or interpretation of a property value
static const PRUint32 kMetricsVersion;
PRInt32 mEventCount;
PRInt32 mSuspendCount;
PRBool mUploading;
nsString mSessionID;
// the next window id to hand out
PRUint32 mNextWindowID;
// The number of times we've tried to upload
PRUint32 mRetryCount;
};
class nsMetricsUtils
{
public:
// Creates a new nsIWritablePropertyBag2 instance.
static nsresult NewPropertyBag(nsIWritablePropertyBag2 **result);
// Creates a new item with the given properties, and appends it to the parent
static nsresult AddChildItem(nsIMetricsEventItem *parent,
const nsAString &childName,
nsIPropertyBag *childProperties);
// Loops until the given number of random bytes have been returned
// from the OS. Returns true on success, or false if no random
// bytes are available
static PRBool GetRandomNoise(void *buf, PRSize size);
// Creates a new element in the metrics namespace, using the given
// ownerDocument and tag.
static nsresult CreateElement(nsIDOMDocument *ownerDoc,
const nsAString &tag, nsIDOMElement **element);
// Returns true if the docshell should be considered a subframe.
static PRBool IsSubframe(nsIDocShellTreeItem *docShell);
// Finds the window id for the DOMWindow containing |node|.
// Returns 0 if the window could not be found.
static PRUint32 FindWindowForNode(nsIDOMNode *node);
};
#endif // nsMetricsService_h__

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

@ -1,832 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsProfileCollector.h"
#include "nsMetricsService.h"
#include "prsystem.h"
#include "nsIXULAppInfo.h"
#include "nsXULAppAPI.h"
#include "nsIServiceManager.h"
#include "nsComponentManagerUtils.h"
#include "nsIExtensionManager.h"
#include "nsIRDFDataSource.h"
#include "nsIRDFService.h"
#include "rdf.h"
#include "nsIDOMPlugin.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsIScreenManager.h"
#include "nsILocalFile.h"
#include "nsDirectoryServiceUtils.h"
#include "nsAutoPtr.h"
#include "nsTArray.h"
#include "nsINavBookmarksService.h"
#include "nsINavHistoryService.h"
#include "nsILivemarkService.h"
#include "nsILocaleService.h"
#include "nsToolkitCompsCID.h"
#include "nsXPCOMCIDInternal.h"
// We need to suppress inclusion of nsString.h
#define nsString_h___
#include "nsIPluginHost.h"
#undef nsString_h___
// Logs data on all installed plugins.
class nsProfileCollector::PluginEnumerator
{
public:
PluginEnumerator() : mMetricsService(nsnull) {}
nsresult Init();
// Creates a MetricsEventItem for each installed plugin, and appends them
// to pluginsItem.
nsresult LogPlugins(nsIMetricsEventItem *pluginsItem);
private:
// Creates and returns a MetricsEventItem for a single plugin, or
// NULL on failure.
already_AddRefed<nsIMetricsEventItem> CreatePluginItem(nsIDOMPlugin *plugin);
nsRefPtr<nsMetricsService> mMetricsService;
};
// Logs data on all installed extensions
class nsProfileCollector::ExtensionEnumerator
{
public:
ExtensionEnumerator() : mMetricsService(nsnull) {}
nsresult Init();
// Creates a MetricsEventItem for each installed extension, and appends them
// to extensionsItem.
nsresult LogExtensions(nsIMetricsEventItem *extensionsItem);
private:
// Creates and returns a MetricsEventItem for a single extension,
// or NULL on failure.
already_AddRefed<nsIMetricsEventItem> CreateExtensionItem(
nsIUpdateItem *extension);
nsRefPtr<nsMetricsService> mMetricsService;
nsCOMPtr<nsIRDFService> mRDFService;
nsCOMPtr<nsIExtensionManager> mExtensionManager;
nsCOMPtr<nsIRDFDataSource> mExtensionsDS;
nsCOMPtr<nsIRDFResource> mDisabledResource;
};
// Counts the number of bookmark items and folders in a container
class nsProfileCollector::BookmarkCounter
{
public:
BookmarkCounter() {}
nsresult Init();
// These values correspond to indices of |count| for CountChildren().
enum BookmarkType {
ITEM,
FOLDER,
LIVEMARK,
SEPARATOR,
kLastBookmarkType
};
// Fills in |count| with the number of children of each BookmarkType.
// If |deep| is true, then the count will include children of all subfolders.
void CountChildren(PRInt64 root, PRBool deep, nsTArray<PRInt32> &count);
private:
void CountRecursive(nsINavHistoryContainerResultNode *root, PRBool deep,
nsTArray<PRInt32> &count);
nsCOMPtr<nsILivemarkService> mLivemarkService;
};
nsProfileCollector::nsProfileCollector()
: mLoggedProfile(PR_FALSE)
{
}
nsProfileCollector::~nsProfileCollector()
{
}
NS_IMPL_ISUPPORTS1(nsProfileCollector, nsIMetricsCollector)
NS_IMETHODIMP
nsProfileCollector::OnAttach()
{
return NS_OK;
}
NS_IMETHODIMP
nsProfileCollector::OnDetach()
{
return NS_OK;
}
NS_IMETHODIMP
nsProfileCollector::OnNewLog()
{
if (mLoggedProfile) {
return NS_OK;
}
nsMetricsService *ms = nsMetricsService::get();
nsCOMPtr<nsIMetricsEventItem> profileItem;
ms->CreateEventItem(NS_LITERAL_STRING("profile"),
getter_AddRefs(profileItem));
NS_ENSURE_STATE(profileItem);
LogCPU(profileItem);
LogMemory(profileItem);
LogOS(profileItem);
LogInstall(profileItem);
LogExtensions(profileItem);
LogPlugins(profileItem);
LogDisplay(profileItem);
LogBookmarks(profileItem);
nsresult rv = ms->LogEvent(profileItem);
NS_ENSURE_SUCCESS(rv, rv);
mLoggedProfile = PR_TRUE;
return NS_OK;
}
nsresult
nsProfileCollector::LogCPU(nsIMetricsEventItem *profile)
{
nsCOMPtr<nsIWritablePropertyBag2> properties;
nsMetricsUtils::NewPropertyBag(getter_AddRefs(properties));
NS_ENSURE_STATE(properties);
char buf[SYS_INFO_BUFFER_LENGTH];
if (PR_GetSystemInfo(PR_SI_ARCHITECTURE, buf, sizeof(buf)) != PR_SUCCESS) {
MS_LOG(("Failed to get architecture"));
return NS_ERROR_FAILURE;
}
properties->SetPropertyAsACString(NS_LITERAL_STRING("arch"),
nsDependentCString(buf));
MS_LOG(("Logged CPU arch=%s", buf));
nsresult rv = nsMetricsUtils::AddChildItem(
profile, NS_LITERAL_STRING("cpu"), properties);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
nsProfileCollector::LogMemory(nsIMetricsEventItem *profile)
{
nsCOMPtr<nsIWritablePropertyBag2> properties;
nsMetricsUtils::NewPropertyBag(getter_AddRefs(properties));
NS_ENSURE_STATE(properties);
static PRUint64 size = PR_GetPhysicalMemorySize();
if (size == 0) {
MS_LOG(("Failed to get physical memory size"));
return NS_ERROR_FAILURE;
}
PRUint64 sizeMB = size >> 20;
properties->SetPropertyAsUint64(NS_LITERAL_STRING("mb"), sizeMB);
MS_LOG(("Logged memory mb=%ull", sizeMB));
nsresult rv = nsMetricsUtils::AddChildItem(
profile, NS_LITERAL_STRING("memory"), properties);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
nsProfileCollector::LogOS(nsIMetricsEventItem *profile)
{
nsCOMPtr<nsIWritablePropertyBag2> properties;
nsMetricsUtils::NewPropertyBag(getter_AddRefs(properties));
NS_ENSURE_STATE(properties);
char buf[SYS_INFO_BUFFER_LENGTH];
if (PR_GetSystemInfo(PR_SI_SYSNAME, buf, sizeof(buf)) != PR_SUCCESS) {
MS_LOG(("Failed to get OS name"));
return NS_ERROR_FAILURE;
}
properties->SetPropertyAsACString(NS_LITERAL_STRING("name"),
nsDependentCString(buf));
MS_LOG(("Logged os name=%s", buf));
if (PR_GetSystemInfo(PR_SI_RELEASE, buf, sizeof(buf)) != PR_SUCCESS) {
MS_LOG(("Failed to get OS version"));
return NS_ERROR_FAILURE;
}
properties->SetPropertyAsACString(NS_LITERAL_STRING("version"),
nsDependentCString(buf));
MS_LOG(("Logged os version=%s", buf));
nsresult rv = nsMetricsUtils::AddChildItem(
profile, NS_LITERAL_STRING("os"), properties);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
nsProfileCollector::LogInstall(nsIMetricsEventItem *profile)
{
nsCOMPtr<nsIWritablePropertyBag2> properties;
nsMetricsUtils::NewPropertyBag(getter_AddRefs(properties));
NS_ENSURE_STATE(properties);
nsCOMPtr<nsIXULAppInfo> appInfo =
do_GetService(XULAPPINFO_SERVICE_CONTRACTID);
NS_ENSURE_STATE(appInfo);
nsCString buildID;
appInfo->GetAppBuildID(buildID);
properties->SetPropertyAsACString(NS_LITERAL_STRING("buildid"), buildID);
MS_LOG(("Logged install buildid=%s", buildID.get()));
nsCOMPtr<nsIExtensionManager> em = do_GetService("@mozilla.org/extensions/manager;1");
NS_ENSURE_STATE(em);
nsCOMPtr<nsIUpdateItem> item;
nsresult rv = em->GetItemForID(NS_LITERAL_STRING("metrics@mozilla.org"), getter_AddRefs(item));
NS_ENSURE_SUCCESS(rv, rv);
// get the metrics extension version
nsAutoString extversion;
rv = item->GetVersion(extversion);
NS_ENSURE_SUCCESS(rv, rv);
properties->SetPropertyAsAString(NS_LITERAL_STRING("extversion"), extversion);
MS_LOG(("Logged install extversion=%s", NS_ConvertUTF16toUTF8(extversion).get()));
// get the application version
nsCString appversion;
appInfo->GetVersion(appversion);
properties->SetPropertyAsACString(NS_LITERAL_STRING("appversion"), appversion);
MS_LOG(("Logged install appversion=%s", appversion.get()));
// get the application locale
nsCOMPtr<nsILocaleService> ls = do_GetService(NS_LOCALESERVICE_CONTRACTID);
NS_ENSURE_STATE(ls);
nsCOMPtr<nsILocale> locale(nsnull);
rv = ls->GetApplicationLocale(getter_AddRefs(locale));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString l;
rv = locale->GetCategory(NS_LITERAL_STRING("NSILOCALE_CTYPE"), l);
NS_ENSURE_SUCCESS(rv, rv);
properties->SetPropertyAsAString(NS_LITERAL_STRING("locale"), l);
MS_LOG(("Logged install locale=%s", NS_ConvertUTF16toUTF8(l).get()));
// The file defaults/pref/channel-prefs.js is exlucded from any
// security update, so we can use its creation time as an indicator
// of when this installation was performed.
nsCOMPtr<nsIFile> prefsDirectory;
NS_GetSpecialDirectory(NS_APP_PREF_DEFAULTS_50_DIR,
getter_AddRefs(prefsDirectory));
nsCOMPtr<nsILocalFile> channelPrefs = do_QueryInterface(prefsDirectory);
NS_ENSURE_STATE(channelPrefs);
rv = channelPrefs->Append(NS_LITERAL_STRING("channel-prefs.js"));
NS_ENSURE_SUCCESS(rv, rv);
nsCString nativePath;
channelPrefs->GetNativePath(nativePath);
PRFileInfo64 fileInfo;
if (PR_GetFileInfo64(nativePath.get(), &fileInfo) == PR_SUCCESS) {
// Convert the time to seconds since the epoch
PRInt64 installTime = fileInfo.creationTime / PR_USEC_PER_SEC;
static const int kSecondsPerDay = 60 * 60 * 24;
// Round down to the nearest full day
installTime = ((installTime / kSecondsPerDay) * kSecondsPerDay);
properties->SetPropertyAsInt64(NS_LITERAL_STRING("installdate"),
installTime);
MS_LOG(("Logged install installdate=%lld", installTime));
}
// TODO: log default= based on default-browser selection
properties->SetPropertyAsBool(NS_LITERAL_STRING("default"), PR_TRUE);
rv = nsMetricsUtils::AddChildItem(profile,
NS_LITERAL_STRING("install"), properties);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
nsProfileCollector::LogExtensions(nsIMetricsEventItem *profile)
{
nsCOMPtr<nsIMetricsEventItem> extensions;
nsMetricsService::get()->CreateEventItem(NS_LITERAL_STRING("extensions"),
getter_AddRefs(extensions));
NS_ENSURE_STATE(extensions);
ExtensionEnumerator enumerator;
nsresult rv = enumerator.Init();
NS_ENSURE_SUCCESS(rv, rv);
rv = enumerator.LogExtensions(extensions);
NS_ENSURE_SUCCESS(rv, rv);
rv = profile->AppendChild(extensions);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
nsProfileCollector::LogPlugins(nsIMetricsEventItem *profile)
{
nsCOMPtr<nsIMetricsEventItem> plugins;
nsMetricsService::get()->CreateEventItem(NS_LITERAL_STRING("plugins"),
getter_AddRefs(plugins));
NS_ENSURE_STATE(plugins);
PluginEnumerator enumerator;
nsresult rv = enumerator.Init();
NS_ENSURE_SUCCESS(rv, rv);
rv = enumerator.LogPlugins(plugins);
NS_ENSURE_SUCCESS(rv, rv);
rv = profile->AppendChild(plugins);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
nsProfileCollector::LogDisplay(nsIMetricsEventItem *profile)
{
nsCOMPtr<nsIWritablePropertyBag2> properties;
nsMetricsUtils::NewPropertyBag(getter_AddRefs(properties));
NS_ENSURE_STATE(properties);
nsCOMPtr<nsIScreenManager> screenManager =
do_GetService("@mozilla.org/gfx/screenmanager;1");
NS_ENSURE_STATE(screenManager);
nsCOMPtr<nsIScreen> primaryScreen;
screenManager->GetPrimaryScreen(getter_AddRefs(primaryScreen));
NS_ENSURE_STATE(primaryScreen);
PRInt32 left, top, width, height;
nsresult rv = primaryScreen->GetRect(&left, &top, &width, &height);
NS_ENSURE_SUCCESS(rv, rv);
properties->SetPropertyAsInt32(NS_LITERAL_STRING("xsize"), width);
properties->SetPropertyAsInt32(NS_LITERAL_STRING("ysize"), height);
MS_LOG(("Logged display xsize=%d ysize=%d", width, height));
PRUint32 numScreens = 0;
if (NS_SUCCEEDED(screenManager->GetNumberOfScreens(&numScreens))) {
properties->SetPropertyAsUint32(NS_LITERAL_STRING("screens"), numScreens);
MS_LOG(("Logged display screens=%d", numScreens));
} else {
MS_LOG(("Could not get number of screens"));
}
rv = nsMetricsUtils::AddChildItem(profile,
NS_LITERAL_STRING("display"), properties);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
nsProfileCollector::LogBookmarks(nsIMetricsEventItem *profile)
{
nsresult rv;
nsMetricsService *ms = nsMetricsService::get();
NS_ENSURE_STATE(ms);
nsCOMPtr<nsIMetricsEventItem> bookmarksItem;
ms->CreateEventItem(NS_LITERAL_STRING("bookmarks"),
getter_AddRefs(bookmarksItem));
NS_ENSURE_STATE(bookmarksItem);
nsCOMPtr<nsINavBookmarksService> bmSvc =
do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID);
NS_ENSURE_STATE(bmSvc);
PRInt64 root = 0;
rv = bmSvc->GetPlacesRoot(&root);
NS_ENSURE_SUCCESS(rv, rv);
BookmarkCounter counter;
rv = counter.Init();
NS_ENSURE_SUCCESS(rv, rv);
LogBookmarkLocation(bookmarksItem, NS_LITERAL_CSTRING("full-tree"),
&counter, root, PR_TRUE);
rv = bmSvc->GetBookmarksMenuFolder(&root);
NS_ENSURE_SUCCESS(rv, rv);
LogBookmarkLocation(bookmarksItem, NS_LITERAL_CSTRING("root"),
&counter, root, PR_FALSE);
rv = bmSvc->GetToolbarFolder(&root);
NS_ENSURE_SUCCESS(rv, rv);
LogBookmarkLocation(bookmarksItem, NS_LITERAL_CSTRING("toolbar"),
&counter, root, PR_FALSE);
rv = profile->AppendChild(bookmarksItem);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
void
nsProfileCollector::LogBookmarkLocation(nsIMetricsEventItem *bookmarksItem,
const nsACString &location,
BookmarkCounter *counter,
PRInt64 root,
PRBool deep)
{
nsTArray<PRInt32> count;
counter->CountChildren(root, deep, count);
nsCOMPtr<nsIWritablePropertyBag2> props;
nsMetricsUtils::NewPropertyBag(getter_AddRefs(props));
if (!props) {
return;
}
props->SetPropertyAsACString(NS_LITERAL_STRING("name"), location);
props->SetPropertyAsInt32(NS_LITERAL_STRING("itemcount"),
count[BookmarkCounter::ITEM]);
props->SetPropertyAsInt32(NS_LITERAL_STRING("foldercount"),
count[BookmarkCounter::FOLDER]);
props->SetPropertyAsInt32(NS_LITERAL_STRING("livemarkcount"),
count[BookmarkCounter::LIVEMARK]);
props->SetPropertyAsInt32(NS_LITERAL_STRING("separatorcount"),
count[BookmarkCounter::SEPARATOR]);
nsMetricsUtils::AddChildItem(bookmarksItem,
NS_LITERAL_STRING("bookmarklocation"), props);
}
nsresult
nsProfileCollector::PluginEnumerator::Init()
{
mMetricsService = nsMetricsService::get();
NS_ENSURE_STATE(mMetricsService);
return NS_OK;
}
nsresult
nsProfileCollector::PluginEnumerator::LogPlugins(
nsIMetricsEventItem *pluginsItem)
{
nsCOMPtr<nsIPluginHost> host = do_GetService("@mozilla.org/plugin/host;1");
NS_ENSURE_STATE(host);
PRUint32 pluginCount = 0;
host->GetPluginCount(&pluginCount);
if (pluginCount == 0) {
return NS_OK;
}
nsIDOMPlugin **plugins = new nsIDOMPlugin*[pluginCount];
NS_ENSURE_TRUE(plugins, NS_ERROR_OUT_OF_MEMORY);
nsresult rv = host->GetPlugins(pluginCount, plugins);
if (NS_SUCCEEDED(rv)) {
for (PRUint32 i = 0; i < pluginCount; ++i) {
nsIDOMPlugin *plugin = plugins[i];
if (!plugin) {
NS_WARNING("null plugin in array");
continue;
}
nsCOMPtr<nsIMetricsEventItem> item = CreatePluginItem(plugin);
if (item) {
pluginsItem->AppendChild(item);
}
NS_RELEASE(plugin);
}
}
delete[] plugins;
return rv;
}
already_AddRefed<nsIMetricsEventItem>
nsProfileCollector::PluginEnumerator::CreatePluginItem(nsIDOMPlugin *plugin)
{
nsCOMPtr<nsIMetricsEventItem> pluginItem;
mMetricsService->CreateEventItem(NS_LITERAL_STRING("plugin"),
getter_AddRefs(pluginItem));
NS_ENSURE_TRUE(pluginItem, nsnull);
nsCOMPtr<nsIWritablePropertyBag2> properties;
nsMetricsUtils::NewPropertyBag(getter_AddRefs(properties));
NS_ENSURE_TRUE(properties, nsnull);
nsString name, filename;
plugin->GetName(name);
plugin->GetFilename(filename);
nsCString hashedName, hashedFilename;
nsresult rv = mMetricsService->HashUTF16(name, hashedName);
NS_ENSURE_SUCCESS(rv, nsnull);
rv = mMetricsService->HashUTF16(filename, hashedFilename);
NS_ENSURE_SUCCESS(rv, nsnull);
properties->SetPropertyAsACString(NS_LITERAL_STRING("name"), hashedName);
properties->SetPropertyAsACString(NS_LITERAL_STRING("filename"),
hashedFilename);
MS_LOG(("Logged plugin name=%s (hashed to %s) filename=%s (hashed to %s)",
NS_ConvertUTF16toUTF8(name).get(), hashedName.get(),
NS_ConvertUTF16toUTF8(filename).get(), hashedFilename.get()));
// TODO(bryner): log the version, if there's a way to find it
pluginItem->SetProperties(properties);
nsIMetricsEventItem *item = nsnull;
pluginItem.swap(item);
return item;
}
nsresult
nsProfileCollector::ExtensionEnumerator::Init()
{
mMetricsService = nsMetricsService::get();
NS_ENSURE_STATE(mMetricsService);
mRDFService = do_GetService("@mozilla.org/rdf/rdf-service;1");
NS_ENSURE_STATE(mRDFService);
mRDFService->GetResource(
NS_LITERAL_CSTRING("http://www.mozilla.org/2004/em-rdf#disabled"),
getter_AddRefs(mDisabledResource));
NS_ENSURE_STATE(mDisabledResource);
mExtensionManager = do_GetService("@mozilla.org/extensions/manager;1");
NS_ENSURE_STATE(mExtensionManager);
mExtensionManager->GetDatasource(getter_AddRefs(mExtensionsDS));
NS_ENSURE_STATE(mExtensionsDS);
return NS_OK;
}
nsresult
nsProfileCollector::ExtensionEnumerator::LogExtensions(
nsIMetricsEventItem *extensionsItem)
{
PRUint32 count = 0;
nsIUpdateItem **extensions = nsnull;
nsresult rv = mExtensionManager->GetItemList(nsIUpdateItem::TYPE_EXTENSION,
&count, &extensions);
NS_ENSURE_SUCCESS(rv, rv);
if (count == 0) {
return NS_OK;
}
NS_ENSURE_STATE(extensions);
for (PRUint32 i = 0; i < count; ++i) {
nsIUpdateItem *extension = extensions[i];
if (!extension) {
NS_WARNING("null extension in array");
continue;
}
nsCOMPtr<nsIMetricsEventItem> item = CreateExtensionItem(extension);
if (item) {
extensionsItem->AppendChild(item);
}
NS_RELEASE(extension);
}
NS_Free(extensions);
return NS_OK;
}
already_AddRefed<nsIMetricsEventItem>
nsProfileCollector::ExtensionEnumerator::CreateExtensionItem(
nsIUpdateItem *extension)
{
nsCOMPtr<nsIMetricsEventItem> extensionItem;
mMetricsService->CreateEventItem(NS_LITERAL_STRING("extension"),
getter_AddRefs(extensionItem));
NS_ENSURE_TRUE(extensionItem, nsnull);
nsCOMPtr<nsIWritablePropertyBag2> properties;
nsMetricsUtils::NewPropertyBag(getter_AddRefs(properties));
NS_ENSURE_TRUE(properties, nsnull);
nsString id, version;
extension->GetId(id);
NS_ENSURE_TRUE(!id.IsEmpty(), nsnull);
nsCString hashedID;
nsresult rv = mMetricsService->HashUTF16(id, hashedID);
NS_ENSURE_SUCCESS(rv, nsnull);
properties->SetPropertyAsACString(
NS_LITERAL_STRING("extensionid"), hashedID);
extension->GetVersion(version);
if (!version.IsEmpty()) {
properties->SetPropertyAsAString(NS_LITERAL_STRING("version"), version);
}
MS_LOG(("Logged extension extensionid=%s (hashed to %s) version=%s",
NS_ConvertUTF16toUTF8(id).get(), hashedID.get(),
NS_ConvertUTF16toUTF8(version).get()));
nsCString resourceID("urn:mozilla:item:");
resourceID.Append(NS_ConvertUTF16toUTF8(id));
nsCOMPtr<nsIRDFResource> itemResource;
mRDFService->GetResource(resourceID, getter_AddRefs(itemResource));
NS_ENSURE_TRUE(itemResource, nsnull);
nsCOMPtr<nsIRDFNode> itemDisabledNode;
mExtensionsDS->GetTarget(itemResource, mDisabledResource, PR_TRUE,
getter_AddRefs(itemDisabledNode));
nsCOMPtr<nsIRDFLiteral> itemDisabledLiteral =
do_QueryInterface(itemDisabledNode);
if (itemDisabledLiteral) {
const PRUnichar *value = nsnull;
itemDisabledLiteral->GetValueConst(&value);
if (nsDependentString(value).Equals(NS_LITERAL_STRING("true"))) {
properties->SetPropertyAsBool(NS_LITERAL_STRING("disabled"), PR_TRUE);
MS_LOG(("Logged extension disabled=true"));
}
}
extensionItem->SetProperties(properties);
nsIMetricsEventItem *item = nsnull;
extensionItem.swap(item);
return item;
}
nsresult
nsProfileCollector::BookmarkCounter::Init()
{
mLivemarkService = do_GetService(NS_LIVEMARKSERVICE_CONTRACTID);
NS_ENSURE_STATE(mLivemarkService);
return NS_OK;
}
void
nsProfileCollector::BookmarkCounter::CountChildren(PRInt64 root, PRBool deep,
nsTArray<PRInt32> &count)
{
count.SetLength(kLastBookmarkType);
for (PRInt32 i = 0; i < kLastBookmarkType; ++i) {
count[i] = 0;
}
nsCOMPtr<nsINavHistoryService> histSvc =
do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID);
if (!histSvc) {
return;
}
nsCOMPtr<nsINavHistoryQuery> query;
histSvc->GetNewQuery(getter_AddRefs(query));
if (!query) {
return;
}
query->SetFolders(&root, 1);
query->SetOnlyBookmarked(PR_TRUE);
nsCOMPtr<nsINavHistoryQueryOptions> options;
histSvc->GetNewQueryOptions(getter_AddRefs(options));
if (!options) {
return;
}
// setting option breaks bookmark count
// const PRUint16 groupMode = nsINavHistoryQueryOptions::GROUP_BY_FOLDER;
// options->SetGroupingMode(&groupMode, 1);
nsCOMPtr<nsINavHistoryResult> result;
histSvc->ExecuteQuery(query, options, getter_AddRefs(result));
if (!result) {
return;
}
nsCOMPtr<nsINavHistoryContainerResultNode> rootNode;
result->GetRoot(getter_AddRefs(rootNode));
if (!rootNode) {
return;
}
CountRecursive(rootNode, deep, count);
}
void
nsProfileCollector::BookmarkCounter::CountRecursive(
nsINavHistoryContainerResultNode *root, PRBool deep,
nsTArray<PRInt32> &count)
{
root->SetContainerOpen(PR_TRUE);
PRUint32 childCount = 0;
root->GetChildCount(&childCount);
for (PRUint32 i = 0; i < childCount; ++i) {
nsCOMPtr<nsINavHistoryResultNode> child;
root->GetChild(i, getter_AddRefs(child));
if (!child) {
continue;
}
PRUint32 type = 0;
child->GetType(&type);
if (type == nsINavHistoryResultNode::RESULT_TYPE_URI)
{
++count[ITEM];
}
else if (type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER)
{
nsCOMPtr<nsINavHistoryContainerResultNode> folder = do_QueryInterface(child);
if (!folder) continue;
PRInt64 folderID;
child->GetItemId(&folderID);
PRBool isLivemark = PR_FALSE;
mLivemarkService->IsLivemark(folderID, &isLivemark);
if (isLivemark) {
++count[LIVEMARK];
} else {
++count[FOLDER];
if (deep) {
CountRecursive(folder, deep, count);
}
}
} else if (type == nsINavHistoryResultNode::RESULT_TYPE_SEPARATOR) {
++count[SEPARATOR];
}
}
root->SetContainerOpen(PR_FALSE);
}

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

@ -1,90 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsProfileCollector_h_
#define nsProfileCollector_h_
#include "nsIMetricsCollector.h"
class nsISupports;
class nsIMetricsEventItem;
class nsIPropertyBag;
// This file defines the profile collector class, which generates
// a profile event at application startup. The profile event logs
// various information about the user's software and hardware configuration.
class nsProfileCollector : public nsIMetricsCollector
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIMETRICSCOLLECTOR
nsProfileCollector();
private:
class PluginEnumerator;
class ExtensionEnumerator;
class BookmarkCounter;
~nsProfileCollector();
// These methods each create a particular item and append it to the profile.
nsresult LogCPU(nsIMetricsEventItem *profile);
nsresult LogMemory(nsIMetricsEventItem *profile);
nsresult LogOS(nsIMetricsEventItem *profile);
nsresult LogInstall(nsIMetricsEventItem *profile);
nsresult LogExtensions(nsIMetricsEventItem *profile);
nsresult LogPlugins(nsIMetricsEventItem *profile);
nsresult LogDisplay(nsIMetricsEventItem *profile);
nsresult LogBookmarks(nsIMetricsEventItem *profile);
void LogBookmarkLocation(nsIMetricsEventItem *bookmarksItem,
const nsACString &location,
BookmarkCounter *counter,
PRInt64 root, PRBool deep);
// Track whether we've logged the profile yet this session.
PRBool mLoggedProfile;
};
#define NS_PROFILECOLLECTOR_CLASSNAME "Profile Collector"
#define NS_PROFILECOLLECTOR_CID \
{ 0x9d5d472d, 0x88c7, 0x4cb2, {0xa6, 0xfb, 0x1f, 0x8e, 0x4d, 0xb5, 0x7e, 0x7e}}
#endif // nsProfileCollector_h_

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

@ -1,50 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// This class defines a templatized hash key type for holding raw pointers.
// Use it like this:
// nsDataHashtable< nsPtrHashKey<SomeClass>, SomeValueType > mTable;
//
// This is identical to nsVoidPtrHashKey with void* replaced by T*.
#ifndef nsPtrHashKey_h_
#define nsPtrHashKey_h_
#include "nsHashKeys.h"
#endif // nsPtrHashKey_h_

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

@ -1,78 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsStringUtils.h"
#include "prprf.h"
void AppendInt(nsAString &str, PRInt64 val)
{
char buf[32];
PR_snprintf(buf, sizeof(buf), "%lld", val);
str.Append(NS_ConvertASCIItoUTF16(buf));
}
void AppendInt(nsAString &str, PRInt32 val)
{
char buf[32];
PR_snprintf(buf, sizeof(buf), "%ld", val);
str.Append(NS_ConvertASCIItoUTF16(buf));
}
PRInt32 FindChar(const nsAString &str, PRUnichar c)
{
const PRUnichar *start;
PRUint32 len = NS_StringGetData(str, &start);
const PRUnichar *iter = start, *end = start + len;
for (; iter != end; ++iter) {
if (*iter == c)
return iter - start;
}
return -1;
}
PRInt32 RFindChar(const nsAString &str, PRUnichar c)
{
const PRUnichar *start;
PRUint32 len = NS_StringGetData(str, &start);
const PRUnichar *end = start + len, *iter = end - 1;
for (; iter >= start; --iter) {
if (*iter == c)
return iter - start;
}
return -1;
}

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

@ -1,64 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsStringUtils_h__
#define nsStringUtils_h__
// TODO: move this into xpcom/glue and extend it with more APIs.
#include "nsStringAPI.h"
/**
* Append integer to string.
*/
void AppendInt(nsAString &str, PRInt32 val);
void AppendInt(nsAString &str, PRInt64 val);
/**
* Find a char in the given string.
* @returns offset of char, or -1 if not found.
*/
PRInt32 FindChar(const nsAString &str, PRUnichar c);
/**
* Find a char in the given string, searching from the end of the string.
* @returns offset of char, or -1 if not found.
*/
PRInt32 RFindChar(const nsAString &str, PRUnichar c);
#endif // nsStringUtils_h__

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

@ -1,527 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Marria Nazif <marria@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsUICommandCollector.h"
#include "nsMetricsService.h"
#include "nsServiceManagerUtils.h"
#include "nsIObserverService.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMEvent.h"
#include "nsIDOMNSEvent.h"
#include "nsIDOMXULCommandEvent.h"
#include "nsIDOMElement.h"
#include "nsIDOMWindow.h"
#include "nsDataHashtable.h"
#include "nsMemory.h"
const nsUICommandCollector::EventHandler nsUICommandCollector::kEvents[] = {
{ "command", &nsUICommandCollector::HandleCommandEvent },
{ "TabMove", &nsUICommandCollector::HandleTabMoveEvent },
{ "popupshowing", &nsUICommandCollector::HandlePopupShowingEvent },
};
NS_IMPL_ISUPPORTS3(nsUICommandCollector, nsIObserver, nsIDOMEventListener,
nsIMetricsCollector)
/* static */
PLDHashOperator nsUICommandCollector::AddCommandEventListener(
const nsIDOMWindow* key, PRUint32 windowID, void* userArg)
{
nsCOMPtr<nsIDOMEventTarget> windowTarget =
do_QueryInterface(const_cast<nsIDOMWindow *>(key));
if (!windowTarget) {
MS_LOG(("Error casting domeventtarget"));
return PL_DHASH_NEXT;
}
nsUICommandCollector* collector = static_cast<nsUICommandCollector*>
(userArg);
collector->AddEventListeners(windowTarget);
return PL_DHASH_NEXT;
}
/* static */
PLDHashOperator nsUICommandCollector::RemoveCommandEventListener(
const nsIDOMWindow* key, PRUint32 windowID, void* userArg)
{
nsCOMPtr<nsIDOMEventTarget> windowTarget =
do_QueryInterface(const_cast<nsIDOMWindow *>(key));
if (!windowTarget) {
MS_LOG(("Error casting domeventtarget"));
return PL_DHASH_NEXT;
}
nsUICommandCollector* collector = static_cast<nsUICommandCollector*>
(userArg);
collector->RemoveEventListeners(windowTarget);
return PL_DHASH_NEXT;
}
nsUICommandCollector::nsUICommandCollector()
{
}
nsUICommandCollector::~nsUICommandCollector()
{
}
// nsIMetricsCollector
NS_IMETHODIMP
nsUICommandCollector::OnAttach()
{
nsresult rv;
nsCOMPtr<nsIObserverService> obsSvc =
do_GetService("@mozilla.org/observer-service;1");
NS_ENSURE_STATE(obsSvc);
// Listen for newly opened windows, so that we can attach a command event
// listener to each window
rv = obsSvc->AddObserver(this, "domwindowopened", PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
// Attach to all existing windows
nsMetricsService *ms = nsMetricsService::get();
NS_ENSURE_STATE(ms);
ms->WindowMap().EnumerateRead(AddCommandEventListener,
static_cast<nsIDOMEventListener*>(this));
return NS_OK;
}
NS_IMETHODIMP
nsUICommandCollector::OnDetach()
{
nsresult rv;
nsCOMPtr<nsIObserverService> obsSvc =
do_GetService("@mozilla.org/observer-service;1");
NS_ENSURE_STATE(obsSvc);
// Remove our observer for open windows
rv = obsSvc->RemoveObserver(this, "domwindowopened");
NS_ENSURE_SUCCESS(rv, rv);
// Also iterate through all windows and try to remove command event
// listeners. It is possible that we never attached one to some
// of the windows (if we were detached and then attached) so
// continue on even if it fails
nsMetricsService *ms = nsMetricsService::get();
NS_ENSURE_STATE(ms);
ms->WindowMap().EnumerateRead(RemoveCommandEventListener,
static_cast<nsIDOMEventListener*>(this));
return NS_OK;
}
NS_IMETHODIMP
nsUICommandCollector::OnNewLog()
{
return NS_OK;
}
// nsIObserver
NS_IMETHODIMP
nsUICommandCollector::Observe(nsISupports *subject,
const char *topic,
const PRUnichar *data)
{
if (strcmp(topic, "domwindowopened") == 0) {
nsCOMPtr<nsIDOMEventTarget> window = do_QueryInterface(subject);
NS_ENSURE_STATE(window);
AddEventListeners(window);
}
return NS_OK;
}
// nsIDOMEventListener
NS_IMETHODIMP
nsUICommandCollector::HandleEvent(nsIDOMEvent* event)
{
// First check that this is an event type that we expect.
// If so, call the appropriate handler method.
nsString type;
nsresult rv = event->GetType(type);
NS_ENSURE_SUCCESS(rv, rv);
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(kEvents); ++i) {
if (NS_ConvertASCIItoUTF16(kEvents[i].event).Equals(type)) {
return (this->*(kEvents[i].handler))(event);
}
}
MS_LOG(("UICommandCollector: Unexpected event type %s received",
NS_ConvertUTF16toUTF8(type).get()));
return NS_ERROR_UNEXPECTED;
}
nsresult
nsUICommandCollector::HandleCommandEvent(nsIDOMEvent* event)
{
PRUint32 window;
if (NS_FAILED(GetEventWindow(event, &window))) {
return NS_OK;
}
nsString targetId, targetAnonId;
if (NS_FAILED(GetEventTargets(event, targetId, targetAnonId))) {
return NS_OK;
}
NS_ASSERTION(!targetId.IsEmpty(), "can't have an empty target id");
nsString keyId;
GetEventKeyId(event, keyId);
// Fill a property bag with what we want to log
nsCOMPtr<nsIWritablePropertyBag2> properties;
nsMetricsUtils::NewPropertyBag(getter_AddRefs(properties));
NS_ENSURE_STATE(properties);
nsresult rv;
rv = properties->SetPropertyAsUint32(NS_LITERAL_STRING("window"), window);
NS_ENSURE_SUCCESS(rv, rv);
rv = properties->SetPropertyAsAString(NS_LITERAL_STRING("action"),
NS_LITERAL_STRING("command"));
NS_ENSURE_SUCCESS(rv, rv);
rv = SetHashedValue(properties, NS_LITERAL_STRING("targetidhash"), targetId);
NS_ENSURE_SUCCESS(rv, rv);
if (!targetAnonId.IsEmpty()) {
rv = SetHashedValue(properties, NS_LITERAL_STRING("targetanonidhash"),
targetAnonId);
NS_ENSURE_SUCCESS(rv, rv);
}
if (!keyId.IsEmpty()) {
rv = SetHashedValue(properties, NS_LITERAL_STRING("keyidhash"), keyId);
NS_ENSURE_SUCCESS(rv, rv);
}
nsMetricsService *ms = nsMetricsService::get();
NS_ENSURE_STATE(ms);
nsCOMPtr<nsIMetricsEventItem> item;
ms->CreateEventItem(NS_LITERAL_STRING("uielement"), getter_AddRefs(item));
NS_ENSURE_STATE(item);
item->SetProperties(properties);
// Capture extra bookmark state onto the event if the target is a bookmark.
rv = LogBookmarkInfo(targetId, item);
NS_ENSURE_SUCCESS(rv, rv);
// Actually log it
rv = ms->LogEvent(item);
NS_ENSURE_SUCCESS(rv, rv);
MS_LOG(("Successfully logged UI Event"));
return NS_OK;
}
nsresult
nsUICommandCollector::HandleTabMoveEvent(nsIDOMEvent* event)
{
PRUint32 window;
if (NS_FAILED(GetEventWindow(event, &window))) {
return NS_OK;
}
// Fill a property bag with what we want to log
nsCOMPtr<nsIWritablePropertyBag2> properties;
nsMetricsUtils::NewPropertyBag(getter_AddRefs(properties));
NS_ENSURE_STATE(properties);
nsresult rv;
rv = properties->SetPropertyAsUint32(NS_LITERAL_STRING("window"), window);
NS_ENSURE_SUCCESS(rv, rv);
rv = properties->SetPropertyAsAString(NS_LITERAL_STRING("action"),
NS_LITERAL_STRING("comand"));
NS_ENSURE_SUCCESS(rv, rv);
// TabMove events just have a dummy target id of "TabMove_Event".
rv = SetHashedValue(properties, NS_LITERAL_STRING("targetidhash"),
NS_LITERAL_STRING("TabMove_Event"));
NS_ENSURE_SUCCESS(rv, rv);
nsMetricsService *ms = nsMetricsService::get();
NS_ENSURE_STATE(ms);
rv = ms->LogEvent(NS_LITERAL_STRING("uielement"), properties);
NS_ENSURE_SUCCESS(rv, rv);
MS_LOG(("Successfully logged UI Event"));
return NS_OK;
}
nsresult
nsUICommandCollector::HandlePopupShowingEvent(nsIDOMEvent* event)
{
PRUint32 window;
if (NS_FAILED(GetEventWindow(event, &window)))
return NS_OK;
nsString targetId, targetAnonId;
if (NS_FAILED(GetEventTargets(event, targetId, targetAnonId)))
return NS_OK;
NS_ASSERTION(!targetId.IsEmpty(), "can't have an empty target id");
if (!targetId.Equals(NS_LITERAL_STRING("identity-popup")) && !targetId.Equals(NS_LITERAL_STRING("editBookmarkPanel")))
return NS_OK;
// Fill a property bag with what we want to log
nsCOMPtr<nsIWritablePropertyBag2> properties;
nsMetricsUtils::NewPropertyBag(getter_AddRefs(properties));
NS_ENSURE_STATE(properties);
nsresult rv;
rv = properties->SetPropertyAsUint32(NS_LITERAL_STRING("window"), window);
NS_ENSURE_SUCCESS(rv, rv);
rv = properties->SetPropertyAsAString(NS_LITERAL_STRING("action"),
NS_LITERAL_STRING("popupshowing"));
NS_ENSURE_SUCCESS(rv, rv);
rv = SetHashedValue(properties, NS_LITERAL_STRING("targetidhash"), targetId);
NS_ENSURE_SUCCESS(rv, rv);
if (!targetAnonId.IsEmpty())
{
rv = SetHashedValue(properties, NS_LITERAL_STRING("targetanonidhash"),
targetAnonId);
NS_ENSURE_SUCCESS(rv, rv);
}
nsMetricsService *ms = nsMetricsService::get();
NS_ENSURE_STATE(ms);
nsCOMPtr<nsIMetricsEventItem> item;
ms->CreateEventItem(NS_LITERAL_STRING("uielement"), getter_AddRefs(item));
NS_ENSURE_STATE(item);
item->SetProperties(properties);
// Actually log it
rv = ms->LogEvent(item);
NS_ENSURE_SUCCESS(rv, rv);
MS_LOG(("Successfully logged UI popupshowing Event"));
return NS_OK;
}
nsresult
nsUICommandCollector::GetEventTargets(nsIDOMEvent *event,
nsString &targetId,
nsString &targetAnonId) const
{
// This code deals with both anonymous and explicit (non-anonymous) content.
//
// For explicit content, we just return the id of the event target in
// targetId, and leave targetAnonId empty. If there is no id, then
// we return failure.
//
// For anonymous content, we return the id of the event target (after
// retargeting), in targetId. We return the anonid of the event's
// originalTarget in targetAnonId, so that XBL child elements can be
// distinguished. If there is no anonid, then we return failure.
// Note that the originalTarget is set after text node retargting, but
// before any XBL retargeting.
//
// We assume that if the originalTarget has no id, we're dealing with
// anonymous content (this isn't always true, but it's good enough for what
// this code does).
nsCOMPtr<nsIDOMNSEvent> nsEvent = do_QueryInterface(event);
NS_ENSURE_STATE(nsEvent);
nsCOMPtr<nsIDOMEventTarget> originalTarget;
nsEvent->GetOriginalTarget(getter_AddRefs(originalTarget));
NS_ENSURE_STATE(originalTarget);
nsString origElementId;
nsCOMPtr<nsIDOMElement> origElement(do_QueryInterface(originalTarget));
if (origElement) {
origElement->GetAttribute(NS_LITERAL_STRING("id"), origElementId);
origElement->GetAttribute(NS_LITERAL_STRING("anonid"), targetAnonId);
}
nsCOMPtr<nsIDOMEventTarget> target;
event->GetTarget(getter_AddRefs(target));
NS_ENSURE_STATE(target);
nsCOMPtr<nsIDOMElement> targetElement(do_QueryInterface(target));
if (targetElement) {
targetElement->GetAttribute(NS_LITERAL_STRING("id"), targetId);
}
MS_LOG(("Original Target Id: %s, Original Target Anonid: %s, Target Id: %s",
NS_ConvertUTF16toUTF8(origElementId).get(),
NS_ConvertUTF16toUTF8(targetAnonId).get(),
NS_ConvertUTF16toUTF8(targetId).get()));
if (targetId.IsEmpty()) {
// There's nothing useful to log in this case -- even if we have an anonid,
// it's not possible to determine its position in the document.
MS_LOG(("Warning: skipping logging because of empty target ID"));
return NS_ERROR_FAILURE;
}
if (origElementId.IsEmpty()) {
// We're dealing with anonymous content, so don't continue if we didn't
// find an anonid.
if (targetAnonId.IsEmpty()) {
MS_LOG(("Warning: skipping logging because of empty anonid"));
return NS_ERROR_FAILURE;
}
} else {
// We're dealing with normal explicit content, so don't return an anonid.
targetAnonId.SetLength(0);
}
return NS_OK;
}
void
nsUICommandCollector::GetEventKeyId(nsIDOMEvent *event, nsString &keyId) const
{
// The source event will give us the original event in the case where a new
// event was dispatched due to a command= attribute.
nsCOMPtr<nsIDOMXULCommandEvent> commandEvent = do_QueryInterface(event);
if (!commandEvent) {
// nsIDOMXULCommandEvent is only in Gecko 1.8.1+
return;
}
nsCOMPtr<nsIDOMEvent> sourceEvent;
commandEvent->GetSourceEvent(getter_AddRefs(sourceEvent));
if (!sourceEvent) {
return;
}
nsCOMPtr<nsIDOMEventTarget> sourceEventTarget;
sourceEvent->GetTarget(getter_AddRefs(sourceEventTarget));
nsCOMPtr<nsIDOMElement> sourceElement = do_QueryInterface(sourceEventTarget);
if (!sourceElement) {
return;
}
nsString namespaceURI, localName;
sourceElement->GetNamespaceURI(namespaceURI);
sourceElement->GetLocalName(localName);
if (namespaceURI.Equals(NS_LITERAL_STRING("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul")) &&
localName.Equals(NS_LITERAL_STRING("key"))) {
sourceElement->GetAttribute(NS_LITERAL_STRING("id"), keyId);
MS_LOG(("Key Id: %s", NS_ConvertUTF16toUTF8(keyId).get()));
}
}
nsresult
nsUICommandCollector::GetEventWindow(nsIDOMEvent *event,
PRUint32 *window) const
{
nsCOMPtr<nsIDOMEventTarget> target;
event->GetTarget(getter_AddRefs(target));
nsCOMPtr<nsIDOMNode> targetNode = do_QueryInterface(target);
if (!targetNode) {
MS_LOG(("Warning: couldn't get window id because target is not a node"));
return NS_ERROR_FAILURE;
}
*window = nsMetricsUtils::FindWindowForNode(targetNode);
return NS_OK;
}
void
nsUICommandCollector::AddEventListeners(nsIDOMEventTarget *window)
{
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(kEvents); ++i) {
// Attach a capturing event listener to the window.
// Use capturing instead of bubbling so that we still record
// the event even if propagation is canceled for some reason.
// Using NS_LITERAL_STRING in const data is not allowed, so convert here.
// This is not performance-sensitive.
nsresult rv;
rv = window->AddEventListener(NS_ConvertASCIItoUTF16(kEvents[i].event),
this, PR_TRUE);
if (NS_FAILED(rv)) {
MS_LOG(("Couldn't add event listener %s", kEvents[i]));
}
}
}
void
nsUICommandCollector::RemoveEventListeners(nsIDOMEventTarget *window)
{
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(kEvents); ++i) {
// Using NS_LITERAL_STRING in const data is not allowed, so convert here.
// This is not performance-sensitive.
nsresult rv;
rv = window->RemoveEventListener(NS_ConvertASCIItoUTF16(kEvents[i].event),
this, PR_TRUE);
if (NS_FAILED(rv)) {
MS_LOG(("Couldn't remove event listener %s", kEvents[i]));
}
}
}
/* static */ nsresult
nsUICommandCollector::SetHashedValue(nsIWritablePropertyBag2 *properties,
const nsString &propertyName,
const nsString &propertyValue) const
{
nsMetricsService *ms = nsMetricsService::get();
NS_ENSURE_STATE(ms);
nsCString hashedValue;
nsresult rv = ms->HashUTF16(propertyValue, hashedValue);
NS_ENSURE_SUCCESS(rv, rv);
return properties->SetPropertyAsACString(propertyName, hashedValue);
}
nsresult
nsUICommandCollector::LogBookmarkInfo(const nsString& id,
nsIMetricsEventItem* parentItem)
{
// TODO: write me!
// see bug #356606
return NS_OK;
}

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

@ -1,126 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Marria Nazif <marria@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsUICommandCollector_h_
#define nsUICommandCollector_h_
#include "nsIObserver.h"
#include "nsIDOMEventListener.h"
#include "nsIMetricsCollector.h"
#include "nsDataHashtable.h"
class nsIDOMWindow;
class nsIMetricsEventItem;
class nsIWritablePropertyBag2;
class nsUICommandCollector : public nsIObserver,
public nsIDOMEventListener,
public nsIMetricsCollector
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
NS_DECL_NSIDOMEVENTLISTENER
NS_DECL_NSIMETRICSCOLLECTOR
static PLDHashOperator AddCommandEventListener(
const nsIDOMWindow* key, PRUint32 windowID, void* userArg);
static PLDHashOperator RemoveCommandEventListener(
const nsIDOMWindow* key, PRUint32 windowID, void* userArg);
nsUICommandCollector();
// Given a command event, determines the appropriate id and anonid values
// to log. Returns failure if no id or anonid exists for the event target.
nsresult GetEventTargets(nsIDOMEvent *event,
nsString &targetId, nsString &targetAnonId) const;
// Given a command event, determines whether the source was a key element.
// If so, keyId is set to the id of the element.
void GetEventKeyId(nsIDOMEvent *event, nsString &keyId) const;
// Given a DOM event, finds the id of the window that contains the target.
nsresult GetEventWindow(nsIDOMEvent *event, PRUint32 *window) const;
private:
// This struct specifies an event we want to handle, and the method
// that handles it.
struct EventHandler {
const char* event;
nsresult (nsUICommandCollector::* handler)(nsIDOMEvent*);
};
// The events we'll handle.
static const EventHandler kEvents[];
~nsUICommandCollector();
// Adds all of our event types as listeners on the window.
void AddEventListeners(nsIDOMEventTarget* window);
// Removes all of our event types as listeners on the window.
void RemoveEventListeners(nsIDOMEventTarget* window);
// Handles a XUL command event.
nsresult HandleCommandEvent(nsIDOMEvent* event);
// Handles a TabMove event from the tabbrowser widget.
nsresult HandleTabMoveEvent(nsIDOMEvent* event);
// Handles a popupshowing event from the tabbrowser widget.
nsresult HandlePopupShowingEvent(nsIDOMEvent* event);
// Checks whether the given target id corresponds to a bookmark resource,
// and if so, adds additional data about the bookmark to parentItem.
nsresult LogBookmarkInfo(const nsString& id,
nsIMetricsEventItem* parentItem);
// Hashes the given property value and adds it to the property bag.
nsresult SetHashedValue(nsIWritablePropertyBag2 *properties,
const nsString &propertyName,
const nsString &propertyValue) const;
};
#define NS_UICOMMANDCOLLECTOR_CLASSNAME "UI Command Collector"
#define NS_UICOMMANDCOLLECTOR_CID \
{ 0xcc2fedc9, 0x8b2e, 0x4e2c, {0x97, 0x07, 0xe2, 0xe5, 0x6b, 0xeb, 0x01, 0x85}}
#endif // nsUICommandCollector_h_

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

@ -1,262 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsWindowCollector.h"
#include "nsMetricsService.h"
#include "nsIObserverService.h"
#include "nsIServiceManager.h"
#include "nsPIDOMWindow.h"
#include "nsIDocShell.h"
#include "nsIDocShellTreeItem.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsServiceManagerUtils.h"
#include "nsDocShellCID.h"
#include "nsAutoPtr.h"
#include "nsITimer.h"
#include "nsComponentManagerUtils.h"
nsWindowCollector::nsWindowCollector()
{
}
nsWindowCollector::~nsWindowCollector()
{
}
NS_IMPL_ISUPPORTS2(nsWindowCollector, nsIMetricsCollector, nsIObserver)
NS_IMETHODIMP
nsWindowCollector::OnAttach()
{
nsCOMPtr<nsIObserverService> obsSvc =
do_GetService("@mozilla.org/observer-service;1");
NS_ENSURE_STATE(obsSvc);
nsresult rv = obsSvc->AddObserver(this, NS_WEBNAVIGATION_CREATE, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
rv = obsSvc->AddObserver(this, NS_CHROME_WEBNAVIGATION_CREATE, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
rv = obsSvc->AddObserver(this, "domwindowopened", PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
rv = obsSvc->AddObserver(this, "domwindowclosed", PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
rv = obsSvc->AddObserver(this, NS_METRICS_WEBNAVIGATION_DESTROY, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
rv = obsSvc->AddObserver(this,
NS_METRICS_CHROME_WEBNAVIGATION_DESTROY, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
nsWindowCollector::OnDetach()
{
nsCOMPtr<nsIObserverService> obsSvc =
do_GetService("@mozilla.org/observer-service;1");
NS_ENSURE_STATE(obsSvc);
nsresult rv = obsSvc->RemoveObserver(this, NS_WEBNAVIGATION_CREATE);
NS_ENSURE_SUCCESS(rv, rv);
rv = obsSvc->RemoveObserver(this, NS_CHROME_WEBNAVIGATION_CREATE);
NS_ENSURE_SUCCESS(rv, rv);
rv = obsSvc->RemoveObserver(this, "domwindowopened");
NS_ENSURE_SUCCESS(rv, rv);
rv = obsSvc->RemoveObserver(this, "domwindowclosed");
NS_ENSURE_SUCCESS(rv, rv);
rv = obsSvc->RemoveObserver(this, NS_METRICS_WEBNAVIGATION_DESTROY);
NS_ENSURE_SUCCESS(rv, rv);
rv = obsSvc->RemoveObserver(this, NS_METRICS_CHROME_WEBNAVIGATION_DESTROY);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
nsWindowCollector::OnNewLog()
{
return NS_OK;
}
struct WindowOpenClosure
{
WindowOpenClosure(nsISupports *subj, nsWindowCollector *coll)
: subject(subj), collector(coll) { }
nsCOMPtr<nsISupports> subject;
nsRefPtr<nsWindowCollector> collector;
};
/* static */ void
nsWindowCollector::WindowOpenCallback(nsITimer *timer, void *closure)
{
WindowOpenClosure *wc = static_cast<WindowOpenClosure *>(closure);
wc->collector->LogWindowOpen(timer, wc->subject);
delete wc;
}
void
nsWindowCollector::LogWindowOpen(nsITimer *timer, nsISupports *subject)
{
mWindowOpenTimers.RemoveElement(timer);
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(subject);
if (!window) {
return;
}
nsCOMPtr<nsIDOMWindowInternal> opener;
window->GetOpener(getter_AddRefs(opener));
nsCOMPtr<nsIWritablePropertyBag2> properties;
nsMetricsUtils::NewPropertyBag(getter_AddRefs(properties));
if (!properties) {
return;
}
if (opener) {
properties->SetPropertyAsUint32(NS_LITERAL_STRING("opener"),
nsMetricsService::GetWindowID(opener));
}
properties->SetPropertyAsUint32(NS_LITERAL_STRING("windowid"),
nsMetricsService::GetWindowID(window));
properties->SetPropertyAsACString(NS_LITERAL_STRING("action"),
NS_LITERAL_CSTRING("open"));
nsMetricsService *ms = nsMetricsService::get();
if (ms) {
ms->LogEvent(NS_LITERAL_STRING("window"), properties);
}
}
NS_IMETHODIMP
nsWindowCollector::Observe(nsISupports *subject,
const char *topic,
const PRUnichar *data)
{
nsCOMPtr<nsIWritablePropertyBag2> properties;
nsresult rv = nsMetricsUtils::NewPropertyBag(getter_AddRefs(properties));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsPIDOMWindow> window;
nsCString action;
if (strcmp(topic, NS_WEBNAVIGATION_CREATE) == 0 ||
strcmp(topic, NS_CHROME_WEBNAVIGATION_CREATE) == 0) {
// Log a window creation event.
action.Assign("create");
nsCOMPtr<nsIDocShellTreeItem> item = do_QueryInterface(subject);
NS_ENSURE_STATE(item);
window = do_GetInterface(subject);
NS_ENSURE_STATE(window);
// We want the window's real parent, even if it crosses a chrome/content
// boundary. This requires going up the docshell tree.
nsCOMPtr<nsIDocShellTreeItem> parentItem;
item->GetParent(getter_AddRefs(parentItem));
nsCOMPtr<nsPIDOMWindow> parentWindow = do_GetInterface(parentItem);
if (parentWindow) {
PRUint32 id = nsMetricsService::GetWindowID(parentWindow);
rv = properties->SetPropertyAsUint32(NS_LITERAL_STRING("parent"), id);
NS_ENSURE_SUCCESS(rv, rv);
}
if (strcmp(topic, NS_CHROME_WEBNAVIGATION_CREATE) == 0) {
rv = properties->SetPropertyAsBool(NS_LITERAL_STRING("chrome"), PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
}
if (nsMetricsUtils::IsSubframe(item)) {
rv = properties->SetPropertyAsBool(NS_LITERAL_STRING("subframe"),
PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
}
} else if (strcmp(topic, "domwindowopened") == 0) {
// We'd like to log a window open event now, but the window opener
// has not yet been set when we receive the domwindowopened notification.
nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID);
NS_ENSURE_STATE(timer);
WindowOpenClosure *wc = new WindowOpenClosure(subject, this);
NS_ENSURE_TRUE(wc, NS_ERROR_OUT_OF_MEMORY);
rv = timer->InitWithFuncCallback(nsWindowCollector::WindowOpenCallback,
wc, 0, nsITimer::TYPE_ONE_SHOT);
NS_ENSURE_SUCCESS(rv, rv);
mWindowOpenTimers.AppendElement(timer);
} else if (strcmp(topic, "domwindowclosed") == 0) {
// Log a window close event.
action.Assign("close");
window = do_QueryInterface(subject);
} else if (strcmp(topic, NS_METRICS_WEBNAVIGATION_DESTROY) == 0 ||
strcmp(topic, NS_METRICS_CHROME_WEBNAVIGATION_DESTROY) == 0) {
// Log a window destroy event.
action.Assign("destroy");
window = do_GetInterface(subject);
nsCOMPtr<nsIDocShellTreeItem> item = do_QueryInterface(subject);
NS_ENSURE_STATE(item);
if (nsMetricsUtils::IsSubframe(item)) {
rv = properties->SetPropertyAsBool(NS_LITERAL_STRING("subframe"),
PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
}
}
if (window) {
rv = properties->SetPropertyAsUint32(NS_LITERAL_STRING("windowid"),
nsMetricsService::GetWindowID(window));
NS_ENSURE_SUCCESS(rv, rv);
rv = properties->SetPropertyAsACString(NS_LITERAL_STRING("action"),
action);
NS_ENSURE_SUCCESS(rv, rv);
nsMetricsService *ms = nsMetricsService::get();
NS_ENSURE_STATE(ms);
rv = ms->LogEvent(NS_LITERAL_STRING("window"), properties);
}
return rv;
}

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

@ -1,109 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsWindowCollector_h_
#define nsWindowCollector_h_
#include "nsIMetricsCollector.h"
#include "nsIObserver.h"
#include "nsTArray.h"
#include "nsCOMPtr.h"
class nsIDOMWindow;
class nsITimer;
// This file defines the window collector class, which monitors window
// creation, opening, closing, and destruction, and records the events into
// the metrics service. This information provides additional context for loads
// into each window.
//
// The window collector also manages the list of assigned window ids, which
// are shared by all interested collectors.
//
// Event descriptions:
//
// <window action="create"/>: logged on new window creation.
// This window can correspond to a toplevel window or to a subframe.
// Attributes:
// windowid: The id of the new window (uint16)
// parent: The id of the window's parent (uint16)
// chrome: Set to true if the window has a chrome docshell (boolean)
//
// <window action="open"/>: logged when window.open() is called.
// This will be logged immediately following <windowcreate/> when a toplevel
// window is opened. It will never be logged for subframe windows.
// Attributes:
// windowid: The id of the opened window (uint16)
// opener: The id of the window's opener (uint16)
//
// <window action="close"/>: logged when a toplevel window is closed.
// Attributes:
// windowid: The id of the closed window (uint16)
//
// <window action="destroy"/>: logged when a window is destroyed.
// Attributes:
// windowid: The id of the destroyed window (uint16).
class nsWindowCollector : public nsIMetricsCollector,
public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIMETRICSCOLLECTOR
NS_DECL_NSIOBSERVER
nsWindowCollector();
// VC6 needs this to be public
void LogWindowOpen(nsITimer *timer, nsISupports *subject);
private:
~nsWindowCollector();
// timer callback
static void WindowOpenCallback(nsITimer *timer, void *closure);
// timers that we're using for deferred window open events
nsTArray< nsCOMPtr<nsITimer> > mWindowOpenTimers;
};
#define NS_WINDOWCOLLECTOR_CLASSNAME "Window Collector"
#define NS_WINDOWCOLLECTOR_CID \
{ 0x56e37604, 0xd593, 0x47e4, {0x87, 0x1f, 0x76, 0x13, 0x64, 0x8e, 0x74, 0x2b}}
#endif // nsWindowCollector_h_

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

@ -1,67 +0,0 @@
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* This file contains trivial implementations of the NSS PORT_* functions
* that md5.c uses.
*/
#include "prmem.h"
#include "prerror.h"
void*
PORT_Alloc(size_t bytes)
{
/* Always allocate a non-zero amount of bytes */
return (void *)PR_Malloc(bytes ? bytes : 1);
}
void
PORT_Free(void *ptr)
{
if (ptr) {
PR_Free(ptr);
}
}
void
PORT_SetError(int value)
{
PR_SetError(value, 0);
return;
}

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

@ -1,89 +0,0 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Google Inc.
# Portions created by the Initial Developer are Copyright (C) 2006
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Brian Ryner <bryner@brianryner.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = test_metrics
CPPSRCS = \
TestMetricsConfig.cpp \
TestUICommandCollector.cpp \
$(NULL)
SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX))
LOCAL_INCLUDES = \
-I$(srcdir)/../src \
-I$(srcdir)/../build \
-I$(DIST)/public/nss \
-I$(DIST)/private/nss \
$(NULL)
LIBS = \
../src/$(LIB_PREFIX)metrics_s.$(LIB_SUFFIX) \
$(BZ2_LIBS) \
$(XPCOM_GLUE_LDOPTS) \
$(NSPR_LIBS) \
$(NULL)
XPCSHELL_TESTS = unit
include $(topsrcdir)/config/rules.mk
CXXFLAGS += $(BZ2_CFLAGS)
# Give the unit tests absolute paths to the data and temp directories.
# For cygwin, we need to convert the paths to native Windows paths.
ifdef CYGWIN_WRAPPER
TESTDATA_DIR := `cygpath -wa $(srcdir)/data`
TEST_TMPDIR := `cygpath -wa .`
else
TESTDATA_DIR := `cd $(srcdir)/data; pwd`
TEST_TMPDIR := `pwd`
endif
check::
@echo Running tests...
@for f in $(SIMPLE_PROGRAMS); do \
echo $$f; $(RUN_TEST_PROGRAM) $(DIST)/bin/$$f \
$(TESTDATA_DIR) $(TEST_TMPDIR); \
done

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

@ -1,54 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// This file defines common macros for C++ unit tests
#define ASSERT_TRUE_RET(cond, ret) \
if (!cond) { \
fprintf(stderr, "FAILED: %s at %s:%d\n", #cond, __FILE__, __LINE__); \
return ret; \
}
#define ASSERT_TRUE(cond) \
if (!cond) { \
fprintf(stderr, "FAILED: %s at %s:%d\n", #cond, __FILE__, __LINE__); \
return ; \
}
#define ASSERT_SUCCESS(res) ASSERT_TRUE(NS_SUCCEEDED(res))
#define ASSERT_FALSE(cond) ASSERT_TRUE(! cond)

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

@ -1,173 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// Unit test for nsMetricsConfig
#include "TestCommon.h"
#include "nsMetricsConfig.h"
#include "nsMetricsService.h"
#include "nsXPCOM.h"
#include "nsILocalFile.h"
#include "nsIClassInfoImpl.h"
#include <stdio.h>
// This singleton must exist in any code that links against libmetrics_s.
// TODO: find a way to declare this in src/ while still allowing it to be
// visible to nsMetricsModule.
NS_DECL_CLASSINFO(nsMetricsService)
static int gTotalTests = 0;
static int gPassedTests = 0;
void TestLoad(const char *testdata_path)
{
++gTotalTests;
nsMetricsConfig config;
ASSERT_TRUE(config.Init());
nsCOMPtr<nsILocalFile> dataFile;
NS_NewNativeLocalFile(nsDependentCString(testdata_path),
PR_TRUE, getter_AddRefs(dataFile));
ASSERT_TRUE(dataFile);
ASSERT_SUCCESS(dataFile->AppendNative(
NS_LITERAL_CSTRING("test_config.xml")));
ASSERT_SUCCESS(config.Load(dataFile));
ASSERT_TRUE(config.IsEventEnabled(NS_LITERAL_STRING(NS_METRICS_NAMESPACE),
NS_LITERAL_STRING("foo")));
ASSERT_TRUE(config.IsEventEnabled(NS_LITERAL_STRING(NS_METRICS_NAMESPACE),
NS_LITERAL_STRING("bar")));
ASSERT_FALSE(config.IsEventEnabled(NS_LITERAL_STRING(NS_METRICS_NAMESPACE),
NS_LITERAL_STRING("baz")));
ASSERT_TRUE(config.EventLimit() == 200);
ASSERT_TRUE(config.UploadInterval() == 1000);
ASSERT_TRUE(config.HasConfig());
++gPassedTests;
}
// Returns true if the contents of |file| match |contents|.
static PRBool CheckFileContents(nsILocalFile *file, const char *contents)
{
nsCString nativePath;
file->GetNativePath(nativePath);
// Now read in the file contents and compare to the expected output
PRFileInfo info;
ASSERT_TRUE_RET(PR_GetFileInfo(nativePath.get(), &info) == PR_SUCCESS,
PR_FALSE);
char *buf = new char[info.size + 1];
ASSERT_TRUE_RET(buf, PR_FALSE);
PRFileDesc *fd = PR_Open(nativePath.get(), PR_RDONLY, 0);
ASSERT_TRUE_RET(fd, PR_FALSE);
ASSERT_TRUE_RET(PR_Read(fd, buf, info.size) == info.size, PR_FALSE);
PR_Close(fd);
buf[info.size] = '\0';
// Leave the file in place if the test failed
ASSERT_TRUE_RET(!strcmp(buf, contents), PR_FALSE);
PR_Delete(nativePath.get());
delete[] buf;
return PR_TRUE;
}
void TestSave(const char *temp_data_path)
{
++gTotalTests;
static const char kFilename[] = "test-save.xml";
static const char kExpectedContents[] =
"<response xmlns=\"http://www.mozilla.org/metrics\"><config>"
"<collectors>"
"<collector type=\"uielement\"/>"
"</collectors>"
"<limit events=\"300\"/>"
"<upload interval=\"500\"/>"
"</config></response>";
nsMetricsConfig config;
ASSERT_TRUE(config.Init());
// The data file goes to the current directory
config.SetEventEnabled(NS_LITERAL_STRING(NS_METRICS_NAMESPACE),
NS_LITERAL_STRING("uielement"), PR_TRUE);
config.SetUploadInterval(500);
config.SetEventLimit(300);
nsCOMPtr<nsILocalFile> outFile;
NS_NewNativeLocalFile(nsDependentCString(temp_data_path),
PR_TRUE, getter_AddRefs(outFile));
ASSERT_TRUE(outFile);
ASSERT_SUCCESS(outFile->AppendNative(nsDependentCString(kFilename)));
ASSERT_SUCCESS(config.Save(outFile));
ASSERT_TRUE(CheckFileContents(outFile, kExpectedContents));
// Now test with no collectors
static const char kExpectedOutputNoEvents[] =
"<response xmlns=\"http://www.mozilla.org/metrics\"><config>"
"<collectors/>"
"<limit events=\"300\"/>"
"<upload interval=\"500\"/>"
"</config></response>";
config.ClearEvents();
ASSERT_SUCCESS(config.Save(outFile));
ASSERT_TRUE(CheckFileContents(outFile, kExpectedOutputNoEvents));
++gPassedTests;
}
int main(int argc, char **argv)
{
if (argc < 2) {
fprintf(stderr, "Usage: %s test_data_path temp_data_path\n", argv[0]);
return 1;
}
TestLoad(argv[1]);
TestSave(argv[2]);
printf("%d/%d tests passed\n", gPassedTests, gTotalTests);
return 0;
}

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

@ -1,282 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics extension.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// Unit test for nsUICommandCollector
#include <stdio.h>
#include "TestCommon.h"
#include "nsXPCOM.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentEvent.h"
#include "nsIDOMElement.h"
#include "nsIDOMEvent.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMText.h"
#include "nsIDOMXULCommandEvent.h"
#include "nsIPrivateDOMEvent.h"
#include "nsComponentManagerUtils.h"
#include "nsUICommandCollector.h"
#include "nsMetricsService.h"
// This is a little unconventional, but it lets us register the metrics
// components statically so that they can initialize properly in the test
// environment, while still allowing us access to non-interface methods.
#include "nsMetricsModule.cpp"
static int gTotalTests = 0;
static int gPassedTests = 0;
class UICommandCollectorTest
{
public:
UICommandCollectorTest() {}
~UICommandCollectorTest() {}
void SetUp();
void TestGetEventTargets();
void TestGetEventKeyId();
private:
nsRefPtr<nsUICommandCollector> mCollector;
nsCOMPtr<nsIDOMDocument> mDocument;
nsCOMPtr<nsIPrivateDOMEvent> mDOMEvent;
nsString kXULNS;
};
void UICommandCollectorTest::SetUp()
{
++gTotalTests;
mCollector = new nsUICommandCollector();
mDocument = do_CreateInstance("@mozilla.org/xml/xml-document;1");
kXULNS.Assign(NS_LITERAL_STRING("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"));
}
void UICommandCollectorTest::TestGetEventTargets()
{
nsCOMPtr<nsIDOMDocumentEvent> docEvent = do_QueryInterface(mDocument);
nsCOMPtr<nsIDOMEvent> event;
docEvent->CreateEvent(NS_LITERAL_STRING("xulcommandevents"),
getter_AddRefs(event));
// The private event interface lets us directly set the target
// and original target for easier testing.
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(event);
ASSERT_TRUE(privateEvent);
nsCOMPtr<nsIDOMElement> buttonElement;
mDocument->CreateElementNS(kXULNS, NS_LITERAL_STRING("button"),
getter_AddRefs(buttonElement));
ASSERT_TRUE(buttonElement);
buttonElement->SetAttribute(NS_LITERAL_STRING("id"),
NS_LITERAL_STRING("btn1"));
// First test the simple case where we have only explicit content.
// Note that originalTarget == target unless set otherwise.
privateEvent->SetTarget(
nsCOMPtr<nsIDOMEventTarget>(do_QueryInterface(buttonElement)));
nsString targetId, targetAnonId;
nsresult rv = mCollector->GetEventTargets(event, targetId, targetAnonId);
ASSERT_TRUE(NS_SUCCEEDED(rv));
ASSERT_TRUE(targetId.Equals(NS_LITERAL_STRING("btn1")));
ASSERT_TRUE(targetAnonId.IsEmpty());
// If there was an anonid, it should be ignored
buttonElement->SetAttribute(NS_LITERAL_STRING("anonid"),
NS_LITERAL_STRING("abc"));
rv = mCollector->GetEventTargets(event, targetId, targetAnonId);
ASSERT_TRUE(NS_SUCCEEDED(rv));
ASSERT_TRUE(targetId.Equals(NS_LITERAL_STRING("btn1")));
ASSERT_TRUE(targetAnonId.IsEmpty());
// If the target has no id, GetEventTargets should fail
buttonElement->RemoveAttribute(NS_LITERAL_STRING("id"));
rv = mCollector->GetEventTargets(event, targetId, targetAnonId);
ASSERT_TRUE(NS_FAILED(rv));
// The same should be true with no anonid
buttonElement->RemoveAttribute(NS_LITERAL_STRING("anonid"));
rv = mCollector->GetEventTargets(event, targetId, targetAnonId);
ASSERT_TRUE(NS_FAILED(rv));
// Empty attributes should work the same as no attributes
buttonElement->SetAttribute(NS_LITERAL_STRING("id"), nsString());
rv = mCollector->GetEventTargets(event, targetId, targetAnonId);
ASSERT_TRUE(NS_FAILED(rv));
// Now test some cases where the originalTarget is different
nsCOMPtr<nsIDOMElement> anonChild;
mDocument->CreateElementNS(kXULNS, NS_LITERAL_STRING("hbox"),
getter_AddRefs(anonChild));
ASSERT_TRUE(anonChild);
privateEvent->SetOriginalTarget(
nsCOMPtr<nsIDOMEventTarget>(do_QueryInterface(anonChild)));
// This is the typical id/anonid case for anonymous content
buttonElement->SetAttribute(NS_LITERAL_STRING("id"),
NS_LITERAL_STRING("btn1"));
anonChild->SetAttribute(NS_LITERAL_STRING("anonid"),
NS_LITERAL_STRING("box1"));
targetId.SetLength(0);
targetAnonId.SetLength(0);
rv = mCollector->GetEventTargets(event, targetId, targetAnonId);
ASSERT_TRUE(NS_SUCCEEDED(rv));
ASSERT_TRUE(targetId.Equals(NS_LITERAL_STRING("btn1")));
ASSERT_TRUE(targetAnonId.Equals(NS_LITERAL_STRING("box1")));
// If there is no id or anonid, it should fail
anonChild->RemoveAttribute(NS_LITERAL_STRING("anonid"));
rv = mCollector->GetEventTargets(event, targetId, targetAnonId);
ASSERT_TRUE(NS_FAILED(rv));
// Test the failure case where the target/originalTarget is not an element
privateEvent->SetOriginalTarget(nsnull); // now mirrors target again
nsCOMPtr<nsIDOMText> textNode;
mDocument->CreateTextNode(NS_LITERAL_STRING("blah"),
getter_AddRefs(textNode));
ASSERT_TRUE(textNode);
privateEvent->SetTarget(
nsCOMPtr<nsIDOMEventTarget>(do_QueryInterface(textNode)));
rv = mCollector->GetEventTargets(event, targetId, targetAnonId);
ASSERT_TRUE(NS_FAILED(rv));
++gPassedTests;
}
void UICommandCollectorTest::TestGetEventKeyId()
{
nsCOMPtr<nsIDOMDocumentEvent> docEvent = do_QueryInterface(mDocument);
nsCOMPtr<nsIDOMEvent> event;
docEvent->CreateEvent(NS_LITERAL_STRING("xulcommandevents"),
getter_AddRefs(event));
// The private event interface lets us directly set the target
// and original target for easier testing.
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(event);
ASSERT_TRUE(privateEvent);
nsCOMPtr<nsIDOMElement> elem;
mDocument->CreateElementNS(kXULNS, NS_LITERAL_STRING("hbox"),
getter_AddRefs(elem));
ASSERT_TRUE(elem);
privateEvent->SetTarget(
nsCOMPtr<nsIDOMEventTarget>(do_QueryInterface(elem)));
// In its initial state, the command event will have no source event.
// GetEventKeyId should leave keyId empty.
nsString keyId;
mCollector->GetEventKeyId(event, keyId);
ASSERT_TRUE(keyId.IsEmpty());
// Now set up a source event
nsCOMPtr<nsIDOMEvent> sourceEvent;
docEvent->CreateEvent(NS_LITERAL_STRING("Events"),
getter_AddRefs(sourceEvent));
nsCOMPtr<nsIPrivateDOMEvent> privateSource = do_QueryInterface(sourceEvent);
ASSERT_TRUE(privateSource);
nsCOMPtr<nsIDOMXULCommandEvent> xcEvent = do_QueryInterface(event);
ASSERT_TRUE(xcEvent);
nsresult rv = xcEvent->InitCommandEvent(NS_LITERAL_STRING("command"),
PR_TRUE, PR_TRUE, nsnull, 0,
PR_FALSE, PR_FALSE, PR_FALSE,
PR_FALSE, sourceEvent);
ASSERT_TRUE(NS_SUCCEEDED(rv));
// The source event will initially point to a non-key element
privateSource->SetTarget(
nsCOMPtr<nsIDOMEventTarget>(do_QueryInterface(elem)));
mCollector->GetEventKeyId(event, keyId);
ASSERT_TRUE(keyId.IsEmpty());
// Create a key element and point the source event there
nsCOMPtr<nsIDOMElement> keyElem;
mDocument->CreateElementNS(kXULNS, NS_LITERAL_STRING("key"),
getter_AddRefs(keyElem));
ASSERT_TRUE(keyElem);
keyElem->SetAttribute(NS_LITERAL_STRING("id"), NS_LITERAL_STRING("keyFoo"));
privateSource->SetTarget(
nsCOMPtr<nsIDOMEventTarget>(do_QueryInterface(keyElem)));
mCollector->GetEventKeyId(event, keyId);
ASSERT_TRUE(keyId.Equals(NS_LITERAL_STRING("keyFoo")));
// Make sure we don't crash if the source event target is a non-element
nsCOMPtr<nsIDOMText> textNode;
mDocument->CreateTextNode(NS_LITERAL_STRING("blah"),
getter_AddRefs(textNode));
ASSERT_TRUE(textNode);
privateSource->SetTarget(
nsCOMPtr<nsIDOMEventTarget>(do_QueryInterface(textNode)));
keyId.SetLength(0);
mCollector->GetEventKeyId(event, keyId);
ASSERT_TRUE(keyId.IsEmpty());
++gPassedTests;
}
int main(int argc, char *argv[])
{
nsStaticModuleInfo staticComps = { "metrics", &NSGetModule };
NS_InitXPCOM3(nsnull, nsnull, nsnull, &staticComps, 1);
// Pre-initialize the metrics service since it's assumed to exist
nsMetricsService::get();
// Use a separate instantiation of the test objects for each test
{
UICommandCollectorTest test;
test.SetUp();
test.TestGetEventTargets();
}
{
UICommandCollectorTest test;
test.SetUp();
test.TestGetEventKeyId();
}
NS_ShutdownXPCOM(nsnull);
printf("%d/%d tests passed\n", gPassedTests, gTotalTests);
return 0;
}

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

@ -1 +0,0 @@
<response xmlns="http://www.mozilla.org/metrics"><config><collectors><collector type="foo"/><collector type="bar"/></collectors><event limit="200"/><upload interval="1000"/></config></response>

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

@ -1,66 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics Service.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// Common functions for MetricsService tests
function getMetricsService() {
return Components.classes["@mozilla.org/extensions/metrics/service;1"]
.getService(Components.interfaces.nsIMetricsService);
}
function createEventItem(ns, name) {
return getMetricsService().createEventItem(ns, name);
}
const EventNS = "http://www.mozilla.org/metrics";
function buildItemChildren(item) {
var items = [];
var child;
for (var i = 0; i < 10; ++i) {
child = createEventItem(EventNS, "child" + i);
items.push(child);
item.appendChild(child);
}
return items;
}
function compareItemChildren(item, children) {
do_check_eq(item.childCount, children.length);
for (var i = 0; i < children.length; ++i) {
do_check_eq(item.childAt(i), children[i]);
}
}

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

@ -1,248 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Metrics Service.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// Unit test for the MetricsEventItem object
function run_test () {
for (var i = 0; i < tests.length && tests[i][0]; ++i) {
if (!tests[i][0].call()) {
do_throw(tests[i][1]);
}
}
}
var tests = [
[ test_create, "createEventItem failed" ],
[ test_properties, "properties set/get failed" ],
[ test_append_count, "appendChild/childCount failed" ],
[ test_childat, "childAt failed" ],
[ test_indexof, "indexOf failed" ],
[ test_insert, "insertChildAt failed" ],
[ test_remove, "removeChildAt failed" ],
[ test_replace, "replaceChildAt failed" ],
[ test_clear, "clearChildren failed" ],
[ null ]
];
function test_create() {
var item = createEventItem(EventNS, "test");
do_check_neq(item, null);
do_check_eq(item.itemNamespace, EventNS);
do_check_eq(item.itemName, "test");
do_check_eq(item.properties, null);
do_check_eq(item.childCount, 0);
return true;
}
function test_properties() {
var item = createEventItem(EventNS, "test");
var properties = {
month: "April",
year: 2006,
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsIPropertyBag) ||
iid.equals(Components.interfaces.nsISupports)) {
return this;
}
}
};
item.properties = properties;
// XPConnect has created a PropertyBag wrapper for us, so we can't
// actually check equality between properties and item.properties.
var month = item.properties.getProperty("month");
do_check_eq(typeof(month), "string");
do_check_eq(month, "April");
var year = item.properties.getProperty("year");
do_check_eq(typeof(year), "number");
do_check_eq(year, 2006);
var day = item.properties.getProperty("day");
do_check_eq(day, undefined);
return true;
}
function test_append_count() {
var item = createEventItem(EventNS, "test");
var children = buildItemChildren(item);
do_check_eq(item.childCount, children.length);
// test input validation
try {
item.appendChild(null);
do_throw("appendChild(null) should fail");
} catch (e) {}
do_check_eq(item.childCount, children.length);
return true;
}
function test_childat() {
var item = createEventItem(EventNS, "test");
var children = buildItemChildren(item);
// test all of the valid children with chilAt().
compareItemChildren(item, children);
// test input validation
try {
item.childAt(-1);
do_throw("childAt(-1)");
} catch (e) {}
try {
item.childAt(children.length);
do_throw("childAt(children.length)");
} catch (e) {}
return true;
}
function test_indexof() {
var item = createEventItem(EventNS, "test");
var children = buildItemChildren(item);
for (var i = 0; i < children.length; ++i) {
do_check_eq(item.indexOf(children[i]), i);
}
do_check_eq(item.indexOf(createEventItem(EventNS, "nothere")), -1);
do_check_eq(item.indexOf(null), -1);
return true;
}
function test_insert() {
var item = createEventItem(EventNS, "test");
var children = buildItemChildren(item);
var i;
var newChild = createEventItem(EventNS, "newchild");
item.insertChildAt(newChild, 1);
children.splice(1, 0, newChild);
compareItemChildren(item, children);
// test inserting at the end
newChild = createEventItem(EventNS, "newchild2");
item.insertChildAt(newChild, item.childCount);
children.push(newChild);
compareItemChildren(item, children);
// test input validation
try {
item.insertChildAt(newChild, -1);
do_throw("insertChildAt(-1)");
} catch (e) {}
compareItemChildren(item, children);
try {
item.insertChildAt(newChild, item.childCount + 1);
do_throw("insertChildAt past end");
} catch (e) {}
compareItemChildren(item, children);
try {
item.insertChildAt(null, item.childCount);
do_throw("insertChildAt(null) should fail");
} catch (e) {}
compareItemChildren(item, children);
return true;
}
function test_remove() {
var item = createEventItem(EventNS, "test");
var children = buildItemChildren(item);
item.removeChildAt(3);
children.splice(3, 1);
compareItemChildren(item, children);
// test input validation
try {
item.removeChildAt(-1);
do_throw("removeChildAt(-1)");
} catch (e) {}
compareItemChildren(item, children);
try {
item.removeChildAt(item.childCount);
do_throw("removeChildAt past end");
} catch (e) {}
compareItemChildren(item, children);
return true;
}
function test_replace() {
var item = createEventItem(EventNS, "test");
var children = buildItemChildren(item);
var newChild = createEventItem(EventNS, "newchild");
item.replaceChildAt(newChild, 6);
children[6] = newChild;
compareItemChildren(item, children);
// test input validation
try {
item.replaceChildAt(newChild, -1);
do_throw("replaceChildAt(-1)");
} catch (e) {}
compareItemChildren(item, children);
try {
item.replaceChildAt(newChild, item.childCount);
do_throw("replaceChildAt past end");
} catch (e) {}
compareItemChildren(item, children);
return true;
}
function test_clear() {
var item = createEventItem(EventNS, "test");
buildItemChildren(item);
item.clearChildren();
compareItemChildren(item, []);
item.clearChildren();
compareItemChildren(item, []);
return true;
}