log some stats about bookmark usage (bug 338016) r=marria,brettw

This commit is contained in:
bryner%brianryner.com 2006-05-25 22:41:16 +00:00
parent 337e318004
commit 505b01b9e9
3 changed files with 408 additions and 3 deletions

View File

@ -75,6 +75,12 @@ else
REQUIRES += widget
endif
ifdef MOZ_PLACES
REQUIRES += places browsercomps
else
REQUIRES += bookmarks
endif
CPPSRCS = \
nsLoadCollector.cpp \
nsMetricsConfig.cpp \

View File

@ -47,15 +47,27 @@
#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"
#ifdef MOZ_PLACES
#include "nsINavBookmarksService.h"
#include "nsINavHistoryService.h"
#include "nsILivemarkService.h"
#include "nsBrowserCompsCID.h"
#else
#include "nsIBookmarksService.h"
#include "nsIRDFContainer.h"
#endif
// We need to suppress inclusion of nsString.h
#define nsString_h___
@ -105,6 +117,53 @@ class nsProfileCollector::ExtensionEnumerator
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.
#ifdef MOZ_PLACES
void CountChildren(PRInt64 root, PRBool deep, nsTArray<PRInt32> &count);
#else
void CountChildren(nsIRDFResource *root,
PRBool deep, nsTArray<PRInt32> &count);
#endif
private:
#ifdef MOZ_PLACES
void CountRecursive(nsINavHistoryContainerResultNode *root, PRBool deep,
nsTArray<PRInt32> &count);
#else
void CountRecursive(nsIRDFResource *root, PRBool deep,
nsTArray<PRInt32> &count);
#endif
#ifdef MOZ_PLACES
nsCOMPtr<nsILivemarkService> mLivemarkService;
#else
nsCOMPtr<nsIRDFDataSource> mDataSource;
nsCOMPtr<nsIRDFResource> mRDFType;
nsCOMPtr<nsIRDFResource> mNCBookmark;
nsCOMPtr<nsIRDFResource> mNCFolder;
nsCOMPtr<nsIRDFResource> mNCLivemark;
nsCOMPtr<nsIRDFResource> mNCSeparator;
#endif
};
nsProfileCollector::nsProfileCollector()
: mLoggedProfile(PR_FALSE)
{
@ -149,6 +208,7 @@ nsProfileCollector::OnNewLog()
LogExtensions(profileItem);
LogPlugins(profileItem);
LogDisplay(profileItem);
LogBookmarks(profileItem);
nsresult rv = ms->LogEvent(profileItem);
NS_ENSURE_SUCCESS(rv, rv);
@ -374,6 +434,122 @@ nsProfileCollector::LogDisplay(nsIMetricsEventItem *profile)
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);
#ifdef MOZ_PLACES
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->GetBookmarksRoot(&root);
NS_ENSURE_SUCCESS(rv, rv);
LogBookmarkLocation(bookmarksItem, NS_LITERAL_CSTRING("root"),
&counter, root, PR_FALSE);
rv = bmSvc->GetToolbarRoot(&root);
NS_ENSURE_SUCCESS(rv, rv);
LogBookmarkLocation(bookmarksItem, NS_LITERAL_CSTRING("toolbar"),
&counter, root, PR_FALSE);
#else
nsCOMPtr<nsIBookmarksService> bmSvc =
do_GetService(NS_BOOKMARKS_SERVICE_CONTRACTID);
NS_ENSURE_STATE(bmSvc);
// This just ensures that the bookmarks are loaded, it doesn't
// read them again if they've already been read.
PRBool loaded;
bmSvc->ReadBookmarks(&loaded);
nsCOMPtr<nsIRDFService> rdfSvc =
do_GetService("@mozilla.org/rdf/rdf-service;1");
NS_ENSURE_STATE(rdfSvc);
nsCOMPtr<nsIRDFResource> root;
rdfSvc->GetResource(NS_LITERAL_CSTRING("NC:BookmarksRoot"),
getter_AddRefs(root));
NS_ENSURE_STATE(root);
BookmarkCounter counter;
rv = counter.Init();
NS_ENSURE_SUCCESS(rv, rv);
LogBookmarkLocation(bookmarksItem, NS_LITERAL_CSTRING("full-tree"),
&counter, root, PR_TRUE);
LogBookmarkLocation(bookmarksItem, NS_LITERAL_CSTRING("root"),
&counter, root, PR_FALSE);
bmSvc->GetBookmarksToolbarFolder(getter_AddRefs(root));
if (root) {
LogBookmarkLocation(bookmarksItem, NS_LITERAL_CSTRING("toolbar"),
&counter, root, PR_FALSE);
}
#endif
rv = profile->AppendChild(bookmarksItem);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
void
nsProfileCollector::LogBookmarkLocation(nsIMetricsEventItem *bookmarksItem,
const nsACString &location,
BookmarkCounter *counter,
#ifdef MOZ_PLACES
PRInt64 root,
#else
nsIRDFResource *root,
#endif
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()
@ -577,3 +753,210 @@ nsProfileCollector::ExtensionEnumerator::CreateExtensionItem(
extensionItem.swap(item);
return item;
}
#ifdef MOZ_PLACES
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;
}
const PRUint32 groupMode = nsINavHistoryQueryOptions::GROUP_BY_FOLDER;
options->SetGroupingMode(&groupMode, 1);
nsCOMPtr<nsINavHistoryResult> result;
histSvc->ExecuteQuery(query, options, getter_AddRefs(result));
if (!result) {
return;
}
nsCOMPtr<nsINavHistoryQueryResultNode> 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<nsINavHistoryFolderResultNode> folder =
do_QueryInterface(child);
if (!folder) {
continue;
}
PRInt64 folderID = 0;
folder->GetFolderId(&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);
}
#else
nsresult
nsProfileCollector::BookmarkCounter::Init()
{
mDataSource = do_GetService(NS_BOOKMARKS_DATASOURCE_CONTRACTID);
NS_ENSURE_STATE(mDataSource);
nsCOMPtr<nsIRDFService> rdfSvc =
do_GetService("@mozilla.org/rdf/rdf-service;1");
NS_ENSURE_STATE(rdfSvc);
rdfSvc->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "type"),
getter_AddRefs(mRDFType));
NS_ENSURE_STATE(mRDFType);
rdfSvc->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Bookmark"),
getter_AddRefs(mNCBookmark));
NS_ENSURE_STATE(mNCBookmark);
rdfSvc->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Folder"),
getter_AddRefs(mNCFolder));
NS_ENSURE_STATE(mNCFolder);
rdfSvc->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Livemark"),
getter_AddRefs(mNCLivemark));
NS_ENSURE_STATE(mNCLivemark);
rdfSvc->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "BookmarkSeparator"),
getter_AddRefs(mNCSeparator));
NS_ENSURE_STATE(mNCSeparator);
return NS_OK;
}
void
nsProfileCollector::BookmarkCounter::CountChildren(nsIRDFResource *root,
PRBool deep,
nsTArray<PRInt32> &count)
{
count.SetLength(kLastBookmarkType);
for (PRUint32 i = 0; i < kLastBookmarkType; ++i) {
count[i] = 0;
}
CountRecursive(root, deep, count);
}
void
nsProfileCollector::BookmarkCounter::CountRecursive(nsIRDFResource *root,
PRBool deep,
nsTArray<PRInt32> &count)
{
nsCOMPtr<nsIRDFContainer> container =
do_CreateInstance("@mozilla.org/rdf/container;1");
if (!container) {
return;
}
nsresult rv = container->Init(mDataSource, root);
if (NS_FAILED(rv)) {
return;
}
nsCOMPtr<nsISimpleEnumerator> elements;
container->GetElements(getter_AddRefs(elements));
if (!elements) {
return;
}
nsCOMPtr<nsISupports> item;
while (NS_SUCCEEDED(elements->GetNext(getter_AddRefs(item)))) {
nsCOMPtr<nsIRDFResource> child = do_QueryInterface(item);
if (!child) {
continue;
}
// Figure out whether the child is a folder
nsCOMPtr<nsIRDFNode> typeNode;
mDataSource->GetTarget(child, mRDFType, PR_TRUE, getter_AddRefs(typeNode));
if (!typeNode) {
continue;
}
if (typeNode == mNCBookmark) {
++count[ITEM];
} else if (typeNode == mNCFolder) {
++count[FOLDER];
if (deep) {
CountRecursive(child, deep, count);
}
} else if (typeNode == mNCLivemark) {
++count[LIVEMARK];
} else if (typeNode == mNCSeparator) {
++count[SEPARATOR];
}
}
}
#endif

View File

@ -44,7 +44,9 @@
class nsISupports;
class nsIMetricsEventItem;
class nsIPropertyBag;
class nsAString;
#ifndef MOZ_PLACES
class nsIRDFResource;
#endif
// This file defines the profile collector class, which generates
// a profile event at application startup. The profile event logs
@ -59,6 +61,10 @@ class nsProfileCollector : public nsIMetricsCollector
nsProfileCollector();
private:
class PluginEnumerator;
class ExtensionEnumerator;
class BookmarkCounter;
~nsProfileCollector();
// These methods each create a particular item and append it to the profile.
@ -69,9 +75,19 @@ class nsProfileCollector : public nsIMetricsCollector
nsresult LogExtensions(nsIMetricsEventItem *profile);
nsresult LogPlugins(nsIMetricsEventItem *profile);
nsresult LogDisplay(nsIMetricsEventItem *profile);
nsresult LogBookmarks(nsIMetricsEventItem *profile);
class PluginEnumerator;
class ExtensionEnumerator;
#ifdef MOZ_PLACES
void LogBookmarkLocation(nsIMetricsEventItem *bookmarksItem,
const nsACString &location,
BookmarkCounter *counter,
PRInt64 root, PRBool deep);
#else
void LogBookmarkLocation(nsIMetricsEventItem *bookmarksItem,
const nsACString &location,
BookmarkCounter *counter,
nsIRDFResource *root, PRBool deep);
#endif
// Track whether we've logged the profile yet this session.
PRBool mLoggedProfile;