зеркало из https://github.com/mozilla/gecko-dev.git
Bug 616761 - Remove deadcode extensions/metrics, r=Mossop, a=ted
This commit is contained in:
Родитель
843cb967df
Коммит
272cba2b78
|
@ -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;
|
||||
}
|
Загрузка…
Ссылка в новой задаче