diff --git a/accessible/src/atk/AtkSocketAccessible.cpp b/accessible/src/atk/AtkSocketAccessible.cpp new file mode 100644 index 000000000000..2a752c4ae8e2 --- /dev/null +++ b/accessible/src/atk/AtkSocketAccessible.cpp @@ -0,0 +1,203 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: + */ +/* ***** 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 + * Novell, Inc. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Brad Taylor (original author) + * + * 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 +#include "AtkSocketAccessible.h" +#include "nsMai.h" +#include "nsMaiInterfaceComponent.h" + +void (*AtkSocketAccessible::g_atk_socket_embed) (AtkSocket*, gchar*) = NULL; +GType AtkSocketAccessible::g_atk_socket_type = G_TYPE_INVALID; +const char* AtkSocketAccessible::sATKSocketEmbedSymbol = "atk_socket_embed"; +const char* AtkSocketAccessible::sATKSocketGetTypeSymbol = "atk_socket_get_type"; + +bool AtkSocketAccessible::gCanEmbed = FALSE; + +/* MaiAtkSocket */ + +#define MAI_TYPE_ATK_SOCKET (mai_atk_socket_get_type ()) +#define MAI_ATK_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),\ + MAI_TYPE_ATK_SOCKET, MaiAtkSocket)) +#define MAI_IS_ATK_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\ + MAI_TYPE_ATK_SOCKET)) +#define MAI_ATK_SOCKET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),\ + MAI_TYPE_ATK_SOCKET,\ + MaiAtkSocketClass)) +#define MAI_IS_ATK_SOCKET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\ + MAI_TYPE_ATK_SOCKET)) +#define MAI_ATK_SOCKET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\ + MAI_TYPE_ATK_SOCKET,\ + MaiAtkSocketClass)) + +typedef struct _MaiAtkSocket MaiAtkSocket; +typedef struct _MaiAtkSocketClass MaiAtkSocketClass; + +struct _MaiAtkSocket +{ + AtkSocket parent; + + nsAccessibleWrap* accWrap; +}; + +struct _MaiAtkSocketClass +{ + AtkSocketClass parent_class; +}; + +G_BEGIN_DECLS + +GType mai_atk_socket_get_type(void); +AtkObject* mai_atk_socket_new(nsAccessibleWrap* aAccWrap); + +void mai_atk_component_iface_init(AtkComponentIface* aIface); +AtkObject* mai_atk_socket_ref_accessible_at_point(AtkComponent *aComponent, + gint aAccX, + gint aAccY, + AtkCoordType aCoordType); +void mai_atk_socket_get_extents(AtkComponent* aComponent, + gint* aAccX, + gint* aAccY, + gint* aAccWidth, + gint* aAccHeight, + AtkCoordType aCoordType); + +G_END_DECLS + +G_DEFINE_TYPE_EXTENDED(MaiAtkSocket, mai_atk_socket, + AtkSocketAccessible::g_atk_socket_type, 0, + G_IMPLEMENT_INTERFACE(ATK_TYPE_COMPONENT, + mai_atk_component_iface_init)) + +void +mai_atk_socket_class_init(MaiAtkSocketClass* aAcc) +{ +} + +void +mai_atk_socket_init(MaiAtkSocket* aAcc) +{ +} + +AtkObject* +mai_atk_socket_new(nsAccessibleWrap* aAccWrap) +{ + NS_ENSURE_TRUE(aAccWrap, NULL); + + MaiAtkSocket* acc = nsnull; + acc = static_cast(g_object_new(MAI_TYPE_ATK_SOCKET, NULL)); + NS_ENSURE_TRUE(acc, NULL); + + acc->accWrap = aAccWrap; + return ATK_OBJECT(acc); +} + +void +mai_atk_component_iface_init(AtkComponentIface* aIface) +{ + NS_ASSERTION(aIface, "Invalid Interface"); + + aIface->ref_accessible_at_point = mai_atk_socket_ref_accessible_at_point; + aIface->get_extents = mai_atk_socket_get_extents; +} + +AtkObject* +mai_atk_socket_ref_accessible_at_point(AtkComponent* aComponent, + gint aX, gint aY, + AtkCoordType aCoordType) +{ + NS_ENSURE_TRUE(MAI_IS_ATK_SOCKET(aComponent), nsnull); + + return refAccessibleAtPointHelper(MAI_ATK_SOCKET(aComponent)->accWrap, + aX, aY, aCoordType); +} + +void +mai_atk_socket_get_extents(AtkComponent* aComponent, + gint* aX, gint* aY, gint* aWidth, gint* aHeight, + AtkCoordType aCoordType) +{ + *aX = *aY = *aWidth = *aHeight = 0; + + if (!MAI_IS_ATK_SOCKET(aComponent)) + return; + + getExtentsHelper(MAI_ATK_SOCKET(aComponent)->accWrap, + aX, aY, aWidth, aHeight, aCoordType); +} + +AtkSocketAccessible::AtkSocketAccessible(nsIContent* aContent, + nsIWeakReference* aShell, + const nsCString& aPlugId) : + nsAccessibleWrap(aContent, aShell) +{ + mAtkObject = mai_atk_socket_new(this); + if (!mAtkObject) + return; + + // Embeds the children of an AtkPlug, specified by plugId, as the children of + // this socket. + // Using G_TYPE macros instead of ATK_SOCKET macros to avoid undefined + // symbols. + if (gCanEmbed && G_TYPE_CHECK_INSTANCE_TYPE(mAtkObject, g_atk_socket_type) && + !aPlugId.IsVoid()) { + AtkSocket* accSocket = + G_TYPE_CHECK_INSTANCE_CAST(mAtkObject, g_atk_socket_type, AtkSocket); + g_atk_socket_embed(accSocket, (gchar*)aPlugId.get()); + } +} + +NS_IMETHODIMP +AtkSocketAccessible::GetNativeInterface(void** aOutAccessible) +{ + *aOutAccessible = mAtkObject; + return NS_OK; +} + +void +AtkSocketAccessible::Shutdown() +{ + if (mAtkObject) { + if (MAI_IS_ATK_SOCKET(mAtkObject)) + MAI_ATK_SOCKET(mAtkObject)->accWrap = nsnull; + g_object_unref(mAtkObject); + mAtkObject = nsnull; + } + nsAccessibleWrap::Shutdown(); +} diff --git a/toolkit/mozapps/installer/wince/nsArchiveExtractor.h b/accessible/src/atk/AtkSocketAccessible.h similarity index 53% rename from toolkit/mozapps/installer/wince/nsArchiveExtractor.h rename to accessible/src/atk/AtkSocketAccessible.h index 2c3976739f65..6905d7bb2476 100644 --- a/toolkit/mozapps/installer/wince/nsArchiveExtractor.h +++ b/accessible/src/atk/AtkSocketAccessible.h @@ -1,4 +1,6 @@ -/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: + */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -12,15 +14,15 @@ * for the specific language governing rights and limitations under the * License. * - * The Original Code is Fennec Installer for WinCE. + * The Original Code is mozilla.org code. * - * The Initial Developer of the Original Code is The Mozilla Foundation. - * - * Portions created by the Initial Developer are Copyright (C) 2009 + * The Initial Developer of the Original Code is + * Novell, Inc. + * Portions created by the Initial Developer are Copyright (C) 2010 * the Initial Developer. All Rights Reserved. * * Contributor(s): - * Alex Pakhotin (original author) + * Brad Taylor (original author) * * 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 @@ -36,45 +38,49 @@ * * ***** END LICENSE BLOCK ***** */ -#pragma once +#ifndef _AtkSocketAccessible_H_ +#define _AtkSocketAccessible_H_ + +#include "nsAccessibleWrap.h" + +// This file gets included by nsAccessibilityService.cpp, which can't include +// atk.h (or glib.h), so we can't rely on it being included. +#ifdef __ATK_H__ +typedef void (*AtkSocketEmbedType) (AtkSocket*, gchar*); +#else +typedef void (*AtkSocketEmbedType) (void*, void*); +#endif /** - * Class to show the progress + * Provides a nsAccessibleWrap wrapper around AtkSocket for out-of-process + * accessibles. */ -class nsExtractorProgress +class AtkSocketAccessible: public nsAccessibleWrap { public: - nsExtractorProgress() {} - virtual void Progress(int nPercentComplete) = 0; /* to be overriden to get progress notifications */ + + // Soft references to AtkSocket + static AtkSocketEmbedType g_atk_socket_embed; +#ifdef __ATK_H__ + static GType g_atk_socket_type; +#endif + static const char* sATKSocketEmbedSymbol; + static const char* sATKSocketGetTypeSymbol; + + /* + * True if the current Atk version supports AtkSocket and it was correctly + * loaded. + */ + static bool gCanEmbed; + + AtkSocketAccessible(nsIContent* aContent, nsIWeakReference* aShell, + const nsCString& aPlugId); + + // nsAccessNode + virtual void Shutdown(); + + // nsIAccessible + NS_IMETHODIMP GetNativeInterface(void** aOutAccessible); }; -/** - * Base archive-extractor class. - * Used to derive a specific archive format implementation. - */ -class nsArchiveExtractor -{ -public: - enum - { - OK = 0, - ERR_FAIL = -1, - ERR_PARAM = -2, - ERR_READ = -3, - ERR_WRITE = -4, - ERR_MEM = -5, - ERR_NO_ARCHIVE = -6, - ERR_EXTRACTION = -7, - }; - - nsArchiveExtractor(const WCHAR *sArchiveName, DWORD dwSfxStubSize, nsExtractorProgress *pProgress); - virtual ~nsArchiveExtractor(); - - virtual int Extract(const WCHAR *sDestinationDir); - virtual int ExtractFile(const WCHAR *sFileName, const WCHAR *sDestinationDir); - -protected: - WCHAR *m_sArchiveName; - nsExtractorProgress *m_pProgress; - DWORD m_dwSfxStubSize; -}; +#endif diff --git a/accessible/src/atk/Makefile.in b/accessible/src/atk/Makefile.in index d72b3d5d1965..4b13253fb8c0 100644 --- a/accessible/src/atk/Makefile.in +++ b/accessible/src/atk/Makefile.in @@ -48,6 +48,7 @@ LIBXUL_LIBRARY = 1 CPPSRCS = \ + AtkSocketAccessible.cpp \ nsAccessNodeWrap.cpp \ nsAccessibleWrap.cpp \ nsDocAccessibleWrap.cpp \ @@ -68,6 +69,7 @@ CPPSRCS = \ $(NULL) EXPORTS = \ + AtkSocketAccessible.h \ nsAccessNodeWrap.h \ nsARIAGridAccessibleWrap.h \ nsAccessibleWrap.h \ diff --git a/accessible/src/atk/nsAccessNodeWrap.cpp b/accessible/src/atk/nsAccessNodeWrap.cpp index 8c4b6463169a..7f5f70d896d9 100644 --- a/accessible/src/atk/nsAccessNodeWrap.cpp +++ b/accessible/src/atk/nsAccessNodeWrap.cpp @@ -1,4 +1,5 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsAccessNodeWrap.h b/accessible/src/atk/nsAccessNodeWrap.h index 6ee2215a8505..e34e22dd6dd0 100644 --- a/accessible/src/atk/nsAccessNodeWrap.h +++ b/accessible/src/atk/nsAccessNodeWrap.h @@ -1,4 +1,5 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsAccessibleRelationWrap.h b/accessible/src/atk/nsAccessibleRelationWrap.h index 6b02017d7128..c7dbbbf26839 100644 --- a/accessible/src/atk/nsAccessibleRelationWrap.h +++ b/accessible/src/atk/nsAccessibleRelationWrap.h @@ -1,6 +1,5 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:expandtab:shiftwidth=2:tabstop=2: - */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsAccessibleWrap.cpp b/accessible/src/atk/nsAccessibleWrap.cpp index 7473d71d2836..5b8234148c27 100644 --- a/accessible/src/atk/nsAccessibleWrap.cpp +++ b/accessible/src/atk/nsAccessibleWrap.cpp @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsAccessibleWrap.h b/accessible/src/atk/nsAccessibleWrap.h index 34fbdcc87371..a45a492d3606 100644 --- a/accessible/src/atk/nsAccessibleWrap.h +++ b/accessible/src/atk/nsAccessibleWrap.h @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsApplicationAccessibleWrap.cpp b/accessible/src/atk/nsApplicationAccessibleWrap.cpp index 0b7446e10974..a4b266df08a4 100644 --- a/accessible/src/atk/nsApplicationAccessibleWrap.cpp +++ b/accessible/src/atk/nsApplicationAccessibleWrap.cpp @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -49,6 +48,7 @@ #include "nsIServiceManager.h" #include "nsAutoPtr.h" #include "nsAccessibilityService.h" +#include "AtkSocketAccessible.h" #include #include @@ -722,8 +722,23 @@ nsApplicationAccessibleWrap::PreCreate() sATKLib = PR_LoadLibrary(sATKLibName); if (sATKLib) { AtkGetTypeType pfn_atk_hyperlink_impl_get_type = (AtkGetTypeType) PR_FindFunctionSymbol(sATKLib, sATKHyperlinkImplGetTypeSymbol); - if (pfn_atk_hyperlink_impl_get_type) { + if (pfn_atk_hyperlink_impl_get_type) g_atk_hyperlink_impl_type = pfn_atk_hyperlink_impl_get_type(); + + AtkGetTypeType pfn_atk_socket_get_type; + pfn_atk_socket_get_type = (AtkGetTypeType) + PR_FindFunctionSymbol(sATKLib, + AtkSocketAccessible::sATKSocketGetTypeSymbol); + if (pfn_atk_socket_get_type) { + AtkSocketAccessible::g_atk_socket_type = + pfn_atk_socket_get_type(); + AtkSocketAccessible::g_atk_socket_embed = (AtkSocketEmbedType) + PR_FindFunctionSymbol(sATKLib, + AtkSocketAccessible + ::sATKSocketEmbedSymbol); + AtkSocketAccessible::gCanEmbed = + AtkSocketAccessible::g_atk_socket_type != G_TYPE_INVALID && + AtkSocketAccessible::g_atk_socket_embed; } } sATKChecked = PR_TRUE; diff --git a/accessible/src/atk/nsApplicationAccessibleWrap.h b/accessible/src/atk/nsApplicationAccessibleWrap.h index b3f03bb05f70..0a91f6ba202d 100644 --- a/accessible/src/atk/nsApplicationAccessibleWrap.h +++ b/accessible/src/atk/nsApplicationAccessibleWrap.h @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsDocAccessibleWrap.cpp b/accessible/src/atk/nsDocAccessibleWrap.cpp index 79d573da2139..8b479d1d5572 100644 --- a/accessible/src/atk/nsDocAccessibleWrap.cpp +++ b/accessible/src/atk/nsDocAccessibleWrap.cpp @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsDocAccessibleWrap.h b/accessible/src/atk/nsDocAccessibleWrap.h index 38f66e175f97..fcd3167d8b6b 100644 --- a/accessible/src/atk/nsDocAccessibleWrap.h +++ b/accessible/src/atk/nsDocAccessibleWrap.h @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsHyperTextAccessibleWrap.h b/accessible/src/atk/nsHyperTextAccessibleWrap.h index 5a2eea3e2d60..f3f12a99a934 100644 --- a/accessible/src/atk/nsHyperTextAccessibleWrap.h +++ b/accessible/src/atk/nsHyperTextAccessibleWrap.h @@ -1,4 +1,5 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMai.h b/accessible/src/atk/nsMai.h index 3de881a01dde..dbb8972de617 100644 --- a/accessible/src/atk/nsMai.h +++ b/accessible/src/atk/nsMai.h @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiHyperlink.cpp b/accessible/src/atk/nsMaiHyperlink.cpp index d9f1a3b71920..ece5281fc1d8 100644 --- a/accessible/src/atk/nsMaiHyperlink.cpp +++ b/accessible/src/atk/nsMaiHyperlink.cpp @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiHyperlink.h b/accessible/src/atk/nsMaiHyperlink.h index 5f9a6649d729..06a9ab8bbbd4 100644 --- a/accessible/src/atk/nsMaiHyperlink.h +++ b/accessible/src/atk/nsMaiHyperlink.h @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceAction.cpp b/accessible/src/atk/nsMaiInterfaceAction.cpp index 4ab38930c4e8..4cc3eb42556a 100644 --- a/accessible/src/atk/nsMaiInterfaceAction.cpp +++ b/accessible/src/atk/nsMaiInterfaceAction.cpp @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceAction.h b/accessible/src/atk/nsMaiInterfaceAction.h index aa23a3080036..3d6f89e3c289 100644 --- a/accessible/src/atk/nsMaiInterfaceAction.h +++ b/accessible/src/atk/nsMaiInterfaceAction.h @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceComponent.cpp b/accessible/src/atk/nsMaiInterfaceComponent.cpp index 863026e66e3b..34bafd1465c9 100644 --- a/accessible/src/atk/nsMaiInterfaceComponent.cpp +++ b/accessible/src/atk/nsMaiInterfaceComponent.cpp @@ -1,5 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 @@ -67,76 +67,84 @@ componentInterfaceInitCB(AtkComponentIface *aIface) aIface->grab_focus = grabFocusCB; } -AtkObject * -refAccessibleAtPointCB(AtkComponent *aComponent, - gint aAccX, gint aAccY, +AtkObject* +refAccessibleAtPointCB(AtkComponent* aComponent, gint aAccX, gint aAccY, AtkCoordType aCoordType) { - nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aComponent)); - if (!accWrap || nsAccUtils::MustPrune(accWrap)) - return nsnull; - - // nsIAccessible getChildAtPoint (x,y) is in screen pixels. - if (aCoordType == ATK_XY_WINDOW) { - nsIntPoint winCoords = - nsCoreUtils::GetScreenCoordsForWindow(accWrap->GetNode()); - aAccX += winCoords.x; - aAccY += winCoords.y; - } - - nsCOMPtr pointAcc; - accWrap->GetChildAtPoint(aAccX, aAccY, getter_AddRefs(pointAcc)); - if (!pointAcc) { - return nsnull; - } - - AtkObject *atkObj = nsAccessibleWrap::GetAtkObject(pointAcc); - if (atkObj) { - g_object_ref(atkObj); - } - return atkObj; + return refAccessibleAtPointHelper(GetAccessibleWrap(ATK_OBJECT(aComponent)), + aAccX, aAccY, aCoordType); } void -getExtentsCB(AtkComponent *aComponent, - gint *aAccX, - gint *aAccY, - gint *aAccWidth, - gint *aAccHeight, - AtkCoordType aCoordType) +getExtentsCB(AtkComponent* aComponent, gint* aX, gint* aY, + gint* aWidth, gint* aHeight, AtkCoordType aCoordType) { - *aAccX = *aAccY = *aAccWidth = *aAccHeight = 0; - - nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aComponent)); - if (!accWrap) - return; - - PRInt32 nsAccX, nsAccY, nsAccWidth, nsAccHeight; - // Returned in screen coordinates - nsresult rv = accWrap->GetBounds(&nsAccX, &nsAccY, - &nsAccWidth, &nsAccHeight); - if (NS_FAILED(rv)) - return; - if (aCoordType == ATK_XY_WINDOW) { - nsIntPoint winCoords = - nsCoreUtils::GetScreenCoordsForWindow(accWrap->GetNode()); - nsAccX -= winCoords.x; - nsAccY -= winCoords.y; - } - - *aAccX = nsAccX; - *aAccY = nsAccY; - *aAccWidth = nsAccWidth; - *aAccHeight = nsAccHeight; + getExtentsHelper(GetAccessibleWrap(ATK_OBJECT(aComponent)), + aX, aY, aWidth, aHeight, aCoordType); } gboolean -grabFocusCB(AtkComponent *aComponent) +grabFocusCB(AtkComponent* aComponent) { - nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aComponent)); - if (!accWrap) - return FALSE; + nsAccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aComponent)); + if (!accWrap) + return FALSE; - nsresult rv = accWrap->TakeFocus(); - return (NS_FAILED(rv)) ? FALSE : TRUE; + nsresult rv = accWrap->TakeFocus(); + return (NS_FAILED(rv)) ? FALSE : TRUE; +} + +AtkObject* +refAccessibleAtPointHelper(nsAccessibleWrap* aAccWrap, gint aX, gint aY, + AtkCoordType aCoordType) +{ + if (!aAccWrap || aAccWrap->IsDefunct() || nsAccUtils::MustPrune(aAccWrap)) + return nsnull; + + // nsAccessible::GetChildAtPoint(x,y) is in screen pixels. + if (aCoordType == ATK_XY_WINDOW) { + nsIntPoint winCoords = + nsCoreUtils::GetScreenCoordsForWindow(aAccWrap->GetNode()); + aX += winCoords.x; + aY += winCoords.y; + } + + nsAccessible* accAtPoint = aAccWrap->GetChildAtPoint(aX, aY, + nsAccessible::eDirectChild); + if (!accAtPoint) + return nsnull; + + AtkObject* atkObj = nsAccessibleWrap::GetAtkObject(accAtPoint); + if (atkObj) + g_object_ref(atkObj); + return atkObj; +} + +void +getExtentsHelper(nsAccessibleWrap* aAccWrap, + gint* aX, gint* aY, gint* aWidth, gint* aHeight, + AtkCoordType aCoordType) +{ + *aX = *aY = *aWidth = *aHeight = 0; + + if (!aAccWrap || aAccWrap->IsDefunct()) + return; + + PRInt32 x = 0, y = 0, width = 0, height = 0; + // Returned in screen coordinates + nsresult rv = aAccWrap->GetBounds(&x, &y, &width, &height); + if (NS_FAILED(rv)) + return; + + if (aCoordType == ATK_XY_WINDOW) { + nsIntPoint winCoords = + nsCoreUtils::GetScreenCoordsForWindow(aAccWrap->GetNode()); + x -= winCoords.x; + y -= winCoords.y; + } + + *aX = x; + *aY = y; + *aWidth = width; + *aHeight = height; } diff --git a/accessible/src/atk/nsMaiInterfaceComponent.h b/accessible/src/atk/nsMaiInterfaceComponent.h index 28cb6e72d859..0fb52cd7f3af 100644 --- a/accessible/src/atk/nsMaiInterfaceComponent.h +++ b/accessible/src/atk/nsMaiInterfaceComponent.h @@ -1,5 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 @@ -46,22 +46,20 @@ G_BEGIN_DECLS /* component interface callbacks */ -void componentInterfaceInitCB(AtkComponentIface *aIface); -AtkObject *refAccessibleAtPointCB(AtkComponent *aComponent, - gint aAccX, gint aAccY, +void componentInterfaceInitCB(AtkComponentIface* aIface); +AtkObject* refAccessibleAtPointCB(AtkComponent* aComponent, + gint aX, gint aY, AtkCoordType aCoordType); -void getExtentsCB(AtkComponent *aComponent, - gint *aAccX, gint *aAccY, - gint *aAccWidth, gint *aAccHeight, +void getExtentsCB(AtkComponent* aComponent, + gint* aX, gint* aY, gint* aWidth, gint* aHeight, AtkCoordType aCoordType); /* the "contains", "get_position", "get_size" can take advantage of * "get_extents", there is no need to implement them now. */ -gboolean grabFocusCB(AtkComponent *aComponent); +gboolean grabFocusCB(AtkComponent* aComponent); -/* what are missing now for atk component */ - -/* ================================================== +/* what are missing now for atk component: + * * add_focus_handler * remove_focus_handler * set_extents @@ -69,8 +67,14 @@ gboolean grabFocusCB(AtkComponent *aComponent); * set_size * get_layer * get_mdi_zorder - * ================================================== */ + +AtkObject* refAccessibleAtPointHelper(nsAccessibleWrap* aAccWrap, + gint aX, gint aY, AtkCoordType aCoordType); +void getExtentsHelper(nsAccessibleWrap* aAccWrap, + gint* aX, gint* aY, gint* aWidth, gint* aHeight, + AtkCoordType aCoordType); + G_END_DECLS #endif /* __MAI_INTERFACE_COMPONENT_H__ */ diff --git a/accessible/src/atk/nsMaiInterfaceDocument.cpp b/accessible/src/atk/nsMaiInterfaceDocument.cpp index 2f48a1491a2e..4c5fd3c2c6e1 100644 --- a/accessible/src/atk/nsMaiInterfaceDocument.cpp +++ b/accessible/src/atk/nsMaiInterfaceDocument.cpp @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceDocument.h b/accessible/src/atk/nsMaiInterfaceDocument.h index 163f80ea35ac..4e5885191825 100644 --- a/accessible/src/atk/nsMaiInterfaceDocument.h +++ b/accessible/src/atk/nsMaiInterfaceDocument.h @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceEditableText.cpp b/accessible/src/atk/nsMaiInterfaceEditableText.cpp index eaf9ddb328bb..3d52d05f4493 100644 --- a/accessible/src/atk/nsMaiInterfaceEditableText.cpp +++ b/accessible/src/atk/nsMaiInterfaceEditableText.cpp @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceEditableText.h b/accessible/src/atk/nsMaiInterfaceEditableText.h index 1f9a7ec2e930..830fe65109fa 100644 --- a/accessible/src/atk/nsMaiInterfaceEditableText.h +++ b/accessible/src/atk/nsMaiInterfaceEditableText.h @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceHyperlinkImpl.cpp b/accessible/src/atk/nsMaiInterfaceHyperlinkImpl.cpp index 1e29336e821d..c798cc647a06 100644 --- a/accessible/src/atk/nsMaiInterfaceHyperlinkImpl.cpp +++ b/accessible/src/atk/nsMaiInterfaceHyperlinkImpl.cpp @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceHyperlinkImpl.h b/accessible/src/atk/nsMaiInterfaceHyperlinkImpl.h index 2ad84a1a9366..c1eaeff826da 100644 --- a/accessible/src/atk/nsMaiInterfaceHyperlinkImpl.h +++ b/accessible/src/atk/nsMaiInterfaceHyperlinkImpl.h @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceHypertext.cpp b/accessible/src/atk/nsMaiInterfaceHypertext.cpp index 5f5b06cf3d73..f2f9b811cfa0 100644 --- a/accessible/src/atk/nsMaiInterfaceHypertext.cpp +++ b/accessible/src/atk/nsMaiInterfaceHypertext.cpp @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceHypertext.h b/accessible/src/atk/nsMaiInterfaceHypertext.h index 0819279d84f4..0b660945168f 100644 --- a/accessible/src/atk/nsMaiInterfaceHypertext.h +++ b/accessible/src/atk/nsMaiInterfaceHypertext.h @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceImage.cpp b/accessible/src/atk/nsMaiInterfaceImage.cpp index 644c2338683c..5a5122998b6d 100644 --- a/accessible/src/atk/nsMaiInterfaceImage.cpp +++ b/accessible/src/atk/nsMaiInterfaceImage.cpp @@ -1,6 +1,5 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceImage.h b/accessible/src/atk/nsMaiInterfaceImage.h index e7f214d4265a..d0419d85d08e 100644 --- a/accessible/src/atk/nsMaiInterfaceImage.h +++ b/accessible/src/atk/nsMaiInterfaceImage.h @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceSelection.cpp b/accessible/src/atk/nsMaiInterfaceSelection.cpp index c0da303ef08b..b0352c2a1507 100644 --- a/accessible/src/atk/nsMaiInterfaceSelection.cpp +++ b/accessible/src/atk/nsMaiInterfaceSelection.cpp @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceSelection.h b/accessible/src/atk/nsMaiInterfaceSelection.h index 15390cb2c230..9bdf5d827017 100644 --- a/accessible/src/atk/nsMaiInterfaceSelection.h +++ b/accessible/src/atk/nsMaiInterfaceSelection.h @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceTable.cpp b/accessible/src/atk/nsMaiInterfaceTable.cpp index 455d6995b743..9cc60b0ad2e7 100644 --- a/accessible/src/atk/nsMaiInterfaceTable.cpp +++ b/accessible/src/atk/nsMaiInterfaceTable.cpp @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceTable.h b/accessible/src/atk/nsMaiInterfaceTable.h index bd290ccc6a04..cd1360434adb 100644 --- a/accessible/src/atk/nsMaiInterfaceTable.h +++ b/accessible/src/atk/nsMaiInterfaceTable.h @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceText.cpp b/accessible/src/atk/nsMaiInterfaceText.cpp index c9d69ccfbd49..e4bab0515528 100644 --- a/accessible/src/atk/nsMaiInterfaceText.cpp +++ b/accessible/src/atk/nsMaiInterfaceText.cpp @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceText.h b/accessible/src/atk/nsMaiInterfaceText.h index 995c13620ed6..c12ddfeab2f1 100644 --- a/accessible/src/atk/nsMaiInterfaceText.h +++ b/accessible/src/atk/nsMaiInterfaceText.h @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceValue.cpp b/accessible/src/atk/nsMaiInterfaceValue.cpp index 5ac0f39a6a22..cc87e39f18c1 100644 --- a/accessible/src/atk/nsMaiInterfaceValue.cpp +++ b/accessible/src/atk/nsMaiInterfaceValue.cpp @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsMaiInterfaceValue.h b/accessible/src/atk/nsMaiInterfaceValue.h index 41c0ef538c77..06b5a14438ba 100644 --- a/accessible/src/atk/nsMaiInterfaceValue.h +++ b/accessible/src/atk/nsMaiInterfaceValue.h @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsRoleMap.h b/accessible/src/atk/nsRoleMap.h index 58fabd078249..6e6377ca7125 100644 --- a/accessible/src/atk/nsRoleMap.h +++ b/accessible/src/atk/nsRoleMap.h @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsRootAccessibleWrap.cpp b/accessible/src/atk/nsRootAccessibleWrap.cpp index 890f3d04a9d5..a3b3fbf46a4e 100644 --- a/accessible/src/atk/nsRootAccessibleWrap.cpp +++ b/accessible/src/atk/nsRootAccessibleWrap.cpp @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsRootAccessibleWrap.h b/accessible/src/atk/nsRootAccessibleWrap.h index bd7a04ed0a7b..8a570eefa145 100644 --- a/accessible/src/atk/nsRootAccessibleWrap.h +++ b/accessible/src/atk/nsRootAccessibleWrap.h @@ -1,6 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsStateMap.h b/accessible/src/atk/nsStateMap.h index 95687176dc8c..68fc51e72ba6 100644 --- a/accessible/src/atk/nsStateMap.h +++ b/accessible/src/atk/nsStateMap.h @@ -1,6 +1,5 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:expandtab:shiftwidth=2:tabstop=2: - */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsTextAccessibleWrap.h b/accessible/src/atk/nsTextAccessibleWrap.h index af855c4051b8..e08cfe90b3fb 100644 --- a/accessible/src/atk/nsTextAccessibleWrap.h +++ b/accessible/src/atk/nsTextAccessibleWrap.h @@ -1,4 +1,5 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsXULListboxAccessibleWrap.h b/accessible/src/atk/nsXULListboxAccessibleWrap.h index 4030268e012e..3dfd88a62181 100644 --- a/accessible/src/atk/nsXULListboxAccessibleWrap.h +++ b/accessible/src/atk/nsXULListboxAccessibleWrap.h @@ -1,4 +1,5 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsXULMenuAccessibleWrap.h b/accessible/src/atk/nsXULMenuAccessibleWrap.h index bff8e0b7969e..cea941edc911 100644 --- a/accessible/src/atk/nsXULMenuAccessibleWrap.h +++ b/accessible/src/atk/nsXULMenuAccessibleWrap.h @@ -1,4 +1,5 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/atk/nsXULTreeGridAccessibleWrap.h b/accessible/src/atk/nsXULTreeGridAccessibleWrap.h index 44932d512fcd..3d71d6eb5e81 100644 --- a/accessible/src/atk/nsXULTreeGridAccessibleWrap.h +++ b/accessible/src/atk/nsXULTreeGridAccessibleWrap.h @@ -1,4 +1,5 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * diff --git a/accessible/src/base/nsAccessibilityService.cpp b/accessible/src/base/nsAccessibilityService.cpp index 545ece530d91..8635962eaca8 100644 --- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -95,6 +95,11 @@ #include "nsHTMLWin32ObjectAccessible.h" #endif +// For embedding plugin accessibles +#ifdef MOZ_ACCESSIBILITY_ATK +#include "AtkSocketAccessible.h" +#endif + #ifndef DISABLE_XFORMS_HOOKS #include "nsXFormsFormControlsAccessible.h" #include "nsXFormsWidgetsAccessible.h" @@ -339,11 +344,12 @@ nsAccessibilityService::CreateHTMLObjectFrameAccessible(nsObjectFrame* aFrame, return CreateOuterDocAccessible(aContent, aPresShell); } -#ifdef XP_WIN +#if defined(XP_WIN) || defined(MOZ_ACCESSIBILITY_ATK) // 2) for plugins - nsCOMPtr pluginInstance ; - aFrame->GetPluginInstance(*getter_AddRefs(pluginInstance)); - if (pluginInstance) { + nsCOMPtr pluginInstance; + if (NS_SUCCEEDED(aFrame->GetPluginInstance(*getter_AddRefs(pluginInstance))) && + pluginInstance) { +#ifdef XP_WIN // Note: pluginPort will be null if windowless. HWND pluginPort = nsnull; aFrame->GetPluginPort(&pluginPort); @@ -353,6 +359,22 @@ nsAccessibilityService::CreateHTMLObjectFrameAccessible(nsObjectFrame* aFrame, pluginPort); NS_IF_ADDREF(accessible); return accessible; + +#elif MOZ_ACCESSIBILITY_ATK + if (!AtkSocketAccessible::gCanEmbed) + return nsnull; + + nsCString plugId; + nsresult rv = pluginInstance->GetValueFromPlugin( + NPPVpluginNativeAccessibleAtkPlugId, &plugId); + if (NS_SUCCEEDED(rv) && !plugId.IsVoid()) { + AtkSocketAccessible* socketAccessible = + new AtkSocketAccessible(aContent, weakShell, plugId); + + NS_IF_ADDREF(socketAccessible); + return socketAccessible; + } +#endif } #endif diff --git a/accessible/src/base/nsRootAccessible.cpp b/accessible/src/base/nsRootAccessible.cpp index f3aa553d87a7..298993b2c8ce 100644 --- a/accessible/src/base/nsRootAccessible.cpp +++ b/accessible/src/base/nsRootAccessible.cpp @@ -193,15 +193,15 @@ nsRootAccessible::NativeState() #ifdef MOZ_XUL PRUint32 chromeFlags = GetChromeFlags(); - if (chromeFlags & nsIWebBrowserChrome::CHROME_WINDOW_RESIZE) { + if (chromeFlags & nsIWebBrowserChrome::CHROME_WINDOW_RESIZE) states |= states::SIZEABLE; - } - if (chromeFlags & nsIWebBrowserChrome::CHROME_TITLEBAR) { // If it has a titlebar it's movable // XXX unless it's minimized or maximized, but not sure // how to detect that + if (chromeFlags & nsIWebBrowserChrome::CHROME_TITLEBAR) states |= states::MOVEABLE; - } + if (chromeFlags & nsIWebBrowserChrome::CHROME_MODAL) + states |= states::MODAL; #endif nsCOMPtr fm = do_GetService(FOCUSMANAGER_CONTRACTID); @@ -215,12 +215,6 @@ nsRootAccessible::NativeState() states |= states::ACTIVE; } -#ifdef MOZ_XUL - if (GetChromeFlags() & nsIWebBrowserChrome::CHROME_MODAL) { - states |= states::MODAL; - } -#endif - return states; } diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 45fbf79d61d2..ce8a308e87fb 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -2296,9 +2296,15 @@ function getShortcutOrURI(aURL, aPostDataRef) { } catch (e) {} } + // encodeURIComponent produces UTF-8, and cannot be used for other charsets. + // escape() works in those cases, but it doesn't uri-encode +, @, and /. + // Therefore we need to manually replace these ASCII characters by their + // encodeURIComponent result, to match the behavior of nsEscape() with + // url_XPAlphas var encodedParam = ""; - if (charset) - encodedParam = escape(convertFromUnicode(charset, param)); + if (charset && charset != "UTF-8") + encodedParam = escape(convertFromUnicode(charset, param)). + replace(/[+@\/]+/g, encodeURIComponent); else // Default charset is UTF-8 encodedParam = encodeURIComponent(param); diff --git a/browser/base/content/extensionsManagerOverlay.xul b/browser/base/content/extensionsManagerOverlay.xul deleted file mode 100644 index 7a4c012475ce..000000000000 --- a/browser/base/content/extensionsManagerOverlay.xul +++ /dev/null @@ -1,50 +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 Asaf Romano -# Portions created by the Initial Developer are Copyright (C) 2005 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Asaf Romano -# -# 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 browserMountPoints.inc - - - - diff --git a/browser/base/content/test/browser_getshortcutoruri.js b/browser/base/content/test/browser_getshortcutoruri.js index 1b319ded812d..d4726b72e6f5 100644 --- a/browser/base/content/test/browser_getshortcutoruri.js +++ b/browser/base/content/test/browser_getshortcutoruri.js @@ -74,6 +74,14 @@ var testData = [ // Explicitly-defined ISO-8859-1 [new bmKeywordData("bmget-escaping2", "http://bmget/?esc=%s&raw=%S&mozcharset=ISO-8859-1", null, "foé"), new keywordResult("http://bmget/?esc=fo%E9&raw=foé", null)], + + // Bug 359809: Test escaping +, /, and @ + // UTF-8 default + [new bmKeywordData("bmget-escaping", "http://bmget/?esc=%s&raw=%S", null, "+/@"), + new keywordResult("http://bmget/?esc=%2B%2F%40&raw=+/@", null)], + // Explicitly-defined ISO-8859-1 + [new bmKeywordData("bmget-escaping2", "http://bmget/?esc=%s&raw=%S&mozcharset=ISO-8859-1", null, "+/@"), + new keywordResult("http://bmget/?esc=%2B%2F%40&raw=+/@", null)], ]; function test() { diff --git a/browser/base/jar.mn b/browser/base/jar.mn index d427c70a196f..c043b39a4bb3 100644 --- a/browser/base/jar.mn +++ b/browser/base/jar.mn @@ -2,7 +2,6 @@ browser.jar: % content browser %content/browser/ contentaccessible=yes #ifdef XP_MACOSX % overlay chrome://mozapps/content/downloads/downloads.xul chrome://browser/content/downloadManagerOverlay.xul -% overlay chrome://mozapps/content/extensions/extensions.xul chrome://browser/content/extensionsManagerOverlay.xul % overlay chrome://global/content/console.xul chrome://browser/content/jsConsoleOverlay.xul % overlay chrome://mozapps/content/update/updates.xul chrome://browser/content/softwareUpdateOverlay.xul #endif @@ -81,7 +80,6 @@ browser.jar: #ifdef XP_MACOSX * content/browser/macBrowserOverlay.xul (content/macBrowserOverlay.xul) * content/browser/downloadManagerOverlay.xul (content/downloadManagerOverlay.xul) -* content/browser/extensionsManagerOverlay.xul (content/extensionsManagerOverlay.xul) * content/browser/jsConsoleOverlay.xul (content/jsConsoleOverlay.xul) * content/browser/softwareUpdateOverlay.xul (content/softwareUpdateOverlay.xul) #endif diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index a5202e126831..ccacbf0946ec 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -62,7 +62,6 @@ XPCOMUtils.defineLazyGetter(this, "PlacesUtils", function() { return PlacesUtils; }); -const PREF_EM_NEW_ADDONS_LIST = "extensions.newAddons"; const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser"; const PREF_PLUGINS_UPDATEURL = "plugins.update.url"; @@ -397,24 +396,6 @@ BrowserGlue.prototype = { if (Services.prefs.prefHasUserValue("app.update.postupdate")) this._showUpdateNotification(); - // If new add-ons were installed during startup open the add-ons manager. - if (Services.prefs.prefHasUserValue(PREF_EM_NEW_ADDONS_LIST)) { - var args = Cc["@mozilla.org/supports-array;1"]. - createInstance(Ci.nsISupportsArray); - var str = Cc["@mozilla.org/supports-string;1"]. - createInstance(Ci.nsISupportsString); - str.data = ""; - args.AppendElement(str); - var str = Cc["@mozilla.org/supports-string;1"]. - createInstance(Ci.nsISupportsString); - str.data = Services.prefs.getCharPref(PREF_EM_NEW_ADDONS_LIST); - args.AppendElement(str); - const EMURL = "chrome://mozapps/content/extensions/extensions.xul"; - const EMFEATURES = "chrome,menubar,extra-chrome,toolbar,dialog=no,resizable"; - Services.ww.openWindow(null, EMURL, "_blank", EMFEATURES, args); - Services.prefs.clearUserPref(PREF_EM_NEW_ADDONS_LIST); - } - // Load the "more info" page for a locked places.sqlite // This property is set earlier by places-database-locked topic. if (this._isPlacesDatabaseLocked) { diff --git a/config/autoconf.mk.in b/config/autoconf.mk.in index 532851a347bd..97becf183350 100644 --- a/config/autoconf.mk.in +++ b/config/autoconf.mk.in @@ -145,7 +145,6 @@ MOZ_TOOLKIT_SEARCH = @MOZ_TOOLKIT_SEARCH@ MOZ_PLACES = @MOZ_PLACES@ MOZ_STORAGE = @MOZ_STORAGE@ MOZ_SAFE_BROWSING = @MOZ_SAFE_BROWSING@ -MOZ_FASTSTART = @MOZ_FASTSTART@ MOZ_URL_CLASSIFIER = @MOZ_URL_CLASSIFIER@ MOZ_ZIPWRITER = @MOZ_ZIPWRITER@ MOZ_MORK = @MOZ_MORK@ diff --git a/configure.in b/configure.in index b617a522992a..f2c0e36b50ba 100644 --- a/configure.in +++ b/configure.in @@ -2188,9 +2188,9 @@ ia64*-hpux*) esac # If we're building with --enable-profiling, we need a frame pointer. if test -z "$MOZ_PROFILING"; then - MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks -fomit-frame-pointer $MOZ_OPTIMIZE_SIZE_TWEAK" + MOZ_OPTIMIZE_FLAGS="-O3 -fomit-frame-pointer" else - MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks -fno-omit-frame-pointer $MOZ_OPTIMIZE_SIZE_TWEAK" + MOZ_OPTIMIZE_FLAGS="-O3 -fno-omit-frame-pointer" fi MOZ_DEBUG_FLAGS="-g" fi @@ -4802,7 +4802,6 @@ MOZ_PSM=1 MOZ_RDF=1 MOZ_REFLOW_PERF= MOZ_SAFE_BROWSING= -MOZ_FASTSTART= MOZ_HELP_VIEWER= MOZ_SPELLCHECK=1 MOZ_SPLASHSCREEN= @@ -6771,18 +6770,6 @@ if test -n "$MOZ_SAFE_BROWSING"; then fi AC_SUBST(MOZ_SAFE_BROWSING) -dnl ======================================================== -dnl = Enable faststart component -dnl ======================================================== -MOZ_ARG_ENABLE_BOOL(faststart, -[ --enable-faststart Enable the faststart component], - MOZ_FASTSTART=1, - MOZ_FASTSTART= ) -if test -n "$MOZ_FASTSTART"; then - AC_DEFINE(MOZ_FASTSTART) -fi -AC_SUBST(MOZ_FASTSTART) - dnl ======================================================== dnl = Enable url-classifier dnl ======================================================== diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index bbaaecc7244f..cbeed4f7dc58 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -1777,6 +1777,25 @@ public: FindInternalContentViewer(const char* aType, ContentViewerType* aLoaderType = nsnull); + /** + * This helper method returns true if the aPattern pattern matches aValue. + * aPattern should not contain leading and trailing slashes (/). + * The pattern has to match the entire value not just a subset. + * aDocument must be a valid pointer (not null). + * + * This is following the HTML5 specification: + * http://dev.w3.org/html5/spec/forms.html#attr-input-pattern + * + * WARNING: This method mutates aPattern and aValue! + * + * @param aValue the string to check. + * @param aPattern the string defining the pattern. + * @param aDocument the owner document of the element. + * @result whether the given string is matches the pattern. + */ + static PRBool IsPatternMatching(nsAString& aValue, nsAString& aPattern, + nsIDocument* aDocument); + /** * Calling this adds support for * ontouch* event handler DOM attributes. diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 60f5c369ee0b..fd93d929a248 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -6552,3 +6552,37 @@ nsContentUtils::FindInternalContentViewer(const char* aType, return NULL; } + +// static +PRBool +nsContentUtils::IsPatternMatching(nsAString& aValue, nsAString& aPattern, + nsIDocument* aDocument) +{ + NS_ASSERTION(aDocument, "aDocument should be a valid pointer (not null)"); + NS_ENSURE_TRUE(aDocument->GetScriptGlobalObject(), PR_TRUE); + + JSContext* ctx = (JSContext*) aDocument->GetScriptGlobalObject()-> + GetContext()->GetNativeContext(); + NS_ENSURE_TRUE(ctx, PR_TRUE); + + JSAutoRequest ar(ctx); + + // The pattern has to match the entire value. + aPattern.Insert(NS_LITERAL_STRING("^(?:"), 0); + aPattern.Append(NS_LITERAL_STRING(")$")); + + JSObject* re = JS_NewUCRegExpObjectNoStatics(ctx, reinterpret_cast + (aPattern.BeginWriting()), + aPattern.Length(), 0); + NS_ENSURE_TRUE(re, PR_TRUE); + + jsval rval = JSVAL_NULL; + size_t idx = 0; + JSBool res; + + res = JS_ExecuteRegExpNoStatics(ctx, re, reinterpret_cast + (aValue.BeginWriting()), + aValue.Length(), &idx, JS_TRUE, &rval); + + return res == JS_FALSE || rval != JSVAL_NULL; +} diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index c2f7590ce733..5b4ab519776f 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -1596,6 +1596,10 @@ nsDocument::~nsDocument() mStyleSheetSetList->Disconnect(); } + if (mAnimationController) { + mAnimationController->Disconnect(); + } + mParentDocument = nsnull; // Kill the subdocument map, doing this will release its strong @@ -5527,7 +5531,7 @@ nsDocument::GetAnimationController() if (!NS_SMILEnabled() || mLoadedAsData || mLoadedAsInteractiveData) return nsnull; - mAnimationController = NS_NewSMILAnimationController(this); + mAnimationController = new nsSMILAnimationController(this); // If there's a presContext then check the animation mode and pause if // necessary. @@ -8338,21 +8342,21 @@ nsDocument::CreateTouch(nsIDOMAbstractView* aView, PRInt32 aRadiusY, float aRotationAngle, float aForce, - nsIDOMTouchPoint** aRetVal) + nsIDOMTouch** aRetVal) { - NS_ADDREF(*aRetVal = new nsDOMTouchPoint(aTarget, - aIdentifier, - aPageX, - aPageY, - aScreenX, - aScreenY, - aClientX, - aClientY, - aRadiusX, - aRadiusY, - aRotationAngle, - aForce)); - return NS_OK;; + NS_ADDREF(*aRetVal = new nsDOMTouch(aTarget, + aIdentifier, + aPageX, + aPageY, + aScreenX, + aScreenY, + aClientX, + aClientY, + aRadiusX, + aRadiusY, + aRotationAngle, + aForce)); + return NS_OK; } NS_IMETHODIMP @@ -8367,7 +8371,7 @@ nsDocument::CreateTouchList(nsIVariant* aPoints, type == nsIDataType::VTYPE_INTERFACE_IS) { nsCOMPtr data; aPoints->GetAsISupports(getter_AddRefs(data)); - nsCOMPtr point = do_QueryInterface(data); + nsCOMPtr point = do_QueryInterface(data); if (point) { retval->Append(point); } @@ -8382,7 +8386,7 @@ nsDocument::CreateTouchList(nsIVariant* aPoints, nsISupports** values = static_cast(rawArray); for (PRUint32 i = 0; i < valueCount; ++i) { nsCOMPtr supports = dont_AddRef(values[i]); - nsCOMPtr point = do_QueryInterface(supports); + nsCOMPtr point = do_QueryInterface(supports); if (point) { retval->Append(point); } diff --git a/content/events/src/nsDOMTouchEvent.cpp b/content/events/src/nsDOMTouchEvent.cpp index e2a77f37dba0..b0f78013271e 100644 --- a/content/events/src/nsDOMTouchEvent.cpp +++ b/content/events/src/nsDOMTouchEvent.cpp @@ -42,98 +42,98 @@ #include "nsIXPCScriptable.h" #include "nsContentUtils.h" -DOMCI_DATA(TouchPoint, nsDOMTouchPoint) +DOMCI_DATA(Touch, nsDOMTouch) -NS_IMPL_CYCLE_COLLECTION_1(nsDOMTouchPoint, mTarget) +NS_IMPL_CYCLE_COLLECTION_1(nsDOMTouch, mTarget) -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMTouchPoint) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMTouchPoint) - NS_INTERFACE_MAP_ENTRY(nsIDOMTouchPoint) - NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(TouchPoint) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMTouch) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMTouch) + NS_INTERFACE_MAP_ENTRY(nsIDOMTouch) + NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Touch) NS_INTERFACE_MAP_END -NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMTouchPoint) -NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMTouchPoint) +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMTouch) +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMTouch) NS_IMETHODIMP -nsDOMTouchPoint::GetIdentifier(PRInt32* aIdentifier) +nsDOMTouch::GetIdentifier(PRInt32* aIdentifier) { *aIdentifier = mIdentifier; return NS_OK; } NS_IMETHODIMP -nsDOMTouchPoint::GetTarget(nsIDOMEventTarget** aTarget) +nsDOMTouch::GetTarget(nsIDOMEventTarget** aTarget) { NS_IF_ADDREF(*aTarget = mTarget); return NS_OK; } NS_IMETHODIMP -nsDOMTouchPoint::GetScreenX(PRInt32* aScreenX) +nsDOMTouch::GetScreenX(PRInt32* aScreenX) { *aScreenX = mScreenX; return NS_OK; } NS_IMETHODIMP -nsDOMTouchPoint::GetScreenY(PRInt32* aScreenY) +nsDOMTouch::GetScreenY(PRInt32* aScreenY) { *aScreenY = mScreenY; return NS_OK; } NS_IMETHODIMP -nsDOMTouchPoint::GetClientX(PRInt32* aClientX) +nsDOMTouch::GetClientX(PRInt32* aClientX) { *aClientX = mClientX; return NS_OK; } NS_IMETHODIMP -nsDOMTouchPoint::GetClientY(PRInt32* aClientY) +nsDOMTouch::GetClientY(PRInt32* aClientY) { *aClientY = mClientY; return NS_OK; } NS_IMETHODIMP -nsDOMTouchPoint::GetPageX(PRInt32* aPageX) +nsDOMTouch::GetPageX(PRInt32* aPageX) { *aPageX = mPageX; return NS_OK; } NS_IMETHODIMP -nsDOMTouchPoint::GetPageY(PRInt32* aPageY) +nsDOMTouch::GetPageY(PRInt32* aPageY) { *aPageY = mPageY; return NS_OK; } NS_IMETHODIMP -nsDOMTouchPoint::GetRadiusX(PRInt32* aRadiusX) +nsDOMTouch::GetRadiusX(PRInt32* aRadiusX) { *aRadiusX = mRadiusX; return NS_OK; } NS_IMETHODIMP -nsDOMTouchPoint::GetRadiusY(PRInt32* aRadiusY) +nsDOMTouch::GetRadiusY(PRInt32* aRadiusY) { *aRadiusY = mRadiusY; return NS_OK; } NS_IMETHODIMP -nsDOMTouchPoint::GetRotationAngle(float* aRotationAngle) +nsDOMTouch::GetRotationAngle(float* aRotationAngle) { *aRotationAngle = mRotationAngle; return NS_OK; } NS_IMETHODIMP -nsDOMTouchPoint::GetForce(float* aForce) +nsDOMTouch::GetForce(float* aForce) { *aForce = mForce; return NS_OK; @@ -170,17 +170,18 @@ nsDOMTouchList::GetLength(PRUint32* aLength) } NS_IMETHODIMP -nsDOMTouchList::Item(PRUint32 aIndex, nsIDOMTouchPoint** aRetVal) +nsDOMTouchList::Item(PRUint32 aIndex, nsIDOMTouch** aRetVal) { NS_IF_ADDREF(*aRetVal = mPoints.SafeObjectAt(aIndex)); return NS_OK; } NS_IMETHODIMP -nsDOMTouchList::IdentifiedPoint(PRInt32 aIdentifier, nsIDOMTouchPoint** aRetVal) +nsDOMTouchList::IdentifiedTouch(PRInt32 aIdentifier, nsIDOMTouch** aRetVal) { + *aRetVal = nsnull; for (PRInt32 i = 0; i < mPoints.Count(); ++i) { - nsCOMPtr point = mPoints[i]; + nsCOMPtr point = mPoints[i]; PRInt32 identifier; if (point && NS_SUCCEEDED(point->GetIdentifier(&identifier)) && aIdentifier == identifier) { diff --git a/content/events/src/nsDOMTouchEvent.h b/content/events/src/nsDOMTouchEvent.h index 7a581439659d..1e0bf457d0c0 100644 --- a/content/events/src/nsDOMTouchEvent.h +++ b/content/events/src/nsDOMTouchEvent.h @@ -42,21 +42,21 @@ #include "nsString.h" #include "nsCOMArray.h" -class nsDOMTouchPoint : public nsIDOMTouchPoint +class nsDOMTouch : public nsIDOMTouch { public: - nsDOMTouchPoint(nsIDOMEventTarget* aTarget, - PRInt32 aIdentifier, - PRInt32 aPageX, - PRInt32 aPageY, - PRInt32 aScreenX, - PRInt32 aScreenY, - PRInt32 aClientX, - PRInt32 aClientY, - PRInt32 aRadiusX, - PRInt32 aRadiusY, - float aRotationAngle, - float aForce) + nsDOMTouch(nsIDOMEventTarget* aTarget, + PRInt32 aIdentifier, + PRInt32 aPageX, + PRInt32 aPageY, + PRInt32 aScreenX, + PRInt32 aScreenY, + PRInt32 aClientX, + PRInt32 aClientY, + PRInt32 aRadiusX, + PRInt32 aRadiusY, + float aRotationAngle, + float aForce) : mTarget(aTarget), mIdentifier(aIdentifier), mPageX(aPageX), @@ -71,8 +71,8 @@ public: mForce(aForce) {} NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMTouchPoint) - NS_DECL_NSIDOMTOUCHPOINT + NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMTouch) + NS_DECL_NSIDOMTOUCH protected: nsCOMPtr mTarget; PRInt32 mIdentifier; @@ -95,17 +95,17 @@ public: NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMTouchList) NS_DECL_NSIDOMTOUCHLIST - void Append(nsIDOMTouchPoint* aPoint) + void Append(nsIDOMTouch* aPoint) { mPoints.AppendObject(aPoint); } - nsIDOMTouchPoint* GetItemAt(PRUint32 aIndex) + nsIDOMTouch* GetItemAt(PRUint32 aIndex) { return mPoints.SafeObjectAt(aIndex); } protected: - nsCOMArray mPoints; + nsCOMArray mPoints; }; class nsDOMTouchEvent : public nsDOMUIEvent, diff --git a/content/html/content/src/nsHTMLInputElement.cpp b/content/html/content/src/nsHTMLInputElement.cpp index 0b0ebff0abf0..bbc1f4523c9c 100644 --- a/content/html/content/src/nsHTMLInputElement.cpp +++ b/content/html/content/src/nsHTMLInputElement.cpp @@ -3813,7 +3813,7 @@ nsHTMLInputElement::HasPatternMismatch() const return PR_FALSE; } - return !IsPatternMatching(value, pattern, doc); + return !nsContentUtils::IsPatternMatching(value, pattern, doc); } void @@ -4095,40 +4095,6 @@ nsHTMLInputElement::IsValidEmailAddress(const nsAString& aValue) return PR_TRUE; } -//static -PRBool -nsHTMLInputElement::IsPatternMatching(nsAString& aValue, nsAString& aPattern, - nsIDocument* aDocument) -{ - NS_ASSERTION(aDocument, "aDocument should be a valid pointer (not null)"); - NS_ENSURE_TRUE(aDocument->GetScriptGlobalObject(), PR_TRUE); - - JSContext* ctx = (JSContext*) aDocument->GetScriptGlobalObject()-> - GetContext()->GetNativeContext(); - NS_ENSURE_TRUE(ctx, PR_TRUE); - - JSAutoRequest ar(ctx); - - // The pattern has to match the entire value. - aPattern.Insert(NS_LITERAL_STRING("^(?:"), 0); - aPattern.Append(NS_LITERAL_STRING(")$")); - - JSObject* re = JS_NewUCRegExpObjectNoStatics(ctx, reinterpret_cast - (aPattern.BeginWriting()), - aPattern.Length(), 0); - NS_ENSURE_TRUE(re, PR_TRUE); - - jsval rval = JSVAL_NULL; - size_t idx = 0; - JSBool res; - - res = JS_ExecuteRegExpNoStatics(ctx, re, reinterpret_cast - (aValue.BeginWriting()), - aValue.Length(), &idx, JS_TRUE, &rval); - - return res == JS_FALSE || rval != JSVAL_NULL; -} - NS_IMETHODIMP_(PRBool) nsHTMLInputElement::IsSingleLineTextControl() const { diff --git a/content/html/content/src/nsHTMLInputElement.h b/content/html/content/src/nsHTMLInputElement.h index dde9ae485d1f..ac084f39bab3 100644 --- a/content/html/content/src/nsHTMLInputElement.h +++ b/content/html/content/src/nsHTMLInputElement.h @@ -368,23 +368,6 @@ protected: */ static PRBool IsValidEmailAddressList(const nsAString& aValue); - /** - * This helper method returns true if the aPattern pattern matches aValue. - * aPattern should not contain leading and trailing slashes (/). - * The pattern has to match the entire value not just a subset. - * aDocument must be a valid pointer (not null). - * - * This is following the HTML5 specification: - * http://dev.w3.org/html5/spec/forms.html#attr-input-pattern - * - * @param aValue the string to check. - * @param aPattern the string defining the pattern. - * @param aDocument the owner document of the element. - * @result whether the given string is matches the pattern. - */ - static PRBool IsPatternMatching(nsAString& aValue, nsAString& aPattern, - nsIDocument* aDocument); - // Helper method nsresult SetValueInternal(const nsAString& aValue, PRBool aUserInput, diff --git a/content/smil/nsSMILAnimationController.cpp b/content/smil/nsSMILAnimationController.cpp index ae102c01e7fc..eadda8e28304 100644 --- a/content/smil/nsSMILAnimationController.cpp +++ b/content/smil/nsSMILAnimationController.cpp @@ -55,64 +55,22 @@ using namespace mozilla::dom; //---------------------------------------------------------------------- // nsSMILAnimationController implementation -// Helper method -static nsRefreshDriver* -GetRefreshDriverForDoc(nsIDocument* aDoc) -{ - nsIPresShell* shell = aDoc->GetShell(); - if (!shell) { - return nsnull; - } - - nsPresContext* context = shell->GetPresContext(); - return context ? context->RefreshDriver() : nsnull; -} - //---------------------------------------------------------------------- // ctors, dtors, factory methods -nsSMILAnimationController::nsSMILAnimationController() +nsSMILAnimationController::nsSMILAnimationController(nsIDocument* aDoc) : mAvgTimeBetweenSamples(0), mResampleNeeded(PR_FALSE), mDeferredStartSampling(PR_FALSE), mRunningSample(PR_FALSE), - mDocument(nsnull) + mDocument(aDoc) { + NS_ABORT_IF_FALSE(aDoc, "need a non-null document"); + mAnimationElementTable.Init(); mChildContainerTable.Init(); -} -nsSMILAnimationController::~nsSMILAnimationController() -{ - StopSampling(GetRefreshDriverForDoc(mDocument)); - NS_ASSERTION(mAnimationElementTable.Count() == 0, - "Animation controller shouldn't be tracking any animation" - " elements when it dies"); -} - -nsSMILAnimationController* NS_NewSMILAnimationController(nsIDocument* aDoc) -{ - nsSMILAnimationController* animationController = - new nsSMILAnimationController(); - NS_ENSURE_TRUE(animationController, nsnull); - - nsresult rv = animationController->Init(aDoc); - if (NS_FAILED(rv)) { - delete animationController; - animationController = nsnull; - } - - return animationController; -} - -nsresult -nsSMILAnimationController::Init(nsIDocument* aDoc) -{ - NS_ENSURE_ARG_POINTER(aDoc); - - // Keep track of document, so we can traverse its set of animation elements - mDocument = aDoc; - nsRefreshDriver* refreshDriver = GetRefreshDriverForDoc(mDocument); + nsRefreshDriver* refreshDriver = GetRefreshDriver(); if (refreshDriver) { mStartTime = refreshDriver->MostRecentRefresh(); } else { @@ -121,8 +79,25 @@ nsSMILAnimationController::Init(nsIDocument* aDoc) mCurrentSampleTime = mStartTime; Begin(); +} - return NS_OK; +nsSMILAnimationController::~nsSMILAnimationController() +{ + NS_ASSERTION(mAnimationElementTable.Count() == 0, + "Animation controller shouldn't be tracking any animation" + " elements when it dies"); +} + +void +nsSMILAnimationController::Disconnect() +{ + NS_ABORT_IF_FALSE(mDocument, "disconnecting when we weren't connected...?"); + NS_ABORT_IF_FALSE(mRefCnt.get() == 1, + "Expecting to disconnect when doc is sole remaining owner"); + + StopSampling(GetRefreshDriver()); + + mDocument = nsnull; // (raw pointer) } //---------------------------------------------------------------------- @@ -135,7 +110,7 @@ nsSMILAnimationController::Pause(PRUint32 aType) if (mPauseState) { mDeferredStartSampling = PR_FALSE; - StopSampling(GetRefreshDriverForDoc(mDocument)); + StopSampling(GetRefreshDriver()); } } @@ -151,7 +126,7 @@ nsSMILAnimationController::Resume(PRUint32 aType) if (wasPaused && !mPauseState && mChildContainerTable.Count()) { Sample(); // Run the first sample manually - MaybeStartSampling(GetRefreshDriverForDoc(mDocument)); + MaybeStartSampling(GetRefreshDriver()); } } @@ -230,7 +205,7 @@ nsSMILAnimationController::RegisterAnimationElement( NS_ABORT_IF_FALSE(mAnimationElementTable.Count() == 1, "we shouldn't have deferred sampling if we already had " "animations registered"); - StartSampling(GetRefreshDriverForDoc(mDocument)); + StartSampling(GetRefreshDriver()); } // else, don't sample until a time container is registered (via AddChild) } } @@ -319,8 +294,8 @@ nsSMILAnimationController::StartSampling(nsRefreshDriver* aRefreshDriver) NS_ASSERTION(!mDeferredStartSampling, "Started sampling but the deferred start flag is still set"); if (aRefreshDriver) { - NS_ABORT_IF_FALSE(!GetRefreshDriverForDoc(mDocument) || - aRefreshDriver == GetRefreshDriverForDoc(mDocument), + NS_ABORT_IF_FALSE(!GetRefreshDriver() || + aRefreshDriver == GetRefreshDriver(), "Starting sampling with wrong refresh driver"); // We're effectively resuming from a pause so update our current sample time // or else it will confuse our "average time between samples" calculations. @@ -335,8 +310,8 @@ nsSMILAnimationController::StopSampling(nsRefreshDriver* aRefreshDriver) if (aRefreshDriver) { // NOTE: The document might already have been detached from its PresContext // (and RefreshDriver), which would make GetRefreshDriverForDoc return null. - NS_ABORT_IF_FALSE(!GetRefreshDriverForDoc(mDocument) || - aRefreshDriver == GetRefreshDriverForDoc(mDocument), + NS_ABORT_IF_FALSE(!GetRefreshDriver() || + aRefreshDriver == GetRefreshDriver(), "Stopping sampling with wrong refresh driver"); aRefreshDriver->RemoveRefreshObserver(this, Flush_Style); } @@ -412,6 +387,11 @@ nsSMILAnimationController::DoSample() void nsSMILAnimationController::DoSample(PRBool aSkipUnchangedContainers) { + if (!mDocument) { + NS_ERROR("Shouldn't be sampling after document has disconnected"); + return; + } + mResampleNeeded = PR_FALSE; // Set running sample flag -- do this before flushing styles so that when we // flush styles we don't end up requesting extra samples @@ -836,7 +816,7 @@ nsSMILAnimationController::AddChild(nsSMILTimeContainer& aChild) if (!mPauseState && mChildContainerTable.Count() == 1) { Sample(); // Run the first sample manually - MaybeStartSampling(GetRefreshDriverForDoc(mDocument)); + MaybeStartSampling(GetRefreshDriver()); } return NS_OK; @@ -848,6 +828,24 @@ nsSMILAnimationController::RemoveChild(nsSMILTimeContainer& aChild) mChildContainerTable.RemoveEntry(&aChild); if (!mPauseState && mChildContainerTable.Count() == 0) { - StopSampling(GetRefreshDriverForDoc(mDocument)); + StopSampling(GetRefreshDriver()); } } + +// Helper method +nsRefreshDriver* +nsSMILAnimationController::GetRefreshDriver() +{ + if (!mDocument) { + NS_ERROR("Requesting refresh driver after document has disconnected!"); + return nsnull; + } + + nsIPresShell* shell = mDocument->GetShell(); + if (!shell) { + return nsnull; + } + + nsPresContext* context = shell->GetPresContext(); + return context ? context->RefreshDriver() : nsnull; +} diff --git a/content/smil/nsSMILAnimationController.h b/content/smil/nsSMILAnimationController.h index 501c4151451a..9b749497ad20 100644 --- a/content/smil/nsSMILAnimationController.h +++ b/content/smil/nsSMILAnimationController.h @@ -70,11 +70,13 @@ class nsIDocument; class nsSMILAnimationController : public nsSMILTimeContainer, public nsARefreshObserver { -protected: - nsSMILAnimationController(); public: + nsSMILAnimationController(nsIDocument* aDoc); ~nsSMILAnimationController(); + // Clears mDocument pointer. (Called by our nsIDocument when it's going away) + void Disconnect(); + // nsSMILContainer virtual void Pause(PRUint32 aType); virtual void Resume(PRUint32 aType); @@ -149,15 +151,13 @@ protected: nsSMILMilestone mMilestone; }; - // Factory methods - friend nsSMILAnimationController* - NS_NewSMILAnimationController(nsIDocument* aDoc); - nsresult Init(nsIDocument* aDoc); - // Cycle-collection implementation helpers PR_STATIC_CALLBACK(PLDHashOperator) CompositorTableEntryTraverse( nsSMILCompositor* aCompositor, void* aArg); + // Returns mDocument's refresh driver, if it's got one. + nsRefreshDriver* GetRefreshDriver(); + // Methods for controlling whether we're sampling void StartSampling(nsRefreshDriver* aRefreshDriver); void StopSampling(nsRefreshDriver* aRefreshDriver); @@ -243,6 +243,4 @@ protected: nsAutoPtr mLastCompositorTable; }; -nsSMILAnimationController* NS_NewSMILAnimationController(nsIDocument *doc); - #endif // NS_SMILANIMATIONCONTROLLER_H_ diff --git a/content/svg/content/src/SVGPathData.h b/content/svg/content/src/SVGPathData.h index 03c147d7b20b..9bb01a66a7f5 100644 --- a/content/svg/content/src/SVGPathData.h +++ b/content/svg/content/src/SVGPathData.h @@ -261,6 +261,14 @@ public: return SVGPathData::CopyFrom(rhs); } + PRBool IsIdentity() const { + if (!mElement) { + NS_ABORT_IF_FALSE(IsEmpty(), "target element propagation failure"); + return PR_TRUE; + } + return PR_FALSE; + } + /** * Exposed so that SVGPathData baseVals can be copied to * SVGPathDataAndOwner objects. Note that callers should also call diff --git a/content/svg/content/src/SVGPathSegListSMILType.cpp b/content/svg/content/src/SVGPathSegListSMILType.cpp index 12791fef94bc..28660c5a2ae5 100644 --- a/content/svg/content/src/SVGPathSegListSMILType.cpp +++ b/content/svg/content/src/SVGPathSegListSMILType.cpp @@ -37,8 +37,14 @@ #include "SVGPathSegListSMILType.h" #include "nsSMILValue.h" #include "SVGPathData.h" +#include "mozilla/Util.h" #include +// Indices of boolean flags within 'arc' segment chunks in path-data arrays +// (where '0' would correspond to the index of the encoded segment type): +#define LARGE_ARC_FLAG_IDX 4 +#define SWEEP_FLAG_IDX 5 + namespace mozilla { /*static*/ SVGPathSegListSMILType SVGPathSegListSMILType::sSingleton; @@ -100,8 +106,8 @@ ArcFlagsDiffer(SVGPathDataAndOwner::const_iterator aPathData1, (SVGPathSegUtils::IsArcType(SVGPathSegUtils::DecodeType(aPathData2[0])), "ArcFlagsDiffer called with non-arc segment"); - return aPathData1[4] != aPathData2[4] || // large arc flag - aPathData1[5] != aPathData2[5]; // sweep flag + return aPathData1[LARGE_ARC_FLAG_IDX] != aPathData2[LARGE_ARC_FLAG_IDX] || + aPathData1[SWEEP_FLAG_IDX] != aPathData2[SWEEP_FLAG_IDX]; } enum PathInterpolationResult { @@ -114,7 +120,7 @@ static PathInterpolationResult CanInterpolate(const SVGPathDataAndOwner& aStart, const SVGPathDataAndOwner& aEnd) { - if (aStart.IsEmpty()) { + if (aStart.IsIdentity()) { return eCanInterpolate; } @@ -161,39 +167,6 @@ CanInterpolate(const SVGPathDataAndOwner& aStart, return result; } -static void -InterpolatePathSegmentData(SVGPathDataAndOwner::const_iterator& aStart, - SVGPathDataAndOwner::const_iterator& aEnd, - SVGPathDataAndOwner::iterator& aResult, - float aUnitDistance) -{ - PRUint32 startType = SVGPathSegUtils::DecodeType(*aStart); - PRUint32 endType = SVGPathSegUtils::DecodeType(*aEnd); - - NS_ABORT_IF_FALSE - (startType == endType, - "InterpolatePathSegmentData expects segment types to be the same!"); - - NS_ABORT_IF_FALSE - (!(SVGPathSegUtils::IsArcType(startType) && ArcFlagsDiffer(aStart, aEnd)), - "InterpolatePathSegmentData cannot interpolate arc segments with different flag values!"); - - PRUint32 argCount = SVGPathSegUtils::ArgCountForType(startType); - - // Copy over segment type. - *aResult++ = *aStart++; - ++aEnd; - - // Interpolate the arguments. - SVGPathDataAndOwner::const_iterator startSegEnd = aStart + argCount; - while (aStart != startSegEnd) { - *aResult = *aStart + (*aEnd - *aStart) * aUnitDistance; - ++aStart; - ++aEnd; - ++aResult; - } -} - enum RelativenessAdjustmentType { eAbsoluteToRelative, eRelativeToAbsolute @@ -213,6 +186,134 @@ AdjustSegmentForRelativeness(RelativenessAdjustmentType aAdjustmentType, } } +/** + * Helper function for AddWeightedPathSegLists, to add multiples of two + * path-segments of the same type. + * + * NOTE: |aSeg1| is allowed to be nsnull, so we use |aSeg2| as the + * authoritative source of things like segment-type and boolean arc flags. + * + * @param aCoeff1 The coefficient to use on the first segment. + * @param aSeg1 An iterator pointing to the first segment. This can be + * null, which is treated as identity (zero). + * @param aCoeff2 The coefficient to use on the second segment. + * @param aSeg2 An iterator pointing to the second segment. + * @param [out] aResultSeg An iterator pointing to where we should write the + * result of this operation. + */ +static inline void +AddWeightedPathSegs(double aCoeff1, + SVGPathDataAndOwner::const_iterator& aSeg1, + double aCoeff2, + SVGPathDataAndOwner::const_iterator& aSeg2, + SVGPathDataAndOwner::iterator& aResultSeg) +{ + NS_ABORT_IF_FALSE(aSeg2, "2nd segment must be non-null"); + NS_ABORT_IF_FALSE(aResultSeg, "result segment must be non-null"); + + PRUint32 segType = SVGPathSegUtils::DecodeType(aSeg2[0]); + NS_ABORT_IF_FALSE(!aSeg1 || SVGPathSegUtils::DecodeType(*aSeg1) == segType, + "unexpected segment type"); + + // FIRST: Directly copy the arguments that don't make sense to add. + aResultSeg[0] = aSeg2[0]; // encoded segment type + + PRBool isArcType = SVGPathSegUtils::IsArcType(segType); + if (isArcType) { + // Copy boolean arc flags. + NS_ABORT_IF_FALSE(!aSeg1 || !ArcFlagsDiffer(aSeg1, aSeg2), + "Expecting arc flags to match"); + aResultSeg[LARGE_ARC_FLAG_IDX] = aSeg2[LARGE_ARC_FLAG_IDX]; + aResultSeg[SWEEP_FLAG_IDX] = aSeg2[SWEEP_FLAG_IDX]; + } + + // SECOND: Add the arguments that are supposed to be added. + // (The 1's below are to account for segment type) + PRUint32 numArgs = SVGPathSegUtils::ArgCountForType(segType); + for (PRUint32 i = 1; i < 1 + numArgs; ++i) { + // Need to skip arc flags for arc-type segments. (already handled them) + if (!(isArcType && (i == LARGE_ARC_FLAG_IDX || i == SWEEP_FLAG_IDX))) { + aResultSeg[i] = (aSeg1 ? aCoeff1 * aSeg1[i] : 0.0) + aCoeff2 * aSeg2[i]; + } + } + + // FINALLY: Shift iterators forward. ("1+" is to include seg-type) + if (aSeg1) { + aSeg1 += 1 + numArgs; + } + aSeg2 += 1 + numArgs; + aResultSeg += 1 + numArgs; +} + +/** + * Helper function for Add & Interpolate, to add multiples of two path-segment + * lists. + * + * NOTE: aList1 and aList2 are assumed to have their segment-types and + * segment-count match exactly (unless aList1 is an identity value). + * + * NOTE: aResult, the output list, is expected to either be an identity value + * (in which case we'll grow it) *or* to already have the exactly right length + * (e.g. in cases where aList1 and aResult are actually the same list). + * + * @param aCoeff1 The coefficient to use on the first path segment list. + * @param aList1 The first path segment list. Allowed to be identity. + * @param aCoeff2 The coefficient to use on the second path segment list. + * @param aList2 The second path segment list. + * @param [out] aResultSeg The resulting path segment list. Allowed to be + * identity, in which case we'll grow it to the right + * size. Also allowed to be the same list as aList1. + */ +static void +AddWeightedPathSegLists(double aCoeff1, const SVGPathDataAndOwner& aList1, + double aCoeff2, const SVGPathDataAndOwner& aList2, + SVGPathDataAndOwner& aResult) +{ + NS_ABORT_IF_FALSE(aCoeff1 >= 0.0 && aCoeff2 >= 0.0, + "expecting non-negative coefficients"); + NS_ABORT_IF_FALSE(!aList2.IsIdentity(), + "expecting 2nd list to be non-identity"); + NS_ABORT_IF_FALSE(aList1.IsIdentity() || aList1.Length() == aList2.Length(), + "expecting 1st list to be identity or to have same " + "length as 2nd list"); + NS_ABORT_IF_FALSE(aResult.IsIdentity() || aResult.Length() == aList2.Length(), + "expecting result list to be identity or to have same " + "length as 2nd list"); + + SVGPathDataAndOwner::const_iterator iter1, end1; + if (aList1.IsIdentity()) { + iter1 = end1 = nsnull; // indicate that this is an identity list + } else { + iter1 = aList1.begin(); + end1 = aList1.end(); + } + SVGPathDataAndOwner::const_iterator iter2 = aList2.begin(); + SVGPathDataAndOwner::const_iterator end2 = aList2.end(); + + // Grow |aResult| if necessary. (NOTE: It's possible that aResult and aList1 + // are the same list, so this may implicitly resize aList1. That's fine, + // because in that case, we will have already set iter1 to nsnull above, to + // record that our first operand is an identity value.) + if (aResult.IsIdentity()) { + DebugOnly success = aResult.SetLength(aList2.Length()); + NS_ABORT_IF_FALSE(success, "infallible nsTArray::SetLength should succeed"); + aResult.SetElement(aList2.Element()); // propagate target element info! + } + + SVGPathDataAndOwner::iterator resultIter = aResult.begin(); + + while ((!iter1 || iter1 != end1) && + iter2 != end2) { + AddWeightedPathSegs(aCoeff1, iter1, + aCoeff2, iter2, + resultIter); + } + NS_ABORT_IF_FALSE((!iter1 || iter1 == end1) && + iter2 == end2 && + resultIter == aResult.end(), + "Very, very bad - path data corrupt"); +} + static void ConvertPathSegmentData(SVGPathDataAndOwner::const_iterator& aStart, SVGPathDataAndOwner::const_iterator& aEnd, @@ -336,40 +437,32 @@ SVGPathSegListSMILType::Add(nsSMILValue& aDest, const SVGPathDataAndOwner& valueToAdd = *static_cast(aValueToAdd.mU.mPtr); - // Allow addition to empty dest. - if (dest.IsEmpty()) { - return dest.CopyFrom(valueToAdd); + if (valueToAdd.IsIdentity()) { // Adding identity value - no-op + return NS_OK; } - PathInterpolationResult check = CanInterpolate(dest, valueToAdd); + if (!dest.IsIdentity()) { + // Neither value is identity; make sure they're compatible. + NS_ABORT_IF_FALSE(dest.Element() == valueToAdd.Element(), + "adding values from different elements...?"); - if (check == eCannotInterpolate) { - // nsSVGUtils::ReportToConsole - can't add path segment lists with different - // numbers of segments, with arcs with different flag values, or with - // incompatible segment types. - return NS_ERROR_FAILURE; - } - - if (check == eRequiresConversion) { - ConvertAllPathSegmentData(dest.begin(), dest.end(), - valueToAdd.begin(), valueToAdd.end(), - dest.begin()); - } - - PRUint32 i = 0; - while (i < dest.Length()) { - PRUint32 type = SVGPathSegUtils::DecodeType(dest[i]); - i++; - PRUint32 segEnd = i + SVGPathSegUtils::ArgCountForType(type); - for (; i < segEnd; ++i) { - dest[i] += valueToAdd[i] * aCount; + PathInterpolationResult check = CanInterpolate(dest, valueToAdd); + if (check == eCannotInterpolate) { + // nsSVGUtils::ReportToConsole - can't add path segment lists with + // different numbers of segments, with arcs that have different flag + // values, or with incompatible segment types. + return NS_ERROR_FAILURE; + } + if (check == eRequiresConversion) { + // Convert dest, in-place, to match the types in valueToAdd: + ConvertAllPathSegmentData(dest.begin(), dest.end(), + valueToAdd.begin(), valueToAdd.end(), + dest.begin()); } } - NS_ABORT_IF_FALSE(i == dest.Length(), "Very, very bad - path data corrupt"); + AddWeightedPathSegLists(1.0, dest, aCount, valueToAdd, dest); - // For now we only support pure 'to' animation. - // nsSVGUtils::ReportToConsole return NS_OK; } @@ -405,6 +498,8 @@ SVGPathSegListSMILType::Interpolate(const nsSMILValue& aStartVal, *static_cast(aEndVal.mU.mPtr); SVGPathDataAndOwner& result = *static_cast(aResult.mU.mPtr); + NS_ABORT_IF_FALSE(result.IsIdentity(), + "expecting outparam to start out as identity"); PathInterpolationResult check = CanInterpolate(start, end); @@ -415,57 +510,22 @@ SVGPathSegListSMILType::Interpolate(const nsSMILValue& aStartVal, return NS_ERROR_FAILURE; } - if (!result.SetLength(end.Length())) { - return NS_ERROR_OUT_OF_MEMORY; + const SVGPathDataAndOwner* startListToUse = &start; + if (check == eRequiresConversion) { + // Can't convert |start| in-place, since it's const. Instead, we copy it + // into |result|, converting the types as we go, and use that as our start. + DebugOnly success = result.SetLength(end.Length()); + NS_ABORT_IF_FALSE(success, "infallible nsTArray::SetLength should succeed"); + result.SetElement(end.Element()); // propagate target element info! + + ConvertAllPathSegmentData(start.begin(), start.end(), + end.begin(), end.end(), + result.begin()); + startListToUse = &result; } - if (start.IsEmpty()) { // identity path - PRUint32 i = 0; - while (i < end.Length()) { - PRUint32 type = SVGPathSegUtils::DecodeType(end[i]); - result[i] = end[i]; - i++; - PRUint32 segEnd = i + SVGPathSegUtils::ArgCountForType(type); - if (SVGPathSegUtils::IsArcType(type)) { - result[i] = end[i] * aUnitDistance; - result[i+1] = end[i+1] * aUnitDistance; - result[i+2] = end[i+2] * aUnitDistance; - // boolean args largeArcFlag and sweepFlag must be the same - result[i+3] = end[i+3]; - result[i+4] = end[i+4]; - result[i+5] = end[i+5] * aUnitDistance; - result[i+6] = end[i+6] * aUnitDistance; - i = segEnd; - } else { - for (; i < segEnd; ++i) { - result[i] = end[i] * aUnitDistance; - } - } - } - NS_ABORT_IF_FALSE(i == end.Length() && i == result.Length(), - "Very, very bad - path data corrupt"); - } else { - SVGPathDataAndOwner::const_iterator pStart = start.begin(); - SVGPathDataAndOwner::const_iterator pStartDataEnd = start.end(); - SVGPathDataAndOwner::const_iterator pEnd = end.begin(); - SVGPathDataAndOwner::const_iterator pEndDataEnd = end.end(); - SVGPathDataAndOwner::iterator pResult = result.begin(); - - if (check == eRequiresConversion) { - ConvertAllPathSegmentData(pStart, pStartDataEnd, pEnd, pEndDataEnd, - pResult); - pStart = pResult; - pStartDataEnd = result.end(); - } - - while (pStart != pStartDataEnd && pEnd != pEndDataEnd) { - InterpolatePathSegmentData(pStart, pEnd, pResult, aUnitDistance); - } - - NS_ABORT_IF_FALSE(pStart == pStartDataEnd && pEnd == pEndDataEnd && - pResult == result.end(), - "Very, very bad - path data corrupt"); - } + AddWeightedPathSegLists(1.0 - aUnitDistance, *startListToUse, + aUnitDistance, end, result); return NS_OK; } diff --git a/content/xul/document/src/nsXULDocument.cpp b/content/xul/document/src/nsXULDocument.cpp index bb5994741a24..bc53d5a5e8c8 100644 --- a/content/xul/document/src/nsXULDocument.cpp +++ b/content/xul/document/src/nsXULDocument.cpp @@ -388,6 +388,12 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXULDocument, nsXMLDocument) tmp->mPendingOverlayLoadNotifications.EnumerateRead(TraverseObservers, &cb); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXULDocument, nsXMLDocument) + delete tmp->mTemplateBuilderTable; + tmp->mTemplateBuilderTable = nsnull; + //XXX We should probably unlink all the objects we traverse. +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + NS_IMPL_ADDREF_INHERITED(nsXULDocument, nsXMLDocument) NS_IMPL_RELEASE_INHERITED(nsXULDocument, nsXMLDocument) @@ -1842,6 +1848,9 @@ nsXULDocument::SetTemplateBuilderFor(nsIContent* aContent, nsIXULTemplateBuilder* aBuilder) { if (! mTemplateBuilderTable) { + if (!aBuilder) { + return NS_OK; + } mTemplateBuilderTable = new BuilderTable; if (! mTemplateBuilderTable || !mTemplateBuilderTable->Init()) { mTemplateBuilderTable = nsnull; diff --git a/content/xul/document/src/nsXULDocument.h b/content/xul/document/src/nsXULDocument.h index 99e1501d8973..e6fb3a995690 100644 --- a/content/xul/document/src/nsXULDocument.h +++ b/content/xul/document/src/nsXULDocument.h @@ -202,8 +202,7 @@ public: nsIAtom* aAttrName, void* aData); - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsXULDocument, - nsXMLDocument) + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXULDocument, nsXMLDocument) virtual nsXPCClassInfo* GetClassInfo(); protected: diff --git a/content/xul/templates/src/nsXULTreeBuilder.cpp b/content/xul/templates/src/nsXULTreeBuilder.cpp index 0c8244dfaf36..3c51222884ed 100644 --- a/content/xul/templates/src/nsXULTreeBuilder.cpp +++ b/content/xul/templates/src/nsXULTreeBuilder.cpp @@ -90,7 +90,8 @@ public: // nsINativeTreeView: Untrusted code can use us NS_IMETHOD EnsureNative() { return NS_OK; } - virtual void NodeWillBeDestroyed(const nsINode* aNode); + // nsIMutationObserver + NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED protected: friend nsresult diff --git a/docshell/test/navigation/NavigationUtils.js b/docshell/test/navigation/NavigationUtils.js index cb3bcaea82ac..32b65bacdd10 100644 --- a/docshell/test/navigation/NavigationUtils.js +++ b/docshell/test/navigation/NavigationUtils.js @@ -45,6 +45,9 @@ var body = "This frame was navigated."; var target_url = "data:text/html," + body + ""; +var popup_body = "This is a popup"; +var target_popup_url = "data:text/html," + popup_body + ""; + /////////////////////////////////////////////////////////////////////////// // Functions that navigate frames /////////////////////////////////////////////////////////////////////////// @@ -208,10 +211,12 @@ function xpcWaitForFinishedFrames(callback, numFrames) { } function searchForFinishedFrames(win) { - if (escape(unescape(win.location)) == escape(target_url) && + if ((escape(unescape(win.location)) == escape(target_url) || + escape(unescape(win.location)) == escape(target_popup_url)) && win.document && win.document.body && - win.document.body.textContent == body && + (win.document.body.textContent == body || + win.document.body.textContent == popup_body) && win.document.readyState == "complete") { if (!contains(win, finishedWindows)) { finishedWindows.push(win); diff --git a/docshell/test/navigation/test_not-opener.html b/docshell/test/navigation/test_not-opener.html index beace33becd6..101ad923dde3 100644 --- a/docshell/test/navigation/test_not-opener.html +++ b/docshell/test/navigation/test_not-opener.html @@ -28,7 +28,7 @@ window.onload = function () { xpcCleanupWindows(); SimpleTest.finish(); - }, 3); + }, 6); } //opener0 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/open.html#window0", "_blank", "width=10,height=10"); diff --git a/dom/base/nsBarProps.cpp b/dom/base/nsBarProps.cpp index a97df9c94818..61ef110b9285 100644 --- a/dom/base/nsBarProps.cpp +++ b/dom/base/nsBarProps.cpp @@ -51,8 +51,11 @@ // // Basic (virtual) BarProp class implementation // -nsBarProp::nsBarProp() : mBrowserChrome(nsnull) +nsBarProp::nsBarProp(nsGlobalWindow *aWindow) { + mDOMWindow = aWindow; + nsISupports *supwin = static_cast(aWindow); + mDOMWindowWeakref = do_GetWeakReference(supwin); } nsBarProp::~nsBarProp() @@ -73,25 +76,19 @@ NS_INTERFACE_MAP_END NS_IMPL_ADDREF(nsBarProp) NS_IMPL_RELEASE(nsBarProp) - -NS_IMETHODIMP -nsBarProp::SetWebBrowserChrome(nsIWebBrowserChrome* aBrowserChrome) -{ - mBrowserChrome = aBrowserChrome; - return NS_OK; -} - NS_IMETHODIMP nsBarProp::GetVisibleByFlag(PRBool *aVisible, PRUint32 aChromeFlag) { *aVisible = PR_FALSE; - NS_ENSURE_TRUE(mBrowserChrome, NS_OK); + + nsCOMPtr browserChrome = GetBrowserChrome(); + NS_ENSURE_TRUE(browserChrome, NS_OK); PRUint32 chromeFlags; - NS_ENSURE_SUCCESS(mBrowserChrome->GetChromeFlags(&chromeFlags), + NS_ENSURE_SUCCESS(browserChrome->GetChromeFlags(&chromeFlags), NS_ERROR_FAILURE); - if(chromeFlags & aChromeFlag) + if (chromeFlags & aChromeFlag) *aVisible = PR_TRUE; return NS_OK; @@ -100,9 +97,10 @@ nsBarProp::GetVisibleByFlag(PRBool *aVisible, PRUint32 aChromeFlag) NS_IMETHODIMP nsBarProp::SetVisibleByFlag(PRBool aVisible, PRUint32 aChromeFlag) { - NS_ENSURE_TRUE(mBrowserChrome, NS_OK); + nsCOMPtr browserChrome = GetBrowserChrome(); + NS_ENSURE_TRUE(browserChrome, NS_OK); - PRBool enabled = PR_FALSE; + PRBool enabled = PR_FALSE; nsCOMPtr securityManager(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID)); @@ -113,23 +111,37 @@ nsBarProp::SetVisibleByFlag(PRBool aVisible, PRUint32 aChromeFlag) PRUint32 chromeFlags; - NS_ENSURE_SUCCESS(mBrowserChrome->GetChromeFlags(&chromeFlags), + NS_ENSURE_SUCCESS(browserChrome->GetChromeFlags(&chromeFlags), NS_ERROR_FAILURE); - if(aVisible) + if (aVisible) chromeFlags |= aChromeFlag; else chromeFlags &= ~aChromeFlag; - NS_ENSURE_SUCCESS(mBrowserChrome->SetChromeFlags(chromeFlags), + NS_ENSURE_SUCCESS(browserChrome->SetChromeFlags(chromeFlags), NS_ERROR_FAILURE); return NS_OK; } +already_AddRefed +nsBarProp::GetBrowserChrome() +{ + // Check that the window is still alive. + nsCOMPtr domwin(do_QueryReferent(mDOMWindowWeakref)); + if (!domwin) + return nsnull; + + nsIWebBrowserChrome *browserChrome = nsnull; + mDOMWindow->GetWebBrowserChrome(&browserChrome); + return browserChrome; +} + // // MenubarProp class implementation // -nsMenubarProp::nsMenubarProp() +nsMenubarProp::nsMenubarProp(nsGlobalWindow *aWindow) + : nsBarProp(aWindow) { } @@ -155,7 +167,8 @@ nsMenubarProp::SetVisible(PRBool aVisible) // ToolbarProp class implementation // -nsToolbarProp::nsToolbarProp() +nsToolbarProp::nsToolbarProp(nsGlobalWindow *aWindow) + : nsBarProp(aWindow) { } @@ -181,7 +194,8 @@ nsToolbarProp::SetVisible(PRBool aVisible) // LocationbarProp class implementation // -nsLocationbarProp::nsLocationbarProp() +nsLocationbarProp::nsLocationbarProp(nsGlobalWindow *aWindow) + : nsBarProp(aWindow) { } @@ -209,7 +223,8 @@ nsLocationbarProp::SetVisible(PRBool aVisible) // PersonalbarProp class implementation // -nsPersonalbarProp::nsPersonalbarProp() +nsPersonalbarProp::nsPersonalbarProp(nsGlobalWindow *aWindow) + : nsBarProp(aWindow) { } @@ -237,7 +252,8 @@ nsPersonalbarProp::SetVisible(PRBool aVisible) // StatusbarProp class implementation // -nsStatusbarProp::nsStatusbarProp() +nsStatusbarProp::nsStatusbarProp(nsGlobalWindow *aWindow) + : nsBarProp(aWindow) { } @@ -264,10 +280,8 @@ nsStatusbarProp::SetVisible(PRBool aVisible) // nsScrollbarsProp::nsScrollbarsProp(nsGlobalWindow *aWindow) +: nsBarProp(aWindow) { - mDOMWindow = aWindow; - nsISupports *supwin = static_cast(aWindow); - mDOMWindowWeakref = do_GetWeakReference(supwin); } nsScrollbarsProp::~nsScrollbarsProp() @@ -341,7 +355,7 @@ nsScrollbarsProp::SetVisible(PRBool aVisible) } /* Notably absent is the part where we notify the chrome window using - mBrowserChrome->SetChromeFlags(). Given the possibility of multiple + GetBrowserChrome()->SetChromeFlags(). Given the possibility of multiple DOM windows (multiple top-level windows, even) within a single chrome window, the historical concept of a single "has scrollbars" flag in the chrome is inapplicable, and we can't tell at this level diff --git a/dom/base/nsBarProps.h b/dom/base/nsBarProps.h index 80cc6838dfb9..f032c10e6b23 100644 --- a/dom/base/nsBarProps.h +++ b/dom/base/nsBarProps.h @@ -56,26 +56,34 @@ class nsIWebBrowserChrome; class nsBarProp : public nsIDOMBarProp { public: - nsBarProp(); + explicit nsBarProp(nsGlobalWindow *aWindow); virtual ~nsBarProp(); NS_DECL_ISUPPORTS - NS_IMETHOD SetWebBrowserChrome(nsIWebBrowserChrome* aBrowserChrome); - NS_IMETHOD GetVisibleByFlag(PRBool *aVisible, PRUint32 aChromeFlag); NS_IMETHOD SetVisibleByFlag(PRBool aVisible, PRUint32 aChromeFlag); protected: - // Weak Reference - nsIWebBrowserChrome* mBrowserChrome; + already_AddRefed GetBrowserChrome(); + + nsGlobalWindow *mDOMWindow; + nsCOMPtr mDOMWindowWeakref; + /* Note the odd double reference to the owning global window. + Since the corresponding DOM window nominally owns this object, + but refcounted ownership of this object can be handed off to + owners unknown, we need a weak ref back to the DOM window. + However we also need access to properties of the DOM Window + that aren't available through interfaces. Then it's either + a weak ref and some skanky casting, or this funky double ref. + Funky beats skanky, so here we are. */ }; // Script "menubar" object class nsMenubarProp : public nsBarProp { public: - nsMenubarProp(); + explicit nsMenubarProp(nsGlobalWindow *aWindow); virtual ~nsMenubarProp(); NS_DECL_NSIDOMBARPROP @@ -85,7 +93,7 @@ public: class nsToolbarProp : public nsBarProp { public: - nsToolbarProp(); + explicit nsToolbarProp(nsGlobalWindow *aWindow); virtual ~nsToolbarProp(); NS_DECL_NSIDOMBARPROP @@ -95,7 +103,7 @@ public: class nsLocationbarProp : public nsBarProp { public: - nsLocationbarProp(); + explicit nsLocationbarProp(nsGlobalWindow *aWindow); virtual ~nsLocationbarProp(); NS_DECL_NSIDOMBARPROP @@ -105,7 +113,7 @@ public: class nsPersonalbarProp : public nsBarProp { public: - nsPersonalbarProp(); + explicit nsPersonalbarProp(nsGlobalWindow *aWindow); virtual ~nsPersonalbarProp(); NS_DECL_NSIDOMBARPROP @@ -115,31 +123,20 @@ public: class nsStatusbarProp : public nsBarProp { public: - nsStatusbarProp(); + explicit nsStatusbarProp(nsGlobalWindow *aWindow); virtual ~nsStatusbarProp(); NS_DECL_NSIDOMBARPROP }; // Script "scrollbars" object -class nsScrollbarsProp : public nsBarProp { +class nsScrollbarsProp : public nsBarProp +{ public: - nsScrollbarsProp(nsGlobalWindow *aWindow); + explicit nsScrollbarsProp(nsGlobalWindow *aWindow); virtual ~nsScrollbarsProp(); NS_DECL_NSIDOMBARPROP - -private: - nsGlobalWindow *mDOMWindow; - nsCOMPtr mDOMWindowWeakref; - /* Note the odd double reference to the owning global window. - Since the corresponding DOM window nominally owns this object, - yet refcounted ownership of this object can be handed off to - owners unknown, we need a weak ref to back to the DOM window. - However we also need access to properties of the DOM Window - that aren't available through interfaces. Then it's either - a weak ref and some skanky casting, or this funky double ref. - Funky beats skanky, so here we are. */ }; #endif /* nsBarProps_h___ */ diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index f360530f31b7..0d9ec21da745 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -1502,7 +1502,7 @@ static nsDOMClassInfoData sClassInfoData[] = { NS_DEFINE_CLASSINFO_DATA(EventException, nsDOMGenericSH, DOM_DEFAULT_SCRIPTABLE_FLAGS) - NS_DEFINE_CLASSINFO_DATA(TouchPoint, nsDOMGenericSH, + NS_DEFINE_CLASSINFO_DATA(Touch, nsDOMGenericSH, DOM_DEFAULT_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(TouchList, nsDOMTouchListSH, ARRAY_SCRIPTABLE_FLAGS) @@ -4321,9 +4321,9 @@ nsDOMClassInfo::Init() DOM_CLASSINFO_MAP_ENTRY(nsIException) DOM_CLASSINFO_MAP_END - DOM_CLASSINFO_MAP_BEGIN_MAYBE_DISABLE(TouchPoint, nsIDOMTouchPoint, + DOM_CLASSINFO_MAP_BEGIN_MAYBE_DISABLE(Touch, nsIDOMTouch, !nsDOMTouchEvent::PrefEnabled()) - DOM_CLASSINFO_MAP_ENTRY(nsIDOMTouchPoint) + DOM_CLASSINFO_MAP_ENTRY(nsIDOMTouch) DOM_CLASSINFO_MAP_END DOM_CLASSINFO_MAP_BEGIN_MAYBE_DISABLE(TouchList, nsIDOMTouchList, diff --git a/dom/base/nsDOMClassInfoClasses.h b/dom/base/nsDOMClassInfoClasses.h index 628f177bdfdc..773ad6f7048b 100644 --- a/dom/base/nsDOMClassInfoClasses.h +++ b/dom/base/nsDOMClassInfoClasses.h @@ -513,7 +513,7 @@ DOMCI_CLASS(IDBDatabaseException) DOMCI_CLASS(EventException) -DOMCI_CLASS(TouchPoint) +DOMCI_CLASS(Touch) DOMCI_CLASS(TouchList) DOMCI_CLASS(TouchEvent) diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 93bc6c608659..747082afba19 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -2428,28 +2428,6 @@ nsGlobalWindow::SetDocShell(nsIDocShell* aDocShell) if (mScreen) mScreen->SetDocShell(aDocShell); - // tell our member elements about the new browserwindow - nsCOMPtr browserChrome; - GetWebBrowserChrome(getter_AddRefs(browserChrome)); - if (mMenubar) { - mMenubar->SetWebBrowserChrome(browserChrome); - } - if (mToolbar) { - mToolbar->SetWebBrowserChrome(browserChrome); - } - if (mLocationbar) { - mLocationbar->SetWebBrowserChrome(browserChrome); - } - if (mPersonalbar) { - mPersonalbar->SetWebBrowserChrome(browserChrome); - } - if (mStatusbar) { - mStatusbar->SetWebBrowserChrome(browserChrome); - } - if (mScrollbars) { - mScrollbars->SetWebBrowserChrome(browserChrome); - } - if (!mDocShell) { MaybeForgiveSpamCount(); CleanUp(PR_FALSE); @@ -3084,15 +3062,10 @@ nsGlobalWindow::GetMenubar(nsIDOMBarProp** aMenubar) *aMenubar = nsnull; if (!mMenubar) { - mMenubar = new nsMenubarProp(); + mMenubar = new nsMenubarProp(this); if (!mMenubar) { return NS_ERROR_OUT_OF_MEMORY; } - - nsCOMPtr browserChrome; - GetWebBrowserChrome(getter_AddRefs(browserChrome)); - - mMenubar->SetWebBrowserChrome(browserChrome); } NS_ADDREF(*aMenubar = mMenubar); @@ -3108,15 +3081,10 @@ nsGlobalWindow::GetToolbar(nsIDOMBarProp** aToolbar) *aToolbar = nsnull; if (!mToolbar) { - mToolbar = new nsToolbarProp(); + mToolbar = new nsToolbarProp(this); if (!mToolbar) { return NS_ERROR_OUT_OF_MEMORY; } - - nsCOMPtr browserChrome; - GetWebBrowserChrome(getter_AddRefs(browserChrome)); - - mToolbar->SetWebBrowserChrome(browserChrome); } NS_ADDREF(*aToolbar = mToolbar); @@ -3132,15 +3100,10 @@ nsGlobalWindow::GetLocationbar(nsIDOMBarProp** aLocationbar) *aLocationbar = nsnull; if (!mLocationbar) { - mLocationbar = new nsLocationbarProp(); + mLocationbar = new nsLocationbarProp(this); if (!mLocationbar) { return NS_ERROR_OUT_OF_MEMORY; } - - nsCOMPtr browserChrome; - GetWebBrowserChrome(getter_AddRefs(browserChrome)); - - mLocationbar->SetWebBrowserChrome(browserChrome); } NS_ADDREF(*aLocationbar = mLocationbar); @@ -3156,15 +3119,10 @@ nsGlobalWindow::GetPersonalbar(nsIDOMBarProp** aPersonalbar) *aPersonalbar = nsnull; if (!mPersonalbar) { - mPersonalbar = new nsPersonalbarProp(); + mPersonalbar = new nsPersonalbarProp(this); if (!mPersonalbar) { return NS_ERROR_OUT_OF_MEMORY; } - - nsCOMPtr browserChrome; - GetWebBrowserChrome(getter_AddRefs(browserChrome)); - - mPersonalbar->SetWebBrowserChrome(browserChrome); } NS_ADDREF(*aPersonalbar = mPersonalbar); @@ -3180,15 +3138,10 @@ nsGlobalWindow::GetStatusbar(nsIDOMBarProp** aStatusbar) *aStatusbar = nsnull; if (!mStatusbar) { - mStatusbar = new nsStatusbarProp(); + mStatusbar = new nsStatusbarProp(this); if (!mStatusbar) { return NS_ERROR_OUT_OF_MEMORY; } - - nsCOMPtr browserChrome; - GetWebBrowserChrome(getter_AddRefs(browserChrome)); - - mStatusbar->SetWebBrowserChrome(browserChrome); } NS_ADDREF(*aStatusbar = mStatusbar); @@ -3208,11 +3161,6 @@ nsGlobalWindow::GetScrollbars(nsIDOMBarProp** aScrollbars) if (!mScrollbars) { return NS_ERROR_OUT_OF_MEMORY; } - - nsCOMPtr browserChrome; - GetWebBrowserChrome(getter_AddRefs(browserChrome)); - - mScrollbars->SetWebBrowserChrome(browserChrome); } NS_ADDREF(*aScrollbars = mScrollbars); diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index dac3c390d91a..e033bf7f20d3 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -589,6 +589,7 @@ private: protected: friend class HashchangeCallback; + friend class nsBarProp; // Object Management virtual ~nsGlobalWindow(); diff --git a/dom/interfaces/events/nsIDOMTouchEvent.idl b/dom/interfaces/events/nsIDOMTouchEvent.idl index f9f9c62b22cd..e3a25ad17cda 100644 --- a/dom/interfaces/events/nsIDOMTouchEvent.idl +++ b/dom/interfaces/events/nsIDOMTouchEvent.idl @@ -42,8 +42,8 @@ interface nsIVariant; * @see http://dvcs.w3.org/hg/webevents/raw-file/tip/touchevents.html */ -[scriptable, uuid(f9f200ad-228f-4879-bc9e-a13bd6bb82ef)] -interface nsIDOMTouchPoint : nsISupports { +[scriptable, uuid(98bc0f7d-5bff-4387-9c42-58af54b48dd5)] +interface nsIDOMTouch : nsISupports { readonly attribute long identifier; readonly attribute nsIDOMEventTarget target; readonly attribute long pageX; @@ -61,8 +61,8 @@ interface nsIDOMTouchPoint : nsISupports { [scriptable, uuid(60706eb7-d50d-4379-b01c-e78e6af84213)] interface nsIDOMTouchList : nsISupports { readonly attribute unsigned long length; - nsIDOMTouchPoint item(in unsigned long index); - nsIDOMTouchPoint identifiedPoint(in long identifier); + nsIDOMTouch item(in unsigned long index); + nsIDOMTouch identifiedTouch(in long identifier); }; [scriptable, uuid(df94b20b-7998-4f00-935c-ee2c6b179711)] @@ -90,19 +90,19 @@ interface nsIDOMTouchEvent : nsIDOMUIEvent { [scriptable, uuid(922e0f11-28b9-4560-9fb8-869fe143845f)] interface nsIDOMDocumentTouch : nsISupports { - nsIDOMTouchPoint createTouch([optional] in nsIDOMAbstractView view, - [optional] in nsIDOMEventTarget target, - [optional] in long identifier, - [optional] in long pageX, - [optional] in long pageY, - [optional] in long screenX, - [optional] in long screenY, - [optional] in long clientX, - [optional] in long clientY, - [optional] in long radiusX, - [optional] in long radiusY, - [optional] in float rotationAngle, - [optional] in float force); + nsIDOMTouch createTouch([optional] in nsIDOMAbstractView view, + [optional] in nsIDOMEventTarget target, + [optional] in long identifier, + [optional] in long pageX, + [optional] in long pageY, + [optional] in long screenX, + [optional] in long screenY, + [optional] in long clientX, + [optional] in long clientY, + [optional] in long radiusX, + [optional] in long radiusY, + [optional] in float rotationAngle, + [optional] in float force); nsIDOMTouchList createTouchList([optional] in nsIVariant aPoints); diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index a037ec6b59b0..343a7c5752a4 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -284,10 +284,9 @@ ContentParent::ActorDestroy(ActorDestroyReason why) TakeMinidump(getter_AddRefs(crashDump)) && CrashReporter::GetIDFromMinidump(crashDump, dumpID); - if (!dumpID.IsEmpty()) { - props->SetPropertyAsAString(NS_LITERAL_STRING("dumpID"), - dumpID); + props->SetPropertyAsAString(NS_LITERAL_STRING("dumpID"), dumpID); + if (!dumpID.IsEmpty()) { CrashReporter::AnnotationTable notes; notes.Init(); notes.Put(NS_LITERAL_CSTRING("ProcessType"), NS_LITERAL_CSTRING("content")); diff --git a/dom/ipc/tests/process_error.xul b/dom/ipc/tests/process_error.xul index b88b73aca0b0..1956bbbcf4d3 100644 --- a/dom/ipc/tests/process_error.xul +++ b/dom/ipc/tests/process_error.xul @@ -19,7 +19,7 @@ 'Subject implements nsIPropertyBag2.'); if ('nsICrashReporter' in Components.interfaces) { - ok(subject.getPropertyAsAString('dumpID'), "dumpID is present"); + ok(subject.getPropertyAsAString('dumpID'), "dumpID is present and not an empty string"); } Services.obs.removeObserver(crashObserver, 'ipc:content-shutdown'); diff --git a/dom/locales/en-US/chrome/layout/css.properties b/dom/locales/en-US/chrome/layout/css.properties index eb7b5659325f..f5eb5e28d77d 100644 --- a/dom/locales/en-US/chrome/layout/css.properties +++ b/dom/locales/en-US/chrome/layout/css.properties @@ -58,6 +58,7 @@ PEGroupRuleEOF=end of @media or @-moz-document rule PEGroupRuleNestedAtRule=%1$S rule not allowed within @media or @-moz-document rule. PEMozDocRuleBadFunc=Expected url(), url-prefix(), or domain() in @-moz-document rule but found '%1$S'. PEMozDocRuleNotURI=Expected URI in @-moz-document rule but found '%1$S'. +PEMozDocRuleNotString=Expected string in @-moz-document rule regexp() function but found '%1$S'. PEAtNSPrefixEOF=namespace prefix in @namespace rule PEAtNSURIEOF=namespace URI in @namespace rule PEAtNSUnexpected=Unexpected token within @namespace: '%1$S'. diff --git a/dom/plugins/ipc/PPluginInstance.ipdl b/dom/plugins/ipc/PPluginInstance.ipdl index d290c3f7fd66..4dfce814e4df 100644 --- a/dom/plugins/ipc/PPluginInstance.ipdl +++ b/dom/plugins/ipc/PPluginInstance.ipdl @@ -104,6 +104,8 @@ child: returns (nullable PPluginScriptableObject value, NPError result); rpc NPP_SetValue_NPNVprivateModeBool(bool value) returns (NPError result); + rpc NPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId() + returns (nsCString plug_id, NPError result); rpc NPP_HandleEvent(NPRemoteEvent event) returns (int16_t handled); diff --git a/dom/plugins/ipc/PluginInstanceChild.cpp b/dom/plugins/ipc/PluginInstanceChild.cpp index 527fdd774345..cf89adab205c 100644 --- a/dom/plugins/ipc/PluginInstanceChild.cpp +++ b/dom/plugins/ipc/PluginInstanceChild.cpp @@ -586,6 +586,35 @@ PluginInstanceChild::AnswerNPP_GetValue_NPPVpluginScriptableNPObject( return true; } +bool +PluginInstanceChild::AnswerNPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId( + nsCString* aPlugId, + NPError* aResult) +{ + AssertPluginThread(); + +#if MOZ_ACCESSIBILITY_ATK + + char* plugId = NULL; + NPError result = NPERR_GENERIC_ERROR; + if (mPluginIface->getvalue) { + result = mPluginIface->getvalue(GetNPP(), + NPPVpluginNativeAccessibleAtkPlugId, + &plugId); + } + + *aPlugId = nsCString(plugId); + *aResult = result; + return true; + +#else + + NS_RUNTIMEABORT("shouldn't be called on non-ATK platforms"); + return false; + +#endif +} + bool PluginInstanceChild::AnswerNPP_SetValue_NPNVprivateModeBool(const bool& value, NPError* result) diff --git a/dom/plugins/ipc/PluginInstanceChild.h b/dom/plugins/ipc/PluginInstanceChild.h index 28a2679b3bba..8dc9e39d6c42 100644 --- a/dom/plugins/ipc/PluginInstanceChild.h +++ b/dom/plugins/ipc/PluginInstanceChild.h @@ -92,7 +92,9 @@ protected: virtual bool AnswerNPP_GetValue_NPPVpluginScriptableNPObject(PPluginScriptableObjectChild** value, NPError* result); - + virtual bool + AnswerNPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId(nsCString* aPlugId, + NPError* aResult); virtual bool AnswerNPP_SetValue_NPNVprivateModeBool(const bool& value, NPError* result); diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index 0567c27e946e..7ed1a714ce5b 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -961,6 +961,23 @@ PluginInstanceParent::NPP_GetValue(NPPVariable aVariable, return NPERR_NO_ERROR; } +#ifdef MOZ_ACCESSIBILITY_ATK + case NPPVpluginNativeAccessibleAtkPlugId: { + nsCString plugId; + NPError rv; + if (!CallNPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId(&plugId, &rv)) { + return NPERR_GENERIC_ERROR; + } + + if (NPERR_NO_ERROR != rv) { + return rv; + } + + (*(nsCString*)_retval) = plugId; + return NPERR_NO_ERROR; + } +#endif + default: PR_LOG(gPluginLog, PR_LOG_WARNING, ("In PluginInstanceParent::NPP_GetValue: Unhandled NPPVariable %i (%s)", diff --git a/dom/src/notification/nsDesktopNotification.cpp b/dom/src/notification/nsDesktopNotification.cpp index b7770adcad53..92f90e9e1e12 100644 --- a/dom/src/notification/nsDesktopNotification.cpp +++ b/dom/src/notification/nsDesktopNotification.cpp @@ -101,11 +101,7 @@ nsDOMDesktopNotification::nsDOMDesktopNotification(const nsAString & title, nsIURI* uri) : mTitle(title) , mDescription(description) -#ifdef ANDROID - , mIconURL((PRUnichar*)L"drawable://desktop_notification") -#else , mIconURL(iconURL) -#endif , mURI(uri) , mAllow(PR_FALSE) , mShowHasBeenCalled(PR_FALSE) diff --git a/dom/tests/mochitest/bugs/Makefile.in b/dom/tests/mochitest/bugs/Makefile.in index 0daa91d1f5f1..3c44bc79a63a 100644 --- a/dom/tests/mochitest/bugs/Makefile.in +++ b/dom/tests/mochitest/bugs/Makefile.in @@ -138,6 +138,8 @@ _TEST_FILES = \ test_bug633133.html \ test_bug642026.html \ test_bug648465.html \ + test_window_bar.html \ + file_window_bar.html \ $(NULL) libs:: $(_TEST_FILES) diff --git a/dom/tests/mochitest/bugs/file_window_bar.html b/dom/tests/mochitest/bugs/file_window_bar.html new file mode 100644 index 000000000000..59b2c16014e0 --- /dev/null +++ b/dom/tests/mochitest/bugs/file_window_bar.html @@ -0,0 +1,7 @@ + + + +Nothing to see here! + + + diff --git a/dom/tests/mochitest/bugs/test_window_bar.html b/dom/tests/mochitest/bugs/test_window_bar.html new file mode 100644 index 000000000000..484c7eaad133 --- /dev/null +++ b/dom/tests/mochitest/bugs/test_window_bar.html @@ -0,0 +1,80 @@ + + + + + Test for Bug 642338 + + + + + +Mozilla Bug 642338 +

+ +
+
+
+ + diff --git a/editor/libeditor/html/nsHTMLDataTransfer.cpp b/editor/libeditor/html/nsHTMLDataTransfer.cpp index 548d95f11ea2..5b3d2d46519e 100644 --- a/editor/libeditor/html/nsHTMLDataTransfer.cpp +++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp @@ -130,6 +130,8 @@ #include "prmem.h" #include "nsStreamUtils.h" #include "nsIPrincipal.h" +#include "nsIDocShell.h" +#include "nsIDocShellTreeItem.h" const PRUnichar nbsp = 160; @@ -1306,12 +1308,21 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromTransferable(nsITransferable *transferable // Try to determine whether we should use a sanitizing fragment sink PRBool isSafe = PR_FALSE; - if (aSourceDoc) { - nsCOMPtr destdomdoc; - rv = GetDocument(getter_AddRefs(destdomdoc)); - NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr destdoc = do_QueryInterface(destdomdoc); - NS_ASSERTION(destdoc, "Where is our destination doc?"); + nsCOMPtr destdomdoc; + rv = GetDocument(getter_AddRefs(destdomdoc)); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr destdoc = do_QueryInterface(destdomdoc); + NS_ASSERTION(destdoc, "Where is our destination doc?"); + nsCOMPtr container = destdoc->GetContainer(); + nsCOMPtr dsti(do_QueryInterface(container)); + nsCOMPtr root; + if (dsti) + dsti->GetRootTreeItem(getter_AddRefs(root)); + nsCOMPtr docShell(do_QueryInterface(root)); + PRUint32 appType; + if (docShell && NS_SUCCEEDED(docShell->GetAppType(&appType))) + isSafe = appType == nsIDocShell::APP_TYPE_EDITOR; + if (!isSafe && aSourceDoc) { nsCOMPtr srcdoc = do_QueryInterface(aSourceDoc); NS_ASSERTION(srcdoc, "Where is our source doc?"); diff --git a/embedding/android/AlertNotification.java b/embedding/android/AlertNotification.java index d63f5ab35395..bdf540457d1a 100644 --- a/embedding/android/AlertNotification.java +++ b/embedding/android/AlertNotification.java @@ -1,4 +1,4 @@ -/* -*- Mode: Java; tab-width: 20; indent-tabs-mode: nil; -*- +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -40,7 +40,11 @@ package org.mozilla.gecko; import android.app.Notification; import android.app.NotificationManager; import android.content.Context; +import android.graphics.*; +import android.net.Uri; +import android.util.Log; import android.widget.RemoteViews; +import java.net.*; import java.text.NumberFormat; public class AlertNotification @@ -56,6 +60,7 @@ public class AlertNotification double mPrevPercent = -1; String mPrevAlertText = ""; static final double UPDATE_THRESHOLD = .01; + Uri mIconUri = null; public AlertNotification(Context aContext, int aNotificationId, int aIcon, String aTitle, String aText, long aWhen) { @@ -80,10 +85,31 @@ public class AlertNotification mNotificationManager.notify(mId, this); } + public void setCustomIcon(Uri aIconUri) { + mIconUri = aIconUri; + // Custom view + int layout = R.layout.notification_icon_text; + RemoteViews view = new RemoteViews(GeckoApp.mAppContext.getPackageName(), layout); + try { + URL url = new URL(aIconUri.toString()); + Bitmap bm = BitmapFactory.decodeStream(url.openStream()); + view.setImageViewBitmap(R.id.notificationImage, bm); + view.setTextViewText(R.id.notificationTitle, mTitle); + if (mText.length() > 0) { + view.setTextViewText(R.id.notificationText, mText); + } + contentView = view; + mNotificationManager.notify(mId, this); + } catch(Exception ex) { + Log.e("GeckoAlert", "failed to create bitmap", ex); + } + + } + public void updateProgress(String aAlertText, long aProgress, long aProgressMax) { if (!mProgressStyle) { // Custom view - int layout = aAlertText.length() > 0 ? R.layout.notification_progress_text : R.layout.notification_progress; + int layout = aAlertText.length() > 0 ? R.layout.notification_progress_text : R.layout.notification_progress; RemoteViews view = new RemoteViews(GeckoApp.mAppContext.getPackageName(), layout); view.setImageViewResource(R.id.notificationImage, mIcon); diff --git a/embedding/android/GeckoApp.java b/embedding/android/GeckoApp.java index 3ac1eac676f3..d74c94df93d9 100644 --- a/embedding/android/GeckoApp.java +++ b/embedding/android/GeckoApp.java @@ -265,7 +265,10 @@ abstract public class GeckoApp } boolean IsUnsupportedDevice() { - // We don't currently support devices with less than 512Mb of RAM, warn on first run + // We don't currently support devices with less than 512Mb of RAM, + // and want to warn if run on such devices. Most 512Mb devices + // report about 350Mb available, so we check - somewhat arbitrarily - + // for a minimum of 300Mb here. File meminfo = new File("/proc/meminfo"); try { BufferedReader br = new BufferedReader(new FileReader(meminfo)); @@ -277,7 +280,7 @@ abstract public class GeckoApp totalMem = st.nextToken(); Log.i("GeckoMemory", "MemTotal: " + Integer.parseInt(totalMem)); - return Integer.parseInt(totalMem) <= 524288L; + return Integer.parseInt(totalMem) < 300000L; } catch (Exception ex) { // Will catch NullPointerException if totalMem isn't found, // a NumberFormatException if the token isn't parsible diff --git a/embedding/android/GeckoAppShell.java b/embedding/android/GeckoAppShell.java index 9eb972b0adbf..5a351d291615 100644 --- a/embedding/android/GeckoAppShell.java +++ b/embedding/android/GeckoAppShell.java @@ -829,6 +829,7 @@ public class GeckoAppShell Field f = drawableClass.getField(resource); icon = f.getInt(null); } catch (Exception e) {} // just means the resource doesn't exist + imageUri = null; } int notificationID = aAlertName.hashCode(); @@ -836,8 +837,10 @@ public class GeckoAppShell // Remove the old notification with the same ID, if any removeNotification(notificationID); - AlertNotification notification = new AlertNotification(GeckoApp.mAppContext, - notificationID, icon, aAlertTitle, aAlertText, System.currentTimeMillis()); + AlertNotification notification = + new AlertNotification(GeckoApp.mAppContext,notificationID, icon, + aAlertTitle, aAlertText, + System.currentTimeMillis()); // The intent to launch when the user clicks the expanded notification Intent notificationIntent = new Intent(GeckoApp.ACTION_ALERT_CLICK); @@ -850,7 +853,7 @@ public class GeckoAppShell PendingIntent contentIntent = PendingIntent.getBroadcast(GeckoApp.mAppContext, 0, notificationIntent, 0); notification.setLatestEventInfo(GeckoApp.mAppContext, aAlertTitle, aAlertText, contentIntent); - + notification.setCustomIcon(imageUri); // The intent to execute when the status entry is deleted by the user with the "Clear All Notifications" button Intent clearNotificationIntent = new Intent(GeckoApp.ACTION_ALERT_CLEAR); clearNotificationIntent.setClassName(GeckoApp.mAppContext, diff --git a/embedding/android/Makefile.in b/embedding/android/Makefile.in index b5d0c920fb18..e92c89df339e 100644 --- a/embedding/android/Makefile.in +++ b/embedding/android/Makefile.in @@ -106,6 +106,7 @@ endif RES_LAYOUT = \ res/layout/notification_progress.xml \ res/layout/notification_progress_text.xml \ + res/layout/notification_icon_text.xml \ $(NULL) RES_VALUES = res/values/colors.xml res/values/themes.xml diff --git a/embedding/android/resources/layout/notification_icon_text.xml b/embedding/android/resources/layout/notification_icon_text.xml new file mode 100644 index 000000000000..2a33012460d1 --- /dev/null +++ b/embedding/android/resources/layout/notification_icon_text.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/gfx/layers/basic/BasicLayers.cpp b/gfx/layers/basic/BasicLayers.cpp index 090dc97fa1fa..f3ca10ae6900 100644 --- a/gfx/layers/basic/BasicLayers.cpp +++ b/gfx/layers/basic/BasicLayers.cpp @@ -56,6 +56,9 @@ #include "ThebesLayerBuffer.h" #include "nsIWidget.h" #include "ReadbackProcessor.h" +#ifdef MOZ_X11 +#include "gfxXlibSurface.h" +#endif #include "GLContext.h" @@ -1624,12 +1627,6 @@ public: mShadow = aShadow; } - virtual void SetBackBufferImage(gfxSharedImageSurface* aBuffer) - { - NS_RUNTIMEABORT("if this default impl is called, |aBuffer| leaks"); - } - - virtual PRBool SupportsSurfaceDescriptor() const { return PR_FALSE; } virtual void SetBackBuffer(const SurfaceDescriptor& aBuffer) { NS_RUNTIMEABORT("if this default impl is called, |aBuffer| leaks"); @@ -1735,12 +1732,6 @@ BasicShadowableContainerLayer::RemoveChild(Layer* aChild) BasicContainerLayer::RemoveChild(aChild); } -static PRBool -IsSurfaceDescriptorValid(const SurfaceDescriptor& aSurface) -{ - return SurfaceDescriptor::T__None != aSurface.type(); -} - class BasicShadowableThebesLayer : public BasicThebesLayer, public BasicShadowableLayer { @@ -1770,8 +1761,6 @@ public: virtual ShadowableLayer* AsShadowableLayer() { return this; } virtual bool MustRetainContent() { return HasShadow(); } - virtual PRBool SupportsSurfaceDescriptor() const { return PR_TRUE; } - void SetBackBufferAndAttrs(const ThebesBuffer& aBuffer, const nsIntRegion& aValidRegion, float aXResolution, float aYResolution, @@ -1955,8 +1944,8 @@ public: } virtual ~BasicShadowableImageLayer() { - if (mBackSurface) { - BasicManager()->ShadowLayerForwarder::DestroySharedSurface(mBackSurface); + if (IsSurfaceDescriptorValid(mBackBuffer)) { + BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer); } MOZ_COUNT_DTOR(BasicShadowableImageLayer); } @@ -1971,14 +1960,14 @@ public: virtual Layer* AsLayer() { return this; } virtual ShadowableLayer* AsShadowableLayer() { return this; } - virtual void SetBackBufferImage(gfxSharedImageSurface* aBuffer) + virtual void SetBackBuffer(const SurfaceDescriptor& aBuffer) { - mBackSurface = aBuffer; + mBackBuffer = aBuffer; } virtual void Disconnect() { - mBackSurface = nsnull; + mBackBuffer = SurfaceDescriptor(); BasicShadowableLayer::Disconnect(); } @@ -1988,7 +1977,7 @@ private: return static_cast(mManager); } - nsRefPtr mBackSurface; + SurfaceDescriptor mBackBuffer; }; void @@ -2000,20 +1989,18 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext) return; if (oldSize != mSize) { - if (mBackSurface) { - BasicManager()->ShadowLayerForwarder::DestroySharedSurface(mBackSurface); - mBackSurface = nsnull; - + if (IsSurfaceDescriptorValid(mBackBuffer)) { BasicManager()->DestroyedImageBuffer(BasicManager()->Hold(this)); + BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer); } - nsRefPtr tmpFrontSurface; + SurfaceDescriptor tmpFrontSurface; // XXX error handling? if (!BasicManager()->AllocDoubleBuffer( mSize, (GetContentFlags() & CONTENT_OPAQUE) ? gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA, - getter_AddRefs(tmpFrontSurface), getter_AddRefs(mBackSurface))) + &tmpFrontSurface, &mBackBuffer)) NS_RUNTIMEABORT("creating ImageLayer 'front buffer' failed!"); BasicManager()->CreatedImageBuffer(BasicManager()->Hold(this), @@ -2021,13 +2008,15 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext) tmpFrontSurface); } - nsRefPtr tmpCtx = new gfxContext(mBackSurface); + nsRefPtr backSurface = + BasicManager()->OpenDescriptor(mBackBuffer); + nsRefPtr tmpCtx = new gfxContext(backSurface); PaintContext(pat, nsIntRegion(nsIntRect(0, 0, mSize.width, mSize.height)), nsnull, 1.0, tmpCtx); BasicManager()->PaintedImage(BasicManager()->Hold(this), - mBackSurface); + mBackBuffer); } @@ -2070,8 +2059,8 @@ public: } virtual ~BasicShadowableCanvasLayer() { - if (mBackBuffer) { - BasicManager()->ShadowLayerForwarder::DestroySharedSurface(mBackBuffer); + if (IsSurfaceDescriptorValid(mBackBuffer)) { + BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer); } MOZ_COUNT_DTOR(BasicShadowableCanvasLayer); } @@ -2087,14 +2076,14 @@ public: virtual Layer* AsLayer() { return this; } virtual ShadowableLayer* AsShadowableLayer() { return this; } - virtual void SetBackBufferImage(gfxSharedImageSurface* aBuffer) + virtual void SetBackBuffer(const SurfaceDescriptor& aBuffer) { mBackBuffer = aBuffer; } - + virtual void Disconnect() { - mBackBuffer = nsnull; + mBackBuffer = SurfaceDescriptor(); BasicShadowableLayer::Disconnect(); } @@ -2104,7 +2093,7 @@ private: return static_cast(mManager); } - nsRefPtr mBackBuffer; + SurfaceDescriptor mBackBuffer; }; void @@ -2116,20 +2105,20 @@ BasicShadowableCanvasLayer::Initialize(const Data& aData) // XXX won't get here currently; need to figure out what to do on // canvas resizes - if (mBackBuffer) { - BasicManager()->ShadowLayerForwarder::DestroySharedSurface(mBackBuffer); - mBackBuffer = nsnull; + + if (IsSurfaceDescriptorValid(mBackBuffer)) { + BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer); BasicManager()->DestroyedCanvasBuffer(BasicManager()->Hold(this)); } - nsRefPtr tmpFrontBuffer; + SurfaceDescriptor tmpFrontBuffer; // XXX error handling? if (!BasicManager()->AllocDoubleBuffer( gfxIntSize(aData.mSize.width, aData.mSize.height), (GetContentFlags() & CONTENT_OPAQUE) ? gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA, - getter_AddRefs(tmpFrontBuffer), getter_AddRefs(mBackBuffer))) + &tmpFrontBuffer, &mBackBuffer)) NS_RUNTIMEABORT("creating CanvasLayer back buffer failed!"); BasicManager()->CreatedCanvasBuffer(BasicManager()->Hold(this), @@ -2149,7 +2138,9 @@ BasicShadowableCanvasLayer::Paint(gfxContext* aContext) // changed areas, much like we do for Thebes layers, as well as // do all sorts of magic to swap out the surface underneath the // canvas' thebes/cairo context. - nsRefPtr tmpCtx = new gfxContext(mBackBuffer); + nsRefPtr backSurface = + BasicManager()->OpenDescriptor(mBackBuffer); + nsRefPtr tmpCtx = new gfxContext(backSurface); tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE); // call BasicCanvasLayer::Paint to draw to our tmp context, because @@ -2442,17 +2433,15 @@ public: ShadowImageLayer::Disconnect(); } - virtual PRBool Init(gfxSharedImageSurface* front, const nsIntSize& size); + virtual PRBool Init(const SurfaceDescriptor& front, const nsIntSize& size); - virtual already_AddRefed - Swap(gfxSharedImageSurface* newFront); + virtual void Swap(const SurfaceDescriptor& aNewFront, SurfaceDescriptor* aNewBack); virtual void DestroyFrontBuffer() { - if (mFrontSurface) { - BasicManager()->ShadowLayerManager::DestroySharedSurface(mFrontSurface, mAllocator); + if (IsSurfaceDescriptorValid(mFrontBuffer)) { + BasicManager()->ShadowLayerManager::DestroySharedSurface(&mFrontBuffer, mAllocator); } - mFrontSurface = nsnull; } virtual void Paint(gfxContext* aContext); @@ -2463,36 +2452,36 @@ protected: return static_cast(mManager); } - // XXX ShmemImage? - nsRefPtr mFrontSurface; + SurfaceDescriptor mFrontBuffer; gfxIntSize mSize; }; PRBool -BasicShadowImageLayer::Init(gfxSharedImageSurface* front, +BasicShadowImageLayer::Init(const SurfaceDescriptor& front, const nsIntSize& size) { - mFrontSurface = front; + mFrontBuffer = front; mSize = gfxIntSize(size.width, size.height); return PR_TRUE; } -already_AddRefed -BasicShadowImageLayer::Swap(gfxSharedImageSurface* newFront) +void +BasicShadowImageLayer::Swap(const SurfaceDescriptor& aNewFront, SurfaceDescriptor* aNewBack) { - already_AddRefed tmp = mFrontSurface.forget(); - mFrontSurface = newFront; - return tmp; + *aNewBack = mFrontBuffer; + mFrontBuffer = aNewFront; } void BasicShadowImageLayer::Paint(gfxContext* aContext) { - if (!mFrontSurface) { + if (!IsSurfaceDescriptorValid(mFrontBuffer)) { return; } - nsRefPtr pat = new gfxPattern(mFrontSurface); + nsRefPtr surface = + BasicManager()->OpenDescriptor(mFrontBuffer); + nsRefPtr pat = new gfxPattern(surface); pat->SetFilter(mFilter); // The visible region can extend outside the image. If we're not @@ -2546,16 +2535,15 @@ public: } virtual void Initialize(const Data& aData); + virtual void Init(const SurfaceDescriptor& aNewFront, const nsIntSize& aSize); - virtual already_AddRefed - Swap(gfxSharedImageSurface* newFront); + void Swap(const SurfaceDescriptor& aNewFront, SurfaceDescriptor* aNewBack); virtual void DestroyFrontBuffer() { - if (mFrontSurface) { - BasicManager()->ShadowLayerManager::DestroySharedSurface(mFrontSurface, mAllocator); + if (IsSurfaceDescriptorValid(mFrontSurface)) { + BasicManager()->ShadowLayerManager::DestroySharedSurface(&mFrontSurface, mAllocator); } - mFrontSurface = nsnull; } virtual void Paint(gfxContext* aContext); @@ -2566,27 +2554,28 @@ private: return static_cast(mManager); } - nsRefPtr mFrontSurface; + SurfaceDescriptor mFrontSurface; }; void BasicShadowCanvasLayer::Initialize(const Data& aData) { - NS_ASSERTION(mFrontSurface == nsnull, - "BasicCanvasLayer::Initialize called twice!"); - NS_ASSERTION(aData.mSurface && !aData.mGLContext, "no comprende OpenGL!"); - - mFrontSurface = static_cast(aData.mSurface); - mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height); + NS_RUNTIMEABORT("Incompatibe surface type"); } -already_AddRefed -BasicShadowCanvasLayer::Swap(gfxSharedImageSurface* newFront) +void +BasicShadowCanvasLayer::Init(const SurfaceDescriptor& aNewFront, const nsIntSize& aSize) { - already_AddRefed tmp = mFrontSurface.forget(); - mFrontSurface = newFront; - return tmp; + mFrontSurface = aNewFront; + mBounds.SetRect(0, 0, aSize.width, aSize.height); +} + +void +BasicShadowCanvasLayer::Swap(const SurfaceDescriptor& aNewFront, SurfaceDescriptor* aNewBack) +{ + *aNewBack = mFrontSurface; + mFrontSurface = aNewFront; } void @@ -2595,11 +2584,13 @@ BasicShadowCanvasLayer::Paint(gfxContext* aContext) NS_ASSERTION(BasicManager()->InDrawing(), "Can only draw in drawing phase"); - if (!mFrontSurface) { + if (!IsSurfaceDescriptorValid(mFrontSurface)) { return; } - nsRefPtr pat = new gfxPattern(mFrontSurface); + nsRefPtr surface = + BasicManager()->OpenDescriptor(mFrontSurface); + nsRefPtr pat = new gfxPattern(surface); pat->SetFilter(mFilter); pat->SetExtend(gfxPattern::EXTEND_PAD); @@ -2830,17 +2821,7 @@ BasicShadowLayerManager::ForwardTransaction() const OpBufferSwap& obs = reply.get_OpBufferSwap(); const SurfaceDescriptor& descr = obs.newBackBuffer(); - BasicShadowableLayer* layer = GetBasicShadowable(obs); - if (layer->SupportsSurfaceDescriptor()) { - layer->SetBackBuffer(descr); - } else { - if (SurfaceDescriptor::TShmem != descr.type()) { - NS_RUNTIMEABORT("non-Shmem surface sent to a layer that expected one!"); - } - nsRefPtr imageSurf = OpenDescriptor(descr); - layer->SetBackBufferImage( - static_cast(imageSurf.get())); - } + GetBasicShadowable(obs)->SetBackBuffer(descr); break; } diff --git a/gfx/layers/ipc/PLayers.ipdl b/gfx/layers/ipc/PLayers.ipdl index 0c88068b5df1..6fc877c62ef5 100644 --- a/gfx/layers/ipc/PLayers.ipdl +++ b/gfx/layers/ipc/PLayers.ipdl @@ -102,14 +102,14 @@ struct OpDestroyThebesFrontBuffer { PLayer layer; }; struct OpCreateCanvasBuffer { PLayer layer; nsIntSize size; - Shmem initialFront; + SurfaceDescriptor initialFront; }; struct OpDestroyCanvasFrontBuffer { PLayer layer; }; struct OpCreateImageBuffer { PLayer layer; nsIntSize size; - Shmem initialFront; + SurfaceDescriptor initialFront; }; struct OpDestroyImageFrontBuffer { PLayer layer; }; @@ -173,12 +173,12 @@ struct OpPaintThebesBuffer { struct OpPaintCanvas { PLayer layer; - Shmem newFrontBuffer; + SurfaceDescriptor newFrontBuffer; }; struct OpPaintImage { PLayer layer; - Shmem newFrontBuffer; + SurfaceDescriptor newFrontBuffer; }; diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index 7876f35c5d93..6d026ee3643b 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -192,7 +192,7 @@ ShadowLayerForwarder::CreatedThebesBuffer(ShadowableLayer* aThebes, const SurfaceDescriptor& aTempFrontBuffer) { OptionalThebesBuffer buffer = null_t(); - if (SurfaceDescriptor::T__None != aTempFrontBuffer.type()) { + if (IsSurfaceDescriptorValid(aTempFrontBuffer)) { buffer = ThebesBuffer(aTempFrontBuffer, aBufferRect, nsIntPoint(0, 0)); @@ -207,21 +207,21 @@ ShadowLayerForwarder::CreatedThebesBuffer(ShadowableLayer* aThebes, void ShadowLayerForwarder::CreatedImageBuffer(ShadowableLayer* aImage, nsIntSize aSize, - gfxSharedImageSurface* aTempFrontSurface) + const SurfaceDescriptor& aTempFrontSurface) { mTxn->AddEdit(OpCreateImageBuffer(NULL, Shadow(aImage), aSize, - aTempFrontSurface->GetShmem())); + aTempFrontSurface)); } void ShadowLayerForwarder::CreatedCanvasBuffer(ShadowableLayer* aCanvas, nsIntSize aSize, - gfxSharedImageSurface* aTempFrontSurface) + const SurfaceDescriptor& aTempFrontSurface) { mTxn->AddEdit(OpCreateCanvasBuffer(NULL, Shadow(aCanvas), aSize, - aTempFrontSurface->GetShmem())); + aTempFrontSurface)); } void @@ -291,17 +291,17 @@ ShadowLayerForwarder::PaintedThebesBuffer(ShadowableLayer* aThebes, } void ShadowLayerForwarder::PaintedImage(ShadowableLayer* aImage, - gfxSharedImageSurface* aNewFrontSurface) + const SurfaceDescriptor& aNewFrontSurface) { mTxn->AddPaint(OpPaintImage(NULL, Shadow(aImage), - aNewFrontSurface->GetShmem())); + aNewFrontSurface)); } void ShadowLayerForwarder::PaintedCanvas(ShadowableLayer* aCanvas, - gfxSharedImageSurface* aNewFrontSurface) + const SurfaceDescriptor& aNewFrontSurface) { mTxn->AddPaint(OpPaintCanvas(NULL, Shadow(aCanvas), - aNewFrontSurface->GetShmem())); + aNewFrontSurface)); } PRBool @@ -636,5 +636,11 @@ ShadowLayerManager::PlatformSyncBeforeReplyUpdate() #endif // !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS) +PRBool +IsSurfaceDescriptorValid(const SurfaceDescriptor& aSurface) +{ + return SurfaceDescriptor::T__None != aSurface.type(); +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/ipc/ShadowLayers.h b/gfx/layers/ipc/ShadowLayers.h index ac349e4cfc21..5f560910d357 100644 --- a/gfx/layers/ipc/ShadowLayers.h +++ b/gfx/layers/ipc/ShadowLayers.h @@ -165,10 +165,10 @@ public: */ void CreatedImageBuffer(ShadowableLayer* aImage, nsIntSize aSize, - gfxSharedImageSurface* aInitialFrontSurface); + const SurfaceDescriptor& aInitialFrontSurface); void CreatedCanvasBuffer(ShadowableLayer* aCanvas, nsIntSize aSize, - gfxSharedImageSurface* aInitialFrontSurface); + const SurfaceDescriptor& aInitialFrontSurface); /** * The specified layer is destroying its buffers. @@ -225,9 +225,9 @@ public: * ImageLayers. This is slow, and will be optimized. */ void PaintedImage(ShadowableLayer* aImage, - gfxSharedImageSurface* aNewFrontSurface); + const SurfaceDescriptor& aNewFrontSurface); void PaintedCanvas(ShadowableLayer* aCanvas, - gfxSharedImageSurface* aNewFrontSurface); + const SurfaceDescriptor& aNewFrontSurface); /** * End the current transaction and forward it to ShadowLayerManager. @@ -569,6 +569,17 @@ class ShadowCanvasLayer : public ShadowLayer, public CanvasLayer { public: + + /** + * CONSTRUCTION PHASE ONLY + * + * Initialize this with a (temporary) front surface with the given + * size. This is expected to be followed with a Swap() in the same + * transaction to bring in real pixels. Init() may only be called + * once. + */ + virtual void Init(const SurfaceDescriptor& front, const nsIntSize& aSize) = 0; + /** * CONSTRUCTION PHASE ONLY * @@ -576,8 +587,7 @@ public: * out the old front surface (the new back surface for the remote * layer). */ - virtual already_AddRefed - Swap(gfxSharedImageSurface* aNewFront) = 0; + virtual void Swap(const SurfaceDescriptor& aNewFront, SurfaceDescriptor* aNewBack) = 0; /** * CONSTRUCTION PHASE ONLY @@ -609,14 +619,13 @@ public: * transaction to bring in real pixels. Init() may only be called * once. */ - virtual PRBool Init(gfxSharedImageSurface* aFront, const nsIntSize& aSize) = 0; + virtual PRBool Init(const SurfaceDescriptor& front, const nsIntSize& aSize) = 0; /** * CONSTRUCTION PHASE ONLY * @see ShadowCanvasLayer::Swap */ - virtual already_AddRefed - Swap(gfxSharedImageSurface* newFront) = 0; + virtual void Swap(const SurfaceDescriptor& aFront, SurfaceDescriptor* aNewBack) = 0; /** * CONSTRUCTION PHASE ONLY @@ -650,6 +659,7 @@ protected: {} }; +PRBool IsSurfaceDescriptorValid(const SurfaceDescriptor& aSurface); } // namespace layers } // namespace mozilla diff --git a/gfx/layers/ipc/ShadowLayersParent.cpp b/gfx/layers/ipc/ShadowLayersParent.cpp index f7f050585b7f..b26eef44d832 100644 --- a/gfx/layers/ipc/ShadowLayersParent.cpp +++ b/gfx/layers/ipc/ShadowLayersParent.cpp @@ -222,13 +222,8 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray& cset, const OpCreateCanvasBuffer& ocb = edit.get_OpCreateCanvasBuffer(); ShadowCanvasLayer* canvas = static_cast( AsShadowLayer(ocb)->AsLayer()); - nsRefPtr front = - gfxSharedImageSurface::Open(ocb.initialFront()); - CanvasLayer::Data data; - data.mSurface = front; - data.mSize = ocb.size(); - canvas->Initialize(data); + canvas->Init(ocb.initialFront(), ocb.size()); break; } @@ -239,9 +234,7 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray& cset, ShadowImageLayer* image = static_cast( AsShadowLayer(ocb)->AsLayer()); - nsRefPtr surf = - gfxSharedImageSurface::Open(ocb.initialFront()); - image->Init(surf, ocb.size()); + image->Init(ocb.initialFront(), ocb.size()); break; } @@ -416,17 +409,17 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray& cset, ShadowCanvasLayer* canvas = static_cast(shadow->AsLayer()); - nsRefPtr newFront = - gfxSharedImageSurface::Open(op.newFrontBuffer()); - nsRefPtr newBack = canvas->Swap(newFront); + SurfaceDescriptor newFront = op.newFrontBuffer(); + SurfaceDescriptor newBack; + canvas->Swap(op.newFrontBuffer(), &newBack); if (newFront == newBack) { - newFront.forget(); + newFront = SurfaceDescriptor(); } canvas->Updated(); replyv.push_back(OpBufferSwap(shadow, NULL, - newBack->GetShmem())); + newBack)); break; } @@ -438,15 +431,15 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray& cset, ShadowImageLayer* image = static_cast(shadow->AsLayer()); - nsRefPtr newFront = - gfxSharedImageSurface::Open(op.newFrontBuffer()); - nsRefPtr newBack = image->Swap(newFront); + SurfaceDescriptor newFront = op.newFrontBuffer(); + SurfaceDescriptor newBack; + image->Swap(op.newFrontBuffer(), &newBack); if (newFront == newBack) { - newFront.forget(); + newFront = SurfaceDescriptor(); } replyv.push_back(OpBufferSwap(shadow, NULL, - newBack->GetShmem())); + newBack)); break; } diff --git a/gfx/layers/opengl/CanvasLayerOGL.cpp b/gfx/layers/opengl/CanvasLayerOGL.cpp index 4e6337a6b676..1035e088160f 100644 --- a/gfx/layers/opengl/CanvasLayerOGL.cpp +++ b/gfx/layers/opengl/CanvasLayerOGL.cpp @@ -52,6 +52,10 @@ #include #endif +#ifdef MOZ_X11 +#include "gfxXlibSurface.h" +#endif + using namespace mozilla; using namespace mozilla::layers; using namespace mozilla::gl; @@ -293,34 +297,40 @@ ShadowCanvasLayerOGL::~ShadowCanvasLayerOGL() void ShadowCanvasLayerOGL::Initialize(const Data& aData) { - mDeadweight = static_cast(aData.mSurface); - gfxSize sz = mDeadweight->GetSize(); - mTexImage = gl()->CreateTextureImage(nsIntSize(sz.width, sz.height), - mDeadweight->GetContentType(), + NS_RUNTIMEABORT("Incompatibe surface type"); +} + +void +ShadowCanvasLayerOGL::Init(const SurfaceDescriptor& aNewFront, const nsIntSize& aSize) +{ + mDeadweight = aNewFront; + nsRefPtr surf = ShadowLayerForwarder::OpenDescriptor(mDeadweight); + + mTexImage = gl()->CreateTextureImage(nsIntSize(aSize.width, aSize.height), + surf->GetContentType(), LOCAL_GL_CLAMP_TO_EDGE); } -already_AddRefed -ShadowCanvasLayerOGL::Swap(gfxSharedImageSurface* aNewFront) +void +ShadowCanvasLayerOGL::Swap(const SurfaceDescriptor& aNewFront, + SurfaceDescriptor* aNewBack) { if (!mDestroyed && mTexImage) { - // XXX this is always just ridiculously slow - - gfxSize sz = aNewFront->GetSize(); + nsRefPtr surf = ShadowLayerForwarder::OpenDescriptor(aNewFront); + gfxSize sz = surf->GetSize(); nsIntRegion updateRegion(nsIntRect(0, 0, sz.width, sz.height)); - mTexImage->DirectUpdate(aNewFront, updateRegion); + mTexImage->DirectUpdate(surf, updateRegion); } - return aNewFront; + *aNewBack = aNewFront; } void ShadowCanvasLayerOGL::DestroyFrontBuffer() { mTexImage = nsnull; - if (mDeadweight) { - mOGLManager->DestroySharedSurface(mDeadweight, mAllocator); - mDeadweight = nsnull; + if (IsSurfaceDescriptorValid(mDeadweight)) { + mOGLManager->DestroySharedSurface(&mDeadweight, mAllocator); } } diff --git a/gfx/layers/opengl/CanvasLayerOGL.h b/gfx/layers/opengl/CanvasLayerOGL.h index ec4dc1f4b064..14a20c038c24 100644 --- a/gfx/layers/opengl/CanvasLayerOGL.h +++ b/gfx/layers/opengl/CanvasLayerOGL.h @@ -110,12 +110,14 @@ public: // CanvasLayer impl virtual void Initialize(const Data& aData); + virtual void Init(const SurfaceDescriptor& aNewFront, const nsIntSize& aSize); + // This isn't meaningful for shadow canvas. virtual void Updated(const nsIntRect&) {} // ShadowCanvasLayer impl - virtual already_AddRefed - Swap(gfxSharedImageSurface* aNewFront); + virtual void Swap(const SurfaceDescriptor& aNewFront, + SurfaceDescriptor* aNewBack); virtual void DestroyFrontBuffer(); @@ -130,11 +132,7 @@ public: private: nsRefPtr mTexImage; - - // XXX FIXME holding to free - nsRefPtr mDeadweight; - - + SurfaceDescriptor mDeadweight; }; } /* layers */ diff --git a/gfx/layers/opengl/ImageLayerOGL.cpp b/gfx/layers/opengl/ImageLayerOGL.cpp index 1d9804eac0e6..51eacfc40800 100644 --- a/gfx/layers/opengl/ImageLayerOGL.cpp +++ b/gfx/layers/opengl/ImageLayerOGL.cpp @@ -790,38 +790,38 @@ ShadowImageLayerOGL::~ShadowImageLayerOGL() {} PRBool -ShadowImageLayerOGL::Init(gfxSharedImageSurface* aFront, +ShadowImageLayerOGL::Init(const SurfaceDescriptor& aFront, const nsIntSize& aSize) { mDeadweight = aFront; - gfxSize sz = mDeadweight->GetSize(); + nsRefPtr surf = ShadowLayerForwarder::OpenDescriptor(aFront); + gfxSize sz = surf->GetSize(); mTexImage = gl()->CreateTextureImage(nsIntSize(sz.width, sz.height), - mDeadweight->GetContentType(), + surf->GetContentType(), LOCAL_GL_CLAMP_TO_EDGE); return PR_TRUE; } -already_AddRefed -ShadowImageLayerOGL::Swap(gfxSharedImageSurface* aNewFront) +void +ShadowImageLayerOGL::Swap(const SurfaceDescriptor& aNewFront, SurfaceDescriptor* aNewBack) { if (!mDestroyed && mTexImage) { + nsRefPtr surf = ShadowLayerForwarder::OpenDescriptor(aNewFront); // XXX this is always just ridiculously slow - - gfxSize sz = aNewFront->GetSize(); + gfxSize sz = surf->GetSize(); nsIntRegion updateRegion(nsIntRect(0, 0, sz.width, sz.height)); - mTexImage->DirectUpdate(aNewFront, updateRegion); + mTexImage->DirectUpdate(surf, updateRegion); } - return aNewFront; + *aNewBack = aNewFront; } void ShadowImageLayerOGL::DestroyFrontBuffer() { mTexImage = nsnull; - if (mDeadweight) { - mOGLManager->DestroySharedSurface(mDeadweight, mAllocator); - mDeadweight = nsnull; + if (IsSurfaceDescriptorValid(mDeadweight)) { + mOGLManager->DestroySharedSurface(&mDeadweight, mAllocator); } } diff --git a/gfx/layers/opengl/ImageLayerOGL.h b/gfx/layers/opengl/ImageLayerOGL.h index 18832a4d6fb6..96ce9d61ee48 100644 --- a/gfx/layers/opengl/ImageLayerOGL.h +++ b/gfx/layers/opengl/ImageLayerOGL.h @@ -245,10 +245,9 @@ public: virtual ~ShadowImageLayerOGL(); // ShadowImageLayer impl - virtual PRBool Init(gfxSharedImageSurface* aFront, const nsIntSize& aSize); + virtual PRBool Init(const SurfaceDescriptor& aFront, const nsIntSize& aSize); - virtual already_AddRefed - Swap(gfxSharedImageSurface* aNewFront); + virtual void Swap(const SurfaceDescriptor& aFront, SurfaceDescriptor* aNewBack); virtual void DestroyFrontBuffer(); @@ -265,11 +264,7 @@ public: private: nsRefPtr mTexImage; - - // XXX FIXME holding to free - nsRefPtr mDeadweight; - - + SurfaceDescriptor mDeadweight; }; } /* layers */ diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index 457d5df22449..d941ccda8e83 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -3084,22 +3084,6 @@ gfxTextRun::~gfxTextRun() MOZ_COUNT_DTOR(gfxTextRun); } -gfxTextRun * -gfxTextRun::Clone(const gfxTextRunFactory::Parameters *aParams, const void *aText, - PRUint32 aLength, gfxFontGroup *aFontGroup, PRUint32 aFlags) -{ - if (!mCharacterGlyphs) - return nsnull; - - nsAutoPtr textRun; - textRun = gfxTextRun::Create(aParams, aText, aLength, aFontGroup, aFlags); - if (!textRun) - return nsnull; - - textRun->CopyGlyphDataFrom(this, 0, mCharacterCount, 0); - return textRun.forget(); -} - PRBool gfxTextRun::SetPotentialLineBreaks(PRUint32 aStart, PRUint32 aLength, PRPackedBool *aBreakBefore, diff --git a/gfx/thebes/gfxFont.h b/gfx/thebes/gfxFont.h index 962dccf7ade8..cecdcc5c35d1 100644 --- a/gfx/thebes/gfxFont.h +++ b/gfx/thebes/gfxFont.h @@ -1702,15 +1702,6 @@ public: static gfxTextRun *Create(const gfxTextRunFactory::Parameters *aParams, const void *aText, PRUint32 aLength, gfxFontGroup *aFontGroup, PRUint32 aFlags); - // Clone this textrun, according to the given parameters. This textrun's - // glyph data is copied, so the text and length must be the same as this - // textrun's. If there's a problem, return null. Actual linebreaks will - // be set as per aParams; there will be no potential linebreaks. - // If aText is not persistent (aFlags & TEXT_IS_PERSISTENT), the - // textrun will copy it. - virtual gfxTextRun *Clone(const gfxTextRunFactory::Parameters *aParams, const void *aText, - PRUint32 aLength, gfxFontGroup *aFontGroup, PRUint32 aFlags); - /** * This class records the information associated with a character in the * input string. It's optimized for the case where there is one glyph diff --git a/gfx/thebes/gfxUserFontSet.cpp b/gfx/thebes/gfxUserFontSet.cpp index b7028e8ac433..956a2451da96 100644 --- a/gfx/thebes/gfxUserFontSet.cpp +++ b/gfx/thebes/gfxUserFontSet.cpp @@ -461,20 +461,10 @@ CacheLayoutTablesFromWOFF(const PRUint8* aFontData, PRUint32 aLength, // Ownership of aFontData passes in here, and the font set must // ensure that it is eventually deleted via NS_Free(). PRBool -gfxUserFontSet::OnLoadComplete(gfxFontEntry *aFontToLoad, +gfxUserFontSet::OnLoadComplete(gfxProxyFontEntry *aProxy, const PRUint8 *aFontData, PRUint32 aLength, nsresult aDownloadStatus) { - NS_ASSERTION(aFontToLoad->mIsProxy, - "trying to load font data for wrong font entry type"); - - if (!aFontToLoad->mIsProxy) { - NS_Free((void*)aFontData); - return PR_FALSE; - } - - gfxProxyFontEntry *pe = static_cast (aFontToLoad); - // download successful, make platform font using font data if (NS_SUCCEEDED(aDownloadStatus)) { gfxFontEntry *fe = nsnull; @@ -496,14 +486,14 @@ gfxUserFontSet::OnLoadComplete(gfxFontEntry *aFontToLoad, if (!saneData) { char buf[1000]; sprintf(buf, "downloaded font rejected for \"%s\"", - NS_ConvertUTF16toUTF8(pe->FamilyName()).get()); + NS_ConvertUTF16toUTF8(aProxy->FamilyName()).get()); NS_WARNING(buf); } #endif if (saneData) { // Here ownership of saneData is passed to the platform, // which will delete it when no longer required - fe = gfxPlatform::GetPlatform()->MakePlatformFont(pe, + fe = gfxPlatform::GetPlatform()->MakePlatformFont(aProxy, saneData, saneLen); if (fe) { @@ -537,7 +527,7 @@ gfxUserFontSet::OnLoadComplete(gfxFontEntry *aFontToLoad, if (gfxFontUtils::ValidateSFNTHeaders(aFontData, aLength)) { // Here ownership of aFontData is passed to the platform, // which will delete it when no longer required - fe = gfxPlatform::GetPlatform()->MakePlatformFont(pe, + fe = gfxPlatform::GetPlatform()->MakePlatformFont(aProxy, aFontData, aLength); aFontData = nsnull; // we must NOT free this below! @@ -557,30 +547,32 @@ gfxUserFontSet::OnLoadComplete(gfxFontEntry *aFontToLoad, if (fe) { // copy OpenType feature/language settings from the proxy to the // newly-created font entry - fe->mFeatureSettings.AppendElements(pe->mFeatureSettings); - fe->mLanguageOverride = pe->mLanguageOverride; + fe->mFeatureSettings.AppendElements(aProxy->mFeatureSettings); + fe->mLanguageOverride = aProxy->mLanguageOverride; - ReplaceFontEntry(pe, fe); - IncrementGeneration(); #ifdef PR_LOGGING + // must do this before ReplaceFontEntry() because that will + // clear the proxy's mFamily pointer! if (LOG_ENABLED()) { nsCAutoString fontURI; - pe->mSrcList[pe->mSrcIndex].mURI->GetSpec(fontURI); + aProxy->mSrcList[aProxy->mSrcIndex].mURI->GetSpec(fontURI); LOG(("userfonts (%p) [src %d] loaded uri: (%s) for (%s) gen: %8.8x\n", - this, pe->mSrcIndex, fontURI.get(), - NS_ConvertUTF16toUTF8(pe->mFamily->Name()).get(), + this, aProxy->mSrcIndex, fontURI.get(), + NS_ConvertUTF16toUTF8(aProxy->mFamily->Name()).get(), PRUint32(mGeneration))); } #endif + ReplaceFontEntry(aProxy, fe); + IncrementGeneration(); return PR_TRUE; } else { #ifdef PR_LOGGING if (LOG_ENABLED()) { nsCAutoString fontURI; - pe->mSrcList[pe->mSrcIndex].mURI->GetSpec(fontURI); + aProxy->mSrcList[aProxy->mSrcIndex].mURI->GetSpec(fontURI); LOG(("userfonts (%p) [src %d] failed uri: (%s) for (%s) error making platform font\n", - this, pe->mSrcIndex, fontURI.get(), - NS_ConvertUTF16toUTF8(pe->mFamily->Name()).get())); + this, aProxy->mSrcIndex, fontURI.get(), + NS_ConvertUTF16toUTF8(aProxy->mFamily->Name()).get())); } #endif } @@ -589,10 +581,10 @@ gfxUserFontSet::OnLoadComplete(gfxFontEntry *aFontToLoad, #ifdef PR_LOGGING if (LOG_ENABLED()) { nsCAutoString fontURI; - pe->mSrcList[pe->mSrcIndex].mURI->GetSpec(fontURI); + aProxy->mSrcList[aProxy->mSrcIndex].mURI->GetSpec(fontURI); LOG(("userfonts (%p) [src %d] failed uri: (%s) for (%s) error %8.8x downloading font data\n", - this, pe->mSrcIndex, fontURI.get(), - NS_ConvertUTF16toUTF8(pe->mFamily->Name()).get(), + this, aProxy->mSrcIndex, fontURI.get(), + NS_ConvertUTF16toUTF8(aProxy->mFamily->Name()).get(), aDownloadStatus)); } #endif @@ -605,7 +597,7 @@ gfxUserFontSet::OnLoadComplete(gfxFontEntry *aFontToLoad, // error occurred, load next src LoadStatus status; - status = LoadNext(pe); + status = LoadNext(aProxy); // Even if loading failed, we need to bump the font-set generation // and return true in order to trigger reflow, so that fallback @@ -731,13 +723,3 @@ gfxUserFontSet::GetFamily(const nsAString& aFamilyName) const return mFontFamilies.GetWeak(key); } - - -void -gfxUserFontSet::RemoveFamily(const nsAString& aFamilyName) -{ - nsAutoString key(aFamilyName); - ToLowerCase(key); - - mFontFamilies.Remove(key); -} diff --git a/gfx/thebes/gfxUserFontSet.h b/gfx/thebes/gfxUserFontSet.h index b63c232a04e0..c1fdc05bff27 100644 --- a/gfx/thebes/gfxUserFontSet.h +++ b/gfx/thebes/gfxUserFontSet.h @@ -203,7 +203,7 @@ public: // initialize the process that loads external font data, which upon // completion will call OnLoadComplete method - virtual nsresult StartLoad(gfxFontEntry *aFontToLoad, + virtual nsresult StartLoad(gfxProxyFontEntry *aProxy, const gfxFontFaceSrc *aFontFaceSrc) = 0; // when download has been completed, pass back data here @@ -212,7 +212,7 @@ public: // reference was next in line) // Ownership of aFontData is passed in here; the font set must // ensure that it is eventually deleted with NS_Free(). - PRBool OnLoadComplete(gfxFontEntry *aFontToLoad, + PRBool OnLoadComplete(gfxProxyFontEntry *aProxy, const PRUint8 *aFontData, PRUint32 aLength, nsresult aDownloadStatus); @@ -236,9 +236,6 @@ protected: gfxMixedFontFamily *GetFamily(const nsAString& aName) const; - // remove family - void RemoveFamily(const nsAString& aFamilyName); - // font families defined by @font-face rules nsRefPtrHashtable mFontFamilies; diff --git a/ipc/chromium/Makefile.in b/ipc/chromium/Makefile.in index 65ecaadfece8..cdd2b61d81a2 100644 --- a/ipc/chromium/Makefile.in +++ b/ipc/chromium/Makefile.in @@ -139,7 +139,6 @@ CPPSRCS += \ base_paths_win.cc \ cpu.cc \ condition_variable_win.cc \ - debug_on_start.cc \ debug_util_win.cc \ event_recorder.cc \ file_util_win.cc \ @@ -173,6 +172,13 @@ CPPSRCS += \ endif # } OS_WIN +ifdef _MSC_VER # { + +CPPSRCS += \ + debug_on_start.cc + +endif # } + ifdef OS_POSIX # { CPPSRCS += \ diff --git a/ipc/chromium/chromium-config.mk b/ipc/chromium/chromium-config.mk index 09fc3db2287e..784fb3f7a6c3 100644 --- a/ipc/chromium/chromium-config.mk +++ b/ipc/chromium/chromium-config.mk @@ -82,7 +82,6 @@ DEFINES += \ -D_SECURE_ATL \ -DCHROMIUM_BUILD \ -DU_STATIC_IMPLEMENTATION \ - -DCOMPILER_MSVC \ -DOS_WIN=1 \ -DWIN32 \ -D_WIN32 \ @@ -90,6 +89,10 @@ DEFINES += \ -DWIN32_LEAN_AND_MEAN \ $(NULL) +ifdef _MSC_VER +DEFINES += -DCOMPILER_MSVC +endif + else # } { OS_LINUX = 1 diff --git a/ipc/chromium/src/base/atomicops.h b/ipc/chromium/src/base/atomicops.h index a31c0822ce79..c78873c4b68f 100644 --- a/ipc/chromium/src/base/atomicops.h +++ b/ipc/chromium/src/base/atomicops.h @@ -124,7 +124,7 @@ Atomic64 Release_Load(volatile const Atomic64* ptr); } // namespace base // Include our platform specific implementation. -#if defined(OS_WIN) && defined(COMPILER_MSVC) && defined(ARCH_CPU_X86_FAMILY) +#if defined(OS_WIN) && defined(ARCH_CPU_X86_FAMILY) #include "base/atomicops_internals_x86_msvc.h" #elif defined(OS_MACOSX) && defined(ARCH_CPU_X86_FAMILY) #include "base/atomicops_internals_x86_macosx.h" diff --git a/ipc/chromium/src/base/atomicops_internals_x86_msvc.h b/ipc/chromium/src/base/atomicops_internals_x86_msvc.h index 4d14a7757784..e44cf16ef42f 100644 --- a/ipc/chromium/src/base/atomicops_internals_x86_msvc.h +++ b/ipc/chromium/src/base/atomicops_internals_x86_msvc.h @@ -42,7 +42,7 @@ inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, return Barrier_AtomicIncrement(ptr, increment); } -#if !(defined(_MSC_VER) && _MSC_VER >= 1400) +#if defined(_MSC_VER) && (_MSC_VER < 1400) #error "We require at least vs2005 for MemoryBarrier" #endif inline void MemoryBarrier() { diff --git a/ipc/chromium/src/base/debug_on_start.h b/ipc/chromium/src/base/debug_on_start.h index ab823cf0e4e7..42f39b2f1f7e 100644 --- a/ipc/chromium/src/base/debug_on_start.h +++ b/ipc/chromium/src/base/debug_on_start.h @@ -11,8 +11,8 @@ #include "base/basictypes.h" -// This only works on Windows. -#if defined(OS_WIN) +// This only works on MSVC. +#if defined(COMPILER_MSVC) #ifndef DECLSPEC_SELECTANY #define DECLSPEC_SELECTANY __declspec(selectany) diff --git a/ipc/chromium/src/base/file_path.cc b/ipc/chromium/src/base/file_path.cc index b1bf6873820d..9af670f018c7 100644 --- a/ipc/chromium/src/base/file_path.cc +++ b/ipc/chromium/src/base/file_path.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include + #include "base/file_path.h" #include "base/logging.h" @@ -288,6 +290,16 @@ std::wstring FilePath::ToWStringHack() const { } #endif +void FilePath::OpenInputStream(std::ifstream& stream) const { + stream.open( +#ifndef __MINGW32__ + path_.c_str(), +#else + base::SysWideToNativeMB(path_).c_str(), +#endif + std::ios::in | std::ios::binary); +} + FilePath FilePath::StripTrailingSeparators() const { FilePath new_path(path_); new_path.StripTrailingSeparatorsInternal(); diff --git a/ipc/chromium/src/base/file_path.h b/ipc/chromium/src/base/file_path.h index e47f1294c0ee..99cbc9d2d438 100644 --- a/ipc/chromium/src/base/file_path.h +++ b/ipc/chromium/src/base/file_path.h @@ -211,6 +211,9 @@ class FilePath { // separator. FilePath StripTrailingSeparators() const; + // Calls open on given ifstream instance + void OpenInputStream(std::ifstream &stream) const; + // Older Chromium code assumes that paths are always wstrings. // This function converts a wstring to a FilePath, and is useful to smooth // porting that old code to the FilePath API. diff --git a/ipc/chromium/src/base/file_util.cc b/ipc/chromium/src/base/file_util.cc index b79a7b6fdade..1154fedf4870 100644 --- a/ipc/chromium/src/base/file_util.cc +++ b/ipc/chromium/src/base/file_util.cc @@ -144,10 +144,10 @@ bool ContentsEqual(const FilePath& filename1, const FilePath& filename2) { // We open the file in binary format even if they are text files because // we are just comparing that bytes are exactly same in both files and not // doing anything smart with text formatting. - std::ifstream file1(filename1.value().c_str(), - std::ios::in | std::ios::binary); - std::ifstream file2(filename2.value().c_str(), - std::ios::in | std::ios::binary); + std::ifstream file1, file2; + + filename1.OpenInputStream(file1); + filename2.OpenInputStream(file2); // Even if both files aren't openable (and thus, in some sense, "equal"), // any unusable file yields a result of "false". diff --git a/ipc/chromium/src/base/histogram.cc b/ipc/chromium/src/base/histogram.cc index 687a5496b2bd..5cd8b4fc0340 100644 --- a/ipc/chromium/src/base/histogram.cc +++ b/ipc/chromium/src/base/histogram.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -10,69 +10,140 @@ #include "base/histogram.h" #include + +#include #include #include "base/logging.h" #include "base/pickle.h" #include "base/string_util.h" +#include "base/logging.h" -using base::TimeDelta; +namespace base { + +#if defined(CHROMIUM_MOZILLA_BUILD) +#define DVLOG(x) LOG(ERROR) +#define CHECK_GT DCHECK_GT +#define CHECK_LT DCHECK_LT +typedef ::Lock Lock; +typedef ::AutoLock AutoLock; +#endif + +// Static table of checksums for all possible 8 bit bytes. +const uint32 Histogram::kCrcTable[256] = {0x0, 0x77073096L, 0xee0e612cL, +0x990951baL, 0x76dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0xedb8832L, +0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x9b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, +0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, +0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, +0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, +0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, +0xa50ab56bL, 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, +0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, 0xc8d75180L, +0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, 0x2802b89eL, +0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, +0xb6662d3dL, 0x76dc4190L, 0x1db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, +0x6b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0xf00f934L, 0x9609a88eL, +0xe10e9818L, 0x7f6a0dbbL, 0x86d3d2dL, 0x91646c97L, 0xe6635c01L, 0x6b6b51f4L, +0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, +0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, +0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, +0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, +0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, +0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, +0x206f85b3L, 0xb966d409L, 0xce61e49fL, 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, +0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, +0x9abfb3b6L, 0x3b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x4db2615L, +0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0xd6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, +0x9309ff9dL, 0xa00ae27L, 0x7d079eb1L, 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, +0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, +0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, +0x60b08ed5L, 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, +0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, +0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, 0xcb61b38cL, +0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, +0x5505262fL, 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, +0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, +0x26d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x5005713L, 0x95bf4a82L, +0xe2b87a14L, 0x7bb12baeL, 0xcb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, +0xbdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, +0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, +0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, +0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, +0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, +0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, +0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, +0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, +0x2d02ef8dL, +}; typedef Histogram::Count Count; // static -const int Histogram::kHexRangePrintingFlag = 0x8000; +const size_t Histogram::kBucketCount_MAX = 16384u; -Histogram::Histogram(const char* name, Sample minimum, - Sample maximum, size_t bucket_count) - : histogram_name_(name), - declared_min_(minimum), - declared_max_(maximum), - bucket_count_(bucket_count), - flags_(0), - ranges_(bucket_count + 1, 0), - sample_(), - registered_(false) { - Initialize(); +Histogram* Histogram::FactoryGet(const std::string& name, + Sample minimum, + Sample maximum, + size_t bucket_count, + Flags flags) { + Histogram* histogram(NULL); + + // Defensive code. + if (minimum < 1) + minimum = 1; + if (maximum > kSampleType_MAX - 1) + maximum = kSampleType_MAX - 1; + + if (!StatisticsRecorder::FindHistogram(name, &histogram)) { + // Extra variable is not needed... but this keeps this section basically + // identical to other derived classes in this file (and compiler will + // optimize away the extra variable. + // To avoid racy destruction at shutdown, the following will be leaked. + Histogram* tentative_histogram = + new Histogram(name, minimum, maximum, bucket_count); + tentative_histogram->InitializeBucketRange(); + tentative_histogram->SetFlags(flags); + histogram = + StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); + } + + DCHECK_EQ(HISTOGRAM, histogram->histogram_type()); + DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count)); + return histogram; } -Histogram::Histogram(const char* name, TimeDelta minimum, - TimeDelta maximum, size_t bucket_count) - : histogram_name_(name), - declared_min_(static_cast (minimum.InMilliseconds())), - declared_max_(static_cast (maximum.InMilliseconds())), - bucket_count_(bucket_count), - flags_(0), - ranges_(bucket_count + 1, 0), - sample_(), - registered_(false) { - Initialize(); -} - -Histogram::~Histogram() { - if (registered_) - StatisticsRecorder::UnRegister(this); - // Just to make sure most derived class did this properly... - DCHECK(ValidateBucketRanges()); +Histogram* Histogram::FactoryTimeGet(const std::string& name, + TimeDelta minimum, + TimeDelta maximum, + size_t bucket_count, + Flags flags) { + return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(), + bucket_count, flags); } void Histogram::Add(int value) { - if (!registered_) - registered_ = StatisticsRecorder::Register(this); - if (value >= kSampleType_MAX) + if (value > kSampleType_MAX - 1) value = kSampleType_MAX - 1; if (value < 0) value = 0; size_t index = BucketIndex(value); - DCHECK(value >= ranges(index)); - DCHECK(value < ranges(index + 1)); + DCHECK_GE(value, ranges(index)); + DCHECK_LT(value, ranges(index + 1)); Accumulate(value, 1, index); } +void Histogram::AddBoolean(bool value) { + DCHECK(false); +} + void Histogram::AddSampleSet(const SampleSet& sample) { sample_.Add(sample); } +void Histogram::SetRangeDescriptions(const DescriptionPair descriptions[]) { + DCHECK(false); +} + // The following methods provide a graphical histogram display. void Histogram::WriteHTMLGraph(std::string* output) const { // TBD(jar) Write a nice HTML bar chart, with divs an mouse-overs etc. @@ -124,7 +195,10 @@ void Histogram::WriteAscii(bool graph_it, const std::string& newline, if (!current && !PrintEmptyBucket(i)) continue; remaining -= current; - StringAppendF(output, "%#*s ", print_width, GetAsciiBucketRange(i).c_str()); + std::string range = GetAsciiBucketRange(i); + output->append(range); + for (size_t j = 0; range.size() + j < print_width + 1; ++j) + output->push_back(' '); if (0 == current && i < bucket_count() - 1 && 0 == snapshot.counts(i + 1)) { while (i < bucket_count() - 1 && 0 == snapshot.counts(i + 1)) ++i; @@ -139,42 +213,230 @@ void Histogram::WriteAscii(bool graph_it, const std::string& newline, output->append(newline); past += current; } - DCHECK(past == sample_count); + DCHECK_EQ(sample_count, past); } -bool Histogram::ValidateBucketRanges() const { - // Standard assertions that all bucket ranges should satisfy. - DCHECK(ranges_.size() == bucket_count_ + 1); - DCHECK(0 == ranges_[0]); - DCHECK(declared_min() == ranges_[1]); - DCHECK(declared_max() == ranges_[bucket_count_ - 1]); - DCHECK(kSampleType_MAX == ranges_[bucket_count_]); +// static +std::string Histogram::SerializeHistogramInfo(const Histogram& histogram, + const SampleSet& snapshot) { + DCHECK_NE(NOT_VALID_IN_RENDERER, histogram.histogram_type()); + + Pickle pickle; + pickle.WriteString(histogram.histogram_name()); + pickle.WriteInt(histogram.declared_min()); + pickle.WriteInt(histogram.declared_max()); + pickle.WriteSize(histogram.bucket_count()); + pickle.WriteUInt32(histogram.range_checksum()); + pickle.WriteInt(histogram.histogram_type()); + pickle.WriteInt(histogram.flags()); + + snapshot.Serialize(&pickle); + return std::string(static_cast(pickle.data()), pickle.size()); +} + +// static +bool Histogram::DeserializeHistogramInfo(const std::string& histogram_info) { + if (histogram_info.empty()) { + return false; + } + + Pickle pickle(histogram_info.data(), + static_cast(histogram_info.size())); + std::string histogram_name; + int declared_min; + int declared_max; + size_t bucket_count; + uint32 range_checksum; + int histogram_type; + int pickle_flags; + SampleSet sample; + + void* iter = NULL; + if (!pickle.ReadString(&iter, &histogram_name) || + !pickle.ReadInt(&iter, &declared_min) || + !pickle.ReadInt(&iter, &declared_max) || + !pickle.ReadSize(&iter, &bucket_count) || + !pickle.ReadUInt32(&iter, &range_checksum) || + !pickle.ReadInt(&iter, &histogram_type) || + !pickle.ReadInt(&iter, &pickle_flags) || + !sample.Histogram::SampleSet::Deserialize(&iter, pickle)) { + LOG(ERROR) << "Pickle error decoding Histogram: " << histogram_name; + return false; + } + DCHECK(pickle_flags & kIPCSerializationSourceFlag); + // Since these fields may have come from an untrusted renderer, do additional + // checks above and beyond those in Histogram::Initialize() + if (declared_max <= 0 || declared_min <= 0 || declared_max < declared_min || + INT_MAX / sizeof(Count) <= bucket_count || bucket_count < 2) { + LOG(ERROR) << "Values error decoding Histogram: " << histogram_name; + return false; + } + + Flags flags = static_cast(pickle_flags & ~kIPCSerializationSourceFlag); + + DCHECK_NE(NOT_VALID_IN_RENDERER, histogram_type); + + Histogram* render_histogram(NULL); + + if (histogram_type == HISTOGRAM) { + render_histogram = Histogram::FactoryGet( + histogram_name, declared_min, declared_max, bucket_count, flags); + } else if (histogram_type == LINEAR_HISTOGRAM) { + render_histogram = LinearHistogram::FactoryGet( + histogram_name, declared_min, declared_max, bucket_count, flags); + } else if (histogram_type == BOOLEAN_HISTOGRAM) { + render_histogram = BooleanHistogram::FactoryGet(histogram_name, flags); + } else { + LOG(ERROR) << "Error Deserializing Histogram Unknown histogram_type: " + << histogram_type; + return false; + } + + DCHECK_EQ(render_histogram->declared_min(), declared_min); + DCHECK_EQ(render_histogram->declared_max(), declared_max); + DCHECK_EQ(render_histogram->bucket_count(), bucket_count); + DCHECK_EQ(render_histogram->range_checksum(), range_checksum); + DCHECK_EQ(render_histogram->histogram_type(), histogram_type); + + if (render_histogram->flags() & kIPCSerializationSourceFlag) { + DVLOG(1) << "Single process mode, histogram observed and not copied: " + << histogram_name; + } else { + DCHECK_EQ(flags & render_histogram->flags(), flags); + render_histogram->AddSampleSet(sample); + } + return true; } -void Histogram::Initialize() { - sample_.Resize(*this); - if (declared_min_ <= 0) - declared_min_ = 1; - if (declared_max_ >= kSampleType_MAX) - declared_max_ = kSampleType_MAX - 1; - DCHECK(declared_min_ > 0); // We provide underflow bucket. - DCHECK(declared_min_ <= declared_max_); - DCHECK(1 < bucket_count_); - size_t maximal_bucket_count = declared_max_ - declared_min_ + 2; - DCHECK(bucket_count_ <= maximal_bucket_count); - DCHECK(0 == ranges_[0]); - ranges_[bucket_count_] = kSampleType_MAX; - InitializeBucketRange(); +//------------------------------------------------------------------------------ +// Methods for the validating a sample and a related histogram. +//------------------------------------------------------------------------------ + +Histogram::Inconsistencies Histogram::FindCorruption( + const SampleSet& snapshot) const { + int inconsistencies = NO_INCONSISTENCIES; + Sample previous_range = -1; // Bottom range is always 0. + int64 count = 0; + for (size_t index = 0; index < bucket_count(); ++index) { + count += snapshot.counts(index); + int new_range = ranges(index); + if (previous_range >= new_range) + inconsistencies |= BUCKET_ORDER_ERROR; + previous_range = new_range; + } + + if (!HasValidRangeChecksum()) + inconsistencies |= RANGE_CHECKSUM_ERROR; + + int64 delta64 = snapshot.redundant_count() - count; + if (delta64 != 0) { + int delta = static_cast(delta64); + if (delta != delta64) + delta = INT_MAX; // Flag all giant errors as INT_MAX. + // Since snapshots of histograms are taken asynchronously relative to + // sampling (and snapped from different threads), it is pretty likely that + // we'll catch a redundant count that doesn't match the sample count. We + // allow for a certain amount of slop before flagging this as an + // inconsistency. Even with an inconsistency, we'll snapshot it again (for + // UMA in about a half hour, so we'll eventually get the data, if it was + // not the result of a corruption. If histograms show that 1 is "too tight" + // then we may try to use 2 or 3 for this slop value. + const int kCommonRaceBasedCountMismatch = 1; + if (delta > 0) { + UMA_HISTOGRAM_COUNTS("Histogram.InconsistentCountHigh", delta); + if (delta > kCommonRaceBasedCountMismatch) + inconsistencies |= COUNT_HIGH_ERROR; + } else { + DCHECK_GT(0, delta); + UMA_HISTOGRAM_COUNTS("Histogram.InconsistentCountLow", -delta); + if (-delta > kCommonRaceBasedCountMismatch) + inconsistencies |= COUNT_LOW_ERROR; + } + } + return static_cast(inconsistencies); +} + +Histogram::ClassType Histogram::histogram_type() const { + return HISTOGRAM; +} + +Histogram::Sample Histogram::ranges(size_t i) const { + return ranges_[i]; +} + +size_t Histogram::bucket_count() const { + return bucket_count_; +} + +// Do a safe atomic snapshot of sample data. +// This implementation assumes we are on a safe single thread. +void Histogram::SnapshotSample(SampleSet* sample) const { + // Note locking not done in this version!!! + *sample = sample_; +} + +bool Histogram::HasConstructorArguments(Sample minimum, + Sample maximum, + size_t bucket_count) { + return ((minimum == declared_min_) && (maximum == declared_max_) && + (bucket_count == bucket_count_)); +} + +bool Histogram::HasConstructorTimeDeltaArguments(TimeDelta minimum, + TimeDelta maximum, + size_t bucket_count) { + return ((minimum.InMilliseconds() == declared_min_) && + (maximum.InMilliseconds() == declared_max_) && + (bucket_count == bucket_count_)); +} + +bool Histogram::HasValidRangeChecksum() const { + return CalculateRangeChecksum() == range_checksum_; +} + +Histogram::Histogram(const std::string& name, Sample minimum, + Sample maximum, size_t bucket_count) + : histogram_name_(name), + declared_min_(minimum), + declared_max_(maximum), + bucket_count_(bucket_count), + flags_(kNoFlags), + ranges_(bucket_count + 1, 0), + range_checksum_(0), + sample_() { + Initialize(); +} + +Histogram::Histogram(const std::string& name, TimeDelta minimum, + TimeDelta maximum, size_t bucket_count) + : histogram_name_(name), + declared_min_(static_cast (minimum.InMilliseconds())), + declared_max_(static_cast (maximum.InMilliseconds())), + bucket_count_(bucket_count), + flags_(kNoFlags), + ranges_(bucket_count + 1, 0), + range_checksum_(0), + sample_() { + Initialize(); +} + +Histogram::~Histogram() { + if (StatisticsRecorder::dump_on_exit()) { + std::string output; + WriteAscii(true, "\n", &output); + LOG(INFO) << output; + } + + // Just to make sure most derived class did this properly... DCHECK(ValidateBucketRanges()); - registered_ = StatisticsRecorder::Register(this); } // Calculate what range of values are held in each bucket. // We have to be careful that we don't pick a ratio between starting points in // consecutive buckets that is sooo small, that the integer bounds are the same // (effectively making one bucket get no values). We need to avoid: -// (ranges_[i] == ranges_[i + 1] +// ranges_[i] == ranges_[i + 1] // To avoid that, we just do a fine-grained bucket width as far as we need to // until we get a ratio that moves us along at least 2 units at a time. From // that bucket onward we do use the exponential growth of buckets. @@ -200,22 +462,27 @@ void Histogram::InitializeBucketRange() { ++current; // Just do a narrow bucket, and keep trying. SetBucketRange(bucket_index, current); } + ResetRangeChecksum(); - DCHECK(bucket_count() == bucket_index); + DCHECK_EQ(bucket_count(), bucket_index); +} + +bool Histogram::PrintEmptyBucket(size_t index) const { + return true; } size_t Histogram::BucketIndex(Sample value) const { // Use simple binary search. This is very general, but there are better // approaches if we knew that the buckets were linearly distributed. - DCHECK(ranges(0) <= value); - DCHECK(ranges(bucket_count()) > value); + DCHECK_LE(ranges(0), value); + DCHECK_GT(ranges(bucket_count()), value); size_t under = 0; size_t over = bucket_count(); size_t mid; do { - DCHECK(over >= under); - mid = (over + under)/2; + DCHECK_GE(over, under); + mid = under + (over - under)/2; if (mid == under) break; if (ranges(mid) <= value) @@ -224,7 +491,8 @@ size_t Histogram::BucketIndex(Sample value) const { over = mid; } while (true); - DCHECK(ranges(mid) <= value && ranges(mid+1) > value); + DCHECK_LE(ranges(mid), value); + CHECK_GT(ranges(mid+1), value); return mid; } @@ -234,7 +502,7 @@ size_t Histogram::BucketIndex(Sample value) const { // buckets), so we need this to make it possible to see what is going on and // not have 0-graphical-height buckets. double Histogram::GetBucketSize(Count current, size_t i) const { - DCHECK(ranges(i + 1) > ranges(i)); + DCHECK_GT(ranges(i + 1), ranges(i)); static const double kTransitionWidth = 5; double denominator = ranges(i + 1) - ranges(i); if (denominator > kTransitionWidth) @@ -242,12 +510,18 @@ double Histogram::GetBucketSize(Count current, size_t i) const { return current/denominator; } -//------------------------------------------------------------------------------ -// The following two methods can be overridden to provide a thread safe -// version of this class. The cost of locking is low... but an error in each -// of these methods has minimal impact. For now, I'll leave this unlocked, -// and I don't believe I can loose more than a count or two. -// The vectors are NOT reallocated, so there is no risk of them moving around. +void Histogram::ResetRangeChecksum() { + range_checksum_ = CalculateRangeChecksum(); +} + +const std::string Histogram::GetAsciiBucketRange(size_t i) const { + std::string result; + if (kHexRangePrintingFlag & flags_) + StringAppendF(&result, "%#x", ranges(i)); + else + StringAppendF(&result, "%d", ranges(i)); + return result; +} // Update histogram data with new sample. void Histogram::Accumulate(Sample value, Count count, size_t index) { @@ -255,19 +529,78 @@ void Histogram::Accumulate(Sample value, Count count, size_t index) { sample_.Accumulate(value, count, index); } -// Do a safe atomic snapshot of sample data. -// This implementation assumes we are on a safe single thread. -void Histogram::SnapshotSample(SampleSet* sample) const { - // Note locking not done in this version!!! - *sample = sample_; +void Histogram::SetBucketRange(size_t i, Sample value) { + DCHECK_GT(bucket_count_, i); + ranges_[i] = value; } -//------------------------------------------------------------------------------ -// Accessor methods +bool Histogram::ValidateBucketRanges() const { + // Standard assertions that all bucket ranges should satisfy. + DCHECK_EQ(bucket_count_ + 1, ranges_.size()); + DCHECK_EQ(0, ranges_[0]); + DCHECK_EQ(declared_min(), ranges_[1]); + DCHECK_EQ(declared_max(), ranges_[bucket_count_ - 1]); + DCHECK_EQ(kSampleType_MAX, ranges_[bucket_count_]); + return true; +} -void Histogram::SetBucketRange(size_t i, Sample value) { - DCHECK(bucket_count_ > i); - ranges_[i] = value; +uint32 Histogram::CalculateRangeChecksum() const { + DCHECK_EQ(ranges_.size(), bucket_count() + 1); + uint32 checksum = static_cast(ranges_.size()); // Seed checksum. + for (size_t index = 0; index < bucket_count(); ++index) + checksum = Crc32(checksum, ranges(index)); + return checksum; +} + +void Histogram::Initialize() { + sample_.Resize(*this); + if (declared_min_ < 1) + declared_min_ = 1; + if (declared_max_ > kSampleType_MAX - 1) + declared_max_ = kSampleType_MAX - 1; + DCHECK_LE(declared_min_, declared_max_); + DCHECK_GT(bucket_count_, 1u); + CHECK_LT(bucket_count_, kBucketCount_MAX); + size_t maximal_bucket_count = declared_max_ - declared_min_ + 2; + DCHECK_LE(bucket_count_, maximal_bucket_count); + DCHECK_EQ(0, ranges_[0]); + ranges_[bucket_count_] = kSampleType_MAX; +} + +// We generate the CRC-32 using the low order bits to select whether to XOR in +// the reversed polynomial 0xedb88320L. This is nice and simple, and allows us +// to keep the quotient in a uint32. Since we're not concerned about the nature +// of corruptions (i.e., we don't care about bit sequencing, since we are +// handling memory changes, which are more grotesque) so we don't bother to +// get the CRC correct for big-endian vs little-ending calculations. All we +// need is a nice hash, that tends to depend on all the bits of the sample, with +// very little chance of changes in one place impacting changes in another +// place. +uint32 Histogram::Crc32(uint32 sum, Histogram::Sample range) { + const bool kUseRealCrc = true; // TODO(jar): Switch to false and watch stats. + if (kUseRealCrc) { + union { + Histogram::Sample range; + unsigned char bytes[sizeof(Histogram::Sample)]; + } converter; + converter.range = range; + for (size_t i = 0; i < sizeof(converter); ++i) + sum = kCrcTable[(sum & 0xff) ^ converter.bytes[i]] ^ (sum >> 8); + } else { + // Use hash techniques provided in ReallyFastHash, except we don't care + // about "avalanching" (which would worsten the hash, and add collisions), + // and we don't care about edge cases since we have an even number of bytes. + union { + Histogram::Sample range; + uint16 ints[sizeof(Histogram::Sample) / 2]; + } converter; + DCHECK_EQ(sizeof(Histogram::Sample), sizeof(converter)); + converter.range = range; + sum += converter.ints[0]; + sum = (sum << 16) ^ sum ^ (static_cast(converter.ints[1]) << 11); + sum += sum >> 11; + } + return sum; } //------------------------------------------------------------------------------ @@ -287,22 +620,17 @@ void Histogram::WriteAsciiHeader(const SampleSet& snapshot, Count sample_count, std::string* output) const { StringAppendF(output, - "Histogram: %s recorded %ld samples", + "Histogram: %s recorded %d samples", histogram_name().c_str(), sample_count); if (0 == sample_count) { - DCHECK(0 == snapshot.sum()); + DCHECK_EQ(snapshot.sum(), 0); } else { double average = static_cast(snapshot.sum()) / sample_count; - double variance = static_cast(snapshot.square_sum())/sample_count - - average * average; - double standard_deviation = sqrt(variance); - StringAppendF(output, - ", average = %.1f, standard deviation = %.1f", - average, standard_deviation); + StringAppendF(output, ", average = %.1f", average); } - if (flags_ & ~kHexRangePrintingFlag ) + if (flags_ & ~kHexRangePrintingFlag) StringAppendF(output, " (flags = 0x%x)", flags_ & ~kHexRangePrintingFlag); } @@ -319,15 +647,6 @@ void Histogram::WriteAsciiBucketContext(const int64 past, } } -const std::string Histogram::GetAsciiBucketRange(size_t i) const { - std::string result; - if (kHexRangePrintingFlag & flags_) - StringAppendF(&result, "%#x", ranges(i)); - else - StringAppendF(&result, "%d", ranges(i)); - return result; -} - void Histogram::WriteAsciiBucketValue(Count current, double scaled_sum, std::string* output) const { StringAppendF(output, " (%d = %3.1f%%)", current, current/scaled_sum); @@ -347,100 +666,6 @@ void Histogram::WriteAsciiBucketGraph(double current_size, double max_size, output->append(" "); } -// static -std::string Histogram::SerializeHistogramInfo(const Histogram& histogram, - const SampleSet& snapshot) { - Pickle pickle; - - pickle.WriteString(histogram.histogram_name()); - pickle.WriteInt(histogram.declared_min()); - pickle.WriteInt(histogram.declared_max()); - pickle.WriteSize(histogram.bucket_count()); - pickle.WriteInt(histogram.histogram_type()); - pickle.WriteInt(histogram.flags()); - - snapshot.Serialize(&pickle); - return std::string(static_cast(pickle.data()), pickle.size()); -} - -// static -void Histogram::DeserializeHistogramList( - const std::vector& histograms) { - for (std::vector::const_iterator it = histograms.begin(); - it < histograms.end(); - ++it) { - DeserializeHistogramInfo(*it); - } -} - -// static -bool Histogram::DeserializeHistogramInfo(const std::string& histogram_info) { - if (histogram_info.empty()) { - return false; - } - - Pickle pickle(histogram_info.data(), - static_cast(histogram_info.size())); - void* iter = NULL; - size_t bucket_count; - int declared_min; - int declared_max; - int histogram_type; - int flags; - std::string histogram_name; - SampleSet sample; - - if (!pickle.ReadString(&iter, &histogram_name) || - !pickle.ReadInt(&iter, &declared_min) || - !pickle.ReadInt(&iter, &declared_max) || - !pickle.ReadSize(&iter, &bucket_count) || - !pickle.ReadInt(&iter, &histogram_type) || - !pickle.ReadInt(&iter, &flags) || - !sample.Histogram::SampleSet::Deserialize(&iter, pickle)) { - LOG(ERROR) << "Picke error decoding Histogram: " << histogram_name; - return false; - } - - Histogram* render_histogram = - StatisticsRecorder::GetHistogram(histogram_name); - - if (render_histogram == NULL) { - if (histogram_type == EXPONENTIAL) { - render_histogram = new Histogram(histogram_name.c_str(), - declared_min, - declared_max, - bucket_count); - } else if (histogram_type == LINEAR) { - render_histogram = reinterpret_cast - (new LinearHistogram(histogram_name.c_str(), - declared_min, - declared_max, - bucket_count)); - } else { - LOG(ERROR) << "Error Deserializing Histogram Unknown histogram_type: " << - histogram_type; - return false; - } - DCHECK(!(flags & kRendererHistogramFlag)); - render_histogram->SetFlags(flags | kRendererHistogramFlag); - } - - DCHECK(declared_min == render_histogram->declared_min()); - DCHECK(declared_max == render_histogram->declared_max()); - DCHECK(bucket_count == render_histogram->bucket_count()); - DCHECK(histogram_type == render_histogram->histogram_type()); - - if (render_histogram->flags() & kRendererHistogramFlag) { - render_histogram->AddSampleSet(sample); - } else { - DLOG(INFO) << "Single thread mode, histogram observed and not copied: " << - histogram_name; - } - - return true; -} - - //------------------------------------------------------------------------------ // Methods for the Histogram::SampleSet class //------------------------------------------------------------------------------ @@ -448,7 +673,10 @@ bool Histogram::DeserializeHistogramInfo(const std::string& histogram_info) { Histogram::SampleSet::SampleSet() : counts_(), sum_(0), - square_sum_(0) { + redundant_count_(0) { +} + +Histogram::SampleSet::~SampleSet() { } void Histogram::SampleSet::Resize(const Histogram& histogram) { @@ -456,7 +684,7 @@ void Histogram::SampleSet::Resize(const Histogram& histogram) { } void Histogram::SampleSet::CheckSize(const Histogram& histogram) const { - DCHECK(counts_.size() == histogram.bucket_count()); + DCHECK_EQ(histogram.bucket_count(), counts_.size()); } @@ -465,10 +693,10 @@ void Histogram::SampleSet::Accumulate(Sample value, Count count, DCHECK(count == 1 || count == -1); counts_[index] += count; sum_ += count * value; - square_sum_ += (count * value) * static_cast(value); - DCHECK(counts_[index] >= 0); - DCHECK(sum_ >= 0); - DCHECK(square_sum_ >= 0); + redundant_count_ += count; + DCHECK_GE(counts_[index], 0); + DCHECK_GE(sum_, 0); + DCHECK_GE(redundant_count_, 0); } Count Histogram::SampleSet::TotalCount() const { @@ -482,29 +710,29 @@ Count Histogram::SampleSet::TotalCount() const { } void Histogram::SampleSet::Add(const SampleSet& other) { - DCHECK(counts_.size() == other.counts_.size()); + DCHECK_EQ(counts_.size(), other.counts_.size()); sum_ += other.sum_; - square_sum_ += other.square_sum_; + redundant_count_ += other.redundant_count_; for (size_t index = 0; index < counts_.size(); ++index) counts_[index] += other.counts_[index]; } void Histogram::SampleSet::Subtract(const SampleSet& other) { - DCHECK(counts_.size() == other.counts_.size()); - // Note: Race conditions in snapshotting a sum or square_sum may lead to - // (temporary) negative values when snapshots are later combined (and deltas - // calculated). As a result, we don't currently CHCEK() for positive values. + DCHECK_EQ(counts_.size(), other.counts_.size()); + // Note: Race conditions in snapshotting a sum may lead to (temporary) + // negative values when snapshots are later combined (and deltas calculated). + // As a result, we don't currently CHCEK() for positive values. sum_ -= other.sum_; - square_sum_ -= other.square_sum_; + redundant_count_ -= other.redundant_count_; for (size_t index = 0; index < counts_.size(); ++index) { counts_[index] -= other.counts_[index]; - DCHECK(counts_[index] >= 0); + DCHECK_GE(counts_[index], 0); } } bool Histogram::SampleSet::Serialize(Pickle* pickle) const { pickle->WriteInt64(sum_); - pickle->WriteInt64(square_sum_); + pickle->WriteInt64(redundant_count_); pickle->WriteSize(counts_.size()); for (size_t index = 0; index < counts_.size(); ++index) { @@ -515,29 +743,31 @@ bool Histogram::SampleSet::Serialize(Pickle* pickle) const { } bool Histogram::SampleSet::Deserialize(void** iter, const Pickle& pickle) { - DCHECK(counts_.size() == 0); - DCHECK(sum_ == 0); - DCHECK(square_sum_ == 0); + DCHECK_EQ(counts_.size(), 0u); + DCHECK_EQ(sum_, 0); + DCHECK_EQ(redundant_count_, 0); size_t counts_size; if (!pickle.ReadInt64(iter, &sum_) || - !pickle.ReadInt64(iter, &square_sum_) || + !pickle.ReadInt64(iter, &redundant_count_) || !pickle.ReadSize(iter, &counts_size)) { return false; } - if (counts_size <= 0) + if (counts_size == 0) return false; - counts_.resize(counts_size, 0); + int count = 0; for (size_t index = 0; index < counts_size; ++index) { - if (!pickle.ReadInt(iter, &counts_[index])) { + int i; + if (!pickle.ReadInt(iter, &i)) return false; - } + counts_.push_back(i); + count += i; } - - return true; + DCHECK_EQ(count, redundant_count_); + return count == redundant_count_; } //------------------------------------------------------------------------------ @@ -545,21 +775,47 @@ bool Histogram::SampleSet::Deserialize(void** iter, const Pickle& pickle) { // buckets. //------------------------------------------------------------------------------ -LinearHistogram::LinearHistogram(const char* name, Sample minimum, - Sample maximum, size_t bucket_count) - : Histogram(name, minimum >= 1 ? minimum : 1, maximum, bucket_count) { - InitializeBucketRange(); - DCHECK(ValidateBucketRanges()); +LinearHistogram::~LinearHistogram() { } -LinearHistogram::LinearHistogram(const char* name, - TimeDelta minimum, TimeDelta maximum, size_t bucket_count) - : Histogram(name, minimum >= TimeDelta::FromMilliseconds(1) ? - minimum : TimeDelta::FromMilliseconds(1), - maximum, bucket_count) { - // Do a "better" (different) job at init than a base classes did... - InitializeBucketRange(); - DCHECK(ValidateBucketRanges()); +Histogram* LinearHistogram::FactoryGet(const std::string& name, + Sample minimum, + Sample maximum, + size_t bucket_count, + Flags flags) { + Histogram* histogram(NULL); + + if (minimum < 1) + minimum = 1; + if (maximum > kSampleType_MAX - 1) + maximum = kSampleType_MAX - 1; + + if (!StatisticsRecorder::FindHistogram(name, &histogram)) { + // To avoid racy destruction at shutdown, the following will be leaked. + LinearHistogram* tentative_histogram = + new LinearHistogram(name, minimum, maximum, bucket_count); + tentative_histogram->InitializeBucketRange(); + tentative_histogram->SetFlags(flags); + histogram = + StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); + } + + DCHECK_EQ(LINEAR_HISTOGRAM, histogram->histogram_type()); + DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count)); + return histogram; +} + +Histogram* LinearHistogram::FactoryTimeGet(const std::string& name, + TimeDelta minimum, + TimeDelta maximum, + size_t bucket_count, + Flags flags) { + return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(), + bucket_count, flags); +} + +Histogram::ClassType LinearHistogram::histogram_type() const { + return LINEAR_HISTOGRAM; } void LinearHistogram::SetRangeDescriptions( @@ -569,6 +825,43 @@ void LinearHistogram::SetRangeDescriptions( } } +LinearHistogram::LinearHistogram(const std::string& name, + Sample minimum, + Sample maximum, + size_t bucket_count) + : Histogram(name, minimum >= 1 ? minimum : 1, maximum, bucket_count) { +} + +LinearHistogram::LinearHistogram(const std::string& name, + TimeDelta minimum, + TimeDelta maximum, + size_t bucket_count) + : Histogram(name, minimum >= TimeDelta::FromMilliseconds(1) ? + minimum : TimeDelta::FromMilliseconds(1), + maximum, bucket_count) { +} + +void LinearHistogram::InitializeBucketRange() { + DCHECK_GT(declared_min(), 0); // 0 is the underflow bucket here. + double min = declared_min(); + double max = declared_max(); + size_t i; + for (i = 1; i < bucket_count(); ++i) { + double linear_range = (min * (bucket_count() -1 - i) + max * (i - 1)) / + (bucket_count() - 2); + SetBucketRange(i, static_cast (linear_range + 0.5)); + } + ResetRangeChecksum(); +} + +double LinearHistogram::GetBucketSize(Count current, size_t i) const { + DCHECK_GT(ranges(i + 1), ranges(i)); + // Adjacent buckets with different widths would have "surprisingly" many (few) + // samples in a histogram if we didn't normalize this way. + double denominator = ranges(i + 1) - ranges(i); + return current/denominator; +} + const std::string LinearHistogram::GetAsciiBucketRange(size_t i) const { int range = ranges(i); BucketDescriptionMap::const_iterator it = bucket_description_.find(range); @@ -582,64 +875,100 @@ bool LinearHistogram::PrintEmptyBucket(size_t index) const { } -void LinearHistogram::InitializeBucketRange() { - DCHECK(0 < declared_min()); // 0 is the underflow bucket here. - double min = declared_min(); - double max = declared_max(); - size_t i; - for (i = 1; i < bucket_count(); ++i) { - double linear_range = (min * (bucket_count() -1 - i) + max * (i - 1)) / - (bucket_count() - 2); - SetBucketRange(i, static_cast (linear_range + 0.5)); +//------------------------------------------------------------------------------ +// This section provides implementation for BooleanHistogram. +//------------------------------------------------------------------------------ + +Histogram* BooleanHistogram::FactoryGet(const std::string& name, Flags flags) { + Histogram* histogram(NULL); + + if (!StatisticsRecorder::FindHistogram(name, &histogram)) { + // To avoid racy destruction at shutdown, the following will be leaked. + BooleanHistogram* tentative_histogram = new BooleanHistogram(name); + tentative_histogram->InitializeBucketRange(); + tentative_histogram->SetFlags(flags); + histogram = + StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); } + + DCHECK_EQ(BOOLEAN_HISTOGRAM, histogram->histogram_type()); + return histogram; } -// Find bucket to increment for sample value. -size_t LinearHistogram::BucketIndex(Sample value) const { - if (value < declared_min()) return 0; - if (value >= declared_max()) return bucket_count() - 1; - size_t index; - index = static_cast(((value - declared_min()) * (bucket_count() - 2)) - / (declared_max() - declared_min()) + 1); - DCHECK(1 <= index && bucket_count() > index); - return index; +Histogram::ClassType BooleanHistogram::histogram_type() const { + return BOOLEAN_HISTOGRAM; } -double LinearHistogram::GetBucketSize(Count current, size_t i) const { - DCHECK(ranges(i + 1) > ranges(i)); - // Adjacent buckets with different widths would have "surprisingly" many (few) - // samples in a histogram if we didn't normalize this way. - double denominator = ranges(i + 1) - ranges(i); - return current/denominator; +void BooleanHistogram::AddBoolean(bool value) { + Add(value ? 1 : 0); +} + +BooleanHistogram::BooleanHistogram(const std::string& name) + : LinearHistogram(name, 1, 2, 3) { } //------------------------------------------------------------------------------ -// This section provides implementation for ThreadSafeHistogram. +// CustomHistogram: //------------------------------------------------------------------------------ -ThreadSafeHistogram::ThreadSafeHistogram(const char* name, Sample minimum, - Sample maximum, size_t bucket_count) - : Histogram(name, minimum, maximum, bucket_count), - lock_() { +Histogram* CustomHistogram::FactoryGet(const std::string& name, + const std::vector& custom_ranges, + Flags flags) { + Histogram* histogram(NULL); + + // Remove the duplicates in the custom ranges array. + std::vector ranges = custom_ranges; + ranges.push_back(0); // Ensure we have a zero value. + std::sort(ranges.begin(), ranges.end()); + ranges.erase(std::unique(ranges.begin(), ranges.end()), ranges.end()); + if (ranges.size() <= 1) { + DCHECK(false); + // Note that we pushed a 0 in above, so for defensive code.... + ranges.push_back(1); // Put in some data so we can index to [1]. } -void ThreadSafeHistogram::Remove(int value) { - if (value >= kSampleType_MAX) - value = kSampleType_MAX - 1; - size_t index = BucketIndex(value); - Accumulate(value, -1, index); + DCHECK_LT(ranges.back(), kSampleType_MAX); + + if (!StatisticsRecorder::FindHistogram(name, &histogram)) { + // To avoid racy destruction at shutdown, the following will be leaked. + CustomHistogram* tentative_histogram = new CustomHistogram(name, ranges); + tentative_histogram->InitializedCustomBucketRange(ranges); + tentative_histogram->SetFlags(flags); + histogram = + StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); + } + + DCHECK_EQ(histogram->histogram_type(), CUSTOM_HISTOGRAM); + DCHECK(histogram->HasConstructorArguments(ranges[1], ranges.back(), + ranges.size())); + return histogram; } -void ThreadSafeHistogram::Accumulate(Sample value, Count count, size_t index) { - AutoLock lock(lock_); - Histogram::Accumulate(value, count, index); +Histogram::ClassType CustomHistogram::histogram_type() const { + return CUSTOM_HISTOGRAM; } -void ThreadSafeHistogram::SnapshotSample(SampleSet* sample) const { - AutoLock lock(lock_); - Histogram::SnapshotSample(sample); -}; +CustomHistogram::CustomHistogram(const std::string& name, + const std::vector& custom_ranges) + : Histogram(name, custom_ranges[1], custom_ranges.back(), + custom_ranges.size()) { + DCHECK_GT(custom_ranges.size(), 1u); + DCHECK_EQ(custom_ranges[0], 0); +} +void CustomHistogram::InitializedCustomBucketRange( + const std::vector& custom_ranges) { + DCHECK_GT(custom_ranges.size(), 1u); + DCHECK_EQ(custom_ranges[0], 0); + DCHECK_LE(custom_ranges.size(), bucket_count()); + for (size_t index = 0; index < custom_ranges.size(); ++index) + SetBucketRange(index, custom_ranges[index]); + ResetRangeChecksum(); +} + +double CustomHistogram::GetBucketSize(Count current, size_t i) const { + return 1; +} //------------------------------------------------------------------------------ // The next section handles global (central) support for all histograms, as well @@ -651,64 +980,70 @@ void ThreadSafeHistogram::SnapshotSample(SampleSet* sample) const { // provide support for all future calls. StatisticsRecorder::StatisticsRecorder() { DCHECK(!histograms_); - lock_ = new Lock; + if (lock_ == NULL) { + // This will leak on purpose. It's the only way to make sure we won't race + // against the static uninitialization of the module while one of our + // static methods relying on the lock get called at an inappropriate time + // during the termination phase. Since it's a static data member, we will + // leak one per process, which would be similar to the instance allocated + // during static initialization and released only on process termination. + lock_ = new base::Lock; + } + base::AutoLock auto_lock(*lock_); histograms_ = new HistogramMap; } StatisticsRecorder::~StatisticsRecorder() { - DCHECK(histograms_); + DCHECK(histograms_ && lock_); if (dump_on_exit_) { std::string output; WriteGraph("", &output); LOG(INFO) << output; } - // Clean up. - delete histograms_; - histograms_ = NULL; - delete lock_; - lock_ = NULL; + HistogramMap* histograms = NULL; + { + base::AutoLock auto_lock(*lock_); + histograms = histograms_; + histograms_ = NULL; + } + delete histograms; + // We don't delete lock_ on purpose to avoid having to properly protect + // against it going away after we checked for NULL in the static methods. } // static -bool StatisticsRecorder::WasStarted() { +bool StatisticsRecorder::IsActive() { + if (lock_ == NULL) + return false; + base::AutoLock auto_lock(*lock_); return NULL != histograms_; } -// static -bool StatisticsRecorder::Register(Histogram* histogram) { +Histogram* StatisticsRecorder::RegisterOrDeleteDuplicate(Histogram* histogram) { + DCHECK(histogram->HasValidRangeChecksum()); + if (lock_ == NULL) + return histogram; + base::AutoLock auto_lock(*lock_); if (!histograms_) - return false; + return histogram; const std::string name = histogram->histogram_name(); - AutoLock auto_lock(*lock_); - - DCHECK(histograms_->end() == histograms_->find(name)) << name << " is already" - "registered as a histogram. Check for duplicate use of the name, or a " - "race where a static initializer could be run by several threads."; - (*histograms_)[name] = histogram; - return true; -} - -// static -void StatisticsRecorder::UnRegister(Histogram* histogram) { - if (!histograms_) - return; - const std::string name = histogram->histogram_name(); - AutoLock auto_lock(*lock_); - DCHECK(histograms_->end() != histograms_->find(name)); - histograms_->erase(name); - if (dump_on_exit_) { - std::string output; - histogram->WriteAscii(true, "\n", &output); - LOG(INFO) << output; + HistogramMap::iterator it = histograms_->find(name); + // Avoid overwriting a previous registration. + if (histograms_->end() == it) { + (*histograms_)[name] = histogram; + } else { + delete histogram; // We already have one by this name. + histogram = it->second; } + return histogram; } // static void StatisticsRecorder::WriteHTMLGraph(const std::string& query, std::string* output) { - if (!histograms_) + if (!IsActive()) return; output->append("About Histograms"); if (!query.empty()) @@ -732,7 +1067,7 @@ void StatisticsRecorder::WriteHTMLGraph(const std::string& query, // static void StatisticsRecorder::WriteGraph(const std::string& query, std::string* output) { - if (!histograms_) + if (!IsActive()) return; if (query.length()) StringAppendF(output, "Collections of histograms for %s\n", query.c_str()); @@ -751,33 +1086,41 @@ void StatisticsRecorder::WriteGraph(const std::string& query, // static void StatisticsRecorder::GetHistograms(Histograms* output) { + if (lock_ == NULL) + return; + base::AutoLock auto_lock(*lock_); if (!histograms_) return; - AutoLock auto_lock(*lock_); for (HistogramMap::iterator it = histograms_->begin(); histograms_->end() != it; ++it) { + DCHECK_EQ(it->first, it->second->histogram_name()); output->push_back(it->second); } } -Histogram* StatisticsRecorder::GetHistogram(const std::string& query) { +bool StatisticsRecorder::FindHistogram(const std::string& name, + Histogram** histogram) { + if (lock_ == NULL) + return false; + base::AutoLock auto_lock(*lock_); if (!histograms_) - return NULL; - AutoLock auto_lock(*lock_); - for (HistogramMap::iterator it = histograms_->begin(); - histograms_->end() != it; - ++it) { - if (it->first.find(query) != std::string::npos) - return it->second; - } - return NULL; + return false; + HistogramMap::iterator it = histograms_->find(name); + if (histograms_->end() == it) + return false; + *histogram = it->second; + return true; } // private static void StatisticsRecorder::GetSnapshot(const std::string& query, Histograms* snapshot) { - AutoLock auto_lock(*lock_); + if (lock_ == NULL) + return; + base::AutoLock auto_lock(*lock_); + if (!histograms_) + return; for (HistogramMap::iterator it = histograms_->begin(); histograms_->end() != it; ++it) { @@ -789,6 +1132,8 @@ void StatisticsRecorder::GetSnapshot(const std::string& query, // static StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; // static -Lock* StatisticsRecorder::lock_ = NULL; +base::Lock* StatisticsRecorder::lock_ = NULL; // static bool StatisticsRecorder::dump_on_exit_ = false; + +} // namespace base diff --git a/ipc/chromium/src/base/histogram.h b/ipc/chromium/src/base/histogram.h index 59981ea07d2c..840b09185974 100644 --- a/ipc/chromium/src/base/histogram.h +++ b/ipc/chromium/src/base/histogram.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -28,97 +28,140 @@ // at the low end of the histogram scale, but allows the histogram to cover a // gigantic range with the addition of very few buckets. -#ifndef BASE_HISTOGRAM_H_ -#define BASE_HISTOGRAM_H_ +// Histograms use a pattern involving a function static variable, that is a +// pointer to a histogram. This static is explicitly initialized on any thread +// that detects a uninitialized (NULL) pointer. The potentially racy +// initialization is not a problem as it is always set to point to the same +// value (i.e., the FactoryGet always returns the same value). FactoryGet +// is also completely thread safe, which results in a completely thread safe, +// and relatively fast, set of counters. To avoid races at shutdown, the static +// pointer is NOT deleted, and we leak the histograms at process termination. + +#ifndef BASE_METRICS_HISTOGRAM_H_ +#define BASE_METRICS_HISTOGRAM_H_ +#pragma once #include <map> #include <string> #include <vector> -#include "base/lock.h" +#if defined(CHROMIUM_MOZILLA_BUILD) +#define BASE_API +#else +#include "base/base_api.h" +#endif +#include "testing/gtest/include/gtest/gtest_prod.h" #include "base/time.h" +#include "base/lock.h" +class Pickle; + +namespace base { //------------------------------------------------------------------------------ // Provide easy general purpose histogram in a macro, just like stats counters. // The first four macros use 50 buckets. -#define HISTOGRAM_TIMES(name, sample) do { \ - static Histogram counter((name), base::TimeDelta::FromMilliseconds(1), \ - base::TimeDelta::FromSeconds(10), 50); \ - counter.AddTime(sample); \ +#define HISTOGRAM_TIMES(name, sample) HISTOGRAM_CUSTOM_TIMES( \ + name, sample, base::TimeDelta::FromMilliseconds(1), \ + base::TimeDelta::FromSeconds(10), 50) + +#define HISTOGRAM_COUNTS(name, sample) HISTOGRAM_CUSTOM_COUNTS( \ + name, sample, 1, 1000000, 50) + +#define HISTOGRAM_COUNTS_100(name, sample) HISTOGRAM_CUSTOM_COUNTS( \ + name, sample, 1, 100, 50) + +#define HISTOGRAM_COUNTS_10000(name, sample) HISTOGRAM_CUSTOM_COUNTS( \ + name, sample, 1, 10000, 50) + +#define HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) do { \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::Histogram::FactoryGet(name, min, max, bucket_count, \ + base::Histogram::kNoFlags); \ + DCHECK_EQ(name, counter->histogram_name()); \ + counter->Add(sample); \ } while (0) -#define HISTOGRAM_COUNTS(name, sample) do { \ - static Histogram counter((name), 1, 1000000, 50); \ - counter.Add(sample); \ +#define HISTOGRAM_PERCENTAGE(name, under_one_hundred) \ + HISTOGRAM_ENUMERATION(name, under_one_hundred, 101) + +// For folks that need real specific times, use this to select a precise range +// of times you want plotted, and the number of buckets you want used. +#define HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) do { \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ + base::Histogram::kNoFlags); \ + DCHECK_EQ(name, counter->histogram_name()); \ + counter->AddTime(sample); \ } while (0) -#define HISTOGRAM_COUNTS_100(name, sample) do { \ - static Histogram counter((name), 1, 100, 50); \ - counter.Add(sample); \ - } while (0) - -#define HISTOGRAM_COUNTS_10000(name, sample) do { \ - static Histogram counter((name), 1, 10000, 50); \ - counter.Add(sample); \ - } while (0) - -#define HISTOGRAM_PERCENTAGE(name, under_one_hundred) do { \ - static LinearHistogram counter((name), 1, 100, 101); \ - counter.Add(under_one_hundred); \ - } while (0) - -// For folks that need real specific times, use this, but you'll only get -// samples that are in the range (overly large samples are discarded). +// DO NOT USE THIS. It is being phased out, in favor of HISTOGRAM_CUSTOM_TIMES. #define HISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) do { \ - static Histogram counter((name), min, max, bucket_count); \ - if ((sample) < (max)) counter.AddTime(sample); \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ + base::Histogram::kNoFlags); \ + DCHECK_EQ(name, counter->histogram_name()); \ + if ((sample) < (max)) counter->AddTime(sample); \ } while (0) -//------------------------------------------------------------------------------ -// This macro set is for a histogram that can support both addition and removal -// of samples. It should be used to render the accumulated asset allocation -// of some samples. For example, it can sample memory allocation sizes, and -// memory releases (as negative samples). -// To simplify the interface, only non-zero values can be sampled, with positive -// numbers indicating addition, and negative numbers implying dimunition -// (removal). -// Note that the underlying ThreadSafeHistogram() uses locking to ensure that -// counts are precise (no chance of losing an addition or removal event, due to -// multithread racing). This precision is required to prevent missed-counts from -// resulting in drift, as the calls to Remove() for a given value should always -// be equal in number or fewer than the corresponding calls to Add(). +// Support histograming of an enumerated value. The samples should always be +// less than boundary_value. -#define ASSET_HISTOGRAM_COUNTS(name, sample) do { \ - static ThreadSafeHistogram counter((name), 1, 1000000, 50); \ - if (0 == sample) break; \ - if (sample >= 0) \ - counter.Add(sample); \ - else\ - counter.Remove(-sample); \ +#define HISTOGRAM_ENUMERATION(name, sample, boundary_value) do { \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::LinearHistogram::FactoryGet(name, 1, boundary_value, \ + boundary_value + 1, base::Histogram::kNoFlags); \ + DCHECK_EQ(name, counter->histogram_name()); \ + counter->Add(sample); \ } while (0) +#define HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) do { \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::CustomHistogram::FactoryGet(name, custom_ranges, \ + base::Histogram::kNoFlags); \ + DCHECK_EQ(name, counter->histogram_name()); \ + counter->Add(sample); \ + } while (0) + + //------------------------------------------------------------------------------ // Define Debug vs non-debug flavors of macros. #ifndef NDEBUG #define DHISTOGRAM_TIMES(name, sample) HISTOGRAM_TIMES(name, sample) #define DHISTOGRAM_COUNTS(name, sample) HISTOGRAM_COUNTS(name, sample) -#define DASSET_HISTOGRAM_COUNTS(name, sample) ASSET_HISTOGRAM_COUNTS(name, \ - sample) #define DHISTOGRAM_PERCENTAGE(name, under_one_hundred) HISTOGRAM_PERCENTAGE(\ name, under_one_hundred) +#define DHISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \ + HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) #define DHISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) \ HISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) +#define DHISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \ + HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) +#define DHISTOGRAM_ENUMERATION(name, sample, boundary_value) \ + HISTOGRAM_ENUMERATION(name, sample, boundary_value) +#define DHISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) \ + HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) #else // NDEBUG #define DHISTOGRAM_TIMES(name, sample) do {} while (0) #define DHISTOGRAM_COUNTS(name, sample) do {} while (0) -#define DASSET_HISTOGRAM_COUNTS(name, sample) do {} while (0) #define DHISTOGRAM_PERCENTAGE(name, under_one_hundred) do {} while (0) +#define DHISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \ + do {} while (0) #define DHISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) \ do {} while (0) +#define DHISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \ + do {} while (0) +#define DHISTOGRAM_ENUMERATION(name, sample, boundary_value) do {} while (0) +#define DHISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) \ + do {} while (0) #endif // NDEBUG @@ -128,103 +171,163 @@ // Not all systems support such UMA, but if they do, the following macros // should work with the service. -static const int kUmaTargetedHistogramFlag = 0x1; +#define UMA_HISTOGRAM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ + name, sample, base::TimeDelta::FromMilliseconds(1), \ + base::TimeDelta::FromSeconds(10), 50) -// This indicates the histogram is shadow copy of renderer histrogram -// constructed by unpick method and updated regularly from renderer upload -// of histograms. -static const int kRendererHistogramFlag = 1 << 4; - -#define UMA_HISTOGRAM_TIMES(name, sample) do { \ - static Histogram counter((name), base::TimeDelta::FromMilliseconds(1), \ - base::TimeDelta::FromSeconds(10), 50); \ - counter.SetFlags(kUmaTargetedHistogramFlag); \ - counter.AddTime(sample); \ - } while (0) - -#define UMA_HISTOGRAM_MEDIUM_TIMES(name, sample) do { \ - static Histogram counter((name), base::TimeDelta::FromMilliseconds(10), \ - base::TimeDelta::FromMinutes(3), 50); \ - counter.SetFlags(kUmaTargetedHistogramFlag); \ - counter.AddTime(sample); \ - } while (0) +#define UMA_HISTOGRAM_MEDIUM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ + name, sample, base::TimeDelta::FromMilliseconds(10), \ + base::TimeDelta::FromMinutes(3), 50) // Use this macro when times can routinely be much longer than 10 seconds. -#define UMA_HISTOGRAM_LONG_TIMES(name, sample) do { \ - static Histogram counter((name), base::TimeDelta::FromMilliseconds(1), \ - base::TimeDelta::FromHours(1), 50); \ - counter.SetFlags(kUmaTargetedHistogramFlag); \ - counter.AddTime(sample); \ +#define UMA_HISTOGRAM_LONG_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ + name, sample, base::TimeDelta::FromMilliseconds(1), \ + base::TimeDelta::FromHours(1), 50) + +#define UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) do { \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ + base::Histogram::kUmaTargetedHistogramFlag); \ + DCHECK_EQ(name, counter->histogram_name()); \ + counter->AddTime(sample); \ } while (0) +// DO NOT USE THIS. It is being phased out, in favor of HISTOGRAM_CUSTOM_TIMES. #define UMA_HISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) do { \ - static Histogram counter((name), min, max, bucket_count); \ - counter.SetFlags(kUmaTargetedHistogramFlag); \ - if ((sample) < (max)) counter.AddTime(sample); \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ + base::Histogram::kUmaTargetedHistogramFlag); \ + DCHECK_EQ(name, counter->histogram_name()); \ + if ((sample) < (max)) counter->AddTime(sample); \ } while (0) -#define UMA_HISTOGRAM_COUNTS(name, sample) do { \ - static Histogram counter((name), 1, 1000000, 50); \ - counter.SetFlags(kUmaTargetedHistogramFlag); \ - counter.Add(sample); \ +#define UMA_HISTOGRAM_COUNTS(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ + name, sample, 1, 1000000, 50) + +#define UMA_HISTOGRAM_COUNTS_100(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ + name, sample, 1, 100, 50) + +#define UMA_HISTOGRAM_COUNTS_10000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ + name, sample, 1, 10000, 50) + +#define UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) do { \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::Histogram::FactoryGet(name, min, max, bucket_count, \ + base::Histogram::kUmaTargetedHistogramFlag); \ + DCHECK_EQ(name, counter->histogram_name()); \ + counter->Add(sample); \ } while (0) -#define UMA_HISTOGRAM_COUNTS_100(name, sample) do { \ - static Histogram counter((name), 1, 100, 50); \ - counter.SetFlags(kUmaTargetedHistogramFlag); \ - counter.Add(sample); \ +#define UMA_HISTOGRAM_MEMORY_KB(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ + name, sample, 1000, 500000, 50) + +#define UMA_HISTOGRAM_MEMORY_MB(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ + name, sample, 1, 1000, 50) + +#define UMA_HISTOGRAM_PERCENTAGE(name, under_one_hundred) \ + UMA_HISTOGRAM_ENUMERATION(name, under_one_hundred, 101) + +#define UMA_HISTOGRAM_BOOLEAN(name, sample) do { \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::BooleanHistogram::FactoryGet(name, \ + base::Histogram::kUmaTargetedHistogramFlag); \ + DCHECK_EQ(name, counter->histogram_name()); \ + counter->AddBoolean(sample); \ } while (0) -#define UMA_HISTOGRAM_COUNTS_10000(name, sample) do { \ - static Histogram counter((name), 1, 10000, 50); \ - counter.SetFlags(kUmaTargetedHistogramFlag); \ - counter.Add(sample); \ +#define UMA_HISTOGRAM_ENUMERATION(name, sample, boundary_value) do { \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::LinearHistogram::FactoryGet(name, 1, boundary_value, \ + boundary_value + 1, base::Histogram::kUmaTargetedHistogramFlag); \ + DCHECK_EQ(name, counter->histogram_name()); \ + counter->Add(sample); \ } while (0) -#define UMA_HISTOGRAM_MEMORY_KB(name, sample) do { \ - static Histogram counter((name), 1000, 500000, 50); \ - counter.SetFlags(kUmaTargetedHistogramFlag); \ - counter.Add(sample); \ - } while (0) - -#define UMA_HISTOGRAM_MEMORY_MB(name, sample) do { \ - static Histogram counter((name), 1, 1000, 50); \ - counter.SetFlags(kUmaTargetedHistogramFlag); \ - counter.Add(sample); \ - } while (0) - -#define UMA_HISTOGRAM_PERCENTAGE(name, under_one_hundred) do { \ - static LinearHistogram counter((name), 1, 100, 101); \ - counter.SetFlags(kUmaTargetedHistogramFlag); \ - counter.Add(under_one_hundred); \ +#define UMA_HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) do { \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::CustomHistogram::FactoryGet(name, custom_ranges, \ + base::Histogram::kUmaTargetedHistogramFlag); \ + DCHECK_EQ(name, counter->histogram_name()); \ + counter->Add(sample); \ } while (0) //------------------------------------------------------------------------------ -class Pickle; +class BooleanHistogram; +class CustomHistogram; +class Histogram; +class LinearHistogram; -class Histogram { +class BASE_API Histogram { public: typedef int Sample; // Used for samples (and ranges of samples). typedef int Count; // Used to count samples in a bucket. static const Sample kSampleType_MAX = INT_MAX; + // Initialize maximum number of buckets in histograms as 16,384. + static const size_t kBucketCount_MAX; typedef std::vector<Count> Counts; typedef std::vector<Sample> Ranges; - static const int kHexRangePrintingFlag; + // These enums are used to facilitate deserialization of renderer histograms + // into the browser. + enum ClassType { + HISTOGRAM, + LINEAR_HISTOGRAM, + BOOLEAN_HISTOGRAM, + CUSTOM_HISTOGRAM, + NOT_VALID_IN_RENDERER + }; enum BucketLayout { EXPONENTIAL, - LINEAR + LINEAR, + CUSTOM + }; + + enum Flags { + kNoFlags = 0, + kUmaTargetedHistogramFlag = 0x1, // Histogram should be UMA uploaded. + + // Indicate that the histogram was pickled to be sent across an IPC Channel. + // If we observe this flag on a histogram being aggregated into after IPC, + // then we are running in a single process mode, and the aggregation should + // not take place (as we would be aggregating back into the source + // histogram!). + kIPCSerializationSourceFlag = 0x10, + + kHexRangePrintingFlag = 0x8000, // Fancy bucket-naming supported. + }; + + enum Inconsistencies { + NO_INCONSISTENCIES = 0x0, + RANGE_CHECKSUM_ERROR = 0x1, + BUCKET_ORDER_ERROR = 0x2, + COUNT_HIGH_ERROR = 0x4, + COUNT_LOW_ERROR = 0x8, + + NEVER_EXCEEDED_VALUE = 0x10 + }; + + struct DescriptionPair { + Sample sample; + const char* description; // Null means end of a list of pairs. }; //---------------------------------------------------------------------------- // Statistic values, developed over the life of the histogram. - class SampleSet { + class BASE_API SampleSet { public: explicit SampleSet(); + ~SampleSet(); + // Adjust size of counts_ for use with given histogram. void Resize(const Histogram& histogram); void CheckSize(const Histogram& histogram) const; @@ -236,7 +339,7 @@ class Histogram { Count counts(size_t i) const { return counts_[i]; } Count TotalCount() const; int64 sum() const { return sum_; } - int64 square_sum() const { return square_sum_; } + int64 redundant_count() const { return redundant_count_; } // Arithmetic manipulation of corresponding elements of the set. void Add(const SampleSet& other); @@ -253,24 +356,50 @@ class Histogram { // Save simple stats locally. Note that this MIGHT get done in base class // without shared memory at some point. int64 sum_; // sum of samples. - int64 square_sum_; // sum of squares of samples. - }; - //---------------------------------------------------------------------------- - Histogram(const char* name, Sample minimum, - Sample maximum, size_t bucket_count); - Histogram(const char* name, base::TimeDelta minimum, - base::TimeDelta maximum, size_t bucket_count); - virtual ~Histogram(); + private: + // Allow tests to corrupt our innards for testing purposes. + FRIEND_TEST(HistogramTest, CorruptSampleCounts); + + // To help identify memory corruption, we reduntantly save the number of + // samples we've accumulated into all of our buckets. We can compare this + // count to the sum of the counts in all buckets, and detect problems. Note + // that due to races in histogram accumulation (if a histogram is indeed + // updated on several threads simultaneously), the tallies might mismatch, + // and also the snapshotting code may asynchronously get a mismatch (though + // generally either race based mismatch cause is VERY rare). + int64 redundant_count_; + }; + + //---------------------------------------------------------------------------- + // minimum should start from 1. 0 is invalid as a minimum. 0 is an implicit + // default underflow bucket. + static Histogram* FactoryGet(const std::string& name, + Sample minimum, + Sample maximum, + size_t bucket_count, + Flags flags); + static Histogram* FactoryTimeGet(const std::string& name, + base::TimeDelta minimum, + base::TimeDelta maximum, + size_t bucket_count, + Flags flags); void Add(int value); + + // This method is an interface, used only by BooleanHistogram. + virtual void AddBoolean(bool value); + // Accept a TimeDelta to increment. - void AddTime(base::TimeDelta time) { + void AddTime(TimeDelta time) { Add(static_cast<int>(time.InMilliseconds())); } void AddSampleSet(const SampleSet& sample); + // This method is an interface, used only by LinearHistogram. + virtual void SetRangeDescriptions(const DescriptionPair descriptions[]); + // The following methods provide graphical histogram displays. void WriteHTMLGraph(std::string* output) const; void WriteAscii(bool graph_it, const std::string& newline, @@ -279,12 +408,10 @@ class Histogram { // Support generic flagging of Histograms. // 0x1 Currently used to mark this histogram to be recorded by UMA.. // 0x8000 means print ranges in hex. - void SetFlags(int flags) { flags_ |= flags; } - void ClearFlags(int flags) { flags_ &= ~flags; } + void SetFlags(Flags flags) { flags_ = static_cast<Flags> (flags_ | flags); } + void ClearFlags(Flags flags) { flags_ = static_cast<Flags>(flags_ & ~flags); } int flags() const { return flags_; } - virtual BucketLayout histogram_type() const { return EXPONENTIAL; } - // Convenience methods for serializing/deserializing the histograms. // Histograms from Renderer process are serialized and sent to the browser. // Browser process reconstructs the histogram from the pickled version @@ -298,37 +425,63 @@ class Histogram { // The following method accepts a list of pickled histograms and // builds a histogram and updates shadow copy of histogram data in the // browser process. - static void DeserializeHistogramList( - const std::vector<std::string>& histograms); - static bool DeserializeHistogramInfo(const std::string& state); + static bool DeserializeHistogramInfo(const std::string& histogram_info); + // Check to see if bucket ranges, counts and tallies in the snapshot are + // consistent with the bucket ranges and checksums in our histogram. This can + // produce a false-alarm if a race occurred in the reading of the data during + // a SnapShot process, but should otherwise be false at all times (unless we + // have memory over-writes, or DRAM failures). + virtual Inconsistencies FindCorruption(const SampleSet& snapshot) const; //---------------------------------------------------------------------------- - // Accessors for serialization and testing. + // Accessors for factory constuction, serialization and testing. //---------------------------------------------------------------------------- - const std::string histogram_name() const { return histogram_name_; } + virtual ClassType histogram_type() const; + const std::string& histogram_name() const { return histogram_name_; } Sample declared_min() const { return declared_min_; } Sample declared_max() const { return declared_max_; } - virtual Sample ranges(size_t i) const { return ranges_[i];} - virtual size_t bucket_count() const { return bucket_count_; } + virtual Sample ranges(size_t i) const; + uint32 range_checksum() const { return range_checksum_; } + virtual size_t bucket_count() const; // Snapshot the current complete set of sample data. // Override with atomic/locked snapshot if needed. virtual void SnapshotSample(SampleSet* sample) const; + virtual bool HasConstructorArguments(Sample minimum, Sample maximum, + size_t bucket_count); + + virtual bool HasConstructorTimeDeltaArguments(TimeDelta minimum, + TimeDelta maximum, + size_t bucket_count); + // Return true iff the range_checksum_ matches current ranges_ vector. + bool HasValidRangeChecksum() const; + protected: + Histogram(const std::string& name, Sample minimum, + Sample maximum, size_t bucket_count); + Histogram(const std::string& name, TimeDelta minimum, + TimeDelta maximum, size_t bucket_count); + + virtual ~Histogram(); + + // Initialize ranges_ mapping. + void InitializeBucketRange(); + // Method to override to skip the display of the i'th bucket if it's empty. - virtual bool PrintEmptyBucket(size_t index) const { return true; } + virtual bool PrintEmptyBucket(size_t index) const; //---------------------------------------------------------------------------- // Methods to override to create histogram with different bucket widths. //---------------------------------------------------------------------------- - // Initialize ranges_ mapping. - virtual void InitializeBucketRange(); // Find bucket to increment for sample value. virtual size_t BucketIndex(Sample value) const; // Get normalized size, relative to the ranges_[i]. virtual double GetBucketSize(Count current, size_t i) const; + // Recalculate range_checksum_. + void ResetRangeChecksum(); + // Return a string description of what goes in a given bucket. // Most commonly this is the numeric value, but in derived classes it may // be a name (or string description) given to the bucket. @@ -349,10 +502,23 @@ class Histogram { // values relate properly to the declared_min_ and declared_max_).. bool ValidateBucketRanges() const; + virtual uint32 CalculateRangeChecksum() const; + private: + // Allow tests to corrupt our innards for testing purposes. + FRIEND_TEST(HistogramTest, CorruptBucketBounds); + FRIEND_TEST(HistogramTest, CorruptSampleCounts); + FRIEND_TEST(HistogramTest, Crc32SampleHash); + FRIEND_TEST(HistogramTest, Crc32TableTest); + + friend class StatisticsRecorder; // To allow it to delete duplicates. + // Post constructor initialization. void Initialize(); + // Checksum function for accumulating range values into a checksum. + static uint32 Crc32(uint32 sum, Sample range); + //---------------------------------------------------------------------------- // Helpers for emitting Ascii graphic. Each method appends data to output. @@ -378,21 +544,21 @@ class Histogram { void WriteAsciiBucketGraph(double current_size, double max_size, std::string* output) const; + //---------------------------------------------------------------------------- + // Table for generating Crc32 values. + static const uint32 kCrcTable[256]; //---------------------------------------------------------------------------- // Invariant values set at/near construction time // ASCII version of original name given to the constructor. All identically - // named instances will be coalesced cross-project TODO(jar). - // If a user needs one histogram name to be called by several places in a - // single process, a central function should be defined by teh user, which - // defins the single declared instance of the named histogram. + // named instances will be coalesced cross-project. const std::string histogram_name_; Sample declared_min_; // Less than this goes into counts_[0] Sample declared_max_; // Over this goes into counts_[bucket_count_ - 1]. size_t bucket_count_; // Dimension of counts_[]. // Flag the histogram for recording by UMA via metric_services.h. - int flags_; + Flags flags_; // For each index, show the least value that can be stored in the // corresponding bucket. We also append one extra element in this array, @@ -400,13 +566,15 @@ class Histogram { // The dimension of ranges_ is bucket_count + 1. Ranges ranges_; + // For redundancy, we store a checksum of all the sample ranges when ranges + // are generated. If ever there is ever a difference, then the histogram must + // have been corrupted. + uint32 range_checksum_; + // Finally, provide the state that changes with the addition of each new // sample. SampleSet sample_; - // Indicate if successfully registered. - bool registered_; - DISALLOW_COPY_AND_ASSIGN(Histogram); }; @@ -414,30 +582,39 @@ class Histogram { // LinearHistogram is a more traditional histogram, with evenly spaced // buckets. -class LinearHistogram : public Histogram { +class BASE_API LinearHistogram : public Histogram { public: - struct DescriptionPair { - Sample sample; - const char* description; // Null means end of a list of pairs. - }; - LinearHistogram(const char* name, Sample minimum, - Sample maximum, size_t bucket_count); + virtual ~LinearHistogram(); - LinearHistogram(const char* name, base::TimeDelta minimum, - base::TimeDelta maximum, size_t bucket_count); - ~LinearHistogram() {} + /* minimum should start from 1. 0 is as minimum is invalid. 0 is an implicit + default underflow bucket. */ + static Histogram* FactoryGet(const std::string& name, + Sample minimum, + Sample maximum, + size_t bucket_count, + Flags flags); + static Histogram* FactoryTimeGet(const std::string& name, + TimeDelta minimum, + TimeDelta maximum, + size_t bucket_count, + Flags flags); + + // Overridden from Histogram: + virtual ClassType histogram_type() const; // Store a list of number/text values for use in rendering the histogram. // The last element in the array has a null in its "description" slot. - void SetRangeDescriptions(const DescriptionPair descriptions[]); - - virtual BucketLayout histogram_type() const { return LINEAR; } + virtual void SetRangeDescriptions(const DescriptionPair descriptions[]); protected: + LinearHistogram(const std::string& name, Sample minimum, + Sample maximum, size_t bucket_count); + + LinearHistogram(const std::string& name, TimeDelta minimum, + TimeDelta maximum, size_t bucket_count); + // Initialize ranges_ mapping. - virtual void InitializeBucketRange(); - // Find bucket to increment for sample value. - virtual size_t BucketIndex(Sample value) const; + void InitializeBucketRange(); virtual double GetBucketSize(Count current, size_t i) const; // If we have a description for a bucket, then return that. Otherwise @@ -461,40 +638,42 @@ class LinearHistogram : public Histogram { //------------------------------------------------------------------------------ // BooleanHistogram is a histogram for booleans. -class BooleanHistogram : public LinearHistogram { +class BASE_API BooleanHistogram : public LinearHistogram { public: - explicit BooleanHistogram(const char* name) - : LinearHistogram(name, 0, 2, 3) { - } + static Histogram* FactoryGet(const std::string& name, Flags flags); - void AddBoolean(bool value) { Add(value ? 1 : 0); } + virtual ClassType histogram_type() const; + + virtual void AddBoolean(bool value); private: + explicit BooleanHistogram(const std::string& name); + DISALLOW_COPY_AND_ASSIGN(BooleanHistogram); }; -//------------------------------------------------------------------------------ -// This section provides implementation for ThreadSafeHistogram. //------------------------------------------------------------------------------ -class ThreadSafeHistogram : public Histogram { +// CustomHistogram is a histogram for a set of custom integers. +class BASE_API CustomHistogram : public Histogram { public: - ThreadSafeHistogram(const char* name, Sample minimum, - Sample maximum, size_t bucket_count); - // Provide the analog to Add() - void Remove(int value); + static Histogram* FactoryGet(const std::string& name, + const std::vector<Sample>& custom_ranges, + Flags flags); + + // Overridden from Histogram: + virtual ClassType histogram_type() const; protected: - // Provide locked versions to get precise counts. - virtual void Accumulate(Sample value, Count count, size_t index); + CustomHistogram(const std::string& name, + const std::vector<Sample>& custom_ranges); - virtual void SnapshotSample(SampleSet* sample) const; + // Initialize ranges_ mapping. + void InitializedCustomBucketRange(const std::vector<Sample>& custom_ranges); + virtual double GetBucketSize(Count current, size_t i) const; - private: - mutable Lock lock_; - - DISALLOW_COPY_AND_ASSIGN(ThreadSafeHistogram); + DISALLOW_COPY_AND_ASSIGN(CustomHistogram); }; //------------------------------------------------------------------------------ @@ -502,7 +681,7 @@ class ThreadSafeHistogram : public Histogram { // general place for histograms to register, and supports a global API for // accessing (i.e., dumping, or graphing) the data in all the histograms. -class StatisticsRecorder { +class BASE_API StatisticsRecorder { public: typedef std::vector<Histogram*> Histograms; @@ -511,13 +690,13 @@ class StatisticsRecorder { ~StatisticsRecorder(); // Find out if histograms can now be registered into our list. - static bool WasStarted(); + static bool IsActive(); - // Register, or add a new histogram to the collection of statistics. - // Return true if registered. - static bool Register(Histogram* histogram); - // Unregister, or remove, a histogram from the collection of statistics. - static void UnRegister(Histogram* histogram); + // Register, or add a new histogram to the collection of statistics. If an + // identically named histogram is already registered, then the argument + // |histogram| will deleted. The returned value is always the registered + // histogram (either the argument, or the pre-existing registered histogram). + static Histogram* RegisterOrDeleteDuplicate(Histogram* histogram); // Methods for printing histograms. Only histograms which have query as // a substring are written to output (an empty string will process all @@ -528,8 +707,12 @@ class StatisticsRecorder { // Method for extracting histograms which were marked for use by UMA. static void GetHistograms(Histograms* output); - // Find a histogram by name. This method is thread safe. - static Histogram* GetHistogram(const std::string& query); + // Find a histogram by name. It matches the exact name. This method is thread + // safe. If a matching histogram is not found, then the |histogram| is + // not changed. + static bool FindHistogram(const std::string& query, Histogram** histogram); + + static bool dump_on_exit() { return dump_on_exit_; } static void set_dump_on_exit(bool enable) { dump_on_exit_ = enable; } @@ -555,4 +738,6 @@ class StatisticsRecorder { DISALLOW_COPY_AND_ASSIGN(StatisticsRecorder); }; -#endif // BASE_HISTOGRAM_H_ +} // namespace base + +#endif // BASE_METRICS_HISTOGRAM_H_ diff --git a/ipc/chromium/src/base/histogram_unittest.cc b/ipc/chromium/src/base/histogram_unittest.cc index 3f2ed4c2dc4c..496ff63d92d1 100644 --- a/ipc/chromium/src/base/histogram_unittest.cc +++ b/ipc/chromium/src/base/histogram_unittest.cc @@ -1,16 +1,15 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Test of Histogram class -#include "base/histogram.h" -#include "base/string_util.h" +#include "base/metrics/histogram.h" +#include "base/scoped_ptr.h" #include "base/time.h" #include "testing/gtest/include/gtest/gtest.h" -using base::TimeDelta; - +namespace base { namespace { class HistogramTest : public testing::Test { @@ -19,11 +18,35 @@ class HistogramTest : public testing::Test { // Check for basic syntax and use. TEST(HistogramTest, StartupShutdownTest) { // Try basic construction - Histogram histogram("TestHistogram", 1, 1000, 10); - Histogram histogram1("Test1Histogram", 1, 1000, 10); + Histogram* histogram(Histogram::FactoryGet( + "TestHistogram", 1, 1000, 10, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), histogram); + Histogram* histogram1(Histogram::FactoryGet( + "Test1Histogram", 1, 1000, 10, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), histogram1); + EXPECT_NE(histogram, histogram1); - LinearHistogram linear_histogram("TestLinearHistogram", 1, 1000, 10); - LinearHistogram linear_histogram1("Test1LinearHistogram", 1, 1000, 10); + + Histogram* linear_histogram(LinearHistogram::FactoryGet( + "TestLinearHistogram", 1, 1000, 10, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), linear_histogram); + Histogram* linear_histogram1(LinearHistogram::FactoryGet( + "Test1LinearHistogram", 1, 1000, 10, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), linear_histogram1); + EXPECT_NE(linear_histogram, linear_histogram1); + + std::vector<int> custom_ranges; + custom_ranges.push_back(1); + custom_ranges.push_back(5); + custom_ranges.push_back(10); + custom_ranges.push_back(20); + custom_ranges.push_back(30); + Histogram* custom_histogram(CustomHistogram::FactoryGet( + "TestCustomHistogram", custom_ranges, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), custom_histogram); + Histogram* custom_histogram1(CustomHistogram::FactoryGet( + "Test1CustomHistogram", custom_ranges, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), custom_histogram1); // Use standard macros (but with fixed samples) HISTOGRAM_TIMES("Test2Histogram", TimeDelta::FromDays(1)); @@ -32,7 +55,7 @@ TEST(HistogramTest, StartupShutdownTest) { DHISTOGRAM_TIMES("Test4Histogram", TimeDelta::FromDays(1)); DHISTOGRAM_COUNTS("Test5Histogram", 30); - ASSET_HISTOGRAM_COUNTS("Test6Histogram", 129); + HISTOGRAM_ENUMERATION("Test6Histogram", 129, 130); // Try to construct samples. Histogram::SampleSet sample1; @@ -57,41 +80,70 @@ TEST(HistogramTest, RecordedStartupTest) { EXPECT_EQ(0U, histograms.size()); // Try basic construction - Histogram histogram("TestHistogram", 1, 1000, 10); + Histogram* histogram(Histogram::FactoryGet( + "TestHistogram", 1, 1000, 10, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), histogram); histograms.clear(); StatisticsRecorder::GetHistograms(&histograms); // Load up lists EXPECT_EQ(1U, histograms.size()); - Histogram histogram1("Test1Histogram", 1, 1000, 10); + Histogram* histogram1(Histogram::FactoryGet( + "Test1Histogram", 1, 1000, 10, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), histogram1); histograms.clear(); StatisticsRecorder::GetHistograms(&histograms); // Load up lists EXPECT_EQ(2U, histograms.size()); - LinearHistogram linear_histogram("TestLinearHistogram", 1, 1000, 10); - LinearHistogram linear_histogram1("Test1LinearHistogram", 1, 1000, 10); + Histogram* linear_histogram(LinearHistogram::FactoryGet( + "TestLinearHistogram", 1, 1000, 10, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), linear_histogram); + histograms.clear(); + StatisticsRecorder::GetHistograms(&histograms); // Load up lists + EXPECT_EQ(3U, histograms.size()); + + Histogram* linear_histogram1(LinearHistogram::FactoryGet( + "Test1LinearHistogram", 1, 1000, 10, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), linear_histogram1); histograms.clear(); StatisticsRecorder::GetHistograms(&histograms); // Load up lists EXPECT_EQ(4U, histograms.size()); + std::vector<int> custom_ranges; + custom_ranges.push_back(1); + custom_ranges.push_back(5); + custom_ranges.push_back(10); + custom_ranges.push_back(20); + custom_ranges.push_back(30); + Histogram* custom_histogram(CustomHistogram::FactoryGet( + "TestCustomHistogram", custom_ranges, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), custom_histogram); + Histogram* custom_histogram1(CustomHistogram::FactoryGet( + "TestCustomHistogram", custom_ranges, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), custom_histogram1); + + histograms.clear(); + StatisticsRecorder::GetHistograms(&histograms); // Load up lists + EXPECT_EQ(5U, histograms.size()); + // Use standard macros (but with fixed samples) HISTOGRAM_TIMES("Test2Histogram", TimeDelta::FromDays(1)); HISTOGRAM_COUNTS("Test3Histogram", 30); histograms.clear(); StatisticsRecorder::GetHistograms(&histograms); // Load up lists - EXPECT_EQ(6U, histograms.size()); + EXPECT_EQ(7U, histograms.size()); - ASSET_HISTOGRAM_COUNTS("TestAssetHistogram", 1000); + HISTOGRAM_ENUMERATION("TestEnumerationHistogram", 20, 200); histograms.clear(); StatisticsRecorder::GetHistograms(&histograms); // Load up lists - EXPECT_EQ(7U, histograms.size()); + EXPECT_EQ(8U, histograms.size()); DHISTOGRAM_TIMES("Test4Histogram", TimeDelta::FromDays(1)); DHISTOGRAM_COUNTS("Test5Histogram", 30); histograms.clear(); StatisticsRecorder::GetHistograms(&histograms); // Load up lists #ifndef NDEBUG - EXPECT_EQ(9U, histograms.size()); + EXPECT_EQ(10U, histograms.size()); #else - EXPECT_EQ(7U, histograms.size()); + EXPECT_EQ(8U, histograms.size()); #endif } @@ -102,78 +154,137 @@ TEST(HistogramTest, RangeTest) { recorder.GetHistograms(&histograms); EXPECT_EQ(0U, histograms.size()); - Histogram histogram("Histogram", 1, 64, 8); // As mentioned in header file. + Histogram* histogram(Histogram::FactoryGet( + "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file. // Check that we got a nice exponential when there was enough rooom. - EXPECT_EQ(0, histogram.ranges(0)); + EXPECT_EQ(0, histogram->ranges(0)); int power_of_2 = 1; for (int i = 1; i < 8; i++) { - EXPECT_EQ(power_of_2, histogram.ranges(i)); + EXPECT_EQ(power_of_2, histogram->ranges(i)); power_of_2 *= 2; } - EXPECT_EQ(INT_MAX, histogram.ranges(8)); + EXPECT_EQ(INT_MAX, histogram->ranges(8)); - Histogram short_histogram("Histogram Shortened", 1, 7, 8); + Histogram* short_histogram(Histogram::FactoryGet( + "Histogram Shortened", 1, 7, 8, Histogram::kNoFlags)); // Check that when the number of buckets is short, we get a linear histogram // for lack of space to do otherwise. for (int i = 0; i < 8; i++) - EXPECT_EQ(i, short_histogram.ranges(i)); - EXPECT_EQ(INT_MAX, short_histogram.ranges(8)); + EXPECT_EQ(i, short_histogram->ranges(i)); + EXPECT_EQ(INT_MAX, short_histogram->ranges(8)); - LinearHistogram linear_histogram("Linear", 1, 7, 8); + Histogram* linear_histogram(LinearHistogram::FactoryGet( + "Linear", 1, 7, 8, Histogram::kNoFlags)); // We also get a nice linear set of bucket ranges when we ask for it for (int i = 0; i < 8; i++) - EXPECT_EQ(i, linear_histogram.ranges(i)); - EXPECT_EQ(INT_MAX, linear_histogram.ranges(8)); + EXPECT_EQ(i, linear_histogram->ranges(i)); + EXPECT_EQ(INT_MAX, linear_histogram->ranges(8)); - LinearHistogram linear_broad_histogram("Linear widened", 2, 14, 8); + Histogram* linear_broad_histogram(LinearHistogram::FactoryGet( + "Linear widened", 2, 14, 8, Histogram::kNoFlags)); // ...but when the list has more space, then the ranges naturally spread out. for (int i = 0; i < 8; i++) - EXPECT_EQ(2 * i, linear_broad_histogram.ranges(i)); - EXPECT_EQ(INT_MAX, linear_broad_histogram.ranges(8)); + EXPECT_EQ(2 * i, linear_broad_histogram->ranges(i)); + EXPECT_EQ(INT_MAX, linear_broad_histogram->ranges(8)); - ThreadSafeHistogram threadsafe_histogram("ThreadSafe", 1, 32, 15); + Histogram* transitioning_histogram(Histogram::FactoryGet( + "LinearAndExponential", 1, 32, 15, Histogram::kNoFlags)); // When space is a little tight, we transition from linear to exponential. - // This is what happens in both the basic histogram, and the threadsafe - // variant (which is derived). - EXPECT_EQ(0, threadsafe_histogram.ranges(0)); - EXPECT_EQ(1, threadsafe_histogram.ranges(1)); - EXPECT_EQ(2, threadsafe_histogram.ranges(2)); - EXPECT_EQ(3, threadsafe_histogram.ranges(3)); - EXPECT_EQ(4, threadsafe_histogram.ranges(4)); - EXPECT_EQ(5, threadsafe_histogram.ranges(5)); - EXPECT_EQ(6, threadsafe_histogram.ranges(6)); - EXPECT_EQ(7, threadsafe_histogram.ranges(7)); - EXPECT_EQ(9, threadsafe_histogram.ranges(8)); - EXPECT_EQ(11, threadsafe_histogram.ranges(9)); - EXPECT_EQ(14, threadsafe_histogram.ranges(10)); - EXPECT_EQ(17, threadsafe_histogram.ranges(11)); - EXPECT_EQ(21, threadsafe_histogram.ranges(12)); - EXPECT_EQ(26, threadsafe_histogram.ranges(13)); - EXPECT_EQ(32, threadsafe_histogram.ranges(14)); - EXPECT_EQ(INT_MAX, threadsafe_histogram.ranges(15)); + EXPECT_EQ(0, transitioning_histogram->ranges(0)); + EXPECT_EQ(1, transitioning_histogram->ranges(1)); + EXPECT_EQ(2, transitioning_histogram->ranges(2)); + EXPECT_EQ(3, transitioning_histogram->ranges(3)); + EXPECT_EQ(4, transitioning_histogram->ranges(4)); + EXPECT_EQ(5, transitioning_histogram->ranges(5)); + EXPECT_EQ(6, transitioning_histogram->ranges(6)); + EXPECT_EQ(7, transitioning_histogram->ranges(7)); + EXPECT_EQ(9, transitioning_histogram->ranges(8)); + EXPECT_EQ(11, transitioning_histogram->ranges(9)); + EXPECT_EQ(14, transitioning_histogram->ranges(10)); + EXPECT_EQ(17, transitioning_histogram->ranges(11)); + EXPECT_EQ(21, transitioning_histogram->ranges(12)); + EXPECT_EQ(26, transitioning_histogram->ranges(13)); + EXPECT_EQ(32, transitioning_histogram->ranges(14)); + EXPECT_EQ(INT_MAX, transitioning_histogram->ranges(15)); + + std::vector<int> custom_ranges; + custom_ranges.push_back(0); + custom_ranges.push_back(9); + custom_ranges.push_back(10); + custom_ranges.push_back(11); + custom_ranges.push_back(300); + Histogram* test_custom_histogram(CustomHistogram::FactoryGet( + "TestCustomRangeHistogram", custom_ranges, Histogram::kNoFlags)); + + EXPECT_EQ(custom_ranges[0], test_custom_histogram->ranges(0)); + EXPECT_EQ(custom_ranges[1], test_custom_histogram->ranges(1)); + EXPECT_EQ(custom_ranges[2], test_custom_histogram->ranges(2)); + EXPECT_EQ(custom_ranges[3], test_custom_histogram->ranges(3)); + EXPECT_EQ(custom_ranges[4], test_custom_histogram->ranges(4)); recorder.GetHistograms(&histograms); - EXPECT_EQ(5U, histograms.size()); + EXPECT_EQ(6U, histograms.size()); } +TEST(HistogramTest, CustomRangeTest) { + StatisticsRecorder recorder; + StatisticsRecorder::Histograms histograms; + + // Check that missing leading zero is handled by an auto-insertion. + std::vector<int> custom_ranges; + // Don't include a zero. + custom_ranges.push_back(9); + custom_ranges.push_back(10); + custom_ranges.push_back(11); + Histogram* test_custom_histogram(CustomHistogram::FactoryGet( + "TestCustomRangeHistogram", custom_ranges, Histogram::kNoFlags)); + + EXPECT_EQ(0, test_custom_histogram->ranges(0)); // Auto added + EXPECT_EQ(custom_ranges[0], test_custom_histogram->ranges(1)); + EXPECT_EQ(custom_ranges[1], test_custom_histogram->ranges(2)); + EXPECT_EQ(custom_ranges[2], test_custom_histogram->ranges(3)); + + // Check that unsorted data with dups is handled gracefully. + const int kSmall = 7; + const int kMid = 8; + const int kBig = 9; + custom_ranges.clear(); + custom_ranges.push_back(kBig); + custom_ranges.push_back(kMid); + custom_ranges.push_back(kSmall); + custom_ranges.push_back(kSmall); + custom_ranges.push_back(kMid); + custom_ranges.push_back(0); // Push an explicit zero. + custom_ranges.push_back(kBig); + + Histogram* unsorted_histogram(CustomHistogram::FactoryGet( + "TestCustomUnsortedDupedHistogram", custom_ranges, Histogram::kNoFlags)); + EXPECT_EQ(0, unsorted_histogram->ranges(0)); + EXPECT_EQ(kSmall, unsorted_histogram->ranges(1)); + EXPECT_EQ(kMid, unsorted_histogram->ranges(2)); + EXPECT_EQ(kBig, unsorted_histogram->ranges(3)); +} + + // Make sure histogram handles out-of-bounds data gracefully. TEST(HistogramTest, BoundsTest) { const size_t kBucketCount = 50; - Histogram histogram("Bounded", 10, 100, kBucketCount); + Histogram* histogram(Histogram::FactoryGet( + "Bounded", 10, 100, kBucketCount, Histogram::kNoFlags)); // Put two samples "out of bounds" above and below. - histogram.Add(5); - histogram.Add(-50); + histogram->Add(5); + histogram->Add(-50); - histogram.Add(100); - histogram.Add(10000); + histogram->Add(100); + histogram->Add(10000); // Verify they landed in the underflow, and overflow buckets. Histogram::SampleSet sample; - histogram.SnapshotSample(&sample); + histogram->SnapshotSample(&sample); EXPECT_EQ(2, sample.counts(0)); EXPECT_EQ(0, sample.counts(1)); - size_t array_size = histogram.bucket_count(); + size_t array_size = histogram->bucket_count(); EXPECT_EQ(kBucketCount, array_size); EXPECT_EQ(0, sample.counts(array_size - 2)); EXPECT_EQ(2, sample.counts(array_size - 1)); @@ -181,113 +292,111 @@ TEST(HistogramTest, BoundsTest) { // Check to be sure samples land as expected is "correct" buckets. TEST(HistogramTest, BucketPlacementTest) { - Histogram histogram("Histogram", 1, 64, 8); // As mentioned in header file. + Histogram* histogram(Histogram::FactoryGet( + "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file. // Check that we got a nice exponential since there was enough rooom. - EXPECT_EQ(0, histogram.ranges(0)); + EXPECT_EQ(0, histogram->ranges(0)); int power_of_2 = 1; for (int i = 1; i < 8; i++) { - EXPECT_EQ(power_of_2, histogram.ranges(i)); + EXPECT_EQ(power_of_2, histogram->ranges(i)); power_of_2 *= 2; } - EXPECT_EQ(INT_MAX, histogram.ranges(8)); + EXPECT_EQ(INT_MAX, histogram->ranges(8)); // Add i+1 samples to the i'th bucket. - histogram.Add(0); + histogram->Add(0); power_of_2 = 1; for (int i = 1; i < 8; i++) { for (int j = 0; j <= i; j++) - histogram.Add(power_of_2); + histogram->Add(power_of_2); power_of_2 *= 2; } // Leave overflow bucket empty. // Check to see that the bucket counts reflect our additions. Histogram::SampleSet sample; - histogram.SnapshotSample(&sample); - EXPECT_EQ(INT_MAX, histogram.ranges(8)); + histogram->SnapshotSample(&sample); + EXPECT_EQ(INT_MAX, histogram->ranges(8)); for (int i = 0; i < 8; i++) EXPECT_EQ(i + 1, sample.counts(i)); } -static const char kAssetTestHistogramName[] = "AssetCountTest"; -static const char kAssetTestDebugHistogramName[] = "DAssetCountTest"; -void AssetCountFunction(int sample) { - ASSET_HISTOGRAM_COUNTS(kAssetTestHistogramName, sample); - DASSET_HISTOGRAM_COUNTS(kAssetTestDebugHistogramName, sample); -} -// Check that asset can be added and removed from buckets. -TEST(HistogramTest, AssetCountTest) { - // Start up a recorder system to identify all histograms. - StatisticsRecorder recorder; - - // Call through the macro to instantiate the static variables. - AssetCountFunction(100); // Put a sample in the bucket for 100. - - // Find the histogram. - StatisticsRecorder::Histograms histogram_list; - StatisticsRecorder::GetHistograms(&histogram_list); - ASSERT_NE(0U, histogram_list.size()); - const Histogram* our_histogram = NULL; - const Histogram* our_debug_histogram = NULL; - for (StatisticsRecorder::Histograms::iterator it = histogram_list.begin(); - it != histogram_list.end(); - ++it) { - if (!(*it)->histogram_name().compare(kAssetTestHistogramName)) - our_histogram = *it; - else if (!(*it)->histogram_name().compare(kAssetTestDebugHistogramName)) { - our_debug_histogram = *it; - } - } - ASSERT_TRUE(our_histogram); -#ifndef NDEBUG - EXPECT_TRUE(our_debug_histogram); -#else - EXPECT_FALSE(our_debug_histogram); -#endif - // Verify it has a 1 in exactly one bucket (where we put the sample). - Histogram::SampleSet sample; - our_histogram->SnapshotSample(&sample); - int match_count = 0; - for (size_t i = 0; i < our_histogram->bucket_count(); ++i) { - if (sample.counts(i) > 0) { - EXPECT_LT(++match_count, 2) << "extra count in bucket " << i; - } - } - EXPECT_EQ(1, match_count); - - // Remove our sample. - AssetCountFunction(-100); // Remove a sample from the bucket for 100. - our_histogram->SnapshotSample(&sample); // Extract data set. - - // Verify that the bucket is now empty, as are all the other buckets. - for (size_t i = 0; i < our_histogram->bucket_count(); ++i) { - EXPECT_EQ(0, sample.counts(i)) << "extra count in bucket " << i; - } - - if (!our_debug_histogram) - return; // This is a production build. - - // Repeat test with debug histogram. Note that insertion and deletion above - // should have cancelled each other out. - AssetCountFunction(100); // Add a sample into the bucket for 100. - our_debug_histogram->SnapshotSample(&sample); - match_count = 0; - for (size_t i = 0; i < our_debug_histogram->bucket_count(); ++i) { - if (sample.counts(i) > 0) { - EXPECT_LT(++match_count, 2) << "extra count in bucket " << i; - } - } - EXPECT_EQ(1, match_count); - - // Remove our sample. - AssetCountFunction(-100); // Remove a sample from the bucket for 100. - our_debug_histogram->SnapshotSample(&sample); // Extract data set. - - // Verify that the bucket is now empty, as are all the other buckets. - for (size_t i = 0; i < our_debug_histogram->bucket_count(); ++i) { - EXPECT_EQ(0, sample.counts(i)) << "extra count in bucket " << i; - } -} - } // namespace + +//------------------------------------------------------------------------------ +// We can't be an an anonymous namespace while being friends, so we pop back +// out to the base namespace here. We need to be friends to corrupt the +// internals of the histogram and/or sampleset. +TEST(HistogramTest, CorruptSampleCounts) { + Histogram* histogram(Histogram::FactoryGet( + "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file. + + EXPECT_EQ(0, histogram->sample_.redundant_count()); + histogram->Add(20); // Add some samples. + histogram->Add(40); + EXPECT_EQ(2, histogram->sample_.redundant_count()); + + Histogram::SampleSet snapshot; + histogram->SnapshotSample(&snapshot); + EXPECT_EQ(Histogram::NO_INCONSISTENCIES, 0); + EXPECT_EQ(0, histogram->FindCorruption(snapshot)); // No default corruption. + EXPECT_EQ(2, snapshot.redundant_count()); + + snapshot.counts_[3] += 100; // Sample count won't match redundant count. + EXPECT_EQ(Histogram::COUNT_LOW_ERROR, histogram->FindCorruption(snapshot)); + snapshot.counts_[2] -= 200; + EXPECT_EQ(Histogram::COUNT_HIGH_ERROR, histogram->FindCorruption(snapshot)); + + // But we can't spot a corruption if it is compensated for. + snapshot.counts_[1] += 100; + EXPECT_EQ(0, histogram->FindCorruption(snapshot)); +} + +TEST(HistogramTest, CorruptBucketBounds) { + Histogram* histogram(Histogram::FactoryGet( + "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file. + + Histogram::SampleSet snapshot; + histogram->SnapshotSample(&snapshot); + EXPECT_EQ(Histogram::NO_INCONSISTENCIES, 0); + EXPECT_EQ(0, histogram->FindCorruption(snapshot)); // No default corruption. + + std::swap(histogram->ranges_[1], histogram->ranges_[2]); + EXPECT_EQ(Histogram::BUCKET_ORDER_ERROR | Histogram::RANGE_CHECKSUM_ERROR, + histogram->FindCorruption(snapshot)); + + std::swap(histogram->ranges_[1], histogram->ranges_[2]); + EXPECT_EQ(0, histogram->FindCorruption(snapshot)); + + ++histogram->ranges_[3]; + EXPECT_EQ(Histogram::RANGE_CHECKSUM_ERROR, + histogram->FindCorruption(snapshot)); + + // Show that two simple changes don't offset each other + --histogram->ranges_[4]; + EXPECT_EQ(Histogram::RANGE_CHECKSUM_ERROR, + histogram->FindCorruption(snapshot)); + + // Repair histogram so that destructor won't DCHECK(). + --histogram->ranges_[3]; + ++histogram->ranges_[4]; +} + +// Table was generated similarly to sample code for CRC-32 given on: +// http://www.w3.org/TR/PNG/#D-CRCAppendix. +TEST(HistogramTest, Crc32TableTest) { + for (int i = 0; i < 256; ++i) { + uint32 checksum = i; + for (int j = 0; j < 8; ++j) { + const uint32 kReversedPolynomial = 0xedb88320L; + if (checksum & 1) + checksum = kReversedPolynomial ^ (checksum >> 1); + else + checksum >>= 1; + } + EXPECT_EQ(Histogram::kCrcTable[i], checksum); + } +} + +} // namespace base diff --git a/ipc/chromium/src/base/message_loop.cc b/ipc/chromium/src/base/message_loop.cc index 6e62692ef644..96629936ac7f 100644 --- a/ipc/chromium/src/base/message_loop.cc +++ b/ipc/chromium/src/base/message_loop.cc @@ -191,9 +191,9 @@ void MessageLoop::RunHandler() { #if defined(OS_WIN) if (exception_restoration_) { LPTOP_LEVEL_EXCEPTION_FILTER current_filter = GetTopSEHFilter(); - __try { + MOZ_SEH_TRY { RunInternal(); - } __except(SEHFilter(current_filter)) { + } MOZ_SEH_EXCEPT(SEHFilter(current_filter)) { } return; } @@ -206,16 +206,15 @@ void MessageLoop::RunHandler() { void MessageLoop::RunInternal() { DCHECK(this == current()); - +#if !defined(CHROMIUM_MOZILLA_BUILD) StartHistogrammer(); - -#if defined(OS_WIN) && !defined(CHROMIUM_MOZILLA_BUILD) +#if defined(OS_WIN) if (state_->dispatcher) { pump_win()->RunWithDispatcher(this, state_->dispatcher); return; } #endif - +#endif pump_->Run(this); } @@ -535,31 +534,40 @@ bool MessageLoop::PendingTask::operator<(const PendingTask& other) const { // Method and data for histogramming events and actions taken by each instance // on each thread. +#if !defined(CHROMIUM_MOZILLA_BUILD) // static bool MessageLoop::enable_histogrammer_ = false; +#endif // static void MessageLoop::EnableHistogrammer(bool enable) { +#if !defined(CHROMIUM_MOZILLA_BUILD) enable_histogrammer_ = enable; +#endif } void MessageLoop::StartHistogrammer() { +#if !defined(CHROMIUM_MOZILLA_BUILD) if (enable_histogrammer_ && !message_histogram_.get() - && StatisticsRecorder::WasStarted()) { + && base::StatisticsRecorder::IsActive()) { DCHECK(!thread_name_.empty()); - message_histogram_.reset( - new LinearHistogram(("MsgLoop:" + thread_name_).c_str(), - kLeastNonZeroMessageId, - kMaxMessageId, - kNumberOfDistinctMessagesDisplayed)); + message_histogram_.reset(static_cast<base::LinearHistogram*>( + base::LinearHistogram::FactoryGet(("MsgLoop:" + thread_name_).c_str(), + kLeastNonZeroMessageId, + kMaxMessageId, + kNumberOfDistinctMessagesDisplayed, + base::Histogram::kNoFlags))); message_histogram_->SetFlags(message_histogram_->kHexRangePrintingFlag); message_histogram_->SetRangeDescriptions(event_descriptions_); } +#endif } void MessageLoop::HistogramEvent(int event) { +#if !defined(CHROMIUM_MOZILLA_BUILD) if (message_histogram_.get()) message_histogram_->Add(event); +#endif } // Provide a macro that takes an expression (such as a constant, or macro @@ -578,8 +586,9 @@ void MessageLoop::HistogramEvent(int event) { // in the pair (i.e., the quoted string) when printing out a histogram. #define VALUE_TO_NUMBER_AND_NAME(name) {name, #name}, +#if !defined(CHROMIUM_MOZILLA_BUILD) // static -const LinearHistogram::DescriptionPair MessageLoop::event_descriptions_[] = { +const base::LinearHistogram::DescriptionPair MessageLoop::event_descriptions_[] = { // Provide some pretty print capability in our histogram for our internal // messages. @@ -589,6 +598,7 @@ const LinearHistogram::DescriptionPair MessageLoop::event_descriptions_[] = { {-1, NULL} // The list must be null terminated, per API to histogram. }; +#endif //------------------------------------------------------------------------------ // MessageLoopForUI diff --git a/ipc/chromium/src/base/message_loop.h b/ipc/chromium/src/base/message_loop.h index 9673e9132125..186715fbef3d 100644 --- a/ipc/chromium/src/base/message_loop.h +++ b/ipc/chromium/src/base/message_loop.h @@ -10,7 +10,12 @@ #include <string> #include <vector> +#if defined(CHROMIUM_MOZILLA_BUILD) +#include <map> +#include "base/lock.h" +#else #include "base/histogram.h" +#endif #include "base/message_pump.h" #include "base/observer_list.h" #include "base/ref_counted.h" @@ -375,8 +380,10 @@ public: // If message_histogram_ is NULL, this is a no-op. void HistogramEvent(int event); - static const LinearHistogram::DescriptionPair event_descriptions_[]; +#if !defined(CHROMIUM_MOZILLA_BUILD) + static const base::LinearHistogram::DescriptionPair event_descriptions_[]; static bool enable_histogrammer_; +#endif Type type_; @@ -403,9 +410,10 @@ public: bool exception_restoration_; std::string thread_name_; +#if !defined(CHROMIUM_MOZILLA_BUILD) // A profiling histogram showing the counts of various messages and events. - scoped_ptr<LinearHistogram> message_histogram_; - + scoped_ptr<base::LinearHistogram> message_histogram_; +#endif // A null terminated list which creates an incoming_queue of tasks that are // aquired under a mutex for processing on this instance's thread. These tasks // have not yet been sorted out into items for our work_queue_ vs items that diff --git a/ipc/chromium/src/base/platform_thread_win.cc b/ipc/chromium/src/base/platform_thread_win.cc index 2dd325e9f485..627e1b150ee2 100644 --- a/ipc/chromium/src/base/platform_thread_win.cc +++ b/ipc/chromium/src/base/platform_thread_win.cc @@ -57,10 +57,10 @@ void PlatformThread::SetName(const char* name) { info.dwThreadID = CurrentId(); info.dwFlags = 0; - __try { + MOZ_SEH_TRY { RaiseException(kVCThreadNameException, 0, sizeof(info)/sizeof(DWORD), reinterpret_cast<DWORD_PTR*>(&info)); - } __except(EXCEPTION_CONTINUE_EXECUTION) { + } MOZ_SEH_EXCEPT(EXCEPTION_CONTINUE_EXECUTION) { } } diff --git a/ipc/chromium/src/base/process_util_win.cc b/ipc/chromium/src/base/process_util_win.cc index 030fbc9fe6bb..151ab0ff8cad 100644 --- a/ipc/chromium/src/base/process_util_win.cc +++ b/ipc/chromium/src/base/process_util_win.cc @@ -321,6 +321,7 @@ bool DidProcessCrash(bool* child_exited, ProcessHandle handle) { return false; } +#ifndef CHROMIUM_MOZILLA_BUILD // All other exit codes indicate crashes. // TODO(jar): Remove histogramming code when UMA stats are consistent with @@ -349,7 +350,7 @@ bool DidProcessCrash(bool* child_exited, ProcessHandle handle) { mid_significant_histogram.SetFlags(kUmaTargetedHistogramFlag | LinearHistogram::kHexRangePrintingFlag); mid_significant_histogram.Add((exitcode >> 12) & 0xFF); - +#endif return true; } diff --git a/ipc/chromium/src/base/third_party/nspr/prtime.cc b/ipc/chromium/src/base/third_party/nspr/prtime.cc index e6176aae328c..e87e08cc3920 100644 --- a/ipc/chromium/src/base/third_party/nspr/prtime.cc +++ b/ipc/chromium/src/base/third_party/nspr/prtime.cc @@ -143,7 +143,7 @@ PR_ImplodeTime(const PRExplodedTime *exploded) // Convert from Windows epoch to NSPR epoch, and 100-nanoseconds units // to microsecond units. PRTime result = - static_cast<PRTime>((uli.QuadPart / 10) - 11644473600000000i64); + static_cast<PRTime>((uli.QuadPart / 10) - GG_LONGLONG(11644473600000000)); // Adjust for time zone and dst. Convert from seconds to microseconds. result -= (exploded->tm_params.tp_gmt_offset + exploded->tm_params.tp_dst_offset) * kSecondsToMicroseconds; diff --git a/ipc/chromium/src/base/time_win.cc b/ipc/chromium/src/base/time_win.cc index fa2486882c11..2f9adcb3cd78 100644 --- a/ipc/chromium/src/base/time_win.cc +++ b/ipc/chromium/src/base/time_win.cc @@ -251,7 +251,7 @@ class NowSingleton : public base::SystemMonitor::PowerObserver { // we keep our last_seen_ stay correctly in sync. DWORD now = tick_function(); if (now < last_seen_) - rollover_ += TimeDelta::FromMilliseconds(0x100000000I64); // ~49.7 days. + rollover_ += TimeDelta::FromMilliseconds(GG_LONGLONG(0x100000000)); // ~49.7 days. last_seen_ = now; return TimeDelta::FromMilliseconds(now) + rollover_; } diff --git a/ipc/chromium/src/base/win_util.cc b/ipc/chromium/src/base/win_util.cc index e15f87a957a5..f6094ed4a50e 100644 --- a/ipc/chromium/src/base/win_util.cc +++ b/ipc/chromium/src/base/win_util.cc @@ -283,7 +283,7 @@ bool Subclass(HWND window, WNDPROC subclass_proc) { reinterpret_cast<WNDPROC>(GetWindowLongPtr(window, GWLP_WNDPROC)); if (original_handler != subclass_proc) { win_util::SetWindowProc(window, subclass_proc); - SetProp(window, kHandlerKey, original_handler); + SetProp(window, kHandlerKey, (void*)original_handler); return true; } return false; diff --git a/ipc/chromium/src/chrome/common/ipc_channel_win.cc b/ipc/chromium/src/chrome/common/ipc_channel_win.cc index fdf44584b483..0f8df0cc259e 100644 --- a/ipc/chromium/src/chrome/common/ipc_channel_win.cc +++ b/ipc/chromium/src/chrome/common/ipc_channel_win.cc @@ -65,16 +65,19 @@ void Channel::ChannelImpl::Close() { pipe_ = INVALID_HANDLE_VALUE; } +#ifndef CHROMIUM_MOZILLA_BUILD // Make sure all IO has completed. base::Time start = base::Time::Now(); +#endif while (input_state_.is_pending || output_state_.is_pending) { MessageLoopForIO::current()->WaitForIOCompletion(INFINITE, this); } +#ifndef CHROMIUM_MOZILLA_BUILD if (waited) { // We want to see if we block the message loop for too long. UMA_HISTOGRAM_TIMES("AsyncIO.IPCChannelClose", base::Time::Now() - start); } - +#endif while (!output_queue_.empty()) { Message* m = output_queue_.front(); output_queue_.pop(); diff --git a/ipc/glue/AsyncChannel.cpp b/ipc/glue/AsyncChannel.cpp index 2780a737f570..729f4e2af257 100644 --- a/ipc/glue/AsyncChannel.cpp +++ b/ipc/glue/AsyncChannel.cpp @@ -469,7 +469,10 @@ void AsyncChannel::OnChannelOpened() { AssertIOThread(); - mChannelState = ChannelOpening; + { + MutexAutoLock lock(mMutex); + mChannelState = ChannelOpening; + } /*assert*/mTransport->Connect(); } diff --git a/ipc/glue/WindowsMessageLoop.h b/ipc/glue/WindowsMessageLoop.h index aed6f14fd69f..5746f58e51cd 100644 --- a/ipc/glue/WindowsMessageLoop.h +++ b/ipc/glue/WindowsMessageLoop.h @@ -44,7 +44,7 @@ #include <windows.h> #include "base/basictypes.h" -#include "nsTraceRefCnt.h" +#include "nsTraceRefcnt.h" namespace mozilla { namespace ipc { diff --git a/js/src/configure.in b/js/src/configure.in index ab2046bee47a..fb32aa308598 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -2107,9 +2107,9 @@ ia64*-hpux*) esac # If we're building with --enable-profiling, we need a frame pointer. if test -z "$MOZ_PROFILING"; then - MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks -fomit-frame-pointer $MOZ_OPTIMIZE_SIZE_TWEAK" + MOZ_OPTIMIZE_FLAGS="-O3 -fomit-frame-pointer" else - MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks -fno-omit-frame-pointer $MOZ_OPTIMIZE_SIZE_TWEAK" + MOZ_OPTIMIZE_FLAGS="-O3 -fno-omit-frame-pointer" fi MOZ_DEBUG_FLAGS="-g" fi diff --git a/js/src/xpconnect/src/dom_quickstubs.qsconf b/js/src/xpconnect/src/dom_quickstubs.qsconf index 57f9e1e8cbbf..22585da2bb60 100644 --- a/js/src/xpconnect/src/dom_quickstubs.qsconf +++ b/js/src/xpconnect/src/dom_quickstubs.qsconf @@ -204,7 +204,7 @@ members = [ 'nsIDOMNSUIEvent.pageY', 'nsIDOMNSUIEvent.isChar', - 'nsIDOMTouchPoint.*', + 'nsIDOMTouch.*', 'nsIDOMTouchList.*', 'nsIDOMTouchEvent.*', @@ -508,7 +508,7 @@ irregularFilenames = { 'nsIIndexedDatabaseUsageCallback': 'nsIIndexedDatabaseManager', - 'nsIDOMTouchPoint': 'nsIDOMTouchEvent', + 'nsIDOMTouch': 'nsIDOMTouchEvent', 'nsIDOMTouchList': 'nsIDOMTouchEvent', } diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index b6377399f54f..97feb6d927dd 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -3687,11 +3687,9 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt CHECK_ONLY_ONE_BIT(FCDATA_FUNC_IS_FULL_CTOR, FCDATA_MAY_NEED_SCROLLFRAME); CHECK_ONLY_ONE_BIT(FCDATA_FUNC_IS_FULL_CTOR, FCDATA_IS_POPUP); CHECK_ONLY_ONE_BIT(FCDATA_FUNC_IS_FULL_CTOR, FCDATA_SKIP_ABSPOS_PUSH); - CHECK_ONLY_ONE_BIT(FCDATA_FUNC_IS_FULL_CTOR, FCDATA_FORCE_VIEW); CHECK_ONLY_ONE_BIT(FCDATA_FUNC_IS_FULL_CTOR, FCDATA_DISALLOW_GENERATED_CONTENT); CHECK_ONLY_ONE_BIT(FCDATA_FUNC_IS_FULL_CTOR, FCDATA_ALLOW_BLOCK_STYLES); - CHECK_ONLY_ONE_BIT(FCDATA_MAY_NEED_SCROLLFRAME, FCDATA_FORCE_VIEW); #undef CHECK_ONLY_ONE_BIT NS_ASSERTION(!(bits & FCDATA_FORCED_NON_SCROLLABLE_BLOCK) || ((bits & FCDATA_FUNC_IS_FULL_CTOR) && @@ -3755,8 +3753,7 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt newFrame); NS_ASSERTION(NS_SUCCEEDED(rv), "InitAndRestoreFrame failed"); // See whether we need to create a view - nsContainerFrame::CreateViewForFrame(newFrame, - (bits & FCDATA_FORCE_VIEW) != 0); + nsContainerFrame::CreateViewForFrame(newFrame, PR_FALSE); frameToAddToList = newFrame; } @@ -4797,8 +4794,7 @@ nsCSSFrameConstructor::FindSVGData(Element* aElement, // and do the PassesConditionalProcessingTests call in // nsSVGOuterSVGFrame::Init. static const FrameConstructionData sOuterSVGData = - FCDATA_DECL(FCDATA_FORCE_VIEW | FCDATA_SKIP_ABSPOS_PUSH | - FCDATA_DISALLOW_GENERATED_CONTENT, + FCDATA_DECL(FCDATA_SKIP_ABSPOS_PUSH | FCDATA_DISALLOW_GENERATED_CONTENT, NS_NewSVGOuterSVGFrame); return &sOuterSVGData; } @@ -4944,10 +4940,6 @@ nsCSSFrameConstructor::ConstructSVGForeignObjectFrame(nsFrameConstructorState& a &blockFrame, childItems, PR_TRUE, aItem.mPendingBinding); - // Give the blockFrame a view so that GetOffsetTo works for descendants - // of blockFrame with views... - nsHTMLContainerFrame::CreateViewForFrame(blockFrame, PR_TRUE); - newFrame->SetInitialChildList(nsnull, childItems); *aNewFrame = newFrame; diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index 3b3124e50b9e..fa7c13def223 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -698,40 +698,35 @@ private: /* If FCDATA_SKIP_ABSPOS_PUSH is set, don't push this frame as an absolute containing block, no matter what its style says. */ #define FCDATA_SKIP_ABSPOS_PUSH 0x200 - /* If FCDATA_FORCE_VIEW is set, then force creation of a view for the frame. - this is only used if a scrollframe is not created and a full constructor - isn't used, so this flag shouldn't be used with - FCDATA_MAY_NEED_SCROLLFRAME or FCDATA_FUNC_IS_FULL_CTOR. */ -#define FCDATA_FORCE_VIEW 0x400 /* If FCDATA_DISALLOW_GENERATED_CONTENT is set, then don't allow generated content when processing kids of this frame. This should not be used with FCDATA_FUNC_IS_FULL_CTOR */ -#define FCDATA_DISALLOW_GENERATED_CONTENT 0x800 +#define FCDATA_DISALLOW_GENERATED_CONTENT 0x400 /* If FCDATA_IS_TABLE_PART is set, then the frame is some sort of table-related thing and we should not attempt to fetch a table-cell parent for it if it's inside another table-related frame. */ -#define FCDATA_IS_TABLE_PART 0x1000 +#define FCDATA_IS_TABLE_PART 0x800 /* If FCDATA_IS_INLINE is set, then the frame is a non-replaced CSS inline box. */ -#define FCDATA_IS_INLINE 0x2000 +#define FCDATA_IS_INLINE 0x1000 /* If FCDATA_IS_LINE_PARTICIPANT is set, the frame is something that will return true for IsFrameOfType(nsIFrame::eLineParticipant) */ -#define FCDATA_IS_LINE_PARTICIPANT 0x4000 +#define FCDATA_IS_LINE_PARTICIPANT 0x2000 /* If FCDATA_IS_LINE_BREAK is set, the frame is something that will induce a line break boundary before and after itself. */ -#define FCDATA_IS_LINE_BREAK 0x8000 +#define FCDATA_IS_LINE_BREAK 0x4000 /* If FCDATA_ALLOW_BLOCK_STYLES is set, allow block styles when processing children. This should not be used with FCDATA_FUNC_IS_FULL_CTOR. */ -#define FCDATA_ALLOW_BLOCK_STYLES 0x10000 +#define FCDATA_ALLOW_BLOCK_STYLES 0x8000 /* If FCDATA_USE_CHILD_ITEMS is set, then use the mChildItems in the relevant FrameConstructionItem instead of trying to process the content's children. This can be used with or without FCDATA_FUNC_IS_FULL_CTOR. The child items might still need table pseudo processing. */ -#define FCDATA_USE_CHILD_ITEMS 0x20000 +#define FCDATA_USE_CHILD_ITEMS 0x10000 /* If FCDATA_FORCED_NON_SCROLLABLE_BLOCK is set, then this block would have been scrollable but has been forced to be non-scrollable due to being in a paginated context. */ -#define FCDATA_FORCED_NON_SCROLLABLE_BLOCK 0x40000 +#define FCDATA_FORCED_NON_SCROLLABLE_BLOCK 0x20000 /* Structure representing information about how a frame should be constructed. */ diff --git a/layout/base/nsRefreshDriver.cpp b/layout/base/nsRefreshDriver.cpp index 65adc383e237..11a045b6bef1 100644 --- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -96,7 +96,7 @@ nsRefreshDriver::GetRefreshTimerType() const return nsITimer::TYPE_ONE_SHOT; } if (HaveAnimationFrameListeners() || sPrecisePref) { - return nsITimer::TYPE_REPEATING_PRECISE; + return nsITimer::TYPE_REPEATING_PRECISE_CAN_SKIP; } return nsITimer::TYPE_REPEATING_SLACK; } @@ -197,7 +197,7 @@ nsRefreshDriver::EnsureTimerStarted(bool aAdjustingTimer) } PRInt32 timerType = GetRefreshTimerType(); - mTimerIsPrecise = (timerType == nsITimer::TYPE_REPEATING_PRECISE); + mTimerIsPrecise = (timerType == nsITimer::TYPE_REPEATING_PRECISE_CAN_SKIP); nsresult rv = mTimer->InitWithCallback(this, GetRefreshTimerInterval(), @@ -391,7 +391,7 @@ nsRefreshDriver::Notify(nsITimer *aTimer) if (mThrottled || (mTimerIsPrecise != - (GetRefreshTimerType() == nsITimer::TYPE_REPEATING_PRECISE))) { + (GetRefreshTimerType() == nsITimer::TYPE_REPEATING_PRECISE_CAN_SKIP))) { // Stop the timer now and restart it here. Stopping is in the mThrottled // case ok because either it's already one-shot, and it just fired, and all // we need to do is null it out, or it's repeating and we need to reset it diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index f01178453b88..75d51cd017e5 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -3040,6 +3040,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, clearance = 0; nscoord topMargin = 0; PRBool mayNeedRetry = PR_FALSE; + PRBool clearedFloats = PR_FALSE; if (applyTopMargin) { // Precompute the blocks top margin value so that we can get the // correct available space (there might be a float that's @@ -3114,7 +3115,9 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, nscoord currentY = aState.mY; // advance mY to the clear position. aState.mY = aState.ClearFloats(aState.mY, breakType, replacedBlock); - + + clearedFloats = aState.mY != currentY; + // Compute clearance. It's the amount we need to add to the top // border-edge of the frame, after applying collapsed margins // from the frame and its children, to get it to line up with @@ -3146,21 +3149,38 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, nsRect availSpace; aState.ComputeBlockAvailSpace(frame, display, floatAvailableSpace, replacedBlock != nsnull, availSpace); - + + // The check for + // (!aState.mReflowState.mFlags.mIsTopOfPage || clearedFloats) + // is to some degree out of paranoia: if we reliably eat up top + // margins at the top of the page as we ought to, it wouldn't be + // needed. + if ((!aState.mReflowState.mFlags.mIsTopOfPage || clearedFloats) && + availSpace.height < 0) { + // We know already that this child block won't fit on this + // page/column due to the top margin or the clearance. So we need + // to get out of here now. (If we don't, most blocks will handle + // things fine, and report break-before, but zero-height blocks + // won't, and will thus make their parent overly-large and force + // *it* to be pushed in its entirety.) + // Doing this means that we also don't need to worry about the + // |availSpace.height += topMargin| below interacting with pushed + // floats (which force nscoord_MAX clearance) to cause a + // constrained height to turn into an unconstrained one. + aState.mY = startingY; + aState.mPrevBottomMargin = incomingMargin; + PushLines(aState, aLine.prev()); + NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus); + *aKeepReflowGoing = PR_FALSE; + return NS_OK; + } + // Now put the Y coordinate back to the top of the top-margin + // clearance, and flow the block. aState.mY -= topMargin; availSpace.y -= topMargin; if (NS_UNCONSTRAINEDSIZE != availSpace.height) { availSpace.height += topMargin; - - // When there is a pushed float, clearance could equal - // NS_UNCONSTRAINEDSIZE (FIXME: is that really a good idea?), but - // we don't want that to change a constrained height to an - // unconstrained one. - if (NS_UNCONSTRAINEDSIZE == availSpace.height) { - --availSpace.height; - } } // Reflow the block into the available space diff --git a/layout/generic/nsHTMLReflowState.h b/layout/generic/nsHTMLReflowState.h index 7a84d8612b4f..e885eeae73c9 100644 --- a/layout/generic/nsHTMLReflowState.h +++ b/layout/generic/nsHTMLReflowState.h @@ -247,10 +247,9 @@ struct nsHTMLReflowState : public nsCSSOffsetState { const nsHTMLReflowState *mCBReflowState; // the available width in which to reflow the frame. The space - // represents the amount of room for the frame's border, padding, - // and content area (not the margin area. The parent frame deals - // with the child frame's margins). The frame size you choose should - // fit within the available width. + // represents the amount of room for the frame's margin, border, + // padding, and content area. The frame size you choose should fit + // within the available width. nscoord availableWidth; // A value of NS_UNCONSTRAINEDSIZE for the available height means diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsObjectFrame.cpp index a4645cbfcc26..ed149b2024cd 100644 --- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -76,7 +76,7 @@ enum { XKeyPress = KeyPress }; #include "nsIViewManager.h" #include "nsIDOMKeyListener.h" #include "nsIDOMDragEvent.h" -#include "nsIPluginHost.h" +#include "nsPluginHost.h" #include "nsString.h" #include "nsReadableUtils.h" #include "prmem.h" @@ -1091,7 +1091,7 @@ nsObjectFrame::ReflowCallbackCanceled() } nsresult -nsObjectFrame::InstantiatePlugin(nsIPluginHost* aPluginHost, +nsObjectFrame::InstantiatePlugin(nsPluginHost* aPluginHost, const char* aMimeType, nsIURI* aURI) { @@ -1122,8 +1122,7 @@ nsObjectFrame::InstantiatePlugin(nsIPluginHost* aPluginHost, if (NS_SUCCEEDED(rv)) pDoc->SetStreamListener(stream); } else { /* embedded mode */ - rv = aPluginHost->InstantiateEmbeddedPlugin(aMimeType, aURI, - mInstanceOwner); + rv = aPluginHost->InstantiateEmbeddedPlugin(aMimeType, aURI, mInstanceOwner, PR_TRUE); } // Note that |this| may very well be destroyed already! @@ -2716,7 +2715,7 @@ nsObjectFrame::Instantiate(const char* aMimeType, nsIURI* aURI) NS_ASSERTION(!mPreventInstantiation, "Say what?"); mPreventInstantiation = PR_TRUE; - rv = InstantiatePlugin(pluginHost, aMimeType, aURI); + rv = InstantiatePlugin(static_cast<nsPluginHost*>(pluginHost.get()), aMimeType, aURI); if (!weakFrame.IsAlive()) { return NS_ERROR_NOT_AVAILABLE; diff --git a/layout/generic/nsObjectFrame.h b/layout/generic/nsObjectFrame.h index 36a493424747..cc4294a35886 100644 --- a/layout/generic/nsObjectFrame.h +++ b/layout/generic/nsObjectFrame.h @@ -57,7 +57,7 @@ class nsIAccessible; #endif class nsPluginInstanceOwner; -class nsIPluginHost; +class nsPluginHost; class nsIPluginInstance; class nsPresContext; class nsDisplayPlugin; @@ -220,7 +220,7 @@ protected: const nsHTMLReflowState& aReflowState, nsHTMLReflowMetrics& aDesiredSize); - nsresult InstantiatePlugin(nsIPluginHost* aPluginHost, + nsresult InstantiatePlugin(nsPluginHost* aPluginHost, const char* aMimetype, nsIURI* aURL); diff --git a/layout/generic/nsTextFrameThebes.cpp b/layout/generic/nsTextFrameThebes.cpp index 46de4a60b1f3..edfa147c6978 100644 --- a/layout/generic/nsTextFrameThebes.cpp +++ b/layout/generic/nsTextFrameThebes.cpp @@ -3036,7 +3036,7 @@ void nsBlinkTimer::Start() nsresult rv; mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv); if (NS_OK == rv) { - mTimer->InitWithCallback(this, 250, nsITimer::TYPE_REPEATING_PRECISE); + mTimer->InitWithCallback(this, 250, nsITimer::TYPE_REPEATING_PRECISE_CAN_SKIP); } } diff --git a/layout/html/tests/printer/index.html b/layout/html/tests/printer/index.html index 2cb413456f15..1e3915f21c59 100644 --- a/layout/html/tests/printer/index.html +++ b/layout/html/tests/printer/index.html @@ -76,7 +76,7 @@ back</a></li> close (doesn't work)</a></li> <li><a href="js/load_new_site_from_js.html">Click link, load page, print, load different URL (doesn't work)</a></li> - <li><a href="js/change_while_in%20printdialog.html">Load different page + <li><a href="js/change_while_in_printdialog.html">Load different page while in Print Dialog</a></li> <li><a href="js/js_pp_timer.html">Timer should run before and after PP</a><br> </li> diff --git a/layout/html/tests/printer/js/change_while_in printdialog.html b/layout/html/tests/printer/js/change_while_in_printdialog.html similarity index 100% rename from layout/html/tests/printer/js/change_while_in printdialog.html rename to layout/html/tests/printer/js/change_while_in_printdialog.html diff --git a/layout/reftests/bugs/368020-5.html b/layout/reftests/bugs/368020-5.html index 42dc1ed66fbd..e120e842c82d 100644 --- a/layout/reftests/bugs/368020-5.html +++ b/layout/reftests/bugs/368020-5.html @@ -5,7 +5,7 @@ </head> <body style="line-height: 3; width: 500px; height: 250px;"> - <span style="background: url(repeatable-diagonal-gradient.png); background-clip: padding-box; background-clip: padding; background-origin: content-box; background-origin: content; border: medium transparent solid; border-width: 7px 4px 2px 18px; padding: 2px 2% 3% 2px; -moz-background-inline-policy: each-box; background-inline-policy: each-box;"> + <span style="background: url(repeatable-diagonal-gradient.png); background-clip: padding-box; background-clip: padding; background-origin: content-box; background-origin: content; border: medium transparent solid; border-width: 7px 4px 2px 18px; padding: 2px 10px 15px 2px; -moz-background-inline-policy: each-box; background-inline-policy: each-box;"> blah<br> blah<br> blah diff --git a/layout/reftests/css-calc/border-radius-1-ref.html b/layout/reftests/css-calc/border-radius-1-ref.html index a8463c3f2510..e5de63e6c6ed 100644 --- a/layout/reftests/css-calc/border-radius-1-ref.html +++ b/layout/reftests/css-calc/border-radius-1-ref.html @@ -3,10 +3,10 @@ <style> p { - height: 200px; - width: 400px; + height: 256px; + width: 512px; background: blue; - border-radius: 13px 14px 14px 5px / 3px 2px 10px 3px; + border-radius: 21px 6px 12px 29px / 5px 16px 10px 3px; } </style> diff --git a/layout/reftests/css-calc/border-radius-1.html b/layout/reftests/css-calc/border-radius-1.html index 6726cb506492..16af05680ac1 100644 --- a/layout/reftests/css-calc/border-radius-1.html +++ b/layout/reftests/css-calc/border-radius-1.html @@ -3,10 +3,20 @@ <style> p { - height: 200px; - width: 400px; + /* We use powers of two here to avoid floating-point issues. + See bug 590181. */ + + height: 256px; + width: 512px; background: blue; - border-radius: -moz-calc(2% + 5px) -moz-calc(4% - 2px) -moz-calc(10px + 1%) -moz-calc(2% - 3px) / -moz-calc(3% - (1px + 1%)) -moz-calc(1%) -moz-calc(10px) 3px; + border-radius: -moz-calc((1/32 * 100%) + 5px) + -moz-calc((1/64 * 100%) - 2px) + -moz-calc(10px + (1/256 * 100%)) + -moz-calc((1/16 * 100%) - 3px) / + -moz-calc((1/32 * 100%) - (1px + (1/128 * 100%))) + -moz-calc(1/16 * 100%) + -moz-calc(10px) + 3px; } </style> diff --git a/layout/reftests/printing/652178-1-ref.html b/layout/reftests/printing/652178-1-ref.html new file mode 100644 index 000000000000..cd9c91ec090a --- /dev/null +++ b/layout/reftests/printing/652178-1-ref.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html class="reftest-print"> +<body> + Something + <div> + <div style="width: 60%; float: left; border: 5px solid green;"> + This should print on page 1 + </div> + + <!-- This just needs to be taller than a page --> + <div style="width: 30%; float: right; border: 5px solid purple; height: 3in"> + </div> + </body> +</html> diff --git a/layout/reftests/printing/652178-1-ref2.html b/layout/reftests/printing/652178-1-ref2.html new file mode 100644 index 000000000000..21aa2a7837ea --- /dev/null +++ b/layout/reftests/printing/652178-1-ref2.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html class="reftest-print"> +<body> + Something + <div style="height: 0"> + <div style="width: 60%; border: 5px solid green;"> + This should print on page 1 + </div> + </div> + + <div style="width: 30%; margin-left: auto; border: 5px solid purple; height: 3in"> + </div> + </body> +</html> diff --git a/layout/reftests/printing/652178-1.html b/layout/reftests/printing/652178-1.html new file mode 100644 index 000000000000..4be937f86795 --- /dev/null +++ b/layout/reftests/printing/652178-1.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html class="reftest-print"> +<body> + Something + <div> + <div style="width: 60%; float: left; border: 5px solid green;"> + This should print on page 1 + </div> + + <!-- This just needs to be taller than a page --> + <div style="width: 30%; float: right; border: 5px solid purple; height: 3in"> + </div> + + <!-- This is needed! --> + <div style="clear: both"></div> + </body> +</html> diff --git a/layout/reftests/printing/reftest.list b/layout/reftests/printing/reftest.list index d838bd5edf45..77684098081a 100644 --- a/layout/reftests/printing/reftest.list +++ b/layout/reftests/printing/reftest.list @@ -19,3 +19,5 @@ == 626395-2b.html 626395-2-ref.html == 626395-2c.html 626395-2-ref.html == 626395-2d.html 626395-2-ref.html +== 652178-1.html 652178-1-ref.html +== 652178-1.html 652178-1-ref2.html diff --git a/layout/reftests/svg/as-image/img-anim-1.html b/layout/reftests/svg/as-image/img-anim-1.html deleted file mode 100644 index 49101db59a0d..000000000000 --- a/layout/reftests/svg/as-image/img-anim-1.html +++ /dev/null @@ -1,19 +0,0 @@ -<html class="reftest-wait"> -<head> -<script> - function snapshot() { - document.documentElement.removeAttribute("class"); - } - function snapshotAfterOnePaint() { - window.addEventListener("MozBeforePaint", snapshot, false); - window.mozRequestAnimationFrame(); - } - /* After the first paint completes (MozReftestInvalidate), then at that - point we wait for *one* more paint, and *then* we take our reftest snapshot. */ - window.addEventListener("MozReftestInvalidate", snapshotAfterOnePaint, false); -</script> -</head> -<body> - <img src="lime-anim-100x100.svg"> -</body> -</html> diff --git a/layout/reftests/svg/as-image/reftest.list b/layout/reftests/svg/as-image/reftest.list index 5465af148538..17171d8d00b1 100644 --- a/layout/reftests/svg/as-image/reftest.list +++ b/layout/reftests/svg/as-image/reftest.list @@ -56,7 +56,6 @@ fails-if(d2d) == img-simple-7.html img-simple-7-ref.html # bug 633072 fails-if(Android) asserts(72) == img-and-image-1.html img-and-image-1-ref.svg # More complex <img> tests -random-if(gtk2Widget) == img-anim-1.html lime100x100-ref.html # bug 612214 == img-content-outside-viewBox-1.html img-content-outside-viewBox-1-ref.html == img-dyn-1.html img-dyn-1-ref.html == img-foreignObject-1.html lime100x100-ref.html diff --git a/layout/reftests/svg/reftest.list b/layout/reftests/svg/reftest.list index d3d266ff8d7f..8ec8ac1e9d88 100644 --- a/layout/reftests/svg/reftest.list +++ b/layout/reftests/svg/reftest.list @@ -211,12 +211,12 @@ fails-if(Android) random-if(gtk2Widget) != text-language-01.xhtml text-language- == tspan-dxdy-05.svg tspan-dxdy-ref.svg == tspan-dxdy-06.svg tspan-dxdy-ref.svg == tspan-dxdy-textPath-01.svg tspan-dxdy-textPath-01-ref.svg -== tspan-rotate-01.svg tspan-rotate-ref.svg -== tspan-rotate-02.svg tspan-rotate-ref.svg -== tspan-rotate-03.svg tspan-rotate-ref.svg -== tspan-rotate-04.svg tspan-rotate-ref.svg -== tspan-rotate-05.svg tspan-rotate-ref.svg -== tspan-rotate-06.svg tspan-rotate-ref.svg +random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) == tspan-rotate-01.svg tspan-rotate-ref.svg # Bug 629718 for random failure on WinXP +random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) == tspan-rotate-02.svg tspan-rotate-ref.svg # Bug 629718 for random failure on WinXP +random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) == tspan-rotate-03.svg tspan-rotate-ref.svg # Bug 629718 for random failure on WinXP +random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) == tspan-rotate-04.svg tspan-rotate-ref.svg # Bug 629718 for random failure on WinXP +random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) == tspan-rotate-05.svg tspan-rotate-ref.svg # Bug 629718 for random failure on WinXP +random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) == tspan-rotate-06.svg tspan-rotate-ref.svg # Bug 629718 for random failure on WinXP == tspan-rotate-textPath-01.svg tspan-rotate-textPath-01-ref.svg == tspan-xy-01.svg tspan-xy-ref.svg == tspan-xy-02.svg tspan-xy-ref.svg diff --git a/layout/style/StyleRule.cpp b/layout/style/StyleRule.cpp index 6c55af738ec1..73c8ef7ebd58 100644 --- a/layout/style/StyleRule.cpp +++ b/layout/style/StyleRule.cpp @@ -953,10 +953,7 @@ public: void DropReference(void); virtual css::Declaration* GetCSSDeclaration(PRBool aAllocate); virtual nsresult SetCSSDeclaration(css::Declaration* aDecl); - virtual nsresult GetCSSParsingEnvironment(nsIURI** aSheetURI, - nsIURI** aBaseURI, - nsIPrincipal** aSheetPrincipal, - css::Loader** aCSSLoader); + virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv); virtual nsIDocument* DocToUpdate(); // Override |AddRef| and |Release| for being a member of @@ -1055,19 +1052,10 @@ DOMCSSDeclarationImpl::GetCSSDeclaration(PRBool aAllocate) } } -/* - * This is a utility function. It will only fail if it can't get a - * parser. This means it can return NS_OK without aURI or aCSSLoader - * being initialized. - */ -nsresult -DOMCSSDeclarationImpl::GetCSSParsingEnvironment(nsIURI** aSheetURI, - nsIURI** aBaseURI, - nsIPrincipal** aSheetPrincipal, - css::Loader** aCSSLoader) +void +DOMCSSDeclarationImpl::GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) { - return GetCSSParsingEnvironmentForRule(mRule, aSheetURI, aBaseURI, - aSheetPrincipal, aCSSLoader); + GetCSSParsingEnvironmentForRule(mRule, aCSSParseEnv); } NS_IMETHODIMP diff --git a/layout/style/nsAnimationManager.cpp b/layout/style/nsAnimationManager.cpp index e90a8fad71d8..a2a9d41bcb36 100644 --- a/layout/style/nsAnimationManager.cpp +++ b/layout/style/nsAnimationManager.cpp @@ -172,13 +172,13 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime, return; } - mNeedsRefreshes = false; - // mStyleRule may be null and valid, if we have no style to apply. if (mStyleRuleRefreshTime.IsNull() || mStyleRuleRefreshTime != aRefreshTime) { mStyleRuleRefreshTime = aRefreshTime; mStyleRule = nsnull; + // We'll set mNeedsRefreshes to true below in all cases where we need them. + mNeedsRefreshes = false; // FIXME(spec): assume that properties in higher animations override // those in lower ones. diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index bb7c9265afdf..47eb784104ad 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -2116,7 +2116,8 @@ CSSParserImpl::ParseMozDocumentRule(RuleAppendFunc aAppendFunc, void* aData) !(eCSSToken_URL == mToken.mType || (eCSSToken_Function == mToken.mType && (mToken.mIdent.LowerCaseEqualsLiteral("url-prefix") || - mToken.mIdent.LowerCaseEqualsLiteral("domain"))))) { + mToken.mIdent.LowerCaseEqualsLiteral("domain") || + mToken.mIdent.LowerCaseEqualsLiteral("regexp"))))) { REPORT_UNEXPECTED_TOKEN(PEMozDocRuleBadFunc); delete urls; return PR_FALSE; @@ -2126,6 +2127,21 @@ CSSParserImpl::ParseMozDocumentRule(RuleAppendFunc aAppendFunc, void* aData) if (mToken.mType == eCSSToken_URL) { cur->func = css::DocumentRule::eURL; CopyUTF16toUTF8(mToken.mIdent, cur->url); + } else if (mToken.mIdent.LowerCaseEqualsLiteral("regexp")) { + // regexp() is different from url-prefix() and domain() (but + // probably the way they *should* have been* in that it requires a + // string argument, and doesn't try to behave like url(). + cur->func = css::DocumentRule::eRegExp; + GetToken(PR_TRUE); + // copy before we know it's valid (but before ExpectSymbol changes + // mToken.mIdent) + CopyUTF16toUTF8(mToken.mIdent, cur->url); + if (eCSSToken_String != mToken.mType || !ExpectSymbol(')', PR_TRUE)) { + REPORT_UNEXPECTED_TOKEN(PEMozDocRuleNotString); + SkipUntil(')'); + delete urls; + return PR_FALSE; + } } else { if (mToken.mIdent.LowerCaseEqualsLiteral("url-prefix")) { cur->func = css::DocumentRule::eURLPrefix; diff --git a/layout/style/nsCSSRules.cpp b/layout/style/nsCSSRules.cpp index 5d0103d36c9d..6d0b9d7f45a8 100644 --- a/layout/style/nsCSSRules.cpp +++ b/layout/style/nsCSSRules.cpp @@ -947,6 +947,8 @@ DocumentRule::List(FILE* out, PRInt32 aIndent) const break; case eDomain: str.AppendLiteral("domain(\""); + case eRegExp: + str.AppendLiteral("regexp(\""); break; } nsCAutoString escapedURL(url->url); @@ -998,6 +1000,9 @@ DocumentRule::GetCssText(nsAString& aCssText) case eDomain: aCssText.AppendLiteral("domain("); break; + case eRegExp: + aCssText.AppendLiteral("regexp("); + break; } nsStyleUtil::AppendEscapedCSSString(NS_ConvertUTF8toUTF16(url->url), aCssText); @@ -1049,9 +1054,10 @@ DocumentRule::DeleteRule(PRUint32 aIndex) // GroupRule interface /* virtual */ PRBool DocumentRule::UseForPresentation(nsPresContext* aPresContext, - nsMediaQueryResultCacheKey& aKey) + nsMediaQueryResultCacheKey& aKey) { - nsIURI *docURI = aPresContext->Document()->GetDocumentURI(); + nsIDocument *doc = aPresContext->Document(); + nsIURI *docURI = doc->GetDocumentURI(); nsCAutoString docURISpec; if (docURI) docURI->GetSpec(docURISpec); @@ -1080,6 +1086,13 @@ DocumentRule::UseForPresentation(nsPresContext* aPresContext, return PR_TRUE; } } break; + case eRegExp: { + NS_ConvertUTF8toUTF16 spec(docURISpec); + NS_ConvertUTF8toUTF16 regex(url->url); + if (nsContentUtils::IsPatternMatching(spec, regex, doc)) { + return PR_TRUE; + } + } break; } } @@ -1721,19 +1734,10 @@ nsCSSKeyframeStyleDeclaration::GetCSSDeclaration(PRBool aAllocate) } } -/* - * This is a utility function. It will only fail if it can't get a - * parser. This means it can return NS_OK without aURI or aCSSLoader - * being initialized. - */ -nsresult -nsCSSKeyframeStyleDeclaration::GetCSSParsingEnvironment(nsIURI** aSheetURI, - nsIURI** aBaseURI, - nsIPrincipal** aSheetPrincipal, - css::Loader** aCSSLoader) +void +nsCSSKeyframeStyleDeclaration::GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) { - return GetCSSParsingEnvironmentForRule(mRule, aSheetURI, aBaseURI, - aSheetPrincipal, aCSSLoader); + GetCSSParsingEnvironmentForRule(mRule, aCSSParseEnv); } NS_IMETHODIMP diff --git a/layout/style/nsCSSRules.h b/layout/style/nsCSSRules.h index 3aeb4cb32bc6..742b26bd65c8 100644 --- a/layout/style/nsCSSRules.h +++ b/layout/style/nsCSSRules.h @@ -156,7 +156,8 @@ public: enum Function { eURL, eURLPrefix, - eDomain + eDomain, + eRegExp }; struct URL { @@ -329,10 +330,7 @@ public: void DropReference() { mRule = nsnull; } virtual mozilla::css::Declaration* GetCSSDeclaration(PRBool aAllocate); virtual nsresult SetCSSDeclaration(mozilla::css::Declaration* aDecl); - virtual nsresult GetCSSParsingEnvironment(nsIURI** aSheetURI, - nsIURI** aBaseURI, - nsIPrincipal** aSheetPrincipal, - mozilla::css::Loader** aCSSLoader); + virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv); virtual nsIDocument* DocToUpdate(); NS_IMETHOD_(nsrefcnt) AddRef(); diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 272a674845a7..c3568b8ed031 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -436,12 +436,12 @@ nsComputedDOMStyle::DocToUpdate() return nsnull; } -nsresult -nsComputedDOMStyle::GetCSSParsingEnvironment(nsIURI**, nsIURI**, nsIPrincipal**, - css::Loader**) +void +nsComputedDOMStyle::GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) { NS_RUNTIMEABORT("called nsComputedDOMStyle::GetCSSParsingEnvironment"); - return NS_ERROR_FAILURE; + // Just in case NS_RUNTIMEABORT ever stops killing us for some reason + aCSSParseEnv.mPrincipal = nsnull; } NS_IMETHODIMP diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index 30287fa586e6..3f61b3d94537 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -107,8 +107,7 @@ public: virtual mozilla::css::Declaration* GetCSSDeclaration(PRBool); virtual nsresult SetCSSDeclaration(mozilla::css::Declaration*); virtual nsIDocument* DocToUpdate(); - virtual nsresult GetCSSParsingEnvironment(nsIURI**, nsIURI**, nsIPrincipal**, - mozilla::css::Loader**); + virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv); private: void AssertFlushedPendingReflows() { diff --git a/layout/style/nsDOMCSSAttrDeclaration.cpp b/layout/style/nsDOMCSSAttrDeclaration.cpp index 9185f7b694ec..294430c97575 100644 --- a/layout/style/nsDOMCSSAttrDeclaration.cpp +++ b/layout/style/nsDOMCSSAttrDeclaration.cpp @@ -170,40 +170,22 @@ nsDOMCSSAttributeDeclaration::GetCSSDeclaration(PRBool aAllocate) return decl; } -/* - * This is a utility function. It will only fail if it can't get a - * parser. This means it can return NS_OK without aURI or aCSSLoader - * being initialized. - */ -nsresult -nsDOMCSSAttributeDeclaration::GetCSSParsingEnvironment(nsIURI** aSheetURI, - nsIURI** aBaseURI, - nsIPrincipal** aSheetPrincipal, - mozilla::css::Loader** aCSSLoader) +void +nsDOMCSSAttributeDeclaration::GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) { NS_ASSERTION(mElement, "Something is severely broken -- there should be an Element here!"); - // null out the out params since some of them may not get initialized below - *aSheetURI = nsnull; - *aBaseURI = nsnull; - *aSheetPrincipal = nsnull; - *aCSSLoader = nsnull; nsIDocument* doc = mElement->GetOwnerDoc(); if (!doc) { // document has been destroyed - return NS_ERROR_NOT_AVAILABLE; + aCSSParseEnv.mPrincipal = nsnull; + return; } - nsCOMPtr<nsIURI> baseURI = mElement->GetBaseURI(); - nsCOMPtr<nsIURI> sheetURI = doc->GetDocumentURI(); - - NS_ADDREF(*aCSSLoader = doc->CSSLoader()); - - baseURI.swap(*aBaseURI); - sheetURI.swap(*aSheetURI); - NS_ADDREF(*aSheetPrincipal = mElement->NodePrincipal()); - - return NS_OK; + aCSSParseEnv.mSheetURI = doc->GetDocumentURI(); + aCSSParseEnv.mBaseURI = mElement->GetBaseURI(); + aCSSParseEnv.mPrincipal = mElement->NodePrincipal(); + aCSSParseEnv.mCSSLoader = doc->CSSLoader(); } NS_IMETHODIMP diff --git a/layout/style/nsDOMCSSAttrDeclaration.h b/layout/style/nsDOMCSSAttrDeclaration.h index bf9d6818d060..1387d2d3b46a 100644 --- a/layout/style/nsDOMCSSAttrDeclaration.h +++ b/layout/style/nsDOMCSSAttrDeclaration.h @@ -76,10 +76,7 @@ public: // If GetCSSDeclaration returns non-null, then the decl it returns // is owned by our current style rule. virtual mozilla::css::Declaration* GetCSSDeclaration(PRBool aAllocate); - virtual nsresult GetCSSParsingEnvironment(nsIURI** aSheetURI, - nsIURI** aBaseURI, - nsIPrincipal** aSheetPrincipal, - mozilla::css::Loader** aCSSLoader); + virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv); NS_IMETHOD GetParentRule(nsIDOMCSSRule **aParent); virtual nsINode* GetParentObject(); diff --git a/layout/style/nsDOMCSSDeclaration.cpp b/layout/style/nsDOMCSSDeclaration.cpp index d53c9d4f020d..ba63fe0632f6 100644 --- a/layout/style/nsDOMCSSDeclaration.cpp +++ b/layout/style/nsDOMCSSDeclaration.cpp @@ -125,18 +125,10 @@ nsDOMCSSDeclaration::SetCssText(const nsAString& aCssText) return NS_ERROR_FAILURE; } - nsresult result; - nsRefPtr<css::Loader> cssLoader; - nsCOMPtr<nsIURI> baseURI, sheetURI; - nsCOMPtr<nsIPrincipal> sheetPrincipal; - - result = GetCSSParsingEnvironment(getter_AddRefs(sheetURI), - getter_AddRefs(baseURI), - getter_AddRefs(sheetPrincipal), - getter_AddRefs(cssLoader)); - - if (NS_FAILED(result)) { - return result; + CSSParsingEnvironment env; + GetCSSParsingEnvironment(env); + if (!env.mPrincipal) { + return NS_ERROR_NOT_AVAILABLE; } // For nsDOMCSSAttributeDeclaration, SetCSSDeclaration will lead to @@ -148,10 +140,11 @@ nsDOMCSSDeclaration::SetCssText(const nsAString& aCssText) nsAutoPtr<css::Declaration> decl(new css::Declaration()); decl->InitializeEmpty(); - nsCSSParser cssParser(cssLoader); + nsCSSParser cssParser(env.mCSSLoader); PRBool changed; - result = cssParser.ParseDeclarations(aCssText, sheetURI, baseURI, - sheetPrincipal, decl, &changed); + nsresult result = cssParser.ParseDeclarations(aCssText, env.mSheetURI, + env.mBaseURI, + env.mPrincipal, decl, &changed); if (NS_FAILED(result) || !changed) { return result; } @@ -271,43 +264,22 @@ nsDOMCSSDeclaration::RemoveProperty(const nsAString& aPropertyName, return RemoveProperty(propID); } -/* static */ nsresult -nsDOMCSSDeclaration::GetCSSParsingEnvironmentForRule( - nsICSSRule* aRule, nsIURI** aSheetURI, - nsIURI** aBaseURI, nsIPrincipal** aSheetPrincipal, - mozilla::css::Loader** aCSSLoader) +/* static */ void +nsDOMCSSDeclaration::GetCSSParsingEnvironmentForRule(nsICSSRule* aRule, + CSSParsingEnvironment& aCSSParseEnv) { - // null out the out params since some of them may not get initialized below - *aSheetURI = nsnull; - *aBaseURI = nsnull; - *aSheetPrincipal = nsnull; - *aCSSLoader = nsnull; - - if (aRule) { - nsIStyleSheet* sheet = aRule->GetStyleSheet(); - if (sheet) { - NS_IF_ADDREF(*aSheetURI = sheet->GetSheetURI()); - NS_IF_ADDREF(*aBaseURI = sheet->GetBaseURI()); - - nsRefPtr<nsCSSStyleSheet> cssSheet(do_QueryObject(sheet)); - if (cssSheet) { - NS_ADDREF(*aSheetPrincipal = cssSheet->Principal()); - } - - nsIDocument* document = sheet->GetOwningDocument(); - if (document) { - NS_ADDREF(*aCSSLoader = document->CSSLoader()); - } - } + nsIStyleSheet* sheet = aRule ? aRule->GetStyleSheet() : nsnull; + nsRefPtr<nsCSSStyleSheet> cssSheet(do_QueryObject(sheet)); + if (!cssSheet) { + aCSSParseEnv.mPrincipal = nsnull; + return; } - nsresult result = NS_OK; - if (!*aSheetPrincipal) { - result = CallCreateInstance("@mozilla.org/nullprincipal;1", - aSheetPrincipal); - } - - return result; + nsIDocument* document = sheet->GetOwningDocument(); + aCSSParseEnv.mSheetURI = sheet->GetSheetURI(); + aCSSParseEnv.mBaseURI = sheet->GetBaseURI(); + aCSSParseEnv.mPrincipal = cssSheet->Principal(); + aCSSParseEnv.mCSSLoader = document ? document->CSSLoader() : nsnull; } nsresult @@ -320,17 +292,10 @@ nsDOMCSSDeclaration::ParsePropertyValue(const nsCSSProperty aPropID, return NS_ERROR_FAILURE; } - nsresult result; - nsRefPtr<css::Loader> cssLoader; - nsCOMPtr<nsIURI> baseURI, sheetURI; - nsCOMPtr<nsIPrincipal> sheetPrincipal; - - result = GetCSSParsingEnvironment(getter_AddRefs(sheetURI), - getter_AddRefs(baseURI), - getter_AddRefs(sheetPrincipal), - getter_AddRefs(cssLoader)); - if (NS_FAILED(result)) { - return result; + CSSParsingEnvironment env; + GetCSSParsingEnvironment(env); + if (!env.mPrincipal) { + return NS_ERROR_NOT_AVAILABLE; } // For nsDOMCSSAttributeDeclaration, SetCSSDeclaration will lead to @@ -341,11 +306,11 @@ nsDOMCSSDeclaration::ParsePropertyValue(const nsCSSProperty aPropID, mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), PR_TRUE); css::Declaration* decl = olddecl->EnsureMutable(); - nsCSSParser cssParser(cssLoader); + nsCSSParser cssParser(env.mCSSLoader); PRBool changed; - result = cssParser.ParseProperty(aPropID, aPropValue, sheetURI, baseURI, - sheetPrincipal, decl, &changed, - aIsImportant); + nsresult result = cssParser.ParseProperty(aPropID, aPropValue, env.mSheetURI, + env.mBaseURI, env.mPrincipal, decl, + &changed, aIsImportant); if (NS_FAILED(result) || !changed) { if (decl != olddecl) { delete decl; diff --git a/layout/style/nsDOMCSSDeclaration.h b/layout/style/nsDOMCSSDeclaration.h index b941a4165344..0e48022a33bd 100644 --- a/layout/style/nsDOMCSSDeclaration.h +++ b/layout/style/nsDOMCSSDeclaration.h @@ -100,22 +100,29 @@ protected: // to it. virtual nsIDocument* DocToUpdate() = 0; - // This will only fail if it can't get a parser or a principal. - // This means it can return NS_OK without aURI or aCSSLoader being - // initialized. - virtual nsresult GetCSSParsingEnvironment(nsIURI** aSheetURI, - nsIURI** aBaseURI, - nsIPrincipal** aSheetPrincipal, - mozilla::css::Loader** aCSSLoader) = 0; + // Information neded to parse a declaration. We need the mSheetURI + // for error reporting, mBaseURI to resolve relative URIs, + // mPrincipal for subresource loads, and mCSSLoader for determining + // whether we're in quirks mode. mBaseURI needs to be a strong + // pointer because of xml:base possibly creating base URIs on the + // fly. This is why we don't use CSSParsingEnvironment as a return + // value, to avoid multiple-refcounting of mBaseURI. + struct CSSParsingEnvironment { + nsIURI* mSheetURI; + nsCOMPtr<nsIURI> mBaseURI; + nsIPrincipal* mPrincipal; + mozilla::css::Loader* mCSSLoader; + }; + + // On failure, mPrincipal should be set to null in aCSSParseEnv. + // If mPrincipal is null, the other members may not be set to + // anything meaningful. + virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) = 0; // An implementation for GetCSSParsingEnvironment for callers wrapping // an nsICSSRule. - static nsresult - GetCSSParsingEnvironmentForRule(nsICSSRule* aRule, - nsIURI** aSheetURI, - nsIURI** aBaseURI, - nsIPrincipal** aSheetPrincipal, - mozilla::css::Loader** aCSSLoader); + static void GetCSSParsingEnvironmentForRule(nsICSSRule* aRule, + CSSParsingEnvironment& aCSSParseEnv); nsresult ParsePropertyValue(const nsCSSProperty aPropID, const nsAString& aPropValue, diff --git a/layout/style/nsFontFaceLoader.cpp b/layout/style/nsFontFaceLoader.cpp index 60b35f13465f..c944b9f1ba08 100644 --- a/layout/style/nsFontFaceLoader.cpp +++ b/layout/style/nsFontFaceLoader.cpp @@ -83,9 +83,9 @@ static PRLogModuleInfo *gFontDownloaderLog = PR_NewLogModule("fontdownloader"); #define LOG_ENABLED() PR_LOG_TEST(gFontDownloaderLog, PR_LOG_DEBUG) -nsFontFaceLoader::nsFontFaceLoader(gfxFontEntry *aFontToLoad, nsIURI *aFontURI, +nsFontFaceLoader::nsFontFaceLoader(gfxProxyFontEntry *aProxy, nsIURI *aFontURI, nsUserFontSet *aFontSet, nsIChannel *aChannel) - : mFontEntry(aFontToLoad), mFontURI(aFontURI), mFontSet(aFontSet), + : mFontEntry(aProxy), mFontURI(aFontURI), mFontSet(aFontSet), mChannel(aChannel) { } @@ -118,9 +118,7 @@ nsFontFaceLoader::StartedLoading(nsIStreamLoader *aStreamLoader) nsITimer::TYPE_ONE_SHOT); } } else { - gfxProxyFontEntry *pe = - static_cast<gfxProxyFontEntry*>(mFontEntry.get()); - pe->mLoadingState = gfxProxyFontEntry::LOADING_SLOWLY; + mFontEntry->mLoadingState = gfxProxyFontEntry::LOADING_SLOWLY; } mStreamLoader = aStreamLoader; } @@ -130,12 +128,7 @@ nsFontFaceLoader::LoadTimerCallback(nsITimer *aTimer, void *aClosure) { nsFontFaceLoader *loader = static_cast<nsFontFaceLoader*>(aClosure); - if (!loader->mFontEntry->mIsProxy) { - return; - } - - gfxProxyFontEntry *pe = - static_cast<gfxProxyFontEntry*>(loader->mFontEntry.get()); + gfxProxyFontEntry *pe = loader->mFontEntry.get(); bool updateUserFontSet = true; // If the entry is loading, check whether it's >75% done; if so, @@ -241,6 +234,7 @@ nsFontFaceLoader::OnStreamComplete(nsIStreamLoader* aLoader, void nsFontFaceLoader::Cancel() { + mFontEntry->mLoadingState = gfxProxyFontEntry::NOT_LOADING; mFontSet = nsnull; if (mLoadTimer) { mLoadTimer->Cancel(); @@ -319,8 +313,8 @@ nsUserFontSet::RemoveLoader(nsFontFaceLoader *aLoader) } nsresult -nsUserFontSet::StartLoad(gfxFontEntry *aFontToLoad, - const gfxFontFaceSrc *aFontFaceSrc) +nsUserFontSet::StartLoad(gfxProxyFontEntry *aProxy, + const gfxFontFaceSrc *aFontFaceSrc) { nsresult rv; @@ -388,7 +382,7 @@ nsUserFontSet::StartLoad(gfxFontEntry *aFontToLoad, NS_ENSURE_SUCCESS(rv, rv); nsRefPtr<nsFontFaceLoader> fontLoader = - new nsFontFaceLoader(aFontToLoad, aFontFaceSrc->mURI, this, channel); + new nsFontFaceLoader(aProxy, aFontFaceSrc->mURI, this, channel); if (!fontLoader) return NS_ERROR_OUT_OF_MEMORY; @@ -442,6 +436,10 @@ nsUserFontSet::StartLoad(gfxFontEntry *aFontToLoad, PRBool nsUserFontSet::UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules) { + // destroy any current loaders, as the entries they refer to + // may be about to get replaced + mLoaders.EnumerateEntries(DestroyIterator, nsnull); + nsTArray<FontFaceRuleRecord> oldRules; mRules.SwapElements(oldRules); diff --git a/layout/style/nsFontFaceLoader.h b/layout/style/nsFontFaceLoader.h index e7379823cdaa..b315e0df5ddd 100644 --- a/layout/style/nsFontFaceLoader.h +++ b/layout/style/nsFontFaceLoader.h @@ -72,7 +72,7 @@ public: // starts loading process, creating and initializing a nsFontFaceLoader obj // returns whether load process successfully started or not - nsresult StartLoad(gfxFontEntry *aFontToLoad, + nsresult StartLoad(gfxProxyFontEntry *aFontToLoad, const gfxFontFaceSrc *aFontFaceSrc); // Called by nsFontFaceLoader when the loader has completed normally. @@ -114,7 +114,7 @@ class nsFontFaceLoader : public nsIStreamLoaderObserver { public: - nsFontFaceLoader(gfxFontEntry *aFontToLoad, nsIURI *aFontURI, + nsFontFaceLoader(gfxProxyFontEntry *aFontToLoad, nsIURI *aFontURI, nsUserFontSet *aFontSet, nsIChannel *aChannel); virtual ~nsFontFaceLoader(); @@ -137,7 +137,7 @@ public: nsISupports* aContext); private: - nsRefPtr<gfxFontEntry> mFontEntry; + nsRefPtr<gfxProxyFontEntry> mFontEntry; nsCOMPtr<nsIURI> mFontURI; nsRefPtr<nsUserFontSet> mFontSet; nsCOMPtr<nsIChannel> mChannel; diff --git a/layout/style/nsLayoutStylesheetCache.cpp b/layout/style/nsLayoutStylesheetCache.cpp index b5bb0935a058..719a463b7771 100644 --- a/layout/style/nsLayoutStylesheetCache.cpp +++ b/layout/style/nsLayoutStylesheetCache.cpp @@ -193,12 +193,6 @@ nsLayoutStylesheetCache::nsLayoutStylesheetCache() NS_ASSERTION(mQuirkSheet, "Could not load quirk.css"); } -nsLayoutStylesheetCache::~nsLayoutStylesheetCache() -{ - gCSSLoader = nsnull; - gStyleCache = nsnull; -} - void nsLayoutStylesheetCache::EnsureGlobal() { diff --git a/layout/style/nsLayoutStylesheetCache.h b/layout/style/nsLayoutStylesheetCache.h index f0d433e0ee16..0d646acd4af3 100644 --- a/layout/style/nsLayoutStylesheetCache.h +++ b/layout/style/nsLayoutStylesheetCache.h @@ -69,7 +69,7 @@ class nsLayoutStylesheetCache private: nsLayoutStylesheetCache(); - ~nsLayoutStylesheetCache(); + ~nsLayoutStylesheetCache() {} static void EnsureGlobal(); void InitFromProfile(); diff --git a/layout/style/test/chrome/Makefile.in b/layout/style/test/chrome/Makefile.in index 735e0c029310..482fa6b1b588 100644 --- a/layout/style/test/chrome/Makefile.in +++ b/layout/style/test/chrome/Makefile.in @@ -49,8 +49,16 @@ _CHROME_FILES = \ bug535806-html.html \ bug535806-xul.xul \ test_hover.html \ + test_moz_document_rules.html \ hover_helper.html \ $(NULL) +_TEST_FILES = \ + moz_document_helper.html \ + $(NULL) + libs:: $(_CHROME_FILES) $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir) + +libs:: $(_TEST_FILES) + $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir) diff --git a/layout/style/test/chrome/moz_document_helper.html b/layout/style/test/chrome/moz_document_helper.html new file mode 100644 index 000000000000..8b331b19e07a --- /dev/null +++ b/layout/style/test/chrome/moz_document_helper.html @@ -0,0 +1,2 @@ +<!DOCTYPE HTML> +<div id="display" style="position: relative"></div> diff --git a/layout/style/test/chrome/test_moz_document_rules.html b/layout/style/test/chrome/test_moz_document_rules.html new file mode 100644 index 000000000000..485eeebe5917 --- /dev/null +++ b/layout/style/test/chrome/test_moz_document_rules.html @@ -0,0 +1,99 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for @-moz-document rules + + + + + + +Mozilla Bug 398962 + +
+
+
+ + diff --git a/layout/style/test/test_animations.html b/layout/style/test/test_animations.html index fe79ed32f9d5..c5e4265621dd 100644 --- a/layout/style/test/test_animations.html +++ b/layout/style/test/test_animations.html @@ -1180,6 +1180,19 @@ is_approx(px_to_num(cs.paddingLeft), 30 + 20 * gTF.ease(0.4), 0.01, "multiprop left at 1900ms"); done_div(); +// Test for https://bugzilla.mozilla.org/show_bug.cgi?id=651456 -- make +// sure that refreshing of animations doesn't break when we get two +// refreshes with the same timestamp. +new_div("-moz-animation: anim2 1s linear"); +is(cs.marginRight, "0px", "bug 651456 at 0ms"); +advance_clock(100); +is(cs.marginRight, "10px", "bug 651456 at 100ms (1)"); +advance_clock(0); // still forces a refresh +is(cs.marginRight, "10px", "bug 651456 at 100ms (2)"); +advance_clock(100); +is(cs.marginRight, "20px", "bug 651456 at 200ms"); +done_div(); + SpecialPowers.DOMWindowUtils.restoreNormalRefresh(); diff --git a/layout/style/test/test_transitions_per_property.html b/layout/style/test/test_transitions_per_property.html index 61defdb0b090..544e15215d67 100644 --- a/layout/style/test/test_transitions_per_property.html +++ b/layout/style/test/test_transitions_per_property.html @@ -555,8 +555,10 @@ function test_radius_transition(prop) { // FIXME: Test a square for now, since we haven't updated to the spec // for vertical components being relative to the height. - div.style.setProperty("width", "200px", ""); - div.style.setProperty("height", "200px", ""); + // Note: We use powers of two here so the floating-point math comes out + // nicely. + div.style.setProperty("width", "256px", ""); + div.style.setProperty("height", "256px", ""); div.style.setProperty("border", "none", ""); div.style.setProperty("padding", "0", ""); @@ -570,14 +572,14 @@ function test_radius_transition(prop) { "radius-valued property " + prop + ": interpolation of radius"); check_distance(prop, "3px", "6px", "15px"); div.style.setProperty("-moz-transition-property", "none", ""); - div.style.setProperty(prop, "5%", ""); - is(cs.getPropertyValue(prop), "10px", + div.style.setProperty(prop, "12.5%", ""); + is(cs.getPropertyValue(prop), "32px", "radius-valued property " + prop + ": computed value before transition"); div.style.setProperty("-moz-transition-property", prop, ""); div.style.setProperty(prop, "25%", ""); - is(cs.getPropertyValue(prop), "20px", + is(cs.getPropertyValue(prop), "40px", "radius-valued property " + prop + ": interpolation of radius"); - check_distance(prop, "5%", "10%", "25%"); + check_distance(prop, "12.5%", "15.625%", "25%"); div.style.setProperty("-moz-transition-property", "none", ""); div.style.setProperty(prop, "3px 8px", ""); is(cs.getPropertyValue(prop), "3px 8px", @@ -588,24 +590,25 @@ function test_radius_transition(prop) { "radius-valued property " + prop + ": interpolation of radius"); check_distance(prop, "3px 8px", "6px 9px", "15px 12px"); div.style.setProperty("-moz-transition-property", "none", ""); - div.style.setProperty(prop, "5% 15%", ""); - is(cs.getPropertyValue(prop), "10px 30px", + div.style.setProperty(prop, "12.5% 6.25%", ""); + is(cs.getPropertyValue(prop), "32px 16px", "radius-valued property " + prop + ": computed value before transition"); div.style.setProperty("-moz-transition-property", prop, ""); div.style.setProperty(prop, "25%", ""); - is(cs.getPropertyValue(prop), "20px 35px", + is(cs.getPropertyValue(prop), "40px 28px", "radius-valued property " + prop + ": interpolation of radius"); - check_distance(prop, "5% 15%", "10% 17.5%", "25%"); + check_distance(prop, "12.5% 6.25%", "15.625% 10.9375%", "25%"); div.style.setProperty("-moz-transition-property", "none", ""); - div.style.setProperty(prop, "8% 12%", ""); - is(cs.getPropertyValue(prop), "16px 24px", + div.style.setProperty(prop, "6.25% 12.5%", ""); + is(cs.getPropertyValue(prop), "16px 32px", "radius-valued property " + prop + ": computed value before transition"); div.style.setProperty("-moz-transition-property", prop, ""); - div.style.setProperty(prop, "40px 20px", ""); - is(cs.getPropertyValue(prop), "22px 23px", + div.style.setProperty(prop, "64px 16px", ""); + is(cs.getPropertyValue(prop), "28px", "radius-valued property " + prop + ": interpolation of radius with mixed units"); - check_distance(prop, "8% 12%", "-moz-calc(6% + 10px) -moz-calc(5px + 9%)", - "40px 20px"); + check_distance(prop, "6.25% 12.5%", + "-moz-calc(4.6875% + 16px) -moz-calc(9.375% + 4px)", + "64px 16px"); test_length_percent_calc_transition(prop); @@ -914,9 +917,11 @@ function test_transform_transition(prop) { expected_uncomputed: 'translateY(-30%)', expected: 'matrix(1, 0, 0, 1, 0px, -15px)' }, { start: 'none', end: 'rotate(90deg) translate(20%, 20%) rotate(-90deg)', - expected_uncomputed: 'rotate(22.5deg) translate(5%, 5%) rotate(-22.5deg)' }, + expected_uncomputed: 'rotate(22.5deg) translate(5%, 5%) rotate(-22.5deg)', + round_error_ok: true }, { start: 'none', end: 'rotate(-90deg) translate(20%, 20%) rotate(90deg)', - expected_uncomputed: 'rotate(-22.5deg) translate(5%, 5%) rotate(22.5deg)' }, + expected_uncomputed: 'rotate(-22.5deg) translate(5%, 5%) rotate(22.5deg)', + round_error_ok: true }, // test percent translation using matrix decomposition { start: 'rotate(45deg) rotate(-45deg)', end: 'rotate(90deg) translate(20%, 20%) rotate(-90deg)', diff --git a/mobile/app/Makefile.in b/mobile/app/Makefile.in index 6fb5cb1125e9..1c062dc4a0a9 100644 --- a/mobile/app/Makefile.in +++ b/mobile/app/Makefile.in @@ -135,7 +135,6 @@ REDIT_PATH = $(LIBXUL_DIST)/bin endif APP_BINARY = $(MOZ_APP_NAME)$(BIN_SUFFIX) -APP_BINARY_FASTSTART = $(MOZ_APP_NAME)faststart$(BIN_SUFFIX) ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) @@ -183,10 +182,6 @@ libs:: ifdef LIBXUL_SDK cp $(LIBXUL_DIST)/bin/xulrunner-stub$(BIN_SUFFIX) $(DIST)/bin/$(APP_BINARY) endif -ifdef MOZ_FASTSTART -ifdef _MSC_VER -endif -endif ifndef SKIP_COPY_XULRUNNER ifdef LIBXUL_SDK $(NSINSTALL) -D $(DIST)/bin/xulrunner diff --git a/mobile/app/mobile.js b/mobile/app/mobile.js index 481b54a458c7..646518e9d24d 100644 --- a/mobile/app/mobile.js +++ b/mobile/app/mobile.js @@ -386,7 +386,6 @@ pref("content.sink.perf_parse_time", 50000000); pref("javascript.options.mem.gc_frequency", 300); pref("javascript.options.mem.high_water_mark", 32); -pref("javascript.options.methodjit.chrome", false); pref("dom.max_chrome_script_run_time", 0); // disable slow script dialog for chrome pref("dom.max_script_run_time", 20); diff --git a/mobile/build.mk b/mobile/build.mk index b082d1b21c81..36712498ccd9 100644 --- a/mobile/build.mk +++ b/mobile/build.mk @@ -81,6 +81,18 @@ deb: package upload:: @$(MAKE) -C mobile/installer upload +ifdef ENABLE_TESTS +# Implemented in testing/testsuite-targets.mk + +mochitest-browser-chrome: + $(RUN_MOCHITEST) --browser-chrome + $(CHECK_TEST_ERROR) + +mochitest:: mochitest-browser-chrome + +.PHONY: mochitest-browser-chrome +endif + ifeq ($(OS_TARGET),Linux) deb: installer endif diff --git a/mobile/chrome/content/browser-ui.js b/mobile/chrome/content/browser-ui.js index 33afb53eb13f..bbed46116d57 100644 --- a/mobile/chrome/content/browser-ui.js +++ b/mobile/chrome/content/browser-ui.js @@ -880,6 +880,8 @@ var BrowserUI = { if (browser.canGoBack) { browser.goBack(); } else if (tab.owner) { + // When going back, always return to the owner (not a sibling). + Browser.selectedTab = tab.owner; this.closeTab(tab); } #ifdef ANDROID diff --git a/mobile/chrome/content/browser.css b/mobile/chrome/content/browser.css index f18b8dcd22a1..3569c2bcac32 100644 --- a/mobile/chrome/content/browser.css +++ b/mobile/chrome/content/browser.css @@ -226,10 +226,15 @@ richlistitem[type="message"]{ -moz-binding: url("chrome://browser/content/bindings/console.xml#message"); } -dialog:not(.content-dialog) { +dialog { -moz-binding: url("chrome://browser/content/bindings/dialog.xml#dialog"); } +/* Do not allow these to inherit from the toolkit binding */ +dialog.content-dialog { + -moz-binding: none; +} + pageaction { -moz-binding: url("chrome://browser/content/bindings/pageaction.xml#pageaction"); } diff --git a/mobile/chrome/content/browser.js b/mobile/chrome/content/browser.js index bf24e4189550..f7d6fe4b89fa 100644 --- a/mobile/chrome/content/browser.js +++ b/mobile/chrome/content/browser.js @@ -717,7 +717,12 @@ var Browser = { let nextTab = this._selectedTab; if (nextTab == aTab) { - nextTab = aTab.owner || this.getTabAtIndex(tabIndex + 1) || this.getTabAtIndex(tabIndex - 1); + nextTab = this.getTabAtIndex(tabIndex + 1) || this.getTabAtIndex(tabIndex - 1); + + // If the next tab is not a sibling, switch back to the parent. + if (aTab.owner && nextTab.owner != aTab.owner) + nextTab = aTab.owner; + if (!nextTab) return null; } diff --git a/mobile/chrome/content/common-ui.js b/mobile/chrome/content/common-ui.js index 5e5b5fc66180..c88846ed9489 100644 --- a/mobile/chrome/content/common-ui.js +++ b/mobile/chrome/content/common-ui.js @@ -196,7 +196,8 @@ var PageActions = { updateSiteMenu: function updateSiteMenu() { this._handlers.forEach(function(action) { let node = document.getElementById(action.id); - node.hidden = !action.callback.call(action.obj, node); + if (node) + node.hidden = !action.callback.call(action.obj, node); }); this._updateAttributes(); }, diff --git a/mobile/chrome/content/extensions.js b/mobile/chrome/content/extensions.js index 2c2d34ae59e5..fefba1da3f2d 100644 --- a/mobile/chrome/content/extensions.js +++ b/mobile/chrome/content/extensions.js @@ -59,6 +59,11 @@ XPCOMUtils.defineLazyGetter(this, "AddonRepository", function() { return AddonRepository; }); +XPCOMUtils.defineLazyGetter(this, "AddonLogger", function() { + Cu.import("resource://gre/modules/AddonLogging.jsm"); + return LogManager.getLogger("FennecExtensions"); +}); + var ExtensionsView = { _strings: {}, _list: null, @@ -447,6 +452,7 @@ var ExtensionsView = { uninstall: function ev_uninstall(aItem) { let opType; if (aItem.getAttribute("type") == "search") { + AddonLogger.log("Removing search engine."); // Make sure the engine isn't hidden before removing it, to make sure it's // visible if the user later re-adds it (works around bug 341833) aItem._engine.hidden = false; @@ -454,7 +460,10 @@ var ExtensionsView = { // the search-engine-modified observer in browser.js will take care of // updating the list } else { + AddonLogger.log("Removing extension."); + if (!aItem.addon) { + AddonLogger.log("No addon object, early return."); this._list.removeChild(aItem); return; } @@ -463,6 +472,7 @@ var ExtensionsView = { opType = this._getOpTypeForOperations(aItem.addon.pendingOperations); if (aItem.addon.pendingOperations & AddonManager.PENDING_UNINSTALL) { + AddonLogger.log("Add-on is not restartless. Keeping in list."); this.showRestart(); // A disabled addon doesn't need a restart so it has no pending ops and @@ -472,6 +482,7 @@ var ExtensionsView = { aItem.setAttribute("opType", opType); } else { + AddonLogger.log("Add-on is restartless. Removed from list."); this._list.removeChild(aItem); } } diff --git a/mobile/chrome/content/forms.js b/mobile/chrome/content/forms.js index 83adacdddf5a..1c6fc14ba9b8 100644 --- a/mobile/chrome/content/forms.js +++ b/mobile/chrome/content/forms.js @@ -580,7 +580,14 @@ FormAssistant.prototype = { let isOpaque = (style.getPropertyValue("opacity") != 0); let rect = aElement.getBoundingClientRect(); - return isVisible && isOpaque && (rect.height != 0 || rect.width != 0); + + // Since the only way to show a drop-down menu for a select when the form + // assistant is enabled is to return true here, a select is allowed to have + // an opacity to 0 in order to let web developpers add a custom design on + // top of it. This is less important to use the form assistant for the + // other types of fields because even if the form assistant won't fired, + // the focus will be in and a VKB will popup if needed + return isVisible && (isOpaque || this._isSelectElement(aElement)) && (rect.height != 0 || rect.width != 0); }, _isSelectElement: function formHelperIsSelectElement(aElement) { diff --git a/mobile/chrome/tests/browser_addons.js b/mobile/chrome/tests/browser_addons.js index 2324f358cdd2..49f1e89a7ff5 100644 --- a/mobile/chrome/tests/browser_addons.js +++ b/mobile/chrome/tests/browser_addons.js @@ -19,6 +19,8 @@ const PREF_GETADDONS_GETSEARCHRESULTS = "extensions.getAddons.search.url"; const PREF_GETADDONS_GETRECOMMENDED = "extensions.getAddons.recommended.url"; const PREF_GETADDONS_BROWSERECOMMENDED = "extensions.getAddons.recommended.browseURL"; const PREF_GETADDONS_UPDATE = "extensions.update.url"; +const PREF_ADDONS_LOGGING = "extensions.logging.enabled"; +const PREF_ADDONS_SECURITY = "extensions.checkUpdateSecurity"; const SEARCH_URL = TESTROOT + "browser_details.xml"; const ADDON_IMG = "chrome://browser/skin/images/alert-addons-30.png"; @@ -76,7 +78,8 @@ function test() { Services.prefs.setCharPref(PREF_GETADDONS_BROWSESEARCHRESULTS, TESTROOT + "browser_install.xml"); Services.prefs.setCharPref(PREF_GETADDONS_GETSEARCHRESULTS, TESTROOT + "browser_install.xml"); Services.prefs.setCharPref(PREF_GETADDONS_UPDATE, TESTROOT + "browser_upgrade.rdf"); - Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false); + Services.prefs.setBoolPref(PREF_ADDONS_SECURITY, false); + Services.prefs.setBoolPref(PREF_ADDONS_LOGGING, true); run_next_test(); } @@ -84,11 +87,15 @@ function end_test() { close_manager(); Services.prefs.clearUserPref(PREF_GETADDONS_GETRECOMMENDED); Services.prefs.clearUserPref(PREF_GETADDONS_BROWSERECOMMENDED); - Services.prefs.clearUserPref(PREF_GETADDONS_GETSEARCHRESULTS); Services.prefs.clearUserPref(PREF_GETADDONS_BROWSESEARCHRESULTS); - finish(); + Services.prefs.clearUserPref(PREF_GETADDONS_GETSEARCHRESULTS); + Services.prefs.clearUserPref(PREF_GETADDONS_UPDATE); + Services.prefs.clearUserPref(PREF_ADDONS_SECURITY); + Services.prefs.clearUserPref(PREF_ADDONS_LOGGING); } +registerCleanupFunction(end_test); + function add_test(test) { gPendingTests.push(test); } @@ -98,8 +105,7 @@ function run_next_test() { info("Test " + gTestsRun + " took " + (Date.now() - gTestStart) + "ms"); if (gPendingTests.length == 0) { - end_test(); - return; + finish(); } gTestsRun++; @@ -356,6 +362,10 @@ function installFromURLBar(aAddon) { return function() { loadUrl(gTestURL, function() { loadUrl(aAddon.sourceURL, null, false); + let elt = get_addon_element(aAddon.id); + ok(!elt, "Addon element is not present before installation"); + if (elt) + info("unexpectedly found element in: " + elt.parentNode.id); checkInstallAlert(true, function() { checkDownloadNotification(function() { checkInstallPopup(aAddon.name, function() { @@ -363,6 +373,7 @@ function installFromURLBar(aAddon) { open_manager(true, function() { isRestartShown(!aAddon.bootstrapped, false, function() { let elt = get_addon_element(aAddon.id); + info("elt.id is " + aAddon.id); if (aAddon.bootstrapped) { checkAddonListing(aAddon, elt, "local"); var button = document.getAnonymousElementByAttribute(elt, "anonid", "uninstall-button"); @@ -379,6 +390,7 @@ function installFromURLBar(aAddon) { close_manager(run_next_test); }, function() { let elt = get_addon_element(aAddon.id); + info("Looking for element with id " + aAddon.id + ": " + elt); return !elt; }); } else { diff --git a/mobile/chrome/tests/browser_tabs.js b/mobile/chrome/tests/browser_tabs.js index 21fa73660ebc..e08fb5e78540 100644 --- a/mobile/chrome/tests/browser_tabs.js +++ b/mobile/chrome/tests/browser_tabs.js @@ -83,6 +83,8 @@ function tab_switch_02() { //Add new tab new_tab_03 = Browser.addTab(testURL_03, true, new_tab_01); + new_tab_04 = Browser.addTab(testURL_03, false, new_tab_01); + checkExpectedSize(); new_tab_03.browser.addEventListener("load", tab_switch_03, true); } @@ -93,7 +95,11 @@ function tab_switch_03() { is(Browser.selectedTab.notification, Elements.browsers.selectedPanel, "Deck has correct browser"); Browser.closeTab(new_tab_03, { forceClose: true }); - is(Browser.selectedTab, new_tab_01, "Closing tab 03 returns to owner"); + is(Browser.selectedTab, new_tab_04, "Closing tab 03 goes to sibling"); + is(Browser.selectedTab.notification, Elements.browsers.selectedPanel, "Deck has correct browser"); + + Browser.closeTab(new_tab_04, { forceClose: true }); + is(Browser.selectedTab, new_tab_01, "Closing tab 04 returns to owner"); is(Browser.selectedTab.notification, Elements.browsers.selectedPanel, "Deck has correct browser"); new_tab_03 = Browser.addTab(testURL_03, true, new_tab_01); diff --git a/mobile/components/AddonUpdateService.js b/mobile/components/AddonUpdateService.js index b305c705d062..a93fb6e456e5 100644 --- a/mobile/components/AddonUpdateService.js +++ b/mobile/components/AddonUpdateService.js @@ -169,9 +169,6 @@ var RecommendedSearchResults = { if (!aData) return; - let stateString = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString); - stateString.data = aData; - // Initialize the file output stream. let ostream = Cc["@mozilla.org/network/safe-file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); ostream.init(aFile, 0x02 | 0x08 | 0x20, 0600, ostream.DEFER_OPEN); diff --git a/mobile/components/SessionStore.js b/mobile/components/SessionStore.js index 181b5b089cd0..33e1cebd58ee 100644 --- a/mobile/components/SessionStore.js +++ b/mobile/components/SessionStore.js @@ -378,6 +378,10 @@ SessionStore.prototype = { if (aBrowser.__SS_restore) return; + // Ignore a transient "about:blank" + if (!aBrowser.canGoBack && aBrowser.currentURI.spec == "about:blank") + return; + delete aBrowser.__SS_data; this._collectTabData(aBrowser); @@ -417,8 +421,7 @@ SessionStore.prototype = { if (delay > 0) { this._saveTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); this._saveTimer.init(this, delay, Ci.nsITimer.TYPE_ONE_SHOT); - } - else { + } else { this.saveState(); } } diff --git a/mobile/confvars.sh b/mobile/confvars.sh index 07a904d81a71..02164fb49cf6 100644 --- a/mobile/confvars.sh +++ b/mobile/confvars.sh @@ -44,7 +44,7 @@ MOZ_BRANDING_DIRECTORY=mobile/branding/nightly MOZ_OFFICIAL_BRANDING_DIRECTORY=mobile/branding/official # MOZ_APP_DISPLAYNAME is set by branding/configure.sh -MOZ_SAFE_BROWSING=0 +MOZ_SAFE_BROWSING= MOZ_SERVICES_SYNC=1 MOZ_ENABLE_LIBXUL=1 diff --git a/mobile/installer/package-manifest.in b/mobile/installer/package-manifest.in index 2c70ffc0d39a..970627ada5cb 100644 --- a/mobile/installer/package-manifest.in +++ b/mobile/installer/package-manifest.in @@ -405,12 +405,11 @@ @BINPATH@/modules/* ; Safe Browsing -#ifdef MOZ_SAFE_BROWSING @BINPATH@/components/nsURLClassifier.manifest +@BINPATH@/components/nsUrlClassifierHashCompleter.js @BINPATH@/components/nsUrlClassifierListManager.js @BINPATH@/components/nsUrlClassifierLib.js @BINPATH@/components/url-classifier.xpt -#endif ; GNOME hooks #ifdef MOZ_ENABLE_GNOME_COMPONENT diff --git a/modules/libpr0n/src/VectorImage.cpp b/modules/libpr0n/src/VectorImage.cpp index a7f6a3cbe884..a4151091354e 100644 --- a/modules/libpr0n/src/VectorImage.cpp +++ b/modules/libpr0n/src/VectorImage.cpp @@ -60,7 +60,6 @@ using namespace mozilla::dom; namespace mozilla { namespace imagelib { -#ifdef MOZ_ENABLE_LIBXUL // Helper-class: SVGRootRenderingObserver class SVGRootRenderingObserver : public nsSVGRenderingObserver { public: @@ -124,7 +123,6 @@ protected: nsRefPtr mDocWrapper; VectorImage* mVectorImage; // Raw pointer because it owns me. }; -#endif // MOZ_ENABLE_LIBXUL // Helper-class: SVGDrawingCallback class SVGDrawingCallback : public gfxDrawingCallback { @@ -669,10 +667,8 @@ VectorImage::OnStopRequest(nsIRequest* aRequest, nsISupports* aCtxt, mIsFullyLoaded = PR_TRUE; mHaveAnimations = mSVGDocumentWrapper->IsAnimated(); -#ifdef MOZ_ENABLE_LIBXUL // Start listening to our image for rendering updates mRenderingObserver = new SVGRootRenderingObserver(mSVGDocumentWrapper, this); -#endif // MOZ_ENABLE_LIBXUL // Tell *our* observers that we're done loading nsCOMPtr observer = do_QueryReferent(mObserver); @@ -711,9 +707,17 @@ VectorImage::OnDataAvailable(nsIRequest* aRequest, nsISupports* aCtxt, void VectorImage::InvalidateObserver() { - nsCOMPtr observer(do_QueryReferent(mObserver)); - if (observer) { - observer->FrameChanged(this, &nsIntRect::GetMaxSizedIntRect()); + if (!mObserver) + return; + + nsCOMPtr containerObs(do_QueryReferent(mObserver)); + if (containerObs) { + containerObs->FrameChanged(this, &nsIntRect::GetMaxSizedIntRect()); + } + + nsCOMPtr decoderObs(do_QueryReferent(mObserver)); + if (decoderObs) { + decoderObs->OnStopFrame(nsnull, imgIContainer::FRAME_CURRENT); } } diff --git a/modules/libpr0n/src/VectorImage.h b/modules/libpr0n/src/VectorImage.h index dfc762e2cb5a..c1e275fcb6e0 100644 --- a/modules/libpr0n/src/VectorImage.h +++ b/modules/libpr0n/src/VectorImage.h @@ -101,9 +101,7 @@ protected: private: nsWeakPtr mObserver; //! imgIDecoderObserver nsRefPtr mSVGDocumentWrapper; -#ifdef MOZ_ENABLE_LIBXUL nsRefPtr mRenderingObserver; -#endif // MOZ_ENABLE_LIBXUL nsIntRect mRestrictedRegion; // If we were created by // ExtractFrame, this is the region diff --git a/modules/libpr0n/test/mochitest/Makefile.in b/modules/libpr0n/test/mochitest/Makefile.in index 3c41e9d18f60..3ee2385baa98 100644 --- a/modules/libpr0n/test/mochitest/Makefile.in +++ b/modules/libpr0n/test/mochitest/Makefile.in @@ -74,11 +74,19 @@ _TEST_FILES = imgutils.js \ test_bug553982.html \ test_bug601470.html \ test_bug614392.html \ - $(NULL) + $(NULL) # Tests disabled due to intermittent orange # test_bug435296.html disabled - See bug 578591 # test_bug478398.html disabled - See bug 579139 +_CHROME_FILES = imgutils.js \ + lime-anim-100x100.svg \ + test_animSVGImage.html \ + $(NULL) + libs:: $(_TEST_FILES) $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir) + +libs:: $(_CHROME_FILES) + $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir) diff --git a/modules/libpr0n/test/mochitest/imgutils.js b/modules/libpr0n/test/mochitest/imgutils.js index c0796174c704..433518547296 100644 --- a/modules/libpr0n/test/mochitest/imgutils.js +++ b/modules/libpr0n/test/mochitest/imgutils.js @@ -1,3 +1,4 @@ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ // Helper file for shared image functionality // // Note that this is use by tests elsewhere in the source tree. When in doubt, @@ -119,3 +120,16 @@ function getImagePref(pref) else return null; } + +// JS implementation of imgIDecoderObserver with stubs for all of its methods. +function ImageDecoderObserverStub() +{ + this.onStartRequest = function onStartRequest(aRequest) {} + this.onStartDecode = function onStartDecode(aRequest) {} + this.onStartContainer = function onStartContainer(aRequest, aContainer) {} + this.onStartFrame = function onStartFrame(aRequest, aFrame) {} + this.onStopFrame = function onStopFrame(aRequest, aFrame) {} + this.onStopContainer = function onStopContainer(aRequest, aContainer) {} + this.onStopDecode = function onStopDecode(aRequest, status, statusArg) {} + this.onStopRequest = function onStopRequest(aRequest, aIsLastPart) {} +} diff --git a/modules/libpr0n/test/mochitest/lime-anim-100x100.svg b/modules/libpr0n/test/mochitest/lime-anim-100x100.svg new file mode 100644 index 000000000000..c6584047d03c --- /dev/null +++ b/modules/libpr0n/test/mochitest/lime-anim-100x100.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/modules/libpr0n/test/mochitest/test_animSVGImage.html b/modules/libpr0n/test/mochitest/test_animSVGImage.html new file mode 100644 index 000000000000..50ac090d8712 --- /dev/null +++ b/modules/libpr0n/test/mochitest/test_animSVGImage.html @@ -0,0 +1,113 @@ + + + + + Test for Bug 610419 + + + + + + + +Mozilla Bug 610419 +

+
+
+ +
+
+
+
+ + diff --git a/modules/plugin/base/public/nsIPluginHost.idl b/modules/plugin/base/public/nsIPluginHost.idl index abaf62102d6a..01f9c5136de3 100644 --- a/modules/plugin/base/public/nsIPluginHost.idl +++ b/modules/plugin/base/public/nsIPluginHost.idl @@ -64,7 +64,7 @@ interface nsIPluginStreamListener; [ptr] native PRLibraryPtr(PRLibrary); [ptr] native nsPluginNativeWindowPtr(nsPluginNativeWindow); -[scriptable, uuid(C198DEAA-3F93-482D-A47C-85FF6514FE07)] +[scriptable, uuid(0BB66261-4114-4D73-8DFC-C3CA997E6817)] interface nsIPluginHost : nsISupports { [noscript] void init(); @@ -84,13 +84,6 @@ interface nsIPluginHost : nsISupports [noscript] nsIPlugin getPlugin(in string aMimeType); - [noscript] void instantiateEmbeddedPlugin(in string aMimeType, in nsIURI aURL, in nsIPluginInstanceOwner aOwner); - - [noscript] void instantiateFullPagePlugin(in string aMimeType, - in nsIURI aURI, - in nsIPluginInstanceOwner aOwner, - out nsIStreamListener aStreamListener); - /** * Instantiate an embedded plugin for an existing channel. The caller is * responsible for opening the channel. It may or may not be already opened diff --git a/modules/plugin/base/src/nsNPAPIPlugin.cpp b/modules/plugin/base/src/nsNPAPIPlugin.cpp index 7ee47d0d5ee1..96781e9a18c0 100644 --- a/modules/plugin/base/src/nsNPAPIPlugin.cpp +++ b/modules/plugin/base/src/nsNPAPIPlugin.cpp @@ -237,10 +237,6 @@ NS_IMPL_ISUPPORTS1(nsNPAPIPlugin, nsIPlugin) nsNPAPIPlugin::nsNPAPIPlugin() { -#if defined(XP_MACOSX) && !defined(__LP64__) - mPluginRefNum = -1; -#endif - memset((void*)&mPluginFuncs, 0, sizeof(mPluginFuncs)); mPluginFuncs.size = sizeof(mPluginFuncs); mPluginFuncs.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; @@ -254,14 +250,6 @@ nsNPAPIPlugin::~nsNPAPIPlugin() mLibrary = nsnull; } -#if defined(XP_MACOSX) && !defined(__LP64__) -void -nsNPAPIPlugin::SetPluginRefNum(short aRefNum) -{ - mPluginRefNum = aRefNum; -} -#endif - void nsNPAPIPlugin::PluginCrashed(const nsAString& pluginDumpID, const nsAString& browserDumpID) @@ -571,10 +559,7 @@ nsNPAPIPlugin::Shutdown() NPError shutdownError; mLibrary->NP_Shutdown(&shutdownError); -#if defined(XP_MACOSX) && !defined(__LP64__) - if (shutdownError == NS_OK && mPluginRefNum > 0) - ::CloseResFile(mPluginRefNum); -#endif + return NS_OK; } diff --git a/modules/plugin/base/src/nsNPAPIPlugin.h b/modules/plugin/base/src/nsNPAPIPlugin.h index 2b704807e537..e539a533d65f 100644 --- a/modules/plugin/base/src/nsNPAPIPlugin.h +++ b/modules/plugin/base/src/nsNPAPIPlugin.h @@ -106,11 +106,6 @@ public: static PRBool RunPluginOOP(const nsPluginTag *aPluginTag); protected: - -#if defined(XP_MACOSX) && !defined(__LP64__) - short mPluginRefNum; -#endif - NPPluginFuncs mPluginFuncs; PluginLibrary* mLibrary; }; diff --git a/modules/plugin/base/src/nsPluginHost.cpp b/modules/plugin/base/src/nsPluginHost.cpp index 80987c471243..fc0ee6224183 100644 --- a/modules/plugin/base/src/nsPluginHost.cpp +++ b/modules/plugin/base/src/nsPluginHost.cpp @@ -965,18 +965,10 @@ NS_IMETHODIMP nsPluginHost::InstantiatePluginForChannel(nsIChannel* aChannel, return NewEmbeddedPluginStreamListener(uri, aOwner, nsnull, aListener); } -// Called by nsPluginInstanceOwner -NS_IMETHODIMP nsPluginHost::InstantiateEmbeddedPlugin(const char *aMimeType, - nsIURI* aURL, - nsIPluginInstanceOwner *aOwner) -{ - return DoInstantiateEmbeddedPlugin(aMimeType, aURL, aOwner, PR_TRUE); -} - nsresult -nsPluginHost::DoInstantiateEmbeddedPlugin(const char *aMimeType, nsIURI* aURL, - nsIPluginInstanceOwner* aOwner, - PRBool aAllowOpeningStreams) +nsPluginHost::InstantiateEmbeddedPlugin(const char *aMimeType, nsIURI* aURL, + nsIPluginInstanceOwner* aOwner, + PRBool aAllowOpeningStreams) { NS_ENSURE_ARG_POINTER(aOwner); @@ -1139,11 +1131,10 @@ nsPluginHost::DoInstantiateEmbeddedPlugin(const char *aMimeType, nsIURI* aURL, return rv; } -// Called by full-page case -NS_IMETHODIMP nsPluginHost::InstantiateFullPagePlugin(const char *aMimeType, - nsIURI* aURI, - nsIPluginInstanceOwner *aOwner, - nsIStreamListener **aStreamListener) +nsresult nsPluginHost::InstantiateFullPagePlugin(const char *aMimeType, + nsIURI* aURI, + nsIPluginInstanceOwner *aOwner, + nsIStreamListener **aStreamListener) { #ifdef PLUGIN_LOGGING nsCAutoString urlSpec; @@ -1650,27 +1641,24 @@ nsPluginTag* nsPluginHost::FindPluginForType(const char* aMimeType, PRBool aCheckEnabled) { - nsPluginTag *plugins = nsnull; - PRInt32 variants, cnt; + if (!aMimeType) { + return nsnull; + } LoadPlugins(); - // if we have a mimetype passed in, search the mPlugins - // linked list for a match - if (aMimeType) { - plugins = mPlugins; - - while (plugins) { - variants = plugins->mVariants; - for (cnt = 0; cnt < variants; cnt++) { - if ((!aCheckEnabled || plugins->IsEnabled()) && - plugins->mMimeTypeArray[cnt] && - (0 == PL_strcasecmp(plugins->mMimeTypeArray[cnt], aMimeType))) { - return plugins; + nsPluginTag *plugin = mPlugins; + while (plugin) { + if (!aCheckEnabled || plugin->IsEnabled()) { + PRInt32 mimeCount = plugin->mVariants; + for (PRInt32 i = 0; i < mimeCount; i++) { + if (plugin->mMimeTypeArray[i] && + (0 == PL_strcasecmp(plugin->mMimeTypeArray[i], aMimeType))) { + return plugin; } } - plugins = plugins->mNext; } + plugin = plugin->mNext; } return nsnull; @@ -1769,25 +1757,8 @@ static nsresult CreateNPAPIPlugin(nsPluginTag *aPluginTag, fullPath = aPluginTag->mFullPath; } -#if defined(XP_MACOSX) && !defined(__LP64__) - short appRefNum = ::CurResFile(); - nsCOMPtr pluginPath; - NS_NewNativeLocalFile(nsDependentCString(fullPath.get()), PR_TRUE, - getter_AddRefs(pluginPath)); - nsPluginFile pluginFile(pluginPath); - short pluginRefNum = pluginFile.OpenPluginResource(); -#endif - rv = nsNPAPIPlugin::CreatePlugin(aPluginTag, aOutNPAPIPlugin); -#if defined(XP_MACOSX) && !defined(__LP64__) - if (NS_SUCCEEDED(rv)) - (*aOutNPAPIPlugin)->SetPluginRefNum(pluginRefNum); - else if (pluginRefNum > 0) - ::CloseResFile(pluginRefNum); - ::UseResFile(appRefNum); -#endif - return rv; } diff --git a/modules/plugin/base/src/nsPluginHost.h b/modules/plugin/base/src/nsPluginHost.h index 7dff25d9ef78..ed3b53554dbc 100644 --- a/modules/plugin/base/src/nsPluginHost.h +++ b/modules/plugin/base/src/nsPluginHost.h @@ -164,12 +164,16 @@ public: // Return the tag for |aLibrary| if found, nsnull if not. nsPluginTag* FindTagForLibrary(PRLibrary* aLibrary); - // The guts of InstantiateEmbeddedPlugin. The last argument should - // be false if we already have an in-flight stream and don't need to - // set up a new stream. - nsresult DoInstantiateEmbeddedPlugin(const char *aMimeType, nsIURI* aURL, - nsIPluginInstanceOwner* aOwner, - PRBool aAllowOpeningStreams); + // The last argument should be false if we already have an in-flight stream + // and don't need to set up a new stream. + nsresult InstantiateEmbeddedPlugin(const char *aMimeType, nsIURI* aURL, + nsIPluginInstanceOwner* aOwner, + PRBool aAllowOpeningStreams); + + nsresult InstantiateFullPagePlugin(const char *aMimeType, + nsIURI* aURI, + nsIPluginInstanceOwner *aOwner, + nsIStreamListener **aStreamListener); // Does not accept NULL and should never fail. nsPluginTag* TagForPlugin(nsNPAPIPlugin* aPlugin); diff --git a/modules/plugin/base/src/nsPluginStreamListenerPeer.cpp b/modules/plugin/base/src/nsPluginStreamListenerPeer.cpp index f580927390c8..5cdf9d4dc2ba 100644 --- a/modules/plugin/base/src/nsPluginStreamListenerPeer.cpp +++ b/modules/plugin/base/src/nsPluginStreamListenerPeer.cpp @@ -658,8 +658,8 @@ nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request, // Make sure to not allow new streams to be opened here; we've // already got a stream for this data; we just need a properly // set up plugin instance. - rv = pluginHost->DoInstantiateEmbeddedPlugin(aContentType.get(), aURL, - mOwner, PR_FALSE); + rv = pluginHost->InstantiateEmbeddedPlugin(aContentType.get(), aURL, + mOwner, PR_FALSE); } else { rv = pluginHost->SetUpPluginInstance(aContentType.get(), aURL, mOwner); diff --git a/modules/plugin/base/src/nsPluginTags.cpp b/modules/plugin/base/src/nsPluginTags.cpp index 3eeb0d992dd1..5cebc3af2e99 100644 --- a/modules/plugin/base/src/nsPluginTags.cpp +++ b/modules/plugin/base/src/nsPluginTags.cpp @@ -113,7 +113,7 @@ mMimeTypeArray(nsnull), mExtensionsArray(nsnull), mLibrary(nsnull), #ifdef XP_MACOSX -mCanUnloadLibrary(!aPluginInfo->fBundle), +mCanUnloadLibrary(PR_FALSE), #else mCanUnloadLibrary(PR_TRUE), #endif diff --git a/modules/plugin/base/src/nsPluginsDir.h b/modules/plugin/base/src/nsPluginsDir.h index 6e9193f33713..1c42d5b47378 100644 --- a/modules/plugin/base/src/nsPluginsDir.h +++ b/modules/plugin/base/src/nsPluginsDir.h @@ -66,9 +66,6 @@ struct nsPluginInfo { char* fFileName; char* fFullPath; char* fVersion; -#ifdef XP_MACOSX - PRBool fBundle; -#endif }; /** @@ -105,9 +102,6 @@ public: * Should be called after GetPluginInfo to free all allocated stuff */ nsresult FreePluginInfo(nsPluginInfo &PluginInfo); - - // Open the resource fork for the plugin - short OpenPluginResource(void); }; #endif /* nsPluginsDir_h_ */ diff --git a/modules/plugin/base/src/nsPluginsDirDarwin.cpp b/modules/plugin/base/src/nsPluginsDirDarwin.cpp index 67a950d95424..83207c2fbe45 100644 --- a/modules/plugin/base/src/nsPluginsDirDarwin.cpp +++ b/modules/plugin/base/src/nsPluginsDirDarwin.cpp @@ -388,63 +388,6 @@ static char* GetNextPluginStringFromHandle(Handle h, short *index) return ret; } -#ifndef __LP64__ -static char* GetPluginString(short id, short index) -{ - Str255 str; - ::GetIndString(str, id, index); - return p2cstrdup(str); -} - -// Opens the resource fork for the plugin -// Also checks if the plugin is a CFBundle and opens gets the correct resource -static short OpenPluginResourceFork(nsIFile *pluginFile) -{ - FSSpec spec; - nsCOMPtr lfm = do_QueryInterface(pluginFile); - if (!lfm || NS_FAILED(lfm->GetFSSpec(&spec))) - return -1; - - Boolean targetIsFolder, wasAliased; - ::ResolveAliasFile(&spec, true, &targetIsFolder, &wasAliased); - short refNum = ::FSpOpenResFile(&spec, fsRdPerm); - if (refNum < 0) { - nsCString path; - pluginFile->GetNativePath(path); - CFBundleRef bundle = getPluginBundle(path.get()); - if (bundle) { - refNum = CFBundleOpenBundleResourceMap(bundle); - ::CFRelease(bundle); - } - } - return refNum; -} - -short nsPluginFile::OpenPluginResource() -{ - return OpenPluginResourceFork(mPlugin); -} - -class nsAutoCloseResourceObject { -public: - nsAutoCloseResourceObject(nsIFile *pluginFile) - { - mRefNum = OpenPluginResourceFork(pluginFile); - } - ~nsAutoCloseResourceObject() - { - if (mRefNum > 0) - ::CloseResFile(mRefNum); - } - PRBool ResourceOpened() - { - return (mRefNum > 0); - } -private: - short mRefNum; -}; -#endif - static PRBool IsCompatibleArch(nsIFile *file) { CFURLRef pluginURL = NULL; @@ -499,12 +442,6 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary) // clear out the info, except for the first field. memset(&info, 0, sizeof(info)); -#ifndef __LP64__ - // Try to open a resource fork in case we have to use it. - nsAutoCloseResourceObject resourceObject(mPlugin); - bool resourceOpened = resourceObject.ResourceOpened(); -#endif - // Try to get a bundle reference. nsCAutoString path; if (NS_FAILED(rv = mPlugin->GetNativePath(path))) @@ -520,22 +457,12 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary) return rv; info.fFileName = PL_strdup(fileName.get()); - // Get fBundle - if (bundle) - info.fBundle = PR_TRUE; - // Get fName if (bundle) { CFTypeRef name = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginName")); if (name && ::CFGetTypeID(name) == ::CFStringGetTypeID()) info.fName = CFStringRefToUTF8Buffer(static_cast(name)); } -#ifndef __LP64__ - if (!info.fName && resourceOpened) { - // 'STR#', 126, 2 => plugin name. - info.fName = GetPluginString(126, 2); - } -#endif // Get fDescription if (bundle) { @@ -543,12 +470,6 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary) if (description && ::CFGetTypeID(description) == ::CFStringGetTypeID()) info.fDescription = CFStringRefToUTF8Buffer(static_cast(description)); } -#ifndef __LP64__ - if (!info.fDescription && resourceOpened) { - // 'STR#', 126, 1 => plugin description. - info.fDescription = GetPluginString(126, 1); - } -#endif // Get fVersion if (bundle) { @@ -604,27 +525,6 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary) } } -#ifndef __LP64__ - // Try to get data from the resource fork - if (!info.fVariantCount && resourceObject.ResourceOpened()) { - mi.typeStrings = ::Get1Resource('STR#', 128); - if (mi.typeStrings) { - info.fVariantCount = (**(short**)mi.typeStrings) / 2; - ::DetachResource(mi.typeStrings); - ::HLock(mi.typeStrings); - } else { - // Don't add this plugin because no mime types could be found - return NS_ERROR_FAILURE; - } - - mi.infoStrings = ::Get1Resource('STR#', 127); - if (mi.infoStrings) { - ::DetachResource(mi.infoStrings); - ::HLock(mi.infoStrings); - } - } -#endif - // Fill in the info struct based on the data in the BPSupportedMIMETypes struct int variantCount = info.fVariantCount; info.fMimeTypeArray = static_cast(NS_Alloc(variantCount * sizeof(char*))); diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp index 35f741b8d55a..a2cf57d182a7 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -1221,9 +1221,10 @@ nsHttpConnectionMgr::nsHalfOpenSocket::~nsHalfOpenSocket() LOG(("Destroying nsHalfOpenSocket [this=%p]\n", this)); if (mEnt) { - PRInt32 index = mEnt->mHalfOpens.IndexOf(this); - NS_ABORT_IF_FALSE(index != -1, "half open complete but no item"); - mEnt->mHalfOpens.RemoveElementAt(index); + // A failure to create the transport object at all + // will result in this not being present in the halfopen table + // so ignore failures of RemoveElement() + mEnt->mHalfOpens.RemoveElement(this); } } diff --git a/netwerk/test/Makefile.in b/netwerk/test/Makefile.in index a7b493469d02..15b468dee54a 100644 --- a/netwerk/test/Makefile.in +++ b/netwerk/test/Makefile.in @@ -68,6 +68,7 @@ SIMPLE_PROGRAMS = \ TestCookie$(BIN_SUFFIX) \ TestServ$(BIN_SUFFIX) \ ReadNTLM$(BIN_SUFFIX) \ + TestProtocols$(BIN_SUFFIX) \ $(NULL) ifndef MOZ_ENABLE_LIBXUL @@ -78,7 +79,6 @@ SIMPLE_PROGRAMS += \ TestStreamTransport$(BIN_SUFFIX) \ TestStreamChannel$(BIN_SUFFIX) \ TestStreamPump$(BIN_SUFFIX) \ - TestProtocols$(BIN_SUFFIX) \ TestIOThreads$(BIN_SUFFIX) \ TestUDPSocketProvider$(BIN_SUFFIX) \ $(NULL) diff --git a/netwerk/test/TestProtocols.cpp b/netwerk/test/TestProtocols.cpp index 8a498c8e6b7b..d530e48eaf53 100644 --- a/netwerk/test/TestProtocols.cpp +++ b/netwerk/test/TestProtocols.cpp @@ -310,7 +310,7 @@ TestAuthPrompt::PromptUsernameAndPassword(const PRUnichar *dialogTitle, *user = NS_StringCloneData(NS_ConvertUTF8toUTF16(buf)); const char *p; -#ifdef XP_UNIX +#if defined(XP_UNIX) && !defined(ANDROID) p = getpass("Enter password: "); #else printf("Enter password: "); @@ -538,7 +538,7 @@ InputTestConsumer::OnStopRequest(nsIRequest *request, nsISupports* context, } LOG(("\tTime to connect: %.3f seconds\n", connectTime)); LOG(("\tTime to read: %.3f seconds.\n", readTime)); - LOG(("\tRead: %lld bytes.\n", info->mBytesRead.mValue)); + LOG(("\tRead: %lld bytes.\n", info->mBytesRead)); if (info->mBytesRead == PRInt64(0)) { } else if (readTime > 0.0) { LOG(("\tThroughput: %.0f bps.\n", (PRFloat64)(info->mBytesRead*PRInt64(8))/readTime)); diff --git a/netwerk/test/unit/test_bug652761.js b/netwerk/test/unit/test_bug652761.js new file mode 100644 index 000000000000..4a7d26190ef1 --- /dev/null +++ b/netwerk/test/unit/test_bug652761.js @@ -0,0 +1,18 @@ +// This is just a crashtest for a url that is rejected at parse time (port 80,000) + +function completeTest(request, data, ctx) +{ + do_test_finished(); +} + +function run_test() +{ + var ios = Components.classes["@mozilla.org/network/io-service;1"]. + getService(Components.interfaces.nsIIOService); + var chan = ios.newChannel("http://localhost:80000/", "", null); + var httpChan = chan.QueryInterface(Components.interfaces.nsIHttpChannel); + httpChan.asyncOpen(new ChannelListener(completeTest, + httpChan, CL_EXPECT_FAILURE), null); + do_test_pending(); +} + diff --git a/other-licenses/atk-1.0/atk/atk.h b/other-licenses/atk-1.0/atk/atk.h index d0bfb9085827..37379d09abef 100644 --- a/other-licenses/atk-1.0/atk/atk.h +++ b/other-licenses/atk-1.0/atk/atk.h @@ -20,6 +20,8 @@ #ifndef __ATK_H__ #define __ATK_H__ +#define __ATK_H_INSIDE__ + #include #include #include @@ -33,11 +35,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -46,4 +50,6 @@ #include #include +#undef __ATK_H_INSIDE__ + #endif /* __ATK_H__ */ diff --git a/other-licenses/atk-1.0/atk/atkplug.h b/other-licenses/atk-1.0/atk/atkplug.h new file mode 100644 index 000000000000..7d6efd4b9d21 --- /dev/null +++ b/other-licenses/atk-1.0/atk/atkplug.h @@ -0,0 +1,61 @@ +/* ATK - Accessibility Toolkit + * Copyright 2009 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if defined(ATK_DISABLE_SINGLE_INCLUDES) && !defined (__ATK_H_INSIDE__) && !defined (ATK_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __ATK_PLUG_H__ +#define __ATK_PLUG_H__ + +G_BEGIN_DECLS + +#define ATK_TYPE_PLUG (atk_plug_get_type ()) +#define ATK_PLUG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_PLUG, AtkPlug)) +#define ATK_IS_PLUG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_PLUG)) +#define ATK_PLUG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ATK_TYPE_PLUG, AtkPlugClass)) +#define ATK_IS_PLUG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ATK_TYPE_PLUG)) +#define ATK_PLUG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ATK_TYPE_PLUG, AtkPlugClass)) + +typedef struct _AtkPlug AtkPlug; +typedef struct _AtkPlugClass AtkPlugClass; + +struct _AtkPlug +{ + AtkObject parent; +}; + +GType atk_plug_get_type (void); + +struct _AtkPlugClass +{ + AtkObjectClass parent_class; + + /* to be subscribed to by atk-bridge */ + + /*< protected >*/ + gchar* (* get_object_id) (AtkPlug* obj); +}; + +AtkObject* atk_plug_new (void); +gchar* atk_plug_get_id (AtkPlug* plug); + +G_END_DECLS + +#endif /* __ATK_PLUG_H__ */ diff --git a/other-licenses/atk-1.0/atk/atksocket.h b/other-licenses/atk-1.0/atk/atksocket.h new file mode 100644 index 000000000000..813d4f3c97a7 --- /dev/null +++ b/other-licenses/atk-1.0/atk/atksocket.h @@ -0,0 +1,65 @@ +/* ATK - Accessibility Toolkit + * Copyright 2009 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if defined(ATK_DISABLE_SINGLE_INCLUDES) && !defined (__ATK_H_INSIDE__) && !defined (ATK_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __ATK_SOCKET_H__ +#define __ATK_SOCKET_H__ + +G_BEGIN_DECLS + +#define ATK_TYPE_SOCKET (atk_socket_get_type ()) +#define ATK_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_SOCKET, AtkSocket)) +#define ATK_IS_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_SOCKET)) +#define ATK_SOCKET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ATK_TYPE_SOCKET, AtkSocketClass)) +#define ATK_IS_SOCKET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ATK_TYPE_SOCKET)) +#define ATK_SOCKET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ATK_TYPE_SOCKET, AtkSocketClass)) + +typedef struct _AtkSocket AtkSocket; +typedef struct _AtkSocketClass AtkSocketClass; + +struct _AtkSocket +{ + AtkObject parent; + + /*< private >*/ + gchar* embedded_plug_id; +}; + +GType atk_socket_get_type (void); + +struct _AtkSocketClass +{ + AtkObjectClass parent_class; + + /* to be subscribed to by atk-bridge */ + + /*< protected >*/ + void (* embed) (AtkSocket *obj, gchar* plug_id); +}; + +AtkObject* atk_socket_new (void); +void atk_socket_embed (AtkSocket* obj, gchar* plug_id); +gboolean atk_socket_is_occupied (AtkSocket* obj); + +G_END_DECLS + +#endif /* __ATK_SOCKET_H__ */ diff --git a/parser/html/nsHtml5Parser.cpp b/parser/html/nsHtml5Parser.cpp index 0859295b9f3e..510beaa5eb20 100644 --- a/parser/html/nsHtml5Parser.cpp +++ b/parser/html/nsHtml5Parser.cpp @@ -398,6 +398,8 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer, // Lazily initialize if uninitialized mDocWriteSpeculativeTreeBuilder = new nsHtml5TreeBuilder(nsnull, mExecutor->GetStage()); + mDocWriteSpeculativeTreeBuilder->setScriptingEnabled( + mTreeBuilder->isScriptingEnabled()); mDocWriteSpeculativeTokenizer = new nsHtml5Tokenizer(mDocWriteSpeculativeTreeBuilder); mDocWriteSpeculativeTokenizer->setInterner(&mAtomTable); diff --git a/parser/htmlparser/tests/mochitest/Makefile.in b/parser/htmlparser/tests/mochitest/Makefile.in index b6425cd4f55a..d2b4ebef5cf8 100644 --- a/parser/htmlparser/tests/mochitest/Makefile.in +++ b/parser/htmlparser/tests/mochitest/Makefile.in @@ -84,6 +84,8 @@ _TEST_FILES = parser_datreader.js \ file_bug594730-9.html \ test_bug599584.html \ iframe_bug599584.html \ + test_bug642908.html \ + file_bug642908.sjs \ test_bug645115.html \ $(NULL) diff --git a/parser/htmlparser/tests/mochitest/file_bug642908.sjs b/parser/htmlparser/tests/mochitest/file_bug642908.sjs new file mode 100644 index 000000000000..73ba20288dab --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug642908.sjs @@ -0,0 +1,16 @@ +function handleRequest(request, response) +{ + if (request.queryString.indexOf("report") != -1) { + response.setHeader("Content-Type", "text/javascript", false); + if (getState("loaded") == "loaded") { + response.write("ok(false, 'There was an attempt to preload the image.');"); + } else { + response.write("ok(true, 'There was no attempt to preload the image.');"); + } + response.write("SimpleTest.finish();"); + } else { + setState("loaded", "loaded"); + response.setHeader("Content-Type", "image/svg", false); + response.write("Not supposed to load this"); + } +} diff --git a/parser/htmlparser/tests/mochitest/test_bug642908.html b/parser/htmlparser/tests/mochitest/test_bug642908.html new file mode 100644 index 000000000000..0adb31c451a8 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/test_bug642908.html @@ -0,0 +1,33 @@ + + + + + Test for Bug 642908 + + + + + +Mozilla Bug 642908 +

+ +
+
+
+ + diff --git a/security/manager/boot/src/Makefile.in b/security/manager/boot/src/Makefile.in index e206dd839d05..d1c53fe19c38 100644 --- a/security/manager/boot/src/Makefile.in +++ b/security/manager/boot/src/Makefile.in @@ -49,7 +49,6 @@ LIBRARY_NAME = pipboot IS_COMPONENT = 1 MODULE_NAME = BOOT EXPORT_LIBRARY = 1 -META_COMPONENT = crypto GRE_MODULE = 1 LIBXUL_LIBRARY = 1 diff --git a/security/manager/pki/src/Makefile.in b/security/manager/pki/src/Makefile.in index ce4b61ed6662..6a6d36bd0bb4 100644 --- a/security/manager/pki/src/Makefile.in +++ b/security/manager/pki/src/Makefile.in @@ -50,7 +50,6 @@ LIBRARY_NAME = pippki IS_COMPONENT = 1 MODULE_NAME = PKI EXPORT_LIBRARY = 1 -META_COMPONENT = crypto GRE_MODULE = 1 LIBXUL_LIBRARY = 1 diff --git a/security/manager/ssl/src/Makefile.in b/security/manager/ssl/src/Makefile.in index c9dd6bf759f6..4e301a5e11d4 100644 --- a/security/manager/ssl/src/Makefile.in +++ b/security/manager/ssl/src/Makefile.in @@ -50,7 +50,6 @@ LIBRARY_NAME = pipnss IS_COMPONENT = 1 MODULE_NAME = NSS EXPORT_LIBRARY = 1 -META_COMPONENT = crypto GRE_MODULE = 1 LIBXUL_LIBRARY = 1 diff --git a/security/manager/ssl/src/nsCertVerificationThread.cpp b/security/manager/ssl/src/nsCertVerificationThread.cpp index 42c0069777a8..b70d448ce69c 100644 --- a/security/manager/ssl/src/nsCertVerificationThread.cpp +++ b/security/manager/ssl/src/nsCertVerificationThread.cpp @@ -133,14 +133,13 @@ void nsCertVerificationThread::Run(void) { MutexAutoLock threadLock(verification_thread_singleton->mMutex); - while (mExitState == ePSMThreadRunning && - (0 == verification_thread_singleton->mJobQ.GetSize())) { + while (!mExitRequested && (0 == verification_thread_singleton->mJobQ.GetSize())) { // no work to do ? let's wait a moment mCond.Wait(); } - if (mExitState != ePSMThreadRunning) + if (mExitRequested) break; job = static_cast(mJobQ.PopFront()); @@ -161,7 +160,6 @@ void nsCertVerificationThread::Run(void) static_cast(mJobQ.PopFront()); delete job; } - verification_thread_singleton->mExitState = ePSMThreadStopped; } } diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index 9673f1fbc67a..d0b55cf8846b 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -398,12 +398,14 @@ nsNSSComponent::~nsNSSComponent() { mSSLThread->requestExit(); delete mSSLThread; + mSSLThread = nsnull; } if (mCertVerificationThread) { mCertVerificationThread->requestExit(); delete mCertVerificationThread; + mCertVerificationThread = nsnull; } PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsNSSComponent::dtor\n")); @@ -2532,18 +2534,11 @@ nsNSSComponent::DoProfileBeforeChange(nsISupports* aSubject) void nsNSSComponent::DoProfileChangeNetRestore() { - /* XXX this doesn't work well, since nothing expects null pointers */ - if (mSSLThread) { - mSSLThread->requestExit(); delete mSSLThread; - } mSSLThread = new nsSSLThread(); if (mSSLThread) mSSLThread->startThread(); - if (mCertVerificationThread) { - mCertVerificationThread->requestExit(); delete mCertVerificationThread; - } mCertVerificationThread = new nsCertVerificationThread(); if (mCertVerificationThread) mCertVerificationThread->startThread(); diff --git a/security/manager/ssl/src/nsPSMBackgroundThread.cpp b/security/manager/ssl/src/nsPSMBackgroundThread.cpp index 201542ed10b7..592e31d114bf 100644 --- a/security/manager/ssl/src/nsPSMBackgroundThread.cpp +++ b/security/manager/ssl/src/nsPSMBackgroundThread.cpp @@ -36,7 +36,6 @@ * ***** END LICENSE BLOCK ***** */ #include "nsPSMBackgroundThread.h" -#include "nsThreadUtils.h" using namespace mozilla; @@ -50,7 +49,7 @@ nsPSMBackgroundThread::nsPSMBackgroundThread() : mThreadHandle(nsnull), mMutex("nsPSMBackgroundThread.mMutex"), mCond(mMutex, "nsPSMBackgroundThread.mCond"), - mExitState(ePSMThreadRunning) + mExitRequested(PR_FALSE) { } @@ -71,13 +70,6 @@ nsPSMBackgroundThread::~nsPSMBackgroundThread() { } -PRUint32 nsPSMBackgroundThread::GetExitStateThreadSafe() -{ - MutexAutoLock threadLock(mMutex); - - return mExitState; -} - void nsPSMBackgroundThread::requestExit() { if (!mThreadHandle) @@ -86,21 +78,13 @@ void nsPSMBackgroundThread::requestExit() { MutexAutoLock threadLock(mMutex); - if (mExitState != ePSMThreadRunning) + if (mExitRequested) return; - mExitState = ePSMThreadStopRequested; + mExitRequested = PR_TRUE; mCond.NotifyAll(); } - // We cannot rely on posting/processing events at this point, because the - // event loop has already terminated by the time we reach here. - while (GetExitStateThreadSafe() < ePSMThreadStopped) { - NS_ProcessNextEvent(nsnull, PR_FALSE); - if (GetExitStateThreadSafe() < ePSMThreadStopped) - PR_Sleep(PR_SecondsToInterval(5)); - } - PR_JoinThread(mThreadHandle); mThreadHandle = nsnull; } diff --git a/security/manager/ssl/src/nsPSMBackgroundThread.h b/security/manager/ssl/src/nsPSMBackgroundThread.h index bc65fe471993..0683ad104112 100644 --- a/security/manager/ssl/src/nsPSMBackgroundThread.h +++ b/security/manager/ssl/src/nsPSMBackgroundThread.h @@ -43,12 +43,6 @@ #include "mozilla/CondVar.h" #include "mozilla/Mutex.h" -enum { - ePSMThreadRunning = 0, - ePSMThreadStopRequested = 1, - ePSMThreadStopped = 2 -}; - class nsPSMBackgroundThread { protected: @@ -59,7 +53,7 @@ protected: PRThread *mThreadHandle; // Shared mutex used for condition variables, - // and to protect access to mExitState. + // and to protect access to mExitRequested. // Derived classes may use it to protect additional // resources. mozilla::Mutex mMutex; @@ -68,7 +62,7 @@ protected: mozilla::CondVar mCond; // Has termination of the SSL thread been requested? - PRUint32 mExitState; + PRBool mExitRequested; public: nsPSMBackgroundThread(); @@ -76,9 +70,6 @@ public: nsresult startThread(); void requestExit(); - -private: - PRUint32 GetExitStateThreadSafe(); }; diff --git a/security/manager/ssl/src/nsSSLThread.cpp b/security/manager/ssl/src/nsSSLThread.cpp index 4085b944a296..e8fdbc811966 100644 --- a/security/manager/ssl/src/nsSSLThread.cpp +++ b/security/manager/ssl/src/nsSSLThread.cpp @@ -510,7 +510,7 @@ PRInt32 nsSSLThread::requestRead(nsNSSSocketInfo *si, void *buf, PRInt32 amount, { MutexAutoLock threadLock(ssl_thread_singleton->mMutex); - if (ssl_thread_singleton->mExitState != ePSMThreadRunning) { + if (ssl_thread_singleton->mExitRequested) { PR_SetError(PR_UNKNOWN_ERROR, 0); return -1; } @@ -737,7 +737,7 @@ PRInt32 nsSSLThread::requestWrite(nsNSSSocketInfo *si, const void *buf, PRInt32 { MutexAutoLock threadLock(ssl_thread_singleton->mMutex); - if (ssl_thread_singleton->mExitState != ePSMThreadRunning) { + if (ssl_thread_singleton->mExitRequested) { PR_SetError(PR_UNKNOWN_ERROR, 0); return -1; } @@ -958,7 +958,7 @@ void nsSSLThread::Run(void) continue; // go back and finally destroy it, before doing anything else } - if (mExitState != ePSMThreadRunning) + if (mExitRequested) break; PRBool pending_work = PR_FALSE; @@ -981,12 +981,12 @@ void nsSSLThread::Run(void) mCond.Wait(); } - } while (!pending_work && mExitState == ePSMThreadRunning && !mSocketScheduledToBeDestroyed); + } while (!pending_work && !mExitRequested && !mSocketScheduledToBeDestroyed); if (mSocketScheduledToBeDestroyed) continue; - if (mExitState != ePSMThreadRunning) + if (mExitRequested) break; if (!pending_work) @@ -1134,7 +1134,6 @@ void nsSSLThread::Run(void) PR_SetPollableEvent(nsSSLIOLayerHelpers::mSharedPollableEvent); } } - ssl_thread_singleton->mExitState = ePSMThreadStopped; } } @@ -1145,7 +1144,7 @@ PRBool nsSSLThread::exitRequested() // no lock - return ssl_thread_singleton->mExitState != ePSMThreadRunning; + return ssl_thread_singleton->mExitRequested; } nsSSLThread *nsSSLThread::ssl_thread_singleton = nsnull; diff --git a/toolkit/Makefile.in b/toolkit/Makefile.in index 4ac7f3a90849..ee06b264475d 100644 --- a/toolkit/Makefile.in +++ b/toolkit/Makefile.in @@ -63,13 +63,6 @@ PARALLEL_DIRS = \ themes \ $(NULL) -ifeq ($(OS_ARCH),WINCE) -ifdef WINCE_WINDOWS_MOBILE -DIRS += mozapps/readstrings -DIRS += mozapps/installer/wince -endif -endif - ifneq (,$(filter gtk2 qt,$(MOZ_WIDGET_TOOLKIT))) PARALLEL_DIRS += system/unixproxy endif diff --git a/toolkit/components/Makefile.in b/toolkit/components/Makefile.in index 52fa4af3bd62..c3e2d8f1bc93 100644 --- a/toolkit/components/Makefile.in +++ b/toolkit/components/Makefile.in @@ -120,10 +120,6 @@ ifdef MOZ_URL_CLASSIFIER PARALLEL_DIRS += url-classifier endif -ifdef MOZ_FASTSTART -PARALLEL_DIRS += faststart -endif - DIRS += \ build \ $(NULL) diff --git a/toolkit/components/alerts/resources/content/alert.js b/toolkit/components/alerts/resources/content/alert.js index 20931b2b78be..40d5ab806728 100644 --- a/toolkit/components/alerts/resources/content/alert.js +++ b/toolkit/components/alerts/resources/content/alert.js @@ -142,7 +142,6 @@ function onAlertLoad() if (window.innerWidth == contentDim.width + 1) --window.innerWidth; -#ifndef WINCE // Start with a 1px width/height, because 0 causes trouble with gtk1/2 gCurrentSize = 1; @@ -157,7 +156,6 @@ function onAlertLoad() gFinalSize = window.outerHeight; window.outerHeight = gCurrentSize; } -#endif // Determine position var x = gOrigin & NS_ALERT_LEFT ? screen.availLeft : @@ -173,11 +171,7 @@ function onAlertLoad() window.moveTo(x, y); -#ifndef WINCE setTimeout(animateAlert, gSlideTime); -#else - setTimeout(closeAlert, gOpenTime); -#endif } function animate(step) diff --git a/toolkit/components/downloads/nsDownloadManager.cpp b/toolkit/components/downloads/nsDownloadManager.cpp index 8559154c58dd..c1055202a562 100644 --- a/toolkit/components/downloads/nsDownloadManager.cpp +++ b/toolkit/components/downloads/nsDownloadManager.cpp @@ -69,7 +69,7 @@ #include "nsEmbedCID.h" #include "nsToolkitCompsCID.h" -#if defined(XP_WIN) && !defined(WINCE) +#ifdef XP_WIN #include #ifdef DOWNLOAD_SCANNER #include "nsDownloadScanner.h" @@ -1139,7 +1139,7 @@ nsDownloadManager::GetDefaultDownloadsDirectory(nsILocalFile **aResult) NS_GET_IID(nsILocalFile), getter_AddRefs(downloadDir)); NS_ENSURE_SUCCESS(rv, rv); -#elif defined(XP_WIN) && !defined(WINCE) +#elif defined(XP_WIN) rv = dirService->Get(NS_WIN_DEFAULT_DOWNLOAD_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(downloadDir)); @@ -2243,7 +2243,7 @@ nsDownload::SetState(DownloadState aState) } } -#if (defined(XP_WIN) && !defined(WINCE)) || defined(XP_MACOSX) || defined(ANDROID) +#if defined(XP_WIN) || defined(XP_MACOSX) || defined(ANDROID) nsCOMPtr fileURL = do_QueryInterface(mTarget); nsCOMPtr file; nsAutoString path; diff --git a/toolkit/components/faststart/FastStartup.js b/toolkit/components/faststart/FastStartup.js deleted file mode 100644 index ac2aefe86423..000000000000 --- a/toolkit/components/faststart/FastStartup.js +++ /dev/null @@ -1,210 +0,0 @@ -/* -*- Mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil; -*- */ -/* ***** 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 FastStartup.js - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Vladimir Vukicevic - * Brian Crowder - * - * 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 ***** */ - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; -const Cu = Components.utils; - -const Timer = Components.Constructor("@mozilla.org/timer;1", "nsITimer", "initWithCallback"); - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -const RESTART_ENV_VAR = "FASTSTART_INITIATED_RESTART"; - -function setenv(key, value) { - let env = Cc["@mozilla.org/process/environment;1"]. - getService(Components.interfaces.nsIEnvironment); - env.set(key, value); -} - -function getenv(key) { - let env = Cc["@mozilla.org/process/environment;1"]. - getService(Components.interfaces.nsIEnvironment); - return env.get(key); -} - -function nsFastStartupObserver() { - let _browserWindowCount = 0; - let _memCleanupTimer; - let _restartTimer; - let _isShuttingDown; - - function stopMemoryCleanup() { - if (_memCleanupTimer) { - _memCleanupTimer.cancel(); - _memCleanupTimer = null; - } - - if (_restartTimer) { - _restartTimer.cancel(); - _restartTimer = null; - } - } - - function scheduleMemoryCleanup() { - if (_isShuttingDown) - return; - - stopMemoryCleanup(); - - function restart() { - setenv(RESTART_ENV_VAR, "1"); - setenv("NO_SPLASH", "1"); - let appstartup = Cc["@mozilla.org/toolkit/app-startup;1"]. - getService(Ci.nsIAppStartup); - appstartup.quit(Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit); - - _restartTimer = null; - } - - function memoryCleanup() { - var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); - - // Do this 3 times, because of a comment in TestGtkEmbed that says this - // gives the cycle collector the best chance at purging things. - os.notifyObservers(null, "memory-pressure", "heap-minimize"); - os.notifyObservers(null, "memory-pressure", "heap-minimize"); - os.notifyObservers(null, "memory-pressure", "heap-minimize"); - - _memCleanupTimer = null; - } - - // wait 30s until firing off the memory cleanup, in case the user - // opens another window right away - _memCleanupTimer = new Timer(memoryCleanup, 30000, Ci.nsITimer.TYPE_ONE_SHOT); - - // Also, begin a countdown to restart the stub in 15 minutes - _restartTimer = new Timer(restart, 60000 * 15, Ci.nsITimer.TYPE_ONE_SHOT); - } - - // - // nsIObserver - // - this.observe = function observe(subject, topic, data) { - var win = subject; - - // XXX the window at this point won't actually have its document loaded -- - // win.document.documentURI will pretty much always be about:blank. We need - // to attach a load handler to actually figure out which document gets loaded. - if (topic == "domwindowopened") { - stopMemoryCleanup(); - _browserWindowCount++; - } else if (topic == "domwindowclosed") { - if (_browserWindowCount > 0) - _browserWindowCount--; - if (_browserWindowCount == 0) { - scheduleMemoryCleanup(); - let prefservice = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService); - prefservice.savePrefFile(null); - } - } else if (topic == "quit-application-granted") { - stopMemoryCleanup(); - _isShuttingDown = true; - let appstartup = Cc["@mozilla.org/toolkit/app-startup;1"]. - getService(Ci.nsIAppStartup); - appstartup.exitLastWindowClosingSurvivalArea(); - } - } - - /* - * QueryInterface - * We expect the WindowWatcher service to retain a strong reference to us, so supporting - * weak references is fine. - */ - this.QueryInterface = XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]); -} - -function nsFastStartupCLH() { } - -nsFastStartupCLH.prototype = { - // - // nsICommandLineHandler - // - handle: function fs_handle(cmdLine) { - // the rest of this only handles -faststart here - - if (cmdLine.handleFlag("shutdown-faststart", false)) { - cmdLine.preventDefault = true; - // Shutdown this service - let appstartup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup); - appstartup.quit(Ci.nsIAppStartup.eAttemptQuit); - return; - } - - if (cmdLine.handleFlag("faststart-hidden", false) || (getenv(RESTART_ENV_VAR) == "1")) - cmdLine.preventDefault = true; - - try { - // did we already initialize faststart? if so, - // nothing to do here. - if (this.inited) - return; - - this.inited = true; - - // Clear this environment variable for subsequent runs - setenv(RESTART_ENV_VAR, "0"); - - let fsobs = new nsFastStartupObserver(); - let wwatch = Cc["@mozilla.org/embedcomp/window-watcher;1"]. - getService(Ci.nsIWindowWatcher); - wwatch.registerNotification(fsobs); - - let obsService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); - obsService.addObserver(fsobs, "quit-application-granted", true); - - let appstartup = Cc["@mozilla.org/toolkit/app-startup;1"]. - getService(Ci.nsIAppStartup); - appstartup.enterLastWindowClosingSurvivalArea(); - } catch (e) { - Cu.reportError(e); - } - }, - - helpInfo: " -faststart-hidden Start the FastStart service\n" + - " -shutdown-faststart Shutdown the FastStart service\n", - - // QI - QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler]), - - // XPCOMUtils factory - classID: Components.ID("{580c6c51-f690-4ce1-9ecc-b678e0c031c7}"), -}; - -var NSGetFactory = XPCOMUtils.generateNSGetFactory([nsFastStartupCLH]); diff --git a/toolkit/components/faststart/FastStartup.manifest b/toolkit/components/faststart/FastStartup.manifest deleted file mode 100644 index 7ee5d7abc5f9..000000000000 --- a/toolkit/components/faststart/FastStartup.manifest +++ /dev/null @@ -1,3 +0,0 @@ -component {580c6c51-f690-4ce1-9ecc-b678e0c031c7} FastStartup.js -contract @mozilla.org/browser/faststart;1 {580c6c51-f690-4ce1-9ecc-b678e0c031c7} -category command-line-handler 00-faststart @mozilla.org/browser/faststart;1 diff --git a/toolkit/components/faststart/Makefile.in b/toolkit/components/faststart/Makefile.in deleted file mode 100644 index 78d99bb0ca44..000000000000 --- a/toolkit/components/faststart/Makefile.in +++ /dev/null @@ -1,63 +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 Mozilla Browser code. -# -# The Initial Developer of the Original Code is the Mozilla Foundation. -# Portions created by the Initial Developer are Copyright (C) 2009 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Vladimir Vukicevic -# -# 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 - -DEFINES += -DMOZ_NO_MOZALLOC - -EXTRA_PP_COMPONENTS = \ - FastStartup.js \ - FastStartup.manifest \ - $(NULL) - -ifdef _MSC_VER -ifdef WINCE -CPPSRCS = \ - faststartstub.cpp \ - $(NULL) - -SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX)) \ - -WIN32_EXE_LDFLAGS += -ENTRY:WinMainCRTStartup -endif -endif - -include $(topsrcdir)/config/rules.mk diff --git a/toolkit/components/faststart/faststartstub.cpp b/toolkit/components/faststart/faststartstub.cpp deleted file mode 100644 index b4f1bceea689..000000000000 --- a/toolkit/components/faststart/faststartstub.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include -#include -#include - -int WINAPI -WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPTSTR lpCmdLine, - int nCmdShow) -{ - PROCESS_INFORMATION pi; - STARTUPINFOW si = { 0 }; - wchar_t modfilename[MAX_PATH]; - wchar_t execname[MAX_PATH]; - wchar_t args[MAX_PATH]; - wcscpy(args, L"-nosplash -faststart-hidden"); - - HMODULE mod = GetModuleHandle(NULL); - GetModuleFileNameW(mod, modfilename, sizeof(modfilename)/sizeof(modfilename[0])); - wchar_t *chomp = wcsstr(modfilename, L"faststart.exe"); - if (!chomp) { - MessageBoxW(NULL, L"Couldn't figure out how to run the faststart service!", L"Faststart Fail", MB_OK); - return 0; - } - - size_t len = chomp - modfilename; - wcsncpy(execname, modfilename, len); - execname[len] = 0; - wcscat(execname, L".exe"); - - BOOL ok = CreateProcessW(execname, args, NULL, NULL, FALSE, 0, - NULL, NULL, &si, &pi); - if (!ok) { - MessageBoxW(NULL, L"Couldn't figure out how to run the faststart service!", L"Faststart Fail", MB_OK); - return 0; - } - return 0; -} diff --git a/toolkit/components/startup/Makefile.in b/toolkit/components/startup/Makefile.in index a454a38b56f6..3fd35bb3fe20 100644 --- a/toolkit/components/startup/Makefile.in +++ b/toolkit/components/startup/Makefile.in @@ -55,7 +55,7 @@ CPPSRCS = \ ifeq (os2,$(MOZ_WIDGET_TOOLKIT)) CPPSRCS += nsUserInfoOS2.cpp else -ifeq (,$(filter-out WINCE WINNT,$(OS_ARCH))) +ifeq ($(OS_ARCH),WINNT) CPPSRCS += nsUserInfoWin.cpp else ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) diff --git a/toolkit/components/startup/nsUserInfoWin.cpp b/toolkit/components/startup/nsUserInfoWin.cpp index 3de31fbabb8f..26d487c0c8ee 100644 --- a/toolkit/components/startup/nsUserInfoWin.cpp +++ b/toolkit/components/startup/nsUserInfoWin.cpp @@ -56,7 +56,6 @@ NS_IMPL_ISUPPORTS1(nsUserInfo,nsIUserInfo) NS_IMETHODIMP nsUserInfo::GetUsername(char **aUsername) { -#ifndef WINCE *aUsername = nsnull; PRUnichar username[256]; @@ -66,9 +65,8 @@ nsUserInfo::GetUsername(char **aUsername) return NS_ERROR_FAILURE; *aUsername = ToNewUTF8String(nsDependentString(username)); - if (*aUsername) return NS_OK; -#endif - return NS_ERROR_FAILURE; + + return (*aUsername) ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP diff --git a/toolkit/content/license.html b/toolkit/content/license.html index b8fa170a1d18..50711ae8a547 100644 --- a/toolkit/content/license.html +++ b/toolkit/content/license.html @@ -3617,7 +3617,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  • This software is based in part on the work of the Independent JPEG Group.
  • -
  • Portions of the OS/2, Windows Mobile and Android versions +
  • Portions of the OS/2 and Android versions of this software are copyright ©1996-2010 The FreeType Project. All rights reserved.
  • diff --git a/toolkit/library/Makefile.in b/toolkit/library/Makefile.in index dacf2dad82dc..45665ec1e95c 100644 --- a/toolkit/library/Makefile.in +++ b/toolkit/library/Makefile.in @@ -70,10 +70,6 @@ ifeq ($(OS_ARCH)_$(GNU_CC),WINNT_) CPPSRCS += dlldeps-xul.cpp endif -ifeq ($(OS_ARCH),WINCE) -CPPSRCS += dlldeps-xul.cpp -endif - ifeq ($(OS_ARCH),OS2) CPPSRCS += dlldeps-xul.cpp endif @@ -130,7 +126,7 @@ GARBAGE += \ endif endif -ifneq (,$(filter OS2 WINCE WINNT,$(OS_ARCH))) +ifneq (,$(filter OS2 WINNT,$(OS_ARCH))) SDK_LIBRARY = $(IMPORT_LIBRARY) else SDK_LIBRARY = $(SHARED_LIBRARY) @@ -227,13 +223,6 @@ ifdef MOZ_CRASHREPORTER OS_LIBS += $(call EXPAND_LIBNAME,wininet) endif endif # WINNT -ifeq ($(OS_ARCH),WINCE) -OS_LIBS += $(call EXPAND_LIBNAME, aygshell uuid ole32 oleaut32 Ws2 ddraw) -OS_LIBS += $(call EXPAND_LIBNAME, ceosutil libcmt comsuppw) -ifdef WINCE_WINDOWS_MOBILE -OS_LIBS += $(call EXPAND_LIBNAME, cellcore) -endif -endif ifdef MOZ_JPROF EXTRA_DSO_LDOPTS += -ljprof diff --git a/toolkit/library/libxul-config.mk b/toolkit/library/libxul-config.mk index c3a555655348..23a88182c36d 100644 --- a/toolkit/library/libxul-config.mk +++ b/toolkit/library/libxul-config.mk @@ -41,7 +41,7 @@ CPPSRCS += \ nsStaticXULComponents.cpp \ $(NULL) -ifeq (,$(filter-out WINCE WINNT,$(OS_ARCH))) +ifeq ($(OS_ARCH),WINNT) REQUIRES += widget gfx CPPSRCS += \ nsDllMain.cpp \ @@ -115,13 +115,8 @@ STATIC_LIBS += \ xpcom_core \ ucvutil_s \ chromium_s \ - $(NULL) - -ifndef WINCE -STATIC_LIBS += \ mozreg_s \ $(NULL) -endif # component libraries COMPONENT_LIBS += \ diff --git a/toolkit/library/libxul-rules.mk b/toolkit/library/libxul-rules.mk index d30ce5394fa1..16143e2382bc 100644 --- a/toolkit/library/libxul-rules.mk +++ b/toolkit/library/libxul-rules.mk @@ -55,10 +55,8 @@ DEFINES += \ $(NULL) ifeq ($(MOZ_WIDGET_TOOLKIT),windows) -ifneq ($(OS_ARCH),WINCE) OS_LIBS += $(call EXPAND_LIBNAME,usp10 oleaut32) endif -endif export:: dlldeps.cpp diff --git a/toolkit/library/nsDllMain.cpp b/toolkit/library/nsDllMain.cpp index 5380854bcde4..b26dcdd86f0a 100644 --- a/toolkit/library/nsDllMain.cpp +++ b/toolkit/library/nsDllMain.cpp @@ -46,11 +46,7 @@ extern "C" { #endif BOOL APIENTRY DllMain( -#ifdef WINCE - HANDLE hModule, -#else HINSTANCE hModule, -#endif DWORD reason, LPVOID lpReserved ) { diff --git a/toolkit/library/nsStaticXULComponents.cpp b/toolkit/library/nsStaticXULComponents.cpp index 13f61f62facf..4719bd5a51c2 100644 --- a/toolkit/library/nsStaticXULComponents.cpp +++ b/toolkit/library/nsStaticXULComponents.cpp @@ -283,6 +283,7 @@ MODULE(jsperf) \ SERVICES_CRYPTO_MODULE \ MOZ_APP_COMPONENT_MODULES \ + MODULE(nsTelemetryModule) \ /* end of list */ #define MODULE(_name) \ diff --git a/toolkit/locales/l10n.mk b/toolkit/locales/l10n.mk index ceab1928705d..ba4b69bf165f 100644 --- a/toolkit/locales/l10n.mk +++ b/toolkit/locales/l10n.mk @@ -155,10 +155,6 @@ endif $(NSINSTALL) -D $(DIST)/l10n-stage/$(PKG_PATH) cd $(DIST)/l10n-stage; \ $(MAKE_PACKAGE) -ifeq (WINCE,$(OS_ARCH)) - cd $(DIST)/l10n-stage; \ - $(MAKE_CAB) -endif ifdef MAKE_COMPLETE_MAR $(MAKE) -C $(MOZDEPTH)/tools/update-packaging full-update AB_CD=$(AB_CD) \ MOZ_PKG_PRETTYNAMES=$(MOZ_PKG_PRETTYNAMES) \ @@ -177,9 +173,6 @@ endif $(MAKE) clobber-zip AB_CD=$(AB_CD) $(NSINSTALL) -D $(DIST)/$(PKG_PATH) mv -f "$(DIST)/l10n-stage/$(PACKAGE)" "$(ZIP_OUT)" -ifeq (WINCE,$(OS_ARCH)) - mv -f "$(DIST)/l10n-stage/$(PKG_BASENAME).cab" "$(DIST)/$(PKG_PATH)$(PKG_BASENAME).cab" -endif repackage-zip-%: $(STAGEDIST) @$(MAKE) repackage-zip AB_CD=$* ZIP_IN="$(ZIP_IN)" diff --git a/toolkit/mozapps/downloads/content/downloads.js b/toolkit/mozapps/downloads/content/downloads.js index d6dc678cb45f..9ddb998f4de9 100644 --- a/toolkit/mozapps/downloads/content/downloads.js +++ b/toolkit/mozapps/downloads/content/downloads.js @@ -295,7 +295,6 @@ function openDownload(aDownload) } catch (e) { } #ifdef XP_WIN -#ifndef WINCE // On Vista and above, we rely on native security prompting for // downloaded content unless it's disabled. try { @@ -306,7 +305,6 @@ function openDownload(aDownload) dontAsk = true; } } catch (ex) { } -#endif #endif if (!dontAsk) { @@ -492,12 +490,10 @@ function Startup() }, false); #ifdef XP_WIN -#ifndef WINCE let tempScope = {}; Cu.import("resource://gre/modules/DownloadTaskbarProgress.jsm", tempScope); tempScope.DownloadTaskbarProgress.onDownloadWindowLoad(window); #endif -#endif } function Shutdown() diff --git a/toolkit/mozapps/extensions/XPIProvider.jsm b/toolkit/mozapps/extensions/XPIProvider.jsm index efc27a94f9cd..45fb3f92cf6e 100644 --- a/toolkit/mozapps/extensions/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/XPIProvider.jsm @@ -198,7 +198,7 @@ SafeInstallOperation.prototype = { " to " + aTargetDirectory.path, e); throw e; } - this._installedFiles.push({ oldFile: null, newFile: newFile }); + this._installedFiles.push({ oldFile: oldFile, newFile: newFile }); }, _installDirectory: function(aDirectory, aTargetDirectory, aCopy) { diff --git a/toolkit/mozapps/extensions/content/extensions.js b/toolkit/mozapps/extensions/content/extensions.js index 977a8d0be40a..1f029c7e787c 100644 --- a/toolkit/mozapps/extensions/content/extensions.js +++ b/toolkit/mozapps/extensions/content/extensions.js @@ -1948,11 +1948,11 @@ var gSearchView = { var elements = []; function createSearchResults(aObjsList, aIsInstall, aIsRemote) { - aObjsList.forEach(function(aObj) { - let score = 0; - if (aQuery.length > 0) { + aObjsList.forEach(function(aObj, aIndex) { + let score = aObjsList.length - aIndex; + if (!aIsRemote && aQuery.length > 0) { score = self.getMatchScore(aObj, aQuery); - if (score == 0 && !aIsRemote) + if (score == 0) return; } diff --git a/toolkit/mozapps/extensions/test/browser/browser_searching.js b/toolkit/mozapps/extensions/test/browser/browser_searching.js index d5bffda77a9c..960d8b4225a5 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_searching.js +++ b/toolkit/mozapps/extensions/test/browser/browser_searching.js @@ -212,8 +212,8 @@ function get_expected_results(aSortBy, aLocalExpected) { var expectedOrder = null, unknownOrder = null; switch (aSortBy) { case "relevancescore": - expectedOrder = [ "remote4" , "addon2", "remote1" , "remote2", - "install2", "addon1", "install1", "remote3" ]; + expectedOrder = [ "addon2" , "remote1", "install2", "addon1", + "install1", "remote2", "remote3" , "remote4" ]; unknownOrder = []; break; case "name": diff --git a/toolkit/mozapps/installer/packager.mk b/toolkit/mozapps/installer/packager.mk index 2ed05d207a33..97f47c3c934a 100644 --- a/toolkit/mozapps/installer/packager.mk +++ b/toolkit/mozapps/installer/packager.mk @@ -47,7 +47,7 @@ ifndef MOZ_PKG_FORMAT ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) MOZ_PKG_FORMAT = DMG else -ifeq (,$(filter-out OS2 WINNT WINCE, $(OS_ARCH))) +ifeq (,$(filter-out OS2 WINNT, $(OS_ARCH))) MOZ_PKG_FORMAT = ZIP else ifeq (,$(filter-out SunOS, $(OS_ARCH))) @@ -67,7 +67,7 @@ endif endif endif # MOZ_PKG_FORMAT -ifneq (,$(filter WINNT WINCE,$(OS_ARCH))) +ifeq ($(OS_ARCH),WINNT) INSTALLER_DIR = windows endif @@ -83,22 +83,8 @@ SDK_SUFFIX = $(PKG_SUFFIX) SDK = $(SDK_PATH)$(PKG_BASENAME).sdk$(SDK_SUFFIX) MAKE_PACKAGE = $(error What is a $(MOZ_PKG_FORMAT) package format?); -MAKE_CAB = $(error Don't know how to make a CAB!); _ABS_DIST = $(call core_abspath,$(DIST)) -ifdef WINCE -ifndef WINCE_WINDOWS_MOBILE -CABARGS += -s -endif -ifdef MOZ_FASTSTART -CABARGS += -faststart -endif -VSINSTALLDIR ?= $(error VSINSTALLDIR not set, must be set to the Visual Studio install directory) -MAKE_CAB = $(PYTHON) $(MOZILLA_DIR)/build/package/wince/make_wince_cab.py \ - $(CABARGS) "$(VSINSTALLDIR)/SmartDevices/SDK/SDKTools/cabwiz.exe" \ - "$(MOZ_PKG_DIR)" "$(MOZ_APP_DISPLAYNAME)" "$(PKG_PATH)$(PKG_BASENAME).cab" -endif - CREATE_FINAL_TAR = $(TAR) -c --owner=0 --group=0 --numeric-owner \ --mode="go-w" -f UNPACK_TAR = tar -xf- @@ -127,11 +113,6 @@ INNER_MAKE_PACKAGE = $(ZIP) -r9D $(PACKAGE) $(MOZ_PKG_DIR) INNER_UNMAKE_PACKAGE = $(UNZIP) $(UNPACKAGE) MAKE_SDK = $(ZIP) -r9D $(SDK) $(MOZ_APP_NAME)-sdk endif -ifeq ($(MOZ_PKG_FORMAT),CAB) -PKG_SUFFIX = .cab -INNER_MAKE_PACKAGE = $(MAKE_CAB) -INNER_UNMAKE_PACKAGE = $(error Unpacking CAB files is not supported) -endif ifeq ($(MOZ_PKG_FORMAT),SFX7Z) PKG_SUFFIX = .exe INNER_MAKE_PACKAGE = rm -f app.7z && \ @@ -535,7 +516,7 @@ ifeq ($(OS_ARCH),OS2) STRIP = $(MOZILLA_DIR)/toolkit/mozapps/installer/os2/strip.cmd endif -ifneq (,$(filter WINNT WINCE OS2,$(OS_ARCH))) +ifneq (,$(filter WINNT OS2,$(OS_ARCH))) PKGCP_OS = dos else PKGCP_OS = unix @@ -698,7 +679,7 @@ make-sourcestamp-file:: # dist/sdk/lib -> prefix/lib/appname-devel-version/lib # prefix/lib/appname-devel-version/* symlinks to the above directories install:: stage-package -ifneq (,$(filter WINNT WINCE,$(OS_ARCH))) +ifeq ($(OS_ARCH),WINNT) $(error "make install" is not supported on this platform. Use "make package" instead.) endif ifeq (bundle,$(MOZ_FS_LAYOUT)) @@ -762,9 +743,6 @@ make-sdk: ifeq ($(OS_TARGET), WINNT) INSTALLER_PACKAGE = $(DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe endif -ifeq ($(OS_TARGET), WINCE) -INSTALLER_PACKAGE = $(DIST)/$(PKG_PATH)$(PKG_BASENAME).cab -endif # These are necessary because some of our packages/installers contain spaces # in their filenames and GNU Make's $(wildcard) function doesn't properly diff --git a/toolkit/mozapps/installer/wince/Makefile.in b/toolkit/mozapps/installer/wince/Makefile.in deleted file mode 100644 index 98993c75c024..000000000000 --- a/toolkit/mozapps/installer/wince/Makefile.in +++ /dev/null @@ -1,76 +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 Fennec Installer for WinCE. -# -# The Initial Developer of the Original Code is The Mozilla Foundation. -# -# Portions created by the Initial Developer are Copyright (C) 2009 -# the Mozilla Foundation . All Rights Reserved. -# -# Contributor(s): -# Alex Pakhotin (original author) -# -# 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 - -export NO_SHUNT = 1 -USE_STATIC_LIBS = 1 - -PROGRAM = xulrunner-stub-installer.sfx - -REQUIRES = lib7z - -CPPSRCS = \ - nsInstaller.cpp \ - nsInstallerDlg.cpp \ - nsArchiveExtractor.cpp \ - ns7zipExtractor.cpp \ - nsSetupStrings.cpp \ - $(NULL) - -LOCAL_INCLUDES += -I$(srcdir)/../../readstrings - -RCINCLUDE = nsInstallerppc.rc - -DEFINES += -D_UNICODE - -LIBS += $(DEPTH)/toolkit/mozapps/readstrings/$(LIB_PREFIX)readstrings.$(LIB_SUFFIX) \ - $(DIST)/lib/7z.lib \ - $(NULL) - -OS_LIBS += aygshell.lib commctrl.lib note_prj.lib oleaut32.lib ole32.lib libcmt.lib coredll.lib corelibc.lib - -WIN32_EXE_LDFLAGS += -ENTRY:WinMain - -DIRS += uninstall - -include $(topsrcdir)/config/rules.mk diff --git a/toolkit/mozapps/installer/wince/ns7zipExtractor.cpp b/toolkit/mozapps/installer/wince/ns7zipExtractor.cpp deleted file mode 100644 index 5e0cb70a6c6d..000000000000 --- a/toolkit/mozapps/installer/wince/ns7zipExtractor.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */ -/* ***** 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 Fennec Installer for WinCE. - * - * The Initial Developer of the Original Code is The Mozilla Foundation. - * - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Alex Pakhotin (original author) - * - * 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 "wtypes.h" -#include "nsArchiveExtractor.h" -#include "ns7zipExtractor.h" -#include "7zLib.h" - -static nsExtractorProgress *g_pProgress = NULL; - -static void ExtractProgressCallback(int nPercentComplete) -{ - if (g_pProgress) - { - g_pProgress->Progress(nPercentComplete); - } -} - -static void ShowError() -{ - MessageBoxW(GetForegroundWindow(), GetExtractorError(), L"Extractor", MB_OK|MB_ICONERROR); -} - -ns7zipExtractor::ns7zipExtractor(const WCHAR *sArchiveName, DWORD dwSfxStubSize, nsExtractorProgress *pProgress) : - nsArchiveExtractor(sArchiveName, dwSfxStubSize, pProgress) -{ - g_pProgress = pProgress; -} - -ns7zipExtractor::~ns7zipExtractor() -{ - g_pProgress = NULL; -} - -int ns7zipExtractor::Extract(const WCHAR *sDestinationDir) -{ - int res = SzExtractSfx(m_sArchiveName, m_dwSfxStubSize, NULL, sDestinationDir, ExtractProgressCallback); - if (res != 0) - ShowError(); - return res; -} - -int ns7zipExtractor::ExtractFile(const WCHAR *sFileName, const WCHAR *sDestinationDir) -{ - int res = SzExtractSfx(m_sArchiveName, m_dwSfxStubSize, sFileName, sDestinationDir, NULL); - if (res != 0) - ShowError(); - return res; -} diff --git a/toolkit/mozapps/installer/wince/ns7zipExtractor.h b/toolkit/mozapps/installer/wince/ns7zipExtractor.h deleted file mode 100644 index 1e5dc24089d1..000000000000 --- a/toolkit/mozapps/installer/wince/ns7zipExtractor.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */ -/* ***** 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 Fennec Installer for WinCE. - * - * The Initial Developer of the Original Code is The Mozilla Foundation. - * - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Alex Pakhotin (original author) - * - * 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 ***** */ - -#pragma once - -#include "nsArchiveExtractor.h" - -class ns7zipExtractor : public nsArchiveExtractor -{ -public: - ns7zipExtractor(const WCHAR *sArchiveName, DWORD dwSfxStubSize, nsExtractorProgress *pProgress); - virtual ~ns7zipExtractor(); - - virtual int Extract(const WCHAR *sDestinationDir); - virtual int ExtractFile(const WCHAR *sFileName, const WCHAR *sDestinationDir); -}; diff --git a/toolkit/mozapps/installer/wince/nsArchiveExtractor.cpp b/toolkit/mozapps/installer/wince/nsArchiveExtractor.cpp deleted file mode 100644 index 79bed63d825a..000000000000 --- a/toolkit/mozapps/installer/wince/nsArchiveExtractor.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */ -/* ***** 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 Fennec Installer for WinCE. - * - * The Initial Developer of the Original Code is The Mozilla Foundation. - * - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Alex Pakhotin (original author) - * - * 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 "wtypes.h" -#include "nsArchiveExtractor.h" - -nsArchiveExtractor::nsArchiveExtractor(const WCHAR *sArchiveName, DWORD dwSfxStubSize, nsExtractorProgress *pProgress) : - m_sArchiveName(NULL), m_pProgress(pProgress), m_dwSfxStubSize(dwSfxStubSize) -{ - if (sArchiveName) - m_sArchiveName = wcsdup(sArchiveName); -} - -nsArchiveExtractor::~nsArchiveExtractor() -{ - free(m_sArchiveName); -} - -int nsArchiveExtractor::Extract(const WCHAR *sDestinationDir) -{ - return OK; -} - -int nsArchiveExtractor::ExtractFile(const WCHAR *sFileName, const WCHAR *sDestinationDir) -{ - return OK; -} diff --git a/toolkit/mozapps/installer/wince/nsInstaller.cpp b/toolkit/mozapps/installer/wince/nsInstaller.cpp deleted file mode 100644 index 7fbd9157992b..000000000000 --- a/toolkit/mozapps/installer/wince/nsInstaller.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */ -/* ***** 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 Fennec Installer for WinCE. - * - * The Initial Developer of the Original Code is The Mozilla Foundation. - * - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Alex Pakhotin (original author) - * - * 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 ***** */ - -/** - * - * nsInstaller.cpp : Mozilla Fennec Installer - * - */ - -#include -#include -#include "nsSetupStrings.h" -#include "nsInstaller.h" -#include "ns7zipExtractor.h" -#include "nsInstallerDlg.h" - -const WCHAR c_sStringsFile[] = L"setup.ini"; - -// Global Variables: -nsSetupStrings Strings; - -HINSTANCE g_hInst; -WCHAR g_sSourcePath[MAX_PATH]; -WCHAR g_sExeFullFileName[MAX_PATH]; -WCHAR g_sExeFileName[MAX_PATH]; -DWORD g_dwExeSize; - -// Forward declarations of functions included in this code module: -BOOL InitInstance(HINSTANCE, int); -DWORD GetExeSize(); -BOOL PostExtract(); -BOOL LoadStrings(); - -/////////////////////////////////////////////////////////////////////////////// -// -// WinMain -// -/////////////////////////////////////////////////////////////////////////////// -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPTSTR lpCmdLine, - int nCmdShow) -{ - int nResult = -1; - - if (!InitInstance(hInstance, nCmdShow)) - return nResult; - - nsInstallerDlg::GetInstance()->Init(g_hInst); - nResult = nsInstallerDlg::GetInstance()->DoModal(); - - return nResult; -} - -/////////////////////////////////////////////////////////////////////////////// -// -// InitInstance -// -/////////////////////////////////////////////////////////////////////////////// -BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) -{ - g_hInst = hInstance; - - InitCommonControls(); - - g_sExeFileName[0] = L'\0'; - if (GetModuleFileName(NULL, g_sExeFullFileName, MAX_PATH) == 0) - return FALSE; - - wcscpy(g_sSourcePath, g_sExeFullFileName); - WCHAR *sSlash = wcsrchr(g_sSourcePath, L'\\'); - wcscpy(g_sExeFileName, sSlash + 1); - *sSlash = L'\0'; // cut the file name - - g_dwExeSize = GetExeSize(); - - return LoadStrings(); -} - -/////////////////////////////////////////////////////////////////////////////// -// -// GetExeSize -// -/////////////////////////////////////////////////////////////////////////////// - -DWORD AbsoluteSeek(HANDLE, DWORD); -void ReadBytes(HANDLE, LPVOID, DWORD); - -DWORD GetExeSize() -{ - DWORD dwSize = 0; - HANDLE hImage; - - DWORD dwSectionOffset; - DWORD dwCoffHeaderOffset; - DWORD moreDosHeader[16]; - - ULONG NTSignature; - - IMAGE_DOS_HEADER image_dos_header; - IMAGE_FILE_HEADER image_file_header; - IMAGE_OPTIONAL_HEADER image_optional_header; - IMAGE_SECTION_HEADER image_section_header; - - // Open the EXE file. - hImage = CreateFile(g_sExeFullFileName, GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (INVALID_HANDLE_VALUE == hImage) - { - ErrorMsg(L"Could not open the EXE"); - return 0; - } - - // Read the MS-DOS image header. - ReadBytes(hImage, &image_dos_header, sizeof(image_dos_header)); - - if (IMAGE_DOS_SIGNATURE != image_dos_header.e_magic) - { - ErrorMsg(L"Unknown file format."); - return 0; - } - - // Read more MS-DOS header. - ReadBytes(hImage, moreDosHeader, sizeof(moreDosHeader)); - - // Get actual COFF header. - dwCoffHeaderOffset = AbsoluteSeek(hImage, image_dos_header.e_lfanew) + sizeof(ULONG); - - ReadBytes (hImage, &NTSignature, sizeof(NTSignature)); - - if (IMAGE_NT_SIGNATURE != NTSignature) - { - ErrorMsg(L"Missing NT signature. Unknown file type."); - return 0; - } - - dwSectionOffset = dwCoffHeaderOffset + IMAGE_SIZEOF_FILE_HEADER + IMAGE_SIZEOF_NT_OPTIONAL_HEADER; - - ReadBytes(hImage, &image_file_header, IMAGE_SIZEOF_FILE_HEADER); - - // Read optional header. - ReadBytes(hImage, &image_optional_header, IMAGE_SIZEOF_NT_OPTIONAL_HEADER); - - WORD nNumSections = image_file_header.NumberOfSections; - - for (WORD i = 0; i < nNumSections; i++) - { - ReadBytes(hImage, &image_section_header, sizeof(IMAGE_SECTION_HEADER)); - - DWORD dwRawData = image_section_header.PointerToRawData + image_section_header.SizeOfRawData; - if (dwRawData > dwSize) - dwSize = dwRawData; - } - - CloseHandle(hImage); - - return dwSize; -} - -DWORD AbsoluteSeek(HANDLE hFile, DWORD offset) -{ - DWORD newOffset; - - if ((newOffset = SetFilePointer(hFile, offset, NULL, FILE_BEGIN)) == 0xFFFFFFFF) - ErrorMsg(L"SetFilePointer failed"); - - return newOffset; -} - -void ReadBytes(HANDLE hFile, LPVOID buffer, DWORD size) -{ - DWORD bytes; - - if (!ReadFile(hFile, buffer, size, &bytes, NULL)) - ErrorMsg(L"ReadFile failed"); - else if (size != bytes) - ErrorMsg(L"Read the wrong number of bytes"); -} - -////////////////////////////////////////////////////////////////////////// -// -// Read strings resource from the attached archive -// -////////////////////////////////////////////////////////////////////////// -BOOL LoadStrings() -{ - WCHAR *sExtractPath = L"\\Temp\\"; - WCHAR sExtractedStringsFile[MAX_PATH]; - _snwprintf(sExtractedStringsFile, MAX_PATH, L"%s%s", sExtractPath, c_sStringsFile); - - ns7zipExtractor archiveExtractor(g_sExeFullFileName, g_dwExeSize, NULL); - - int nResult = archiveExtractor.ExtractFile(c_sStringsFile, sExtractPath); - - if (nResult != 0) - return FALSE; - - BOOL bResult = Strings.LoadStrings(sExtractedStringsFile); - DeleteFile(sExtractedStringsFile); - - return bResult; -} diff --git a/toolkit/mozapps/installer/wince/nsInstaller.h b/toolkit/mozapps/installer/wince/nsInstaller.h deleted file mode 100644 index 0efa979d034f..000000000000 --- a/toolkit/mozapps/installer/wince/nsInstaller.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */ -/* ***** 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 Fennec Installer for WinCE. - * - * The Initial Developer of the Original Code is The Mozilla Foundation. - * - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Alex Pakhotin (original author) - * - * 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 ***** */ - -#pragma once -#include "resourceppc.h" - -extern nsSetupStrings Strings; -extern const WCHAR c_sStringsFile[]; - -extern WCHAR g_sSourcePath[MAX_PATH]; -extern WCHAR g_sExeFileName[MAX_PATH]; -extern WCHAR g_sExeFullFileName[MAX_PATH]; -extern DWORD g_dwExeSize; - -#define ErrorMsg(msg) MessageBoxW(GetForegroundWindow(), msg, L"Setup", MB_OK|MB_ICONERROR) -bool ConvertToChar(const WCHAR *wstr, char *str); diff --git a/toolkit/mozapps/installer/wince/nsInstallerDlg.cpp b/toolkit/mozapps/installer/wince/nsInstallerDlg.cpp deleted file mode 100644 index 2f95edf01e82..000000000000 --- a/toolkit/mozapps/installer/wince/nsInstallerDlg.cpp +++ /dev/null @@ -1,524 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */ -/* ***** 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 Fennec Installer for WinCE. - * - * The Initial Developer of the Original Code is The Mozilla Foundation. - * - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Alex Pakhotin (original author) - * - * 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 ***** */ - -/** - * - * nsInstallerDlg.cpp : Mozilla Fennec Installer UI. - * - */ - -#include -#include -#include - -#include "nsSetupStrings.h" -#include "nsInstaller.h" -#include "ns7zipExtractor.h" -#include "nsInstallerDlg.h" - -#define WM_DIALOGCREATED (WM_USER + 1) - -const WCHAR c_sInstallPathTemplate[] = L"%s\\%s"; -const WCHAR c_sExtractCardPathTemplate[] = L"\\%s%s\\%s"; -const WCHAR c_sAppRegKeyTemplate[] = L"Software\\Mozilla\\%s"; -const WCHAR c_sFastStartTemplate[] = L"%s\\%sfaststart.exe"; - -// Message handler for the dialog -BOOL CALLBACK DlgMain(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - return nsInstallerDlg::GetInstance()->DlgMain(hDlg, message, wParam, lParam); -} - -/////////////////////////////////////////////////////////////////////////////// -// -// nsInstallerDlg dialog -// -/////////////////////////////////////////////////////////////////////////////// - -nsInstallerDlg::nsInstallerDlg() -{ - m_hInst = NULL; - m_hDlg = NULL; - m_bFastStart = FALSE; - m_sExtractPath[0] = 0; - m_sInstallPath[0] = 0; - m_sProgramFiles[0] = 0; - m_sErrorMsg[0] = 0; -} - -nsInstallerDlg* nsInstallerDlg::GetInstance() -{ - static nsInstallerDlg dlg; - return &dlg; -} - -void nsInstallerDlg::Init(HINSTANCE hInst) -{ - m_hInst = hInst; -} - -int nsInstallerDlg::DoModal() -{ - return (int)DialogBox(m_hInst, (LPCTSTR)IDD_MAIN, 0, ::DlgMain); -} - -BOOL CALLBACK nsInstallerDlg::DlgMain(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) - { - case WM_INITDIALOG: - return OnInitDialog(hDlg, wParam, lParam); - - case WM_DIALOGCREATED: - return OnDialogCreated(hDlg); - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - case IDCANCEL: - EndDialog(hDlg, LOWORD(wParam)); - return TRUE; - - case IDC_BTN_INSTALL: - if (OnBtnExtract()) - EndDialog(hDlg, IDOK); - return TRUE; - } - break; - - case WM_CLOSE: - EndDialog(hDlg, message); - return TRUE; - } - return FALSE; -} - -BOOL nsInstallerDlg::OnInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam) -{ - // Create a Done button and size it. - SHINITDLGINFO shidi; - shidi.dwMask = SHIDIM_FLAGS; - shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN | SHIDIF_EMPTYMENU; - shidi.hDlg = hDlg; - SHInitDialog(&shidi); - - m_hDlg = hDlg; - - SetWindowText(m_hDlg, Strings.GetString(StrID_WindowCaption)); - SetControlWindowText(IDC_STATIC_TITLE, Strings.GetString(StrID_WindowCaption)); - SetControlWindowText(IDC_STATIC_INSTALL, Strings.GetString(StrID_InstallTo)); - SetControlWindowText(IDC_BTN_INSTALL, Strings.GetString(StrID_Install)); - SetControlWindowText(IDCANCEL, Strings.GetString(StrID_Cancel)); - - if (!SHGetSpecialFolderPath(m_hDlg, m_sProgramFiles, CSIDL_PROGRAM_FILES, FALSE)) - wcscpy(m_sProgramFiles, L"\\Program Files"); - - _snwprintf(m_sInstallPath, MAX_PATH, c_sInstallPathTemplate, - m_sProgramFiles, Strings.GetString(StrID_AppShortName)); - - SendMessageToControl(IDC_CMB_PATH, CB_ADDSTRING, 0, (LPARAM)(m_sInstallPath)); - FindMemCards(); - SendMessageToControl(IDC_CMB_PATH, CB_SETCURSEL, 0, 0); - - EnableWindow(GetDlgItem(m_hDlg, IDC_BTN_INSTALL), FALSE); - - PostMessage(m_hDlg, WM_DIALOGCREATED, 0, 0); - - return TRUE; -} - -void nsInstallerDlg::FindMemCards() -{ - WIN32_FIND_DATA fd; - HANDLE hFlashCard = FindFirstFlashCard(&fd); - if (hFlashCard != INVALID_HANDLE_VALUE) - { - WCHAR sPath[MAX_PATH]; - do - { - if (wcslen(fd.cFileName) > 0) - { - _snwprintf(sPath, MAX_PATH, c_sExtractCardPathTemplate, - fd.cFileName, m_sProgramFiles, Strings.GetString(StrID_AppShortName)); - SendMessageToControl(IDC_CMB_PATH, CB_ADDSTRING, 0, (LPARAM)(sPath)); - } - } while(FindNextFlashCard(hFlashCard, &fd) && *fd.cFileName); - } -} - -BOOL nsInstallerDlg::OnDialogCreated(HWND hDlg) -{ - BOOL bUninstallCancelled = FALSE; - if (RunUninstall(&bUninstallCancelled) && bUninstallCancelled) - { - // Cancel installation - PostMessage(hDlg, WM_CLOSE, 0, 0); - } - else - EnableWindow(GetDlgItem(m_hDlg, IDC_BTN_INSTALL), TRUE); - - return TRUE; -} - -BOOL nsInstallerDlg::OnBtnExtract() -{ - BOOL bResult = FALSE; - - EnableWindow(GetDlgItem(m_hDlg, IDC_BTN_INSTALL), FALSE); - EnableWindow(GetDlgItem(m_hDlg, IDCANCEL), FALSE); - - int nPathIndex = SendMessageToControl(IDC_CMB_PATH, CB_GETCURSEL, 0, 0); - if (nPathIndex >= 0) - SendMessageToControl(IDC_CMB_PATH, CB_GETLBTEXT, nPathIndex, (LPARAM)(m_sInstallPath)); - - wcscpy(m_sExtractPath, m_sInstallPath); - - // Remove the last directory ("Fennec") from the path as it is already in the archive - WCHAR *sSlash = wcsrchr(m_sExtractPath, L'\\'); - if (sSlash) - *sSlash = 0; - - ns7zipExtractor archiveExtractor(g_sExeFullFileName, g_dwExeSize, this); - - SendMessageToControl(IDC_PROGRESS, PBM_SETRANGE, 0, (LPARAM) MAKELPARAM (0, 100)); // progress in percents - SendMessageToControl(IDC_PROGRESS, PBM_SETPOS, 0, 0); - - int nResult = archiveExtractor.Extract(m_sExtractPath); - if (nResult == 0) - { - Progress(100); // 100% - bResult = PostExtract(); - } - - EnableWindow(GetDlgItem(m_hDlg, IDC_BTN_INSTALL), TRUE); - EnableWindow(GetDlgItem(m_hDlg, IDCANCEL), TRUE); - - if (bResult) - { - MessageBoxW(m_hDlg, Strings.GetString(StrID_InstalledSuccessfully), - Strings.GetString(StrID_WindowCaption), MB_OK|MB_ICONINFORMATION); - } - else - { - WCHAR sMsg[c_nMaxErrorLen]; - if (nResult != 0) - _snwprintf(sMsg, c_nMaxErrorLen, L"%s %d", Strings.GetString(StrID_ExtractionError), nResult); - else - _snwprintf(sMsg, c_nMaxErrorLen, L"%s\n%s", Strings.GetString(StrID_ThereWereErrors), m_sErrorMsg); - - MessageBoxW(m_hDlg, sMsg, Strings.GetString(StrID_WindowCaption), MB_OK|MB_ICONERROR); - } - - return bResult; -} - -LRESULT nsInstallerDlg::SendMessageToControl(int nCtlID, UINT Msg, WPARAM wParam /*= 0*/, LPARAM lParam /*= 0*/) -{ - return SendMessage(GetDlgItem(m_hDlg, nCtlID), Msg, wParam, lParam); -} - -void nsInstallerDlg::SetControlWindowText(int nCtlID, const WCHAR *sText) -{ - SetWindowText(GetDlgItem(m_hDlg, nCtlID), sText); -} - -/////////////////////////////////////////////////////////////////////////////// -// -// ZipProgress member override -// -/////////////////////////////////////////////////////////////////////////////// -void nsInstallerDlg::Progress(int n) -{ - SendMessageToControl(IDC_PROGRESS, PBM_SETPOS, (WPARAM)n, 0); -} - -////////////////////////////////////////////////////////////////////////// -// -// PostExtract - additional step after extraction -// -////////////////////////////////////////////////////////////////////////// - -#define RUN_AND_CHECK(fn) \ - if (!fn()) { \ - bResult = FALSE; \ - AddErrorMsg(L ## #fn ## L" failed"); \ - } - -BOOL nsInstallerDlg::PostExtract() -{ - BOOL bResult = TRUE; - - m_bFastStart = FastStartFileExists(); - - RUN_AND_CHECK(CreateShortcut) - - RUN_AND_CHECK(StoreInstallPath) - - MoveSetupStrings(); - - RUN_AND_CHECK(SilentFirstRun) - - RUN_AND_CHECK(RunSetupCab) - - return bResult; -} - -BOOL nsInstallerDlg::StoreInstallPath() -{ - HKEY hKey; - WCHAR sRegFennecKey[MAX_PATH]; - _snwprintf(sRegFennecKey, MAX_PATH, c_sAppRegKeyTemplate, Strings.GetString(StrID_AppShortName)); - - // Store the installation path - to be used by the uninstaller - LONG result = RegCreateKeyEx(HKEY_LOCAL_MACHINE, sRegFennecKey, 0, REG_NONE, - REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL); - if (result == ERROR_SUCCESS) - { - result = RegSetValueEx(hKey, L"Path", 0, REG_SZ, (BYTE* const)m_sInstallPath, (wcslen(m_sInstallPath)+1)*sizeof(WCHAR)); - RegCloseKey(hKey); - } - - return (result == ERROR_SUCCESS); -} - -// Creates shortcuts for Fennec and (optionally) FastStart service. -// Note: The shortcut names have to be in sync with DeleteShortcut in Uninstaller.cpp -BOOL nsInstallerDlg::CreateShortcut() -{ - BOOL result = FALSE; - - WCHAR sFennecPath[MAX_PATH]; - _snwprintf(sFennecPath, MAX_PATH, L"\"%s\\%s.exe\"", m_sInstallPath, Strings.GetString(StrID_AppShortName)); - - WCHAR sProgramsPath[MAX_PATH]; - if (SHGetSpecialFolderPath(m_hDlg, sProgramsPath, CSIDL_PROGRAMS, FALSE)) - { - WCHAR sShortcutPath[MAX_PATH]; - _snwprintf(sShortcutPath, MAX_PATH, L"%s\\%s.lnk", sProgramsPath, Strings.GetString(StrID_AppShortName)); - - // Delete the old shortcut if it exists - if(SetFileAttributes(sShortcutPath, FILE_ATTRIBUTE_NORMAL)) - DeleteFile(sShortcutPath); - - result = SHCreateShortcut(sShortcutPath, sFennecPath); - } - - if (m_bFastStart) - { - WCHAR sFastStartPath[MAX_PATH]; - _snwprintf(sFastStartPath, MAX_PATH, L"\"%s\\%sfaststart.exe\"", m_sInstallPath, Strings.GetString(StrID_AppShortName)); - - WCHAR sStartupPath[MAX_PATH]; - if (SHGetSpecialFolderPath(m_hDlg, sStartupPath, CSIDL_STARTUP, FALSE)) - { - WCHAR sStartupShortcutPath[MAX_PATH]; - _snwprintf(sStartupShortcutPath, MAX_PATH, L"%s\\%sFastStart.lnk", sStartupPath, Strings.GetString(StrID_AppShortName)); - - if(SetFileAttributes(sStartupShortcutPath, FILE_ATTRIBUTE_NORMAL)) - DeleteFile(sStartupShortcutPath); - - result = SHCreateShortcut(sStartupShortcutPath, sFastStartPath) && result; - } - } - - return result; -} - -BOOL nsInstallerDlg::MoveSetupStrings() -{ - WCHAR sExtractedStringsFile[MAX_PATH]; - _snwprintf(sExtractedStringsFile, MAX_PATH, L"%s\\%s", m_sExtractPath, c_sStringsFile); - - WCHAR sNewStringsFile[MAX_PATH]; - _snwprintf(sNewStringsFile, MAX_PATH, L"%s\\%s", m_sInstallPath, c_sStringsFile); - - return MoveFile(sExtractedStringsFile, sNewStringsFile); -} - -BOOL nsInstallerDlg::SilentFirstRun() -{ - SetControlWindowText(IDC_STATUS_TEXT, Strings.GetString(StrID_CreatingUserProfile)); - UpdateWindow(m_hDlg); // make sure the text is drawn - - WCHAR sCmdLine[MAX_PATH]; - WCHAR *sParams = NULL; - if (m_bFastStart) - { - // Run fast start exe instead - it will create the profile and stay in the background - _snwprintf(sCmdLine, MAX_PATH, c_sFastStartTemplate, m_sInstallPath, Strings.GetString(StrID_AppShortName)); - } - else - { - _snwprintf(sCmdLine, MAX_PATH, L"%s\\%s.exe", m_sInstallPath, Strings.GetString(StrID_AppShortName)); - sParams = L"-silent -nosplash"; - } - PROCESS_INFORMATION pi; - BOOL bResult = CreateProcess(sCmdLine, sParams, - NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi); - if (bResult) - { - // Wait for it to finish (since the system is likely to be busy - // while it launches anyways). The process may never terminate - // if FastStart is enabled, so don't wait longer than 10 seconds. - WaitForSingleObject(pi.hProcess, 10000); - } - - if (m_bFastStart) - { - // When the FastStart is enabled, Fennec is being loaded in the background, - // user cannot launch it with a shortcut, and the system is busy at the moment, - // so we'll just wait here. - - // Class name: appName + "MessageWindow" - WCHAR sClassName[MAX_PATH]; - _snwprintf(sClassName, MAX_PATH, L"%s%s", Strings.GetString(StrID_AppShortName), L"MessageWindow"); - - // Wait until the hidden window gets created or for some timeout (~10s seems to be reasonable) - HWND handle = NULL; - for (int i = 0; i < 20 && !handle; i++) - { - handle = ::FindWindowW(sClassName, NULL); - Sleep(500); - } - } - - SetWindowText(GetDlgItem(m_hDlg, IDC_STATUS_TEXT), L""); - return bResult; -} - -BOOL nsInstallerDlg::RunSetupCab() -{ - BOOL bResult = FALSE; - - WCHAR sCabPath[MAX_PATH]; - WCHAR sParams[MAX_PATH + 20]; - _snwprintf(sCabPath, MAX_PATH, L"%s\\setup.cab", m_sInstallPath); - - // Run "wceload.exe /noui Fennec.cab" - _snwprintf(sParams, MAX_PATH, L"/noui \"%s\"", sCabPath); - PROCESS_INFORMATION pi; - bResult = CreateProcess(L"\\Windows\\wceload.exe", - sParams, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi); - if (bResult) - { - // Wait for it to finish - WaitForSingleObject(pi.hProcess, INFINITE); - } - - return bResult; -} - -void nsInstallerDlg::AddErrorMsg(WCHAR* sErr) -{ - WCHAR sMsg[c_nMaxErrorLen]; - _snwprintf(sMsg, c_nMaxErrorLen, L"%s. LastError = %d\n", sErr, GetLastError()); - wcsncat(m_sErrorMsg, sMsg, c_nMaxErrorLen - wcslen(m_sErrorMsg)); -} - -////////////////////////////////////////////////////////////////////////// -// -// Uninstall previous installation -// -////////////////////////////////////////////////////////////////////////// - -BOOL nsInstallerDlg::GetInstallPath(WCHAR *sPath) -{ - HKEY hKey; - WCHAR sRegFennecKey[MAX_PATH]; - _snwprintf(sRegFennecKey, MAX_PATH, c_sAppRegKeyTemplate, Strings.GetString(StrID_AppShortName)); - - LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, sRegFennecKey, 0, KEY_ALL_ACCESS, &hKey); - if (result == ERROR_SUCCESS) - { - DWORD dwType = NULL; - DWORD dwCount = MAX_PATH * sizeof(WCHAR); - result = RegQueryValueEx(hKey, L"Path", NULL, &dwType, (LPBYTE)sPath, &dwCount); - - RegCloseKey(hKey); - } - - return (result == ERROR_SUCCESS); -} - -BOOL nsInstallerDlg::RunUninstall(BOOL *pbCancelled) -{ - BOOL bResult = FALSE; - WCHAR sUninstallPath[MAX_PATH]; - if (GetInstallPath(sUninstallPath)) - { - if (wcslen(sUninstallPath) > 0 && sUninstallPath[wcslen(sUninstallPath)-1] != '\\') - wcscat(sUninstallPath, L"\\"); - - WCHAR sParam[MAX_PATH+10]; - _snwprintf(sParam, MAX_PATH+9, L"[remove] %s", sUninstallPath); - - wcscat(sUninstallPath, L"uninstall.exe"); - - PROCESS_INFORMATION pi; - bResult = CreateProcess(sUninstallPath, sParam, - NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi); - if (bResult) - { - // Wait for it to finish - WaitForSingleObject(pi.hProcess, INFINITE); - - if (pbCancelled != NULL) - { - DWORD dwExitCode = 0; - GetExitCodeProcess(pi.hProcess, &dwExitCode); - *pbCancelled = (dwExitCode == IDCANCEL); - } - } - } - return bResult; -} - -////////////////////////////////////////////////////////////////////////// -// -// Helper functions -// -////////////////////////////////////////////////////////////////////////// - -BOOL nsInstallerDlg::FastStartFileExists() -{ - WCHAR sFastStartPath[MAX_PATH]; - _snwprintf(sFastStartPath, MAX_PATH, c_sFastStartTemplate, m_sInstallPath, Strings.GetString(StrID_AppShortName)); - // Check if file exists - return (GetFileAttributes(sFastStartPath) != INVALID_FILE_ATTRIBUTES); -} diff --git a/toolkit/mozapps/installer/wince/nsInstallerDlg.h b/toolkit/mozapps/installer/wince/nsInstallerDlg.h deleted file mode 100644 index 80e52c5bee9e..000000000000 --- a/toolkit/mozapps/installer/wince/nsInstallerDlg.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */ -/* ***** 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 Fennec Installer for WinCE. - * - * The Initial Developer of the Original Code is The Mozilla Foundation. - * - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Alex Pakhotin (original author) - * - * 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 ***** */ - -#pragma once - -/** - * nsInstallerDlg dialog - */ -class nsInstallerDlg : public nsExtractorProgress -{ -public: - static nsInstallerDlg* GetInstance(); - void Init(HINSTANCE hInst); - int DoModal(); - virtual void Progress(int n); // gets progress notifications - INT_PTR DlgMain(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); - const WCHAR* GetExtractPath() { return m_sInstallPath; } - -private: - nsInstallerDlg(); - BOOL OnInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam); - void FindMemCards(); - BOOL OnDialogCreated(HWND hDlg); - BOOL OnBtnExtract(); - LRESULT SendMessageToControl(int nCtlID, UINT Msg, WPARAM wParam = 0, LPARAM lParam = 0); - void SetControlWindowText(int nCtlID, const WCHAR *sText); - - BOOL PostExtract(); - BOOL StoreInstallPath(); - BOOL CreateShortcut(); - BOOL MoveSetupStrings(); - BOOL SilentFirstRun(); - BOOL RunSetupCab(); - - BOOL GetInstallPath(WCHAR *sPath); - BOOL RunUninstall(BOOL *pbCancelled); - - void AddErrorMsg(WCHAR* sErr); - BOOL FastStartFileExists(); - - static const int c_nMaxErrorLen = 2048; - - HINSTANCE m_hInst; - HWND m_hDlg; - BOOL m_bFastStart; - WCHAR m_sProgramFiles[MAX_PATH]; - WCHAR m_sExtractPath[MAX_PATH]; - WCHAR m_sInstallPath[MAX_PATH]; - WCHAR m_sErrorMsg[c_nMaxErrorLen]; -}; diff --git a/toolkit/mozapps/installer/wince/nsInstallerppc.rc b/toolkit/mozapps/installer/wince/nsInstallerppc.rc deleted file mode 100644 index 13c4112acc29..000000000000 --- a/toolkit/mozapps/installer/wince/nsInstallerppc.rc +++ /dev/null @@ -1,162 +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 Fennec Installer for WinCE. - * - * The Initial Developer of the Original Code is The Mozilla Foundation. - * - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Alex Pakhotin (original author) - * - * 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 ***** */ - -// Microsoft Visual C++ generated resource script. -// -#include "resourceppc.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#define APSTUDIO_HIDDEN_SYMBOLS -#include "resdefce.h" -#undef APSTUDIO_HIDDEN_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_NSINSTALLER ICON "xulrunnerinstaller.ico" - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_MAIN DIALOG 0, 0, 156, 129 -STYLE DS_SETFONT | DS_SETFOREGROUND | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION -EXSTYLE 0x80000000L -CAPTION "Mozilla Setup" -FONT 8, "MS Shell Dlg" -BEGIN - ICON IDI_NSINSTALLER,IDC_STATIC,7,3,20,20,SS_REALSIZEIMAGE - LTEXT "XULRunner Setup",IDC_STATIC_TITLE,39,8,106,8,SS_NOPREFIX - LTEXT "Install XULRunner to",IDC_STATIC_INSTALL,2,26,142,11 - PUSHBUTTON "Install",IDC_BTN_INSTALL,2,57,70,20 - PUSHBUTTON "Cancel",IDCANCEL,84,57,70,20 - CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,2,84,152,9 - COMBOBOX IDC_CMB_PATH,2,37,152,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "",IDC_STATUS_TEXT,2,98,152,19 -END - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resourceppc.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""resdefce.h""\r\n" - "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n" - "LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US\r\n" - "#pragma code_page(1252)\r\n" - "#include ""nsInstallerppc.rc2"" // non-Microsoft Visual C++ edited resources\r\n" - "#endif\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_MAIN, DIALOG - BEGIN - LEFTMARGIN, 2 - RIGHTMARGIN, 154 - END -END -#endif // APSTUDIO_INVOKED - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#include "nsInstallerppc.rc2" // non-Microsoft Visual C++ edited resources -#endif - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/toolkit/mozapps/installer/wince/nsInstallerppc.rc2 b/toolkit/mozapps/installer/wince/nsInstallerppc.rc2 deleted file mode 100644 index 8dc2f2828d2d..000000000000 --- a/toolkit/mozapps/installer/wince/nsInstallerppc.rc2 +++ /dev/null @@ -1,17 +0,0 @@ -// -// nsInstallerPPC.rc2 - resources Microsoft Visual C++ does not edit directly -// - -#ifdef APSTUDIO_INVOKED -#error this file is not editable by Microsoft Visual C++ -#endif //APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// Add manually edited resources here... - -///////////////////////////////////////////////////////////////////////////// -HI_RES_AWARE CEUX {1} // turn off the emulation layer - // Remove this resource to enable pixel- - // doubling on platforms that support it -///////////////////////////////////////////////////////////////////////////// diff --git a/toolkit/mozapps/installer/wince/nsSetupStrings.cpp b/toolkit/mozapps/installer/wince/nsSetupStrings.cpp deleted file mode 100644 index e7676f791b59..000000000000 --- a/toolkit/mozapps/installer/wince/nsSetupStrings.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */ -/* ***** 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 Fennec Installer for WinCE. - * - * The Initial Developer of the Original Code is The Mozilla Foundation. - * - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Alex Pakhotin (original author) - * - * 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 ***** */ - -/** - * - * Class to work with localizable string resources - * - */ - -#include -#include "nsSetupStrings.h" -#include "readstrings.h" -#include "errors.h" - -#define STR_KEY(x) #x "\0" -const char *kSetupStrKeys = -#include "nsSetupStrings.inc" -; -#undef STR_KEY - -nsSetupStrings::nsSetupStrings() -{ - m_sBuf = NULL; - memset(m_arrStrings, 0, sizeof(m_arrStrings)); -} - -nsSetupStrings::~nsSetupStrings() -{ - delete[] m_sBuf; -} - -BOOL nsSetupStrings::LoadStrings(WCHAR *sFileName) -{ - if (!sFileName) - return FALSE; - - BOOL bResult = FALSE; - char strings[kNumberOfStrings][MAX_TEXT_LEN]; - if (ReadStrings(sFileName, kSetupStrKeys, kNumberOfStrings, strings) == OK) - { - int nSize = 0; - for (int i = 0; i < kNumberOfStrings; i++) - { - nSize += strlen(strings[i]) + 1; - } - - m_sBuf = new WCHAR[nSize]; - if (!m_sBuf) - return FALSE; - - WCHAR *p = m_sBuf; - for (int i = 0; i < kNumberOfStrings; i++) - { - int len = strlen(strings[i]) + 1; - MultiByteToWideChar(CP_UTF8, 0, strings[i], len, p, len); - m_arrStrings[i] = p; - p += len; - } - - bResult = TRUE; - } - - return bResult; -} - -const WCHAR* nsSetupStrings::GetString(int nID) -{ - if (nID >= kNumberOfStrings) - return L""; - else - return m_arrStrings[nID]; -} diff --git a/toolkit/mozapps/installer/wince/nsSetupStrings.h b/toolkit/mozapps/installer/wince/nsSetupStrings.h deleted file mode 100644 index 9c8d19657d68..000000000000 --- a/toolkit/mozapps/installer/wince/nsSetupStrings.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */ -/* ***** 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 Fennec Installer for WinCE. - * - * The Initial Developer of the Original Code is The Mozilla Foundation. - * - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Alex Pakhotin (original author) - * - * 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 ***** */ - -/** - * - * Class to work with localizable string resources - * - */ - -#pragma once - -#define STR_KEY(x) StrID_##x, -enum -{ - #include "nsSetupStrings.inc" - StrID_NumberOfStrings -}; -#undef STR_KEY - -class nsSetupStrings -{ -public: - nsSetupStrings(); - ~nsSetupStrings(); - - BOOL LoadStrings(TCHAR *sFileName); - const TCHAR* GetString(int nID); - -private: - - static const int kNumberOfStrings = StrID_NumberOfStrings; - TCHAR* m_sBuf; - TCHAR* m_arrStrings[kNumberOfStrings]; -}; diff --git a/toolkit/mozapps/installer/wince/nsSetupStrings.inc b/toolkit/mozapps/installer/wince/nsSetupStrings.inc deleted file mode 100644 index 396f369a4b65..000000000000 --- a/toolkit/mozapps/installer/wince/nsSetupStrings.inc +++ /dev/null @@ -1,15 +0,0 @@ - STR_KEY(AppShortName) - STR_KEY(AppLongName) - STR_KEY(WindowCaption) - STR_KEY(InstallTo) - STR_KEY(Install) - STR_KEY(Cancel) - STR_KEY(InstalledSuccessfully) - STR_KEY(ExtractionError) - STR_KEY(ThereWereErrors) - STR_KEY(CreatingUserProfile) - STR_KEY(UninstallCaption) - STR_KEY(FilesWillBeRemoved) - STR_KEY(AreYouSure) - STR_KEY(InstallationNotFound) - STR_KEY(UninstalledSuccessfully) diff --git a/toolkit/mozapps/installer/wince/readme.txt b/toolkit/mozapps/installer/wince/readme.txt deleted file mode 100644 index 30d96306fa58..000000000000 --- a/toolkit/mozapps/installer/wince/readme.txt +++ /dev/null @@ -1,13 +0,0 @@ -FennecInstaller implementation to replace CAB installer. - -This version extracts a 7z file appended to the EXE, i.e. works like a -self-extracted archive. - -For example if you want to install fennec-1.0a3pre.en-US.wince-arm.7z, build -the program, run the following command: - - cat fennec_installer.exe fennec-1.0a3pre.en-US.wince-arm.7z >fennec-1.0a3pre.en-US.wince-arm.exe - -Then copy fennec-1.0a3pre.en-US.wince-arm.exe to a device and run it. - -Note: Requires lib7z. diff --git a/toolkit/mozapps/installer/wince/resourceppc.h b/toolkit/mozapps/installer/wince/resourceppc.h deleted file mode 100644 index 22e01ca55a79..000000000000 --- a/toolkit/mozapps/installer/wince/resourceppc.h +++ /dev/null @@ -1,27 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by nsInstallerppc.rc -// -#define IDS_APP_TITLE 1 -#define IDI_NSINSTALLER 101 -#define IDR_MENU 102 -#define IDD_MAIN 103 -#define IDC_BTN_INSTALL 1000 -#define IDC_PROGRESS 1001 -#define IDC_CMB_PATH 1002 -#define IDC_STATUS_TEXT 1003 -#define IDC_STATIC_TITLE 1004 -#define IDC_STATIC_INSTALL 1005 -#define IDC_STATIC -1 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 129 -#define _APS_NEXT_COMMAND_VALUE 32771 -#define _APS_NEXT_CONTROL_VALUE 1006 -#define _APS_NEXT_SYMED_VALUE 110 -#endif -#endif diff --git a/toolkit/mozapps/installer/wince/uninstall/Makefile.in b/toolkit/mozapps/installer/wince/uninstall/Makefile.in deleted file mode 100644 index a7f1d29d2fa6..000000000000 --- a/toolkit/mozapps/installer/wince/uninstall/Makefile.in +++ /dev/null @@ -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 Fennec Installer for WinCE. -# -# The Initial Developer of the Original Code is The Mozilla Foundation. -# -# Portions created by the Initial Developer are Copyright (C) 2009 -# the Mozilla Foundation . All Rights Reserved. -# -# Contributor(s): -# Alex Pakhotin (original author) -# -# 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 - -PROGRAM = uninstall$(BIN_SUFFIX) - -CPPSRCS = \ - Uninstall.cpp \ - ../nsSetupStrings.cpp \ - $(NULL) - -LIBS += $(DEPTH)/toolkit/mozapps/readstrings/$(LIB_PREFIX)readstrings.$(LIB_SUFFIX) - -OS_LIBS += aygshell.lib commctrl.lib - -LOCAL_INCLUDES += -I$(srcdir)/.. -I$(srcdir)/../../../readstrings - -RCINCLUDE = Uninstall.rc - -# Statically link the CRT when possible -USE_STATIC_LIBS = 1 - -WIN32_EXE_LDFLAGS += -ENTRY:WinMain - -include $(topsrcdir)/config/rules.mk - diff --git a/toolkit/mozapps/installer/wince/uninstall/Uninstall.cpp b/toolkit/mozapps/installer/wince/uninstall/Uninstall.cpp deleted file mode 100644 index 84bd5f312eda..000000000000 --- a/toolkit/mozapps/installer/wince/uninstall/Uninstall.cpp +++ /dev/null @@ -1,543 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */ -/* ***** 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 Fennec Installer for WinCE. - * - * The Initial Developer of the Original Code is The Mozilla Foundation. - * - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Alex Pakhotin (original author) - * - * 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 ***** */ - -/** - * - * Uninstall.cpp : Mozilla Fennec Uninstaller - * - */ - -#include -#include -#include - -#include "nsSetupStrings.h" -#include "resource.h" - -#define WM_DIALOGCREATED (WM_USER + 1) - -const WCHAR c_sStringsFile[] = L"setup.ini"; -nsSetupStrings Strings; - -BOOL g_bRunFromSetupDll = FALSE; - -WCHAR g_sInstallPath[MAX_PATH]; -WCHAR g_sUninstallPath[MAX_PATH]; -HWND g_hDlg = NULL; - -const WCHAR c_sAppRegKeyTemplate[] = L"Software\\Mozilla\\%s"; - -const DWORD c_nTempBufSize = MAX_PATH * 2; -const WCHAR c_sRemoveParam[] = L"[remove]"; -const WCHAR c_sSetupParam[] = L"[setup]"; // means executed by Setup.dll - -// Retry counter for the file/directory deletion -int nTotalRetries = 0; -const int c_nMaxTotalRetries = 10; -const int c_nMaxOneFileRetries = 6; -const int c_nRetryDelay = 500; //milliseconds - -int g_nDirsDeleted = 0; -const int c_nMaxDirs = 25; // approximate number of dirs just to show some progress - -enum { - ErrOK = 0, - ErrCancel = IDCANCEL, - ErrNoStrings = -1, - ErrInstallationNotFound = -2, - ErrShutdownFailed = -3, -}; - -int g_nResult = ErrOK; - -// Forward declarations -BOOL GetModulePath(WCHAR *sPath); -BOOL LoadStrings(); -BOOL GetInstallPath(WCHAR *sPath); -BOOL DeleteShortcut(HWND hwndParent); -BOOL DeleteDirectory(const WCHAR* sPathToDelete); -BOOL DeleteRegistryKey(); -BOOL CopyAndLaunch(); -BOOL ShutdownFastStartService(const WCHAR *sInstallPath); -BOOL RunSystemUninstall(); - -BOOL CALLBACK DlgUninstall(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); -BOOL OnDialogInit(HWND hDlg); -BOOL OnDialogCreated(HWND hDlg); -int OnUninstall(HWND hDlg); -void UpdateProgress(); - -/////////////////////////////////////////////////////////////////////////////// -// Main -// -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPTSTR lpCmdLine, - int nCmdShow) -{ - HWND hWnd = GetForegroundWindow(); - *g_sUninstallPath = 0; - - WCHAR *sCommandLine = GetCommandLine(); - WCHAR *sRemoveParam = wcsstr(sCommandLine, c_sRemoveParam); - WCHAR g_bRunFromSetupDll = (wcsstr(sCommandLine, c_sSetupParam) != NULL); - if (sRemoveParam != NULL) - { - // Launched from a temp directory with parameters "[remove] \Program Files\Fennec\" - wcscpy(g_sUninstallPath, sRemoveParam + wcslen(c_sRemoveParam) + 1); - } - else - { - // Just copy this EXE and launch it from a temp location with a special parameter - // to delete itself in the installation directory - if (CopyAndLaunch()) - return ErrOK; - } - // Perform uninstallation when executed with a special parameter - // (or in case when CopyAndLaunch failed - just execute in place) - - if (!LoadStrings()) - { - MessageBoxW(hWnd, L"Cannot find the strings file.", L"Uninstall", MB_OK|MB_ICONWARNING); - return ErrNoStrings; - } - - if (GetInstallPath(g_sInstallPath)) - { - int nDlgResult = DialogBox(hInstance, (LPCTSTR)IDD_MAIN, NULL, (DLGPROC)DlgUninstall); - if (nDlgResult != ErrOK) - g_nResult = nDlgResult; - } - else - { - MessageBoxW(hWnd, Strings.GetString(StrID_InstallationNotFound), - Strings.GetString(StrID_UninstallCaption), MB_OK|MB_ICONINFORMATION); - return ErrInstallationNotFound; - } - - return g_nResult; -} - -int Uninstall(HWND hWnd) -{ - // Remove all installed files - DeleteDirectory(g_sInstallPath); - DeleteShortcut(hWnd); - DeleteRegistryKey(); - - if (!g_bRunFromSetupDll) - RunSystemUninstall(); - - // TODO: May probably handle errors during deletion (such as locked directories) - // and notify user. Right now just return OK. - return ErrOK; -} - -/////////////////////////////////////////////////////////////////////////////// -// Dialog -// -BOOL CALLBACK DlgUninstall(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) - { - case WM_INITDIALOG: - return OnDialogInit(hDlg); - - case WM_DIALOGCREATED: - return OnDialogCreated(hDlg); - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - EndDialog(hDlg, ErrOK); - return TRUE; - - case IDCANCEL: - EndDialog(hDlg, ErrCancel); - return TRUE; - - case IDC_BTN_UNINSTALL: - g_nResult = OnUninstall(hDlg); - return TRUE; - } - break; - - case WM_CLOSE: - EndDialog(hDlg, ErrCancel); - return TRUE; - } - return FALSE; -} - -BOOL OnDialogCreated(HWND) -{ - ShutdownFastStartService(g_sInstallPath); - // Just continue regardless of the result - return TRUE; -} - -BOOL OnDialogInit(HWND hDlg) -{ - g_hDlg = hDlg; - PostMessage(hDlg, WM_DIALOGCREATED, 0, 0); - - SetWindowText(hDlg, Strings.GetString(StrID_UninstallCaption)); - - SHINITDLGINFO shidi; - shidi.dwMask = SHIDIM_FLAGS; - shidi.dwFlags = SHIDIF_SIPDOWN | SHIDIF_EMPTYMENU; - shidi.hDlg = hDlg; - SHInitDialog(&shidi); - - // Hide the Done button - SHDoneButton(hDlg, SHDB_HIDE); - - // Init controls - WCHAR sMsg[c_nTempBufSize]; - _snwprintf(sMsg, c_nTempBufSize, L"%s %s", Strings.GetString(StrID_FilesWillBeRemoved), g_sInstallPath); - SetWindowText(GetDlgItem(hDlg, IDC_STATIC_TEXT), sMsg); - SetWindowText(GetDlgItem(hDlg, IDC_QUESTION_TEXT), Strings.GetString(StrID_AreYouSure)); - SetWindowText(GetDlgItem(hDlg, IDC_BTN_UNINSTALL), L"OK"); // TODO: Use localized text "Uninstall" - SetWindowText(GetDlgItem(hDlg, IDCANCEL), Strings.GetString(StrID_Cancel)); - ShowWindow(GetDlgItem(hDlg, IDC_PROGRESS), SW_HIDE); - ShowWindow(GetDlgItem(hDlg, IDOK), SW_HIDE); - - return TRUE; -} - -int OnUninstall(HWND hDlg) -{ - SetWindowText(GetDlgItem(hDlg, IDC_QUESTION_TEXT), L""); - ShowWindow(GetDlgItem(hDlg, IDC_BTN_UNINSTALL), SW_HIDE); - ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_HIDE); - ShowWindow(GetDlgItem(hDlg, IDC_PROGRESS), SW_SHOW); - SendMessage(GetDlgItem(hDlg, IDC_PROGRESS), PBM_SETRANGE, 0, (LPARAM) MAKELPARAM (0, c_nMaxDirs)); - SendMessage(GetDlgItem(hDlg, IDC_PROGRESS), PBM_SETPOS, 0, 0); - - UpdateWindow(hDlg); // make sure the text is drawn - - int ret = Uninstall(hDlg); - - if (ret == ErrOK) - { - SetWindowText(GetDlgItem(hDlg, IDC_STATIC_TEXT), Strings.GetString(StrID_UninstalledSuccessfully)); - } - else - { - //TODO: Localize this message. It might be shown later when the errors will be handled - SetWindowText(GetDlgItem(hDlg, IDC_STATIC_TEXT), L"There were errors during uninstallation."); - } - - ShowWindow(GetDlgItem(hDlg, IDC_PROGRESS), SW_HIDE); - ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); - - return ret; -} - -void UpdateProgress() -{ - SendMessage(GetDlgItem(g_hDlg, IDC_PROGRESS), PBM_SETPOS, (WPARAM)g_nDirsDeleted, 0); -} - -/////////////////////////////////////////////////////////////////////////////// -// Utility functions -// - -BOOL LoadStrings() -{ - // Locate and load the strings file used by installer - if (*g_sUninstallPath == 0) - GetModulePath(g_sUninstallPath); - - WCHAR sStringsFile[MAX_PATH]; - _snwprintf(sStringsFile, MAX_PATH, L"%s\\%s", g_sUninstallPath, c_sStringsFile); - - return Strings.LoadStrings(sStringsFile); -} - -BOOL GetModulePath(WCHAR *sPath) -{ - if (GetModuleFileName(NULL, sPath, MAX_PATH) == 0) - return FALSE; - - WCHAR *sSlash = wcsrchr(sPath, L'\\') + 1; - *sSlash = L'\0'; // cut the file name - - return TRUE; -} - -BOOL GetInstallPath(WCHAR *sPath) -{ - HKEY hKey; - WCHAR sRegFennecKey[MAX_PATH]; - _snwprintf(sRegFennecKey, MAX_PATH, c_sAppRegKeyTemplate, Strings.GetString(StrID_AppShortName)); - - LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, sRegFennecKey, 0, KEY_ALL_ACCESS, &hKey); - if (result == ERROR_SUCCESS) - { - DWORD dwType = NULL; - DWORD dwCount = MAX_PATH * sizeof(WCHAR); - result = RegQueryValueEx(hKey, L"Path", NULL, &dwType, (LPBYTE)sPath, &dwCount); - - RegCloseKey(hKey); - } - - return (result == ERROR_SUCCESS); -} - -BOOL DeleteDirectory(const WCHAR* sPathToDelete) -{ - BOOL bResult = TRUE; - HANDLE hFile; - WCHAR sFilePath[MAX_PATH]; - WCHAR sPattern[MAX_PATH]; - WIN32_FIND_DATA findData; - - wcscpy(sPattern, sPathToDelete); - wcscat(sPattern, L"\\*.*"); - hFile = FindFirstFile(sPattern, &findData); - if (hFile != INVALID_HANDLE_VALUE) - { - do - { - if (findData.cFileName[0] != L'.') - { - _snwprintf(sFilePath, MAX_PATH, L"%s\\%s", sPathToDelete, findData.cFileName); - - if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - // Delete subdirectory - if (!DeleteDirectory(sFilePath)) - bResult = FALSE; - } - else - { - // Set file attributes - if (SetFileAttributes(sFilePath, FILE_ATTRIBUTE_NORMAL)) - { - // Delete file - if (!DeleteFile(sFilePath) && nTotalRetries < c_nMaxTotalRetries) - { - BOOL bDeleted = FALSE; - nTotalRetries++; - for (int nRetry = 0; nRetry < c_nMaxOneFileRetries; nRetry++) - { - Sleep(c_nRetryDelay); - if (DeleteFile(sFilePath)) - { - bDeleted = TRUE; - break; - } - } - if (!bDeleted) - bResult = FALSE; - } - } - } - } - } while (FindNextFile(hFile, &findData)); - - // Close handle - FindClose(hFile); - } - - // Set directory attributes - if (SetFileAttributes(sPathToDelete, FILE_ATTRIBUTE_NORMAL)) - { - g_nDirsDeleted++; - UpdateProgress(); - // Delete directory - if (!RemoveDirectory(sPathToDelete) && nTotalRetries < c_nMaxTotalRetries) - { - BOOL bDeleted = FALSE; - nTotalRetries++; - for (int nRetry = 0; nRetry < c_nMaxOneFileRetries; nRetry++) - { - Sleep(c_nRetryDelay); - if (RemoveDirectory(sPathToDelete)) - { - bDeleted = TRUE; - break; - } - } - if (!bDeleted) - bResult = FALSE; - } - } - - return bResult; -} - -// Deletes shortcuts for Fennec and FastStart service created by the installer. -// Note: The shortcut names have to be in sync with CreateShortcut in nsInstallerDlg.cpp -BOOL DeleteShortcut(HWND hwndParent) -{ - BOOL result = FALSE; - - WCHAR sProgramsPath[MAX_PATH]; - if (SHGetSpecialFolderPath(hwndParent, sProgramsPath, CSIDL_PROGRAMS, FALSE)) - { - WCHAR sShortcutPath[MAX_PATH]; - _snwprintf(sShortcutPath, MAX_PATH, L"%s\\%s.lnk", sProgramsPath, Strings.GetString(StrID_AppShortName)); - - - if(SetFileAttributes(sShortcutPath, FILE_ATTRIBUTE_NORMAL)) - result = DeleteFile(sShortcutPath); - } - - // Handle faststart shortcut - WCHAR sStartupPath[MAX_PATH]; - if (SHGetSpecialFolderPath(hwndParent, sStartupPath, CSIDL_STARTUP, FALSE)) - { - WCHAR sStartupShortcutPath[MAX_PATH]; - _snwprintf(sStartupShortcutPath, MAX_PATH, L"%s\\%sFastStart.lnk", sStartupPath, Strings.GetString(StrID_AppShortName)); - - // It may not exist - just ignore that - if(SetFileAttributes(sStartupShortcutPath, FILE_ATTRIBUTE_NORMAL)) - DeleteFile(sStartupShortcutPath); - } - - return result; -} - -BOOL DeleteRegistryKey() -{ - WCHAR sRegFennecKey[MAX_PATH]; - _snwprintf(sRegFennecKey, MAX_PATH, c_sAppRegKeyTemplate, Strings.GetString(StrID_AppShortName)); - - LONG result = RegDeleteKey(HKEY_LOCAL_MACHINE, sRegFennecKey); - return (result == ERROR_SUCCESS); -} - -// Copy to a temp directory and launch from there -BOOL CopyAndLaunch() -{ - WCHAR sNewName[] = L"\\Temp\\uninstall.exe"; - WCHAR sModule[MAX_PATH]; - if (GetModuleFileName(NULL, sModule, MAX_PATH) == 0 || !GetModulePath(g_sUninstallPath)) - return FALSE; - if (CopyFile(sModule, sNewName, FALSE)) - { - PROCESS_INFORMATION pi; - WCHAR sParam[c_nTempBufSize]; - if (g_bRunFromSetupDll) - _snwprintf(sParam, c_nTempBufSize, L"%s %s %s", c_sSetupParam, c_sRemoveParam, g_sUninstallPath); - else - _snwprintf(sParam, c_nTempBufSize, L"%s %s", c_sRemoveParam, g_sUninstallPath); - - // Launch "\Temp\uninstall.exe remove \Program Files\Fennec\" - return CreateProcess(sNewName, sParam, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi); - } - else - return FALSE; -} - -BOOL ConvertToChar(const WCHAR *wstr, char *str, DWORD bufSize) -{ - return 0 != WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, bufSize, NULL, NULL); -} - -BOOL ShutdownFastStartService(const WCHAR *wsInstallPath) -{ - BOOL result = TRUE; - - // Class name: appName + "MessageWindow" - WCHAR sClassName[c_nTempBufSize]; - _snwprintf(sClassName, c_nTempBufSize, L"%s%s", Strings.GetString(StrID_AppShortName), L"MessageWindow"); - - HWND handle = ::FindWindowW(sClassName, NULL); - if (handle) - { - char sPath[MAX_PATH]; - ConvertToChar(wsInstallPath, sPath, MAX_PATH); - size_t pathLen = strlen(sPath); - if (pathLen > 0 && sPath[pathLen-1] != '\\') - { - strcat(sPath, "\\"); - pathLen++; - } - - char sCopyData[MAX_PATH * 3]; - _snprintf(sCopyData, MAX_PATH * 2, "\"%s%S.exe\" -shutdown-faststart", sPath, Strings.GetString(StrID_AppShortName)); - size_t cmdLineLen = strlen(sCopyData); - - char *sRest = sCopyData + cmdLineLen + 1; - strcpy(sRest, sPath); - - COPYDATASTRUCT cds = { - 1, - pathLen + 1 + cmdLineLen, - (void*) sCopyData - }; - ::SendMessage(handle, WM_COPYDATA, 0, (LPARAM)&cds); - - // Wait until it's shut down or for some timeout - for (int i = 0; i < 20 && handle; i++) - { - Sleep(500); - handle = ::FindWindowW(sClassName, NULL); - } - - // The window must not exist if the service shut down properly - result = (handle == NULL); - } - return result; -} - -// Remove the part installed from the CAB -BOOL RunSystemUninstall() -{ - WCHAR sXML[c_nTempBufSize]; - LPWSTR sXMLOut = NULL; - - _snwprintf(sXML, c_nTempBufSize, - L"" - L" " - L" " - L" " - L" " - L" " - L"", - Strings.GetString(StrID_AppLongName)); - - HRESULT hr = DMProcessConfigXML(sXML, CFGFLAG_PROCESS, &sXMLOut); - delete[] sXMLOut; - - return hr == S_OK; -} diff --git a/toolkit/mozapps/installer/wince/uninstall/Uninstall.rc b/toolkit/mozapps/installer/wince/uninstall/Uninstall.rc deleted file mode 100644 index 4d910b6aa5ec..000000000000 --- a/toolkit/mozapps/installer/wince/uninstall/Uninstall.rc +++ /dev/null @@ -1,69 +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 Fennec Installer for WinCE. - * - * The Initial Developer of the Original Code is The Mozilla Foundation. - * - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Alex Pakhotin (original author) - * - * 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 ***** */ - -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -#include "resdefce.h" - -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// Dialog - -IDD_MAIN DIALOG 0, 0, 120, 77 -STYLE DS_CENTER | DS_SETFONT | DS_SETFOREGROUND | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION -EXSTYLE 0x80000000L -CAPTION "Uninstall" -FONT 9, "MS Shell Dlg" -BEGIN - LTEXT "",IDC_STATIC_TEXT,6,6,108,24,SS_NOPREFIX - LTEXT "Uninstall?",IDC_QUESTION_TEXT,6,32,132,11,SS_NOPREFIX - PUSHBUTTON "Uninstall",IDC_BTN_UNINSTALL,15,50,40,20 - PUSHBUTTON "Cancel",IDCANCEL,65,50,40,20 - PUSHBUTTON "OK",IDOK,35,50,50,20 - CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,4,52,110,9 -END - -HI_RES_AWARE CEUX {1} // turn off the emulation layer - -#undef APSTUDIO_READONLY_SYMBOLS diff --git a/toolkit/mozapps/installer/wince/uninstall/resource.h b/toolkit/mozapps/installer/wince/uninstall/resource.h deleted file mode 100644 index b7a6d3055c51..000000000000 --- a/toolkit/mozapps/installer/wince/uninstall/resource.h +++ /dev/null @@ -1,23 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by nsUninstaller.rc -// -#define IDD_MAIN 101 -#define IDC_STATIC_TITLE 1000 -#define IDC_STATIC_TEXT 1001 -#define IDC_QUESTION_TEXT 1002 -#define IDC_BTN_UNINSTALL 1003 -#define IDC_PROGRESS 1004 -#define IDC_STATIC -1 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 32771 -#define _APS_NEXT_CONTROL_VALUE 1005 -#define _APS_NEXT_SYMED_VALUE 110 -#endif -#endif diff --git a/toolkit/mozapps/installer/wince/xulrunnerinstaller.ico b/toolkit/mozapps/installer/wince/xulrunnerinstaller.ico deleted file mode 100644 index 0b65049e8913..000000000000 Binary files a/toolkit/mozapps/installer/wince/xulrunnerinstaller.ico and /dev/null differ diff --git a/toolkit/mozapps/update/nsUpdateService.js b/toolkit/mozapps/update/nsUpdateService.js index 4cc2bdd8457b..401843173f49 100644 --- a/toolkit/mozapps/update/nsUpdateService.js +++ b/toolkit/mozapps/update/nsUpdateService.js @@ -94,9 +94,7 @@ const KEY_APPDIR = "XCurProcD"; const KEY_GRED = "GreD"; #ifdef XP_WIN -#ifndef WINCE #define USE_UPDROOT -#endif #elifdef ANDROID #define USE_UPDROOT #endif @@ -214,7 +212,6 @@ XPCOMUtils.defineLazyGetter(this, "gCanApplyUpdates", function aus_gCanApplyUpda updateTestFile.create(NORMAL_FILE_TYPE, FileUtils.PERMS_FILE); updateTestFile.remove(false); #ifdef XP_WIN -#ifndef WINCE var sysInfo = Cc["@mozilla.org/system-info;1"]. getService(Ci.nsIPropertyBag2); @@ -285,7 +282,6 @@ XPCOMUtils.defineLazyGetter(this, "gCanApplyUpdates", function aus_gCanApplyUpda appDirTestFile.create(NORMAL_FILE_TYPE, FileUtils.PERMS_FILE); appDirTestFile.remove(false); } -#endif //WINCE #endif //XP_WIN } catch (e) { diff --git a/toolkit/mozapps/update/nsUpdateServiceStub.js b/toolkit/mozapps/update/nsUpdateServiceStub.js index d249904b1d26..c39a2f9a1890 100644 --- a/toolkit/mozapps/update/nsUpdateServiceStub.js +++ b/toolkit/mozapps/update/nsUpdateServiceStub.js @@ -47,9 +47,7 @@ const FILE_UPDATE_STATUS = "update.status"; const KEY_APPDIR = "XCurProcD"; #ifdef XP_WIN -#ifndef WINCE #define USE_UPDROOT -#endif #elifdef ANDROID #define USE_UPDROOT #endif diff --git a/toolkit/mozapps/update/test/unit/head_update.js.in b/toolkit/mozapps/update/test/unit/head_update.js.in index e440b2495d1f..a8e3cd230628 100644 --- a/toolkit/mozapps/update/test/unit/head_update.js.in +++ b/toolkit/mozapps/update/test/unit/head_update.js.in @@ -51,12 +51,6 @@ const IS_WIN = true; const IS_WIN = false; #endif -#ifdef WINCE -const IS_WINCE = true; -#else -const IS_WINCE = false; -#endif - #ifdef XP_OS2 const IS_OS2 = true; #else @@ -561,7 +555,7 @@ function setupUpdaterTest(aMarFile) { writeFile(testFile, aTestFile.originalContents); } - // Skip these tests on Windows (includes WinCE) and OS/2 since their + // Skip these tests on Windows and OS/2 since their // implementaions of chmod doesn't really set permissions. if (!IS_WIN && !IS_OS2 && aTestFile.originalPerms) { testFile.permissions = aTestFile.originalPerms; @@ -661,10 +655,6 @@ function cleanupUpdaterTest() { * update log after a successful update. */ function checkUpdateLogContents(aCompareLogFile) { - // Skip this test on Windows CE since it doesn't use relative paths. - if (IS_WINCE) - return; - let updateLog = do_get_file(TEST_ID + UPDATES_DIR_SUFFIX, true); updateLog.append(FILE_UPDATE_LOG); // Skip the first two lines since they contain absolute paths. @@ -678,7 +668,6 @@ function checkUpdateLogContents(aCompareLogFile) { // determistic so the results matching the following need to be ignored. updateLogContents = updateLogContents.replace(/.* a\/b\/7\/7text.*\n/g, ""); - let compareLog = do_get_file(aCompareLogFile); let compareLogContents = readFileBytes(compareLog); @@ -704,7 +693,7 @@ function checkFilesAfterUpdateSuccess() { if (aTestFile.compareFile || aTestFile.compareContents) { do_check_true(testFile.exists()); - // Skip these tests on Windows (includes WinCE) and OS/2 since their + // Skip these tests on Windows and OS/2 since their // implementaions of chmod doesn't really set permissions. if (!IS_WIN && !IS_OS2 && aTestFile.comparePerms) { // Check if the permssions as set in the complete mar file are correct. @@ -788,7 +777,7 @@ function checkFilesAfterUpdateFailure() { if (aTestFile.compareFile || aTestFile.compareContents) { do_check_true(testFile.exists()); - // Skip these tests on Windows (includes WinCE) and OS/2 since their + // Skip these tests on Windows and OS/2 since their // implementaions of chmod doesn't really set permissions. if (!IS_WIN && !IS_OS2 && aTestFile.comparePerms) { // Check the original permssions are retained on the file. diff --git a/toolkit/mozapps/update/test/unit/test_0150_appBinReplaced_xp_win_complete.js b/toolkit/mozapps/update/test/unit/test_0150_appBinReplaced_xp_win_complete.js index 4dff96ae6777..40ddc1d8585e 100644 --- a/toolkit/mozapps/update/test/unit/test_0150_appBinReplaced_xp_win_complete.js +++ b/toolkit/mozapps/update/test/unit/test_0150_appBinReplaced_xp_win_complete.js @@ -192,7 +192,7 @@ ADDITIONAL_TEST_DIRS = [ }]; function run_test() { - if (!IS_WIN || IS_WINCE) { + if (!IS_WIN) { logTestInfo("this test is only applicable to Windows... returning early"); return; } diff --git a/toolkit/mozapps/update/test/unit/test_0151_appBinPatched_xp_win_partial.js b/toolkit/mozapps/update/test/unit/test_0151_appBinPatched_xp_win_partial.js index 71f5c3115749..c2e5d12febb2 100644 --- a/toolkit/mozapps/update/test/unit/test_0151_appBinPatched_xp_win_partial.js +++ b/toolkit/mozapps/update/test/unit/test_0151_appBinPatched_xp_win_partial.js @@ -194,7 +194,7 @@ ADDITIONAL_TEST_DIRS = [ }]; function run_test() { - if (!IS_WIN || IS_WINCE) { + if (!IS_WIN) { logTestInfo("this test is only applicable to Windows... returning early"); return; } diff --git a/toolkit/mozapps/update/test/unit/test_0160_appInUse_xp_win_complete.js b/toolkit/mozapps/update/test/unit/test_0160_appInUse_xp_win_complete.js index 51ab3ae418c3..370e4d4b9861 100644 --- a/toolkit/mozapps/update/test/unit/test_0160_appInUse_xp_win_complete.js +++ b/toolkit/mozapps/update/test/unit/test_0160_appInUse_xp_win_complete.js @@ -185,7 +185,7 @@ ADDITIONAL_TEST_DIRS = [ }]; function run_test() { - if (!IS_WIN || IS_WINCE) { + if (!IS_WIN) { logTestInfo("this test is only applicable to Windows... returning early"); return; } diff --git a/toolkit/mozapps/update/test/unit/test_0170_fileLocked_xp_win_complete.js b/toolkit/mozapps/update/test/unit/test_0170_fileLocked_xp_win_complete.js index 30424c2d7fc8..bc0cf80e72bc 100644 --- a/toolkit/mozapps/update/test/unit/test_0170_fileLocked_xp_win_complete.js +++ b/toolkit/mozapps/update/test/unit/test_0170_fileLocked_xp_win_complete.js @@ -185,7 +185,7 @@ ADDITIONAL_TEST_DIRS = [ }]; function run_test() { - if (!IS_WIN || IS_WINCE) { + if (!IS_WIN) { logTestInfo("this test is only applicable to Windows... returning early"); return; } diff --git a/toolkit/mozapps/update/test/unit/test_0171_fileLocked_xp_win_partial.js b/toolkit/mozapps/update/test/unit/test_0171_fileLocked_xp_win_partial.js index 0f0d21656520..21fa3ab35a35 100644 --- a/toolkit/mozapps/update/test/unit/test_0171_fileLocked_xp_win_partial.js +++ b/toolkit/mozapps/update/test/unit/test_0171_fileLocked_xp_win_partial.js @@ -186,7 +186,7 @@ ADDITIONAL_TEST_DIRS = [ }]; function run_test() { - if (!IS_WIN || IS_WINCE) { + if (!IS_WIN) { logTestInfo("this test is only applicable to Windows... returning early"); return; } diff --git a/toolkit/mozapps/update/test/unit/test_0180_fileInUse_xp_win_complete.js b/toolkit/mozapps/update/test/unit/test_0180_fileInUse_xp_win_complete.js index add37dd8f741..043cf6990ec6 100644 --- a/toolkit/mozapps/update/test/unit/test_0180_fileInUse_xp_win_complete.js +++ b/toolkit/mozapps/update/test/unit/test_0180_fileInUse_xp_win_complete.js @@ -191,7 +191,7 @@ ADDITIONAL_TEST_DIRS = [ }]; function run_test() { - if (!IS_WIN || IS_WINCE) { + if (!IS_WIN) { logTestInfo("this test is only applicable to Windows... returning early"); return; } diff --git a/toolkit/mozapps/update/test/unit/test_0181_fileInUse_xp_win_partial.js b/toolkit/mozapps/update/test/unit/test_0181_fileInUse_xp_win_partial.js index bcb7b1857d14..2e5567d0dfbd 100644 --- a/toolkit/mozapps/update/test/unit/test_0181_fileInUse_xp_win_partial.js +++ b/toolkit/mozapps/update/test/unit/test_0181_fileInUse_xp_win_partial.js @@ -194,7 +194,7 @@ ADDITIONAL_TEST_DIRS = [ }]; function run_test() { - if (!IS_WIN || IS_WINCE) { + if (!IS_WIN) { logTestInfo("this test is only applicable to Windows... returning early"); return; } diff --git a/toolkit/mozapps/update/test/unit/test_0182_rmrfdirFileInUse_xp_win_complete.js b/toolkit/mozapps/update/test/unit/test_0182_rmrfdirFileInUse_xp_win_complete.js index 31e658e10f05..b7d3b2216df7 100644 --- a/toolkit/mozapps/update/test/unit/test_0182_rmrfdirFileInUse_xp_win_complete.js +++ b/toolkit/mozapps/update/test/unit/test_0182_rmrfdirFileInUse_xp_win_complete.js @@ -191,7 +191,7 @@ ADDITIONAL_TEST_DIRS = [ }]; function run_test() { - if (!IS_WIN || IS_WINCE) { + if (!IS_WIN) { logTestInfo("this test is only applicable to Windows... returning early"); return; } diff --git a/toolkit/mozapps/update/test/unit/test_0183_rmrfdirFileInUse_xp_win_partial.js b/toolkit/mozapps/update/test/unit/test_0183_rmrfdirFileInUse_xp_win_partial.js index f30749caa2b8..861a91813846 100644 --- a/toolkit/mozapps/update/test/unit/test_0183_rmrfdirFileInUse_xp_win_partial.js +++ b/toolkit/mozapps/update/test/unit/test_0183_rmrfdirFileInUse_xp_win_partial.js @@ -234,7 +234,7 @@ ADDITIONAL_TEST_DIRS = [ }]; function run_test() { - if (!IS_WIN || IS_WINCE) { + if (!IS_WIN) { logTestInfo("this test is only applicable to Windows... returning early"); return; } diff --git a/toolkit/mozapps/update/test/unit/test_0200_app_launch_apply_update.js b/toolkit/mozapps/update/test/unit/test_0200_app_launch_apply_update.js index 28e7a16b49f7..16ca3a869058 100644 --- a/toolkit/mozapps/update/test/unit/test_0200_app_launch_apply_update.js +++ b/toolkit/mozapps/update/test/unit/test_0200_app_launch_apply_update.js @@ -112,11 +112,6 @@ function run_test() { return; } - if (IS_WINCE) { - logTestInfo("this test is not applicable to Windows CE... returning early"); - return; - } - do_test_pending(); do_register_cleanup(end_test); diff --git a/toolkit/themes/winstripe/global/toolbar.css b/toolkit/themes/winstripe/global/toolbar.css index 7dfa85bedc56..b8636c9d36f3 100644 --- a/toolkit/themes/winstripe/global/toolbar.css +++ b/toolkit/themes/winstripe/global/toolbar.css @@ -47,10 +47,8 @@ toolbox { -moz-appearance: toolbox; background-color: -moz-Dialog; -%ifndef WINCE border-top: 2px solid; -moz-border-top-colors: ThreeDShadow ThreeDHighlight; -%endif } /* ::::: toolbar & menubar ::::: */ diff --git a/toolkit/toolkit-tiers.mk b/toolkit/toolkit-tiers.mk index dc4cb71fe023..6314ca0dc655 100644 --- a/toolkit/toolkit-tiers.mk +++ b/toolkit/toolkit-tiers.mk @@ -58,11 +58,8 @@ ifndef MOZ_NATIVE_ZLIB tier_platform_dirs += modules/zlib endif -ifndef WINCE -tier_platform_dirs += modules/libreg -endif - tier_platform_dirs += \ + modules/libreg \ modules/libpref \ intl \ netwerk \ @@ -95,10 +92,6 @@ endif tier_platform_dirs += gfx/qcms -ifeq ($(OS_ARCH),WINCE) -tier_platform_dirs += modules/lib7z -endif - # # "gecko" - core components # diff --git a/toolkit/xre/Makefile.in b/toolkit/xre/Makefile.in index 648b29476660..875e4cacb4ea 100644 --- a/toolkit/xre/Makefile.in +++ b/toolkit/xre/Makefile.in @@ -53,7 +53,7 @@ XPIDLSRCS = \ nsINativeAppSupport.idl \ $(NULL) -ifneq (,$(filter WINCE WINNT,$(OS_ARCH))) +ifeq ($(OS_ARCH),WINNT) XPIDLSRCS += nsIWinAppHelper.idl endif @@ -71,12 +71,8 @@ CPPSRCS += EventTracer.cpp endif ifdef MOZ_SPLASHSCREEN -ifeq ($(OS_ARCH),WINCE) -CPPSRCS += nsSplashScreenWin.cpp -else CPPSRCS += nsSplashScreenDummy.cpp endif -endif DEFINES += -DIMPL_XREAPI -DMOZ_APP_NAME='"$(MOZ_APP_NAME)"' diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 8b4db05235f3..6dd1338626d0 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -166,10 +166,8 @@ using mozilla::dom::ContentParent; #endif #ifdef XP_WIN -#ifndef WINCE #include #include -#endif #include "nsThreadUtils.h" #endif @@ -219,33 +217,6 @@ using mozilla::dom::ContentParent; #include "AndroidBridge.h" #endif -#ifdef WINCE -class WindowsMutex { -public: - WindowsMutex(const wchar_t *name) { - mHandle = CreateMutexW(0, FALSE, name); - } - - ~WindowsMutex() { - Unlock(); - CloseHandle(mHandle); - } - - PRBool Lock(DWORD timeout = INFINITE) { - DWORD state = WaitForSingleObject(mHandle, timeout); - return state == WAIT_OBJECT_0; - } - - void Unlock() { - if (mHandle) - ReleaseMutex(mHandle); - } - -protected: - HANDLE mHandle; -}; -#endif - extern PRUint32 gRestartMode; extern void InstallSignalHandlers(const char *ProgramName); #include "nsX11ErrorHandler.h" @@ -846,10 +817,6 @@ typedef enum NS_IMETHODIMP nsXULAppInfo::GetUserCanElevate(PRBool *aUserCanElevate) { -#ifdef WINCE - *aUserCanElevate = PR_FALSE; - return NS_OK; -#else HANDLE hToken; VISTA_TOKEN_ELEVATION_TYPE elevationType; @@ -877,7 +844,6 @@ nsXULAppInfo::GetUserCanElevate(PRBool *aUserCanElevate) CloseHandle(hToken); return NS_OK; -#endif // WINCE } #endif @@ -2891,55 +2857,11 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData) isNoSplash |= (PR_GetEnv("NO_SPLASH") != 0); PRBool isNoRemote = (CheckArg("no-remote", PR_FALSE, NULL, PR_FALSE) == ARG_FOUND); -#ifdef WINCE - // synchronize startup; if it looks like we're going to have to - // wait, then open up a splash screen - WindowsMutex winStartupMutex(L"FirefoxStartupMutex"); - - // try to lock the mutex, but only wait 100ms to do so - PRBool needsMutexLock = ! winStartupMutex.Lock(100); - - // If we failed to lock the mutex quickly, then we'll want - // a splash screen for sure. - // - // If we did manage to lock it, then we'll only want one - // a splash screen if there is no existing message window; - // that is, if we are the first instance of the app. - if (!needsMutexLock && !isNoRemote) { - // check to see if there's a remote firefox up - static PRUnichar classNameBuffer[128]; - _snwprintf(classNameBuffer, sizeof(classNameBuffer) / sizeof(PRUnichar), - L"%S%s", - gAppData->name, L"MessageWindow"); - HANDLE h = FindWindowW(classNameBuffer, 0); - if (h) { - // Someone else has the window, and we were able to grab the mutex, - // meaning the other instance ahs presumably already finished starting - // up by now. So no need for a splash screen. - wantsSplash = PR_FALSE; - CloseHandle(h); - } else { - // We couldn't find another window, and we were able to lock the mutex; - // we're likely the first instance starting up, so make sure a splash - // screen gets thrown up. - wantsSplash = PR_TRUE; - } - } -#endif //WINCE - if (wantsSplash && !isNoSplash) splashScreen = nsSplashScreen::GetOrCreate(); if (splashScreen) splashScreen->Open(); - -#ifdef WINCE - // Now that the splash screen is open, wait indefinitely - // for the startup mutex on this thread if we need to. - if (needsMutexLock) - winStartupMutex.Lock(); -#endif //WINCE - #endif //MOZ_SPLASHSCREEN @@ -3406,11 +3328,6 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData) rv = dirProvider.SetProfile(profD, profLD); NS_ENSURE_SUCCESS(rv, 1); -#if defined(WINCE) && defined(MOZ_SPLASHSCREEN) - // give up the mutex, let other app startups happen - winStartupMutex.Unlock(); -#endif - //////////////////////// NOW WE HAVE A PROFILE //////////////////////// #ifdef MOZ_CRASHREPORTER @@ -3947,7 +3864,7 @@ SetupErrorHandling(const char* progname) _SetProcessDEPPolicy(PROCESS_DEP_ENABLE); #endif -#if defined (XP_WIN32) && !defined (WINCE) +#ifdef XP_WIN32 // Suppress the "DLL Foo could not be found" dialog, such that if dependent // libraries (such as GDI+) are not preset, we gracefully fail to load those // XPCOM components, instead of being ungraceful. @@ -3968,10 +3885,8 @@ SetupErrorHandling(const char* progname) InstallSignalHandlers(progname); #endif -#ifndef WINCE // Unbuffer stdout, needed for tinderbox tests. setbuf(stdout, 0); -#endif #if defined(FREEBSD) // Disable all SIGFPE's on FreeBSD, as it has non-IEEE-conformant fp diff --git a/toolkit/xre/nsNativeAppSupportWin.cpp b/toolkit/xre/nsNativeAppSupportWin.cpp index 4a85b7c13e86..96fa305dcfae 100644 --- a/toolkit/xre/nsNativeAppSupportWin.cpp +++ b/toolkit/xre/nsNativeAppSupportWin.cpp @@ -76,9 +76,7 @@ #include #include -#ifndef WINCE #include -#endif #include #include #include @@ -107,12 +105,10 @@ activateWindow( nsIDOMWindowInternal *win ) { // Try to get native window handle. HWND hwnd = hwndForDOMWindow( win ); if ( hwnd ) { -#ifndef WINCE // Can't iconify windows on windows ce // Restore the window if it is minimized. if ( ::IsIconic( hwnd ) ) { ::ShowWindow( hwnd, SW_RESTORE ); } -#endif // Use the OS call, if possible. ::SetForegroundWindow( hwnd ); } else { @@ -313,10 +309,8 @@ public: NS_IMETHOD Stop( PRBool *aResult ); NS_IMETHOD Quit(); NS_IMETHOD Enable(); -#ifndef WINCE // The "old" Start method (renamed). NS_IMETHOD StartDDE(); -#endif // Utility function to handle a Win32-specific command line // option: "-console", which dynamically creates a Windows // console. @@ -324,7 +318,6 @@ public: private: static void HandleCommandLine(const char* aCmdLineString, nsIFile* aWorkingDir, PRUint32 aState); -#ifndef WINCE static HDDEDATA CALLBACK HandleDDENotification( UINT uType, UINT uFmt, HCONV hconv, @@ -339,7 +332,6 @@ private: static HDDEDATA CreateDDEData( LPBYTE value, DWORD len ); static PRBool InitTopicStrings(); static int FindTopic( HSZ topic ); -#endif static void ActivateLastWindow(); static nsresult OpenWindow( const char *urlstr, const char *args ); static nsresult OpenBrowserWindow(); @@ -358,9 +350,7 @@ private: // Note: Insert new values above this line!!!!! topicCount // Count of the number of real topics }; -#ifndef WINCE static HSZ mApplication, mTopics[ topicCount ]; -#endif static DWORD mInstance; static PRBool mCanHandleRequests; static PRUnichar mMutexName[]; @@ -382,7 +372,6 @@ nsNativeAppSupportWin::CheckConsole() { strcmp( "/console", gArgv[i] ) == 0 ) { // Users wants to make sure we have a console. // Try to allocate one. -#ifndef WINCE BOOL rc = ::AllocConsole(); if ( rc ) { // Console allocated. Fix it up so that output works in @@ -429,7 +418,6 @@ nsNativeAppSupportWin::CheckConsole() { // Failed. Probably because there already is one. // There's little we can do, in any case. } -#endif // Remove the console argument from the command line. do { gArgv[i] = gArgv[i + 1]; @@ -481,10 +469,8 @@ const char * const topicNames[] = { "WWW_OpenURL", // Static member definitions. int nsNativeAppSupportWin::mConversations = 0; -#ifndef WINCE HSZ nsNativeAppSupportWin::mApplication = 0; HSZ nsNativeAppSupportWin::mTopics[nsNativeAppSupportWin::topicCount] = { 0 }; -#endif DWORD nsNativeAppSupportWin::mInstance = 0; PRBool nsNativeAppSupportWin::mCanHandleRequests = PR_FALSE; @@ -579,14 +565,7 @@ struct MessageWindow { _wgetcwd(cwd, MAX_PATH); // Construct a narrow UTF8 buffer \0\0 -#ifdef WINCE - // For WinCE, we're stuck with providing our own argv[0] for the remote - // command-line. - NS_ConvertUTF16toUTF8 utf8buffer(L"dummy "); - AppendUTF16toUTF8(cmd, utf8buffer); -#else NS_ConvertUTF16toUTF8 utf8buffer(cmd); -#endif utf8buffer.Append('\0'); AppendUTF16toUTF8(cwd, utf8buffer); utf8buffer.Append('\0'); @@ -600,13 +579,7 @@ struct MessageWindow { }; // Bring the already running Mozilla process to the foreground. // nsWindow will restore the window (if minimized) and raise it. -#ifdef WINCE - // for activating the existing window on wince we need "| 0x01" - // see http://msdn.microsoft.com/en-us/library/ms940024.aspx for details - ::SetForegroundWindow( (HWND)(((ULONG) mHandle) | 0x01) ); -#else ::SetForegroundWindow( mHandle ); -#endif ::SendMessage( mHandle, WM_COPYDATA, 0, (LPARAM)&cds ); return NS_OK; } @@ -702,10 +675,8 @@ nsNativeAppSupportWin::Start( PRBool *aResult ) { // We will be server. rv = msgWindow.Create(); if ( NS_SUCCEEDED( rv ) ) { -#ifndef WINCE // Start up DDE server. this->StartDDE(); -#endif // Tell caller to spin message loop. *aResult = PR_TRUE; } @@ -715,7 +686,7 @@ nsNativeAppSupportWin::Start( PRBool *aResult ) { return rv; } -#ifndef WINCE + PRBool nsNativeAppSupportWin::InitTopicStrings() { for ( int i = 0; i < topicCount; i++ ) { @@ -771,7 +742,7 @@ nsNativeAppSupportWin::StartDDE() { return NS_OK; } -#endif /* WINCE */ + // If no DDE conversations are pending, terminate DDE. NS_IMETHODIMP nsNativeAppSupportWin::Stop( PRBool *aResult ) { @@ -833,7 +804,6 @@ nsNativeAppSupportWin::Quit() { if ( mInstance ) { // Unregister application name. -#ifndef WINCE DdeNameService( mInstance, mApplication, 0, DNS_UNREGISTER ); // Clean up strings. if ( mApplication ) { @@ -847,7 +817,6 @@ nsNativeAppSupportWin::Quit() { } } DdeUninitialize( mInstance ); -#endif mInstance = 0; #if MOZ_DEBUG_DDE printf( "DDE server stopped\n" ); @@ -913,7 +882,7 @@ static nsCString hszValue( DWORD instance, HSZ hsz ) { result += "]"; return result; } -#elif !defined(WINCE) +#else // These are purely a safety measure to avoid the infamous "won't // build non-debug" type Tinderbox flames. static nsCString uTypeDesc( UINT ) { @@ -944,7 +913,6 @@ static void escapeQuotes( nsAString &aString ) { return; } -#ifndef WINCE HDDEDATA CALLBACK nsNativeAppSupportWin::HandleDDENotification( UINT uType, // transaction type UINT uFmt, // clipboard data format @@ -1195,7 +1163,7 @@ nsNativeAppSupportWin::HandleDDENotification( UINT uType, // transaction t #endif return result; } -#endif /* WINCE */ + // Utility function to advance to end of quoted string. // p+offset must point to the comma preceding the arg on entry. // On return, p+result points to the closing '"' (or end of the string @@ -1217,7 +1185,6 @@ static PRInt32 advanceToEndOfQuotedArg( const WCHAR *p, PRInt32 offset, PRInt32 return offset; } -#ifndef WINCE void nsNativeAppSupportWin::ParseDDEArg( const WCHAR* args, int index, nsString& aString) { if ( args ) { nsDependentString temp(args); @@ -1286,7 +1253,6 @@ HDDEDATA nsNativeAppSupportWin::CreateDDEData( LPBYTE value, DWORD len ) { 0 ); return result; } -#endif /* WINCE */ void nsNativeAppSupportWin::ActivateLastWindow() { nsCOMPtr navWin; diff --git a/toolkit/xre/nsSplashScreenWin.cpp b/toolkit/xre/nsSplashScreenWin.cpp deleted file mode 100644 index 460e8d00fff4..000000000000 --- a/toolkit/xre/nsSplashScreenWin.cpp +++ /dev/null @@ -1,317 +0,0 @@ -/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** 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 code. - * - * The Initial Developer of the Original Code is - * mozilla.org - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Vladimir Vukicevic - * - * 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 "nsSplashScreen.h" - -#include - -static ATOM gSplashScreenClass = 0; - -class nsSplashScreenWin; - -static nsSplashScreenWin *gSplashScreen = NULL; - -class nsSplashScreenWin : - public nsSplashScreen -{ -public: - nsSplashScreenWin(); - - virtual void Open(); - virtual void Close(); - virtual void Update(PRInt32 progress); - -protected: - HWND mDialog; - HBITMAP mSplashBitmap, mOldBitmap; - HDC mSplashBitmapDC; - int mWidth, mHeight; - - static DWORD WINAPI ThreadProc(LPVOID splashScreen); - - static LRESULT CALLBACK DialogProc (HWND hWnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam); - - void OnPaint(HDC dc, const PAINTSTRUCT *ps); - - PRInt32 mProgress; -}; - -nsSplashScreen * -nsSplashScreen::GetOrCreate() -{ - if (!gSplashScreen) - gSplashScreen = new nsSplashScreenWin(); - - return gSplashScreen; -} - -nsSplashScreen * -nsSplashScreen::Get() -{ - return gSplashScreen; -} - -nsSplashScreenWin::nsSplashScreenWin() - : mDialog(NULL), mSplashBitmap(NULL), mOldBitmap(NULL), - mSplashBitmapDC(NULL), - mWidth(200), mHeight(100), - mProgress(-1) -{ -} - -void -nsSplashScreenWin::Open() -{ - if (mIsOpen || mDialog) - return; - - mIsOpen = PR_TRUE; - - if (gSplashScreenClass == 0) { - WNDCLASS wc; - memset(&wc, 0, sizeof(WNDCLASS)); - - wc.style = CS_NOCLOSE; - wc.lpfnWndProc = (WNDPROC) DialogProc; - wc.hInstance = GetModuleHandle(0); - wc.hIcon = NULL; - wc.hCursor = NULL; - wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); - wc.lpszMenuName = NULL; - wc.lpszClassName = TEXT("MozillaSplashScreen"); - - gSplashScreenClass = RegisterClass(&wc); - } - - if (mSplashBitmap == NULL) { - wchar_t path[_MAX_PATH]; - if (::GetModuleFileNameW(0, path, _MAX_PATH)) { - wchar_t *slash = wcsrchr(path, '\\'); - if (slash != NULL) - slash[1] = 0; - - wcscat(path, L"splash.bmp"); - -#ifdef WINCE - mSplashBitmap = ::SHLoadDIBitmap(path); -#else -#warning splashscreen needs some code to load bitmaps on non-WinCE - mSplashBitmap = nsnull; -#endif - - if (mSplashBitmap) { - BITMAP bmo; - if (GetObject(mSplashBitmap, sizeof(BITMAP), &bmo) > 0) { - mWidth = bmo.bmWidth; - mHeight = bmo.bmHeight; - - mSplashBitmapDC = CreateCompatibleDC(NULL); - mOldBitmap = (HBITMAP) SelectObject(mSplashBitmapDC, mSplashBitmap); - } else { - DeleteObject(mSplashBitmap); - mSplashBitmap = NULL; - } - } - } - } - - DWORD threadID = 0; - CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ThreadProc, this, 0, &threadID); -} - -DWORD WINAPI -nsSplashScreenWin::ThreadProc(LPVOID splashScreen) -{ - nsSplashScreenWin *sp = (nsSplashScreenWin*) splashScreen; - - int screenWidth = GetSystemMetrics(SM_CXSCREEN); - int screenHeight = GetSystemMetrics(SM_CYSCREEN); - - LONG horizPad = (screenWidth - sp->mWidth) / 2; - LONG vertPad = (screenHeight - sp->mHeight) / 2; - RECT r = { horizPad, - vertPad, - horizPad + sp->mWidth, - vertPad + sp->mHeight }; - - DWORD winStyle = (WS_POPUP | WS_BORDER); - DWORD winStyleEx = WS_EX_NOACTIVATE; - - if(!::AdjustWindowRectEx(&r, winStyle, FALSE, winStyleEx)) - return 0; - - HWND dlg = CreateWindowEx( - winStyleEx, - TEXT("MozillaSplashScreen"), - TEXT("Starting up..."), - winStyle, - r.left, r.top, - (r.right - r.left), (r.bottom - r.top), - HWND_DESKTOP, - NULL, - GetModuleHandle(0), - NULL); - - sp->mDialog = dlg; - - ShowWindow(dlg, SW_SHOW); - SetForegroundWindow(dlg); - - MSG msg; - while (::GetMessage(&msg, NULL, 0, 0)) { - DispatchMessage(&msg); - } - - // window was destroyed, nothing to do - return 0; -} - -void -nsSplashScreenWin::Close() -{ - if (mDialog) { - ShowWindow(mDialog, SW_HIDE); - PostMessage(mDialog, WM_QUIT, 0, 0); - mDialog = NULL; - } - - if (mSplashBitmap) { - SelectObject(mSplashBitmapDC, mOldBitmap); - DeleteObject(mSplashBitmapDC); - DeleteObject(mSplashBitmap); - mOldBitmap = NULL; - mSplashBitmapDC = NULL; - mSplashBitmap = NULL; - } - - mIsOpen = PR_FALSE; -} - -void -nsSplashScreenWin::Update(PRInt32 progress) -{ - if (progress >= 0) - mProgress = progress > 100 ? 100 : progress; - - InvalidateRect(mDialog, NULL, FALSE); -} - -void -nsSplashScreenWin::OnPaint(HDC dc, const PAINTSTRUCT *ps) -{ - RECT progressBar; - - // Paint the splash screen - if (mSplashBitmapDC) { - BitBlt(dc, - 0, 0, gSplashScreen->mWidth, gSplashScreen->mHeight, - gSplashScreen->mSplashBitmapDC, - 0, 0, - SRCCOPY); - } else { - HBRUSH bkgr = CreateSolidBrush(RGB(200,200,200)); - RECT r = { 0, 0, mWidth, mHeight }; - FillRect(dc, &r, bkgr); - DeleteObject(bkgr); - } - - // Size of progress bar area - if (mSplashBitmapDC && - gSplashScreen->mWidth == 440 && - gSplashScreen->mHeight == 180) { - // For now we're tightly tied to a specific splash.bmp design, - // ideally we would determine the region automagically. - progressBar.left = 183; - progressBar.right = 410; - progressBar.top = 148; - progressBar.bottom = 153; - } else { - // The default progress bar will be 2/3 the width of the splash box, - // 9 pixels tall, 10 pixels from the bottom. - progressBar.left = (mWidth / 6); - progressBar.right = mWidth - (mWidth / 6); - progressBar.top = mHeight - 19; - progressBar.bottom = mHeight - 10; - } - - if (mProgress != -1) { - HBRUSH fill = CreateSolidBrush(RGB(0x77,0xC7,0x1C)); - - int maxWidth = progressBar.right - progressBar.left; - progressBar.right = progressBar.left + maxWidth * mProgress / 100; - FillRect(dc, &progressBar, fill); - - DeleteObject(fill); - } -} - -LRESULT CALLBACK -nsSplashScreenWin::DialogProc (HWND hWnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) -{ - switch (uMsg) { - case WM_PAINT: { - PAINTSTRUCT ps; - HDC dc = BeginPaint(hWnd, &ps); - - if (gSplashScreen) - gSplashScreen->OnPaint(dc, &ps); - - EndPaint(hWnd, &ps); - return TRUE; - } - break; - - case WM_DESTROY: - return TRUE; - - case WM_QUIT: - DestroyWindow(hWnd); - return TRUE; - - default: - return DefWindowProc(hWnd, uMsg, wParam, lParam); - } - - return FALSE; -} diff --git a/toolkit/xre/nsWindowsRestart.cpp b/toolkit/xre/nsWindowsRestart.cpp index 20205e86b5af..d2d27a322c72 100644 --- a/toolkit/xre/nsWindowsRestart.cpp +++ b/toolkit/xre/nsWindowsRestart.cpp @@ -172,20 +172,6 @@ MakeCommandLine(int argc, PRUnichar **argv) for (i = 0; i < argc; ++i) len += ArgStrLen(argv[i]) + 1; -#ifdef WINCE - wchar_t *env = mozce_GetEnvironmentCL(); - // XXX There's a buffer overrun here somewhere that causes a heap - // check to fail in the final free of the results of this function - // in WinLaunchChild. I can't honestly figure out where it is, - // because I'm pretty sure with the + 1 above and the wcslen here, - // we have enough room for a trailing NULL. But, adding a little - // bit more slop (the +10) seems to fix the problem. - // - // Supposedly CreateProcessW can modify its arguments, so maybe it's - // doing some scribbling? - len += (wcslen(env)) + 10; -#endif - // Protect against callers that pass 0 arguments if (len == 0) len = 1; @@ -205,11 +191,6 @@ MakeCommandLine(int argc, PRUnichar **argv) *c = '\0'; -#ifdef WINCE - wcscat(s, env); - if (env) - free(env); -#endif return s; } @@ -277,18 +258,6 @@ WinLaunchChild(const PRUnichar *exePath, int argc, PRUnichar **argv) PRUnichar *cl; BOOL ok; -#ifdef WINCE - // Windows Mobile Issue: - // When passing both an image name and a command line to - // CreateProcessW, you need to make sure that the image name - // identially matches the first argument of the command line. If - // they do not match, Windows Mobile will send two "argv[0]" values. - // To avoid this problem, we will strip off the argv here, and - // depend only on the exePath. - argv = argv + 1; - argc--; -#endif - cl = MakeCommandLine(argc, argv); if (!cl) return FALSE; diff --git a/toolkit/xre/nsWindowsWMain.cpp b/toolkit/xre/nsWindowsWMain.cpp index e8ca59973505..a1c0179a7977 100644 --- a/toolkit/xre/nsWindowsWMain.cpp +++ b/toolkit/xre/nsWindowsWMain.cpp @@ -73,25 +73,6 @@ FreeAllocStrings(int argc, char **argv) delete [] argv; } -#ifdef WINCE -/** argc/argv are in/out parameters */ -void ExtractEnvironmentFromCL(int &argc, char **&argv) -{ - for (int x = argc - 1; x >= 0; x--) { - if (!strncmp(argv[x], "--environ:", 10)) { - char* key_val = strdup(argv[x]+10); - putenv(key_val); - free(key_val); - argc -= 1; - char *delete_argv = argv[x]; - if (x < argc) /* if the current argument is not at the tail, shift following arguments. */ - memcpy(&argv[x], &argv[x+1], (argc - x) * sizeof(char*)); - delete [] delete_argv; - } - } -} -#endif - int wmain(int argc, WCHAR **argv) { #ifndef XRE_DONT_PROTECT_DLL_LOAD @@ -112,9 +93,6 @@ int wmain(int argc, WCHAR **argv) return 127; } } -#ifdef WINCE - ExtractEnvironmentFromCL(argc, argvConverted); -#endif argvConverted[argc] = NULL; // need to save argvConverted copy for later deletion. diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp index 1e2c88528c34..f98a798d3908 100644 --- a/toolkit/xre/nsXREDirProvider.cpp +++ b/toolkit/xre/nsXREDirProvider.cpp @@ -259,10 +259,10 @@ nsXREDirProvider::GetFile(const char* aProperty, PRBool* aPersistent, rv = GetUserAppDataDirectory((nsILocalFile**)(nsIFile**) getter_AddRefs(file)); } else if (!strcmp(aProperty, XRE_UPDATE_ROOT_DIR)) { -#if defined(XP_WIN) && !defined(WINCE) +#if defined(XP_WIN) rv = GetUpdateRootDir(getter_AddRefs(file)); #else - // Only supported on Windows other than WINCE, so just immediately fail. + // Only supported on Windows, so just immediately fail. return NS_ERROR_FAILURE; #endif } @@ -824,24 +824,6 @@ GetShellFolderPath(int folder, nsAString& _retval) nsresult rv = NS_OK; -#if defined(WINCE) && !defined(WINCE_WINDOWS_MOBILE) - if (folder == CSIDL_APPDATA || folder == CSIDL_LOCAL_APPDATA) - folder = CSIDL_PROFILE; - - BOOL ok = SHGetSpecialFolderPath(NULL, buf, folder, true); - if (!ok) { - _retval.SetLength(0); - return NS_ERROR_FAILURE; - } - - buf[bufLength - 1] = L'\0'; - _retval.SetLength(wcslen(buf)); - - // sometimes CSIDL_PROFILE shows up without a root slash - if (folder == CSIDL_PROFILE && buf[0] != '\\') { - _retval.Insert('\\', 0); - } -#else LPITEMIDLIST pItemIDList = NULL; if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, folder, &pItemIDList)) && @@ -856,12 +838,10 @@ GetShellFolderPath(int folder, nsAString& _retval) } CoTaskMemFree(pItemIDList); -#endif return rv; } -#ifndef WINCE /** * Provides a fallback for getting the path to APPDATA or LOCALAPPDATA by * querying the registry when the call to SHGetSpecialFolderLocation or @@ -913,7 +893,6 @@ GetRegWindowsAppDataFolder(PRBool aLocal, nsAString& _retval) return NS_OK; } -#endif nsresult nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult) @@ -932,9 +911,6 @@ nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult) PRUint32 bufLength = longPath.GetMutableData(&buf, MAXPATHLEN); NS_ENSURE_TRUE(bufLength >= MAXPATHLEN, NS_ERROR_OUT_OF_MEMORY); -#ifdef WINCE - longPath.Assign(appPath); -#else DWORD len = GetLongPathNameW(appPath.get(), buf, bufLength); // Failing GetLongPathName() is not fatal. @@ -942,7 +918,7 @@ nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult) longPath.Assign(appPath); else longPath.SetLength(len); -#endif + // Use \updates\ if app dir is under Program Files to avoid the // folder virtualization mess on Windows Vista @@ -1049,20 +1025,15 @@ nsXREDirProvider::GetUserDataDirectoryHome(nsILocalFile** aFile, PRBool aLocal) nsString path; if (aLocal) { rv = GetShellFolderPath(CSIDL_LOCAL_APPDATA, path); -#ifndef WINCE if (NS_FAILED(rv)) rv = GetRegWindowsAppDataFolder(aLocal, path); -#endif } if (!aLocal || NS_FAILED(rv)) { rv = GetShellFolderPath(CSIDL_APPDATA, path); -#ifndef WINCE if (NS_FAILED(rv)) { if (!aLocal) rv = GetRegWindowsAppDataFolder(aLocal, path); } -#endif - } NS_ENSURE_SUCCESS(rv, rv); diff --git a/xpcom/base/Makefile.in b/xpcom/base/Makefile.in index 9409b4503ace..4e3ca15c9691 100644 --- a/xpcom/base/Makefile.in +++ b/xpcom/base/Makefile.in @@ -70,6 +70,7 @@ CPPSRCS = \ nsStackWalk.cpp \ nsMemoryReporterManager.cpp \ FunctionTimer.cpp \ + nsTelemetry.cpp \ $(NULL) ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) @@ -140,6 +141,7 @@ XPIDLSRCS = \ nsIUUIDGenerator.idl \ nsIMutable.idl \ nsIMemoryReporter.idl \ + nsITelemetry.idl \ $(NULL) ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) @@ -152,6 +154,8 @@ FORCE_STATIC_LIB = 1 # Force use of PIC FORCE_USE_PIC = 1 +include $(topsrcdir)/config/config.mk +include $(topsrcdir)/ipc/chromium/chromium-config.mk include $(topsrcdir)/config/rules.mk DEFINES += -D_IMPL_NS_COM diff --git a/xpcom/base/nsITelemetry.idl b/xpcom/base/nsITelemetry.idl new file mode 100644 index 000000000000..2c6bb7614412 --- /dev/null +++ b/xpcom/base/nsITelemetry.idl @@ -0,0 +1,76 @@ +/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */ +/* ***** 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 Firefox. + * + * The Initial Developer of the Original Code is + * the Mozilla Foundation . + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Taras Glek + * + * 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" + +[scriptable, uuid(5c9afdb5-0532-47f3-be31-79e13a6db642)] +interface nsITelemetry : nsISupports +{ + /* + * An object containing a snapshot from all of the currently registered histograms. + * { name1: {data1}, name2:{data2}...} + * where data is consists of the following properties: + * min - Minimal bucket size + * max - Maximum bucket size + * histogram_type - 0:Exponential, 1:Linear + * counts - array representing contents of the buckets in the histogram + * ranges - an array with calculated bucket sizes + * sum - sum of the bucket contents + */ + [implicit_jscontext] + readonly attribute jsval histogramSnapshots; + + /** + * Create and return a histogram where bucket sizes increase exponentially. Parameters: + * @param name Unique histogram name + * @param min - Minimal bucket size + * @param max - Maximum bucket size + * @param bucket_count - number of buckets in the histogram. + * The returned object has the following functions: + * add(int) - Adds an int value to the appropriate bucket + * snapshot() - Returns a snapshot of the histogram with the same data fields as in histogramSnapshots() + */ + [implicit_jscontext] + jsval newExponentialHistogram(in ACString name, in PRInt32 min, in PRInt32 max, in PRUint32 bucket_count); + + /* + Same as newExponentialHistogram, but for linear histograms + */ + [implicit_jscontext] + jsval newLinearHistogram(in ACString name, in PRInt32 min, in PRInt32 max, in PRUint32 bucket_count); +}; diff --git a/xpcom/base/nsTelemetry.cpp b/xpcom/base/nsTelemetry.cpp new file mode 100644 index 000000000000..d65977a7cdc6 --- /dev/null +++ b/xpcom/base/nsTelemetry.cpp @@ -0,0 +1,233 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** 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 code. + * + * The Initial Developer of the Original Code is + * Mozilla Corporation. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Taras Glek + * + * 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 ***** */ + +#define XPCOM_TRANSLATE_NSGM_ENTRY_POINT +#include "base/histogram.h" +#include "nsIComponentManager.h" +#include "nsIServiceManager.h" +#include "nsCOMPtr.h" +#include "mozilla/ModuleUtils.h" +#include "nsIXPConnect.h" +#include "mozilla/Services.h" +#include "jsapi.h" +#include "nsStringGlue.h" +#include "nsITelemetry.h" + +using namespace base; +using namespace mozilla; + +class Telemetry : public nsITelemetry +{ + NS_DECL_ISUPPORTS + NS_DECL_NSITELEMETRY + + public: + static Telemetry* GetSingleton(); +}; + +// A static initializer to initialize histogram collection +static StatisticsRecorder gStatisticsRecorder; + +static bool +FillRanges(JSContext *cx, JSObject *array, Histogram *h) +{ + for (size_t i = 0;i < h->bucket_count();i++) { + if (!JS_DefineElement(cx, array, i, INT_TO_JSVAL(h->ranges(i)), NULL, NULL, JSPROP_ENUMERATE)) + return false; + } + return true; +} + +static JSBool +ReflectHistogramSnapshot(JSContext *cx, JSObject *obj, Histogram *h) +{ + Histogram::SampleSet ss; + h->SnapshotSample(&ss); + JSObject *counts_array; + JSObject *rarray; + const size_t count = h->bucket_count(); + if (!(JS_DefineProperty(cx, obj, "min", INT_TO_JSVAL(h->declared_min()), NULL, NULL, JSPROP_ENUMERATE) + && JS_DefineProperty(cx, obj, "max", INT_TO_JSVAL(h->declared_max()), NULL, NULL, JSPROP_ENUMERATE) + && JS_DefineProperty(cx, obj, "histogram_type", INT_TO_JSVAL(h->histogram_type()), NULL, NULL, JSPROP_ENUMERATE) + && JS_DefineProperty(cx, obj, "sum", INT_TO_JSVAL(ss.sum()), NULL, NULL, JSPROP_ENUMERATE) + && (rarray = JS_NewArrayObject(cx, count, NULL)) + && JS_DefineProperty(cx, obj, "ranges", OBJECT_TO_JSVAL(rarray), NULL, NULL, JSPROP_ENUMERATE) + && FillRanges(cx, rarray, h) + && (counts_array = JS_NewArrayObject(cx, count, NULL)) + && JS_DefineProperty(cx, obj, "counts", OBJECT_TO_JSVAL(counts_array), NULL, NULL, JSPROP_ENUMERATE) + )) { + return JS_FALSE; + } + for (size_t i = 0;i < count;i++) { + if (!JS_DefineElement(cx, counts_array, i, INT_TO_JSVAL(ss.counts(i)), NULL, NULL, JSPROP_ENUMERATE)) { + return JS_FALSE; + } + } + return JS_TRUE; +} + +static JSBool +JSHistogram_Add(JSContext *cx, uintN argc, jsval *vp) +{ + jsval *argv = JS_ARGV(cx, vp); + JSString *str; + if (!JS_ConvertArguments(cx, argc, argv, "i", &str)) + return JS_FALSE; + if (!JSVAL_IS_INT(argv[0])) + return JS_FALSE; + JSObject *obj = JS_THIS_OBJECT(cx, vp); + Histogram *h = static_cast(JS_GetPrivate(cx, obj)); + h->Add(JSVAL_TO_INT(argv[0])); + return JS_TRUE; +} + +static JSBool +JSHistogram_Snapshot(JSContext *cx, uintN argc, jsval *vp) +{ + JSObject *obj = JS_THIS_OBJECT(cx, vp); + Histogram *h = static_cast(JS_GetPrivate(cx, obj)); + JSObject *snapshot = JS_NewObject(cx, NULL, NULL, NULL); + if (!snapshot) + return NS_ERROR_FAILURE; + JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(snapshot)); + return ReflectHistogramSnapshot(cx, snapshot, h); +} + +static nsresult +WrapAndReturnHistogram(Histogram *h, JSContext *cx, jsval *ret) +{ + static JSClass JSHistogram_class = { + "JSHistogram", /* name */ + JSCLASS_HAS_PRIVATE, /* flags */ + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS + }; + + JSObject *obj = JS_NewObject(cx, &JSHistogram_class, NULL, NULL); + if (!obj) + return NS_ERROR_FAILURE; + *ret = OBJECT_TO_JSVAL(obj); + return (JS_SetPrivate(cx, obj, h) + && JS_DefineFunction (cx, obj, "add", JSHistogram_Add, 1, 0) + && JS_DefineFunction (cx, obj, "snapshot", JSHistogram_Snapshot, 1, 0)) ? NS_OK : NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +Telemetry::NewExponentialHistogram(const nsACString &name, PRInt32 min, PRInt32 max, PRUint32 size, JSContext *cx, jsval *ret) +{ + Histogram *h = base::Histogram::FactoryGet(name.BeginReading(), min, max, size, base::Histogram::kNoFlags); + return WrapAndReturnHistogram(h, cx, ret); +} + +NS_IMETHODIMP +Telemetry::NewLinearHistogram(const nsACString &name, PRInt32 min, PRInt32 max, PRUint32 size, JSContext *cx, jsval *ret) +{ + Histogram *h = base::LinearHistogram::FactoryGet(name.BeginReading(), min, max, size, base::Histogram::kNoFlags); + return WrapAndReturnHistogram(h, cx, ret); +} + +NS_IMETHODIMP +Telemetry::GetHistogramSnapshots(JSContext *cx, jsval *ret) +{ + JSObject *root_obj = JS_NewObject(cx, NULL, NULL, NULL); + if (!root_obj) + return NS_ERROR_FAILURE; + *ret = OBJECT_TO_JSVAL(root_obj); + + StatisticsRecorder::Histograms h; + StatisticsRecorder::GetHistograms(&h); + for (StatisticsRecorder::Histograms::iterator it = h.begin(); it != h.end();++it) { + Histogram *h = *it; + JSObject *hobj = JS_NewObject(cx, NULL, NULL, NULL); + if (!(hobj + && JS_DefineProperty(cx, root_obj, h->histogram_name().c_str(), + OBJECT_TO_JSVAL(hobj), NULL, NULL, JSPROP_ENUMERATE) + && ReflectHistogramSnapshot(cx, hobj, h))) { + return NS_ERROR_FAILURE; + } + } + return NS_OK; +} + +NS_IMPL_THREADSAFE_ISUPPORTS1(Telemetry, nsITelemetry) + +static Telemetry *gJarHandler = nsnull; + +static void ShutdownTelemetry() +{ + NS_IF_RELEASE(gJarHandler); +} + +Telemetry* Telemetry::GetSingleton() +{ + if (!gJarHandler) { + gJarHandler = new Telemetry(); + NS_ADDREF(gJarHandler); + } + NS_ADDREF(gJarHandler); + return gJarHandler; +} + +NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(Telemetry, Telemetry::GetSingleton) + +#define NS_TELEMETRY_CID \ + {0xf880b792, 0xe6cd, 0x46e7, {0x9c, 0x22, 0x3e, 0x12, 0xc3, 0x8b, 0xc6, 0xca}} +NS_DEFINE_NAMED_CID(NS_TELEMETRY_CID); + +static const mozilla::Module::CIDEntry kTelemetryCIDs[] = { + { &kNS_TELEMETRY_CID, false, NULL, TelemetryConstructor }, + { NULL } +}; + +static const mozilla::Module::ContractIDEntry kTelemetryContracts[] = { + { "@mozilla.org/base/telemetry;1", &kNS_TELEMETRY_CID }, + { NULL } +}; + +static const mozilla::Module kTelemetryModule = { + mozilla::Module::kVersion, + kTelemetryCIDs, + kTelemetryContracts, + NULL, + NULL, + NULL, + ShutdownTelemetry, +}; + +NSMODULE_DEFN(nsTelemetryModule) = &kTelemetryModule; diff --git a/xpcom/io/Makefile.in b/xpcom/io/Makefile.in index 61cd64aba28f..a9036fa164dd 100644 --- a/xpcom/io/Makefile.in +++ b/xpcom/io/Makefile.in @@ -51,7 +51,7 @@ MOZILLA_INTERNAL_API = 1 # work around bug 408258 ifdef GNU_CC ifneq ($(OS_ARCH), Darwin) -MODULE_OPTIMIZE_FLAGS = -Os -fno-strict-aliasing $(MOZ_OPTIMIZE_SIZE_TWEAK) +MODULE_OPTIMIZE_FLAGS = -O3 -fno-strict-aliasing endif endif diff --git a/xpcom/stub/Makefile.in b/xpcom/stub/Makefile.in index b248f903cdb3..3fd4494ef876 100644 --- a/xpcom/stub/Makefile.in +++ b/xpcom/stub/Makefile.in @@ -75,31 +75,31 @@ FORCE_SHARED_LIB = 1 EXTRA_DSO_LDOPTS = $(LIBS_DIR) DEPENDENT_LIBS_LIST += \ - $(LIB_PREFIX)nspr4$(DLL_SUFFIX) \ - $(LIB_PREFIX)plc4$(DLL_SUFFIX) \ - $(LIB_PREFIX)plds4$(DLL_SUFFIX) \ - $(LIB_PREFIX)mozalloc$(DLL_SUFFIX) \ + $(DLL_PREFIX)nspr4$(DLL_SUFFIX) \ + $(DLL_PREFIX)plc4$(DLL_SUFFIX) \ + $(DLL_PREFIX)plds4$(DLL_SUFFIX) \ + $(DLL_PREFIX)mozalloc$(DLL_SUFFIX) \ $(NULL) ifdef MOZ_ENABLE_LIBXUL DEPENDENT_LIBS_LIST += \ - $(LIB_PREFIX)nssutil3$(DLL_SUFFIX) \ - $(LIB_PREFIX)softokn3$(DLL_SUFFIX) \ - $(LIB_PREFIX)nss3$(DLL_SUFFIX) \ - $(LIB_PREFIX)ssl3$(DLL_SUFFIX) \ - $(LIB_PREFIX)smime3$(DLL_SUFFIX) \ + $(DLL_PREFIX)nssutil3$(DLL_SUFFIX) \ + $(DLL_PREFIX)softokn3$(DLL_SUFFIX) \ + $(DLL_PREFIX)nss3$(DLL_SUFFIX) \ + $(DLL_PREFIX)ssl3$(DLL_SUFFIX) \ + $(DLL_PREFIX)smime3$(DLL_SUFFIX) \ $(NULL) ifdef JS_SHARED_LIBRARY -DEPENDENT_LIBS_LIST += $(LIB_PREFIX)mozjs$(DLL_SUFFIX) +DEPENDENT_LIBS_LIST += $(DLL_PREFIX)mozjs$(DLL_SUFFIX) endif ifndef MOZ_NATIVE_SQLITE ifeq ($(OS_TARGET),OS2) DEPENDENT_LIBS_LIST += mozsqlt3.dll else -DEPENDENT_LIBS_LIST += $(LIB_PREFIX)mozsqlite3$(DLL_SUFFIX) +DEPENDENT_LIBS_LIST += $(DLL_PREFIX)mozsqlite3$(DLL_SUFFIX) endif endif @@ -108,7 +108,7 @@ EXTRA_DSO_LDOPTS += $(DIST)/bin/XUL DEPENDENT_LIBS_LIST += XUL else EXTRA_DSO_LIBS = xul -DEPENDENT_LIBS_LIST += $(LIB_PREFIX)xul$(DLL_SUFFIX) +DEPENDENT_LIBS_LIST += $(DLL_PREFIX)xul$(DLL_SUFFIX) endif else #!MOZ_ENABLE_LIBXUL @@ -117,7 +117,7 @@ EXTRA_DSO_LIBS = xpcom_core ifeq ($(OS_TARGET),OS2) DEPENDENT_LIBS_LIST += xpcomcor.dll else -DEPENDENT_LIBS_LIST += $(LIB_PREFIX)xpcom_core$(DLL_SUFFIX) +DEPENDENT_LIBS_LIST += $(DLL_PREFIX)xpcom_core$(DLL_SUFFIX) endif endif #ifdef MOZ_ENABLE_LIBXUL diff --git a/xpcom/tests/unit/test_nsITelemetry.js b/xpcom/tests/unit/test_nsITelemetry.js new file mode 100644 index 000000000000..8de4edaf7be6 --- /dev/null +++ b/xpcom/tests/unit/test_nsITelemetry.js @@ -0,0 +1,38 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +const Cc = Components.classes; +const Ci = Components.interfaces; + +const Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry); + +function test_histogram(histogram_constructor, name, min, max, bucket_count) { + var h = histogram_constructor(name, min, max, bucket_count); + + var r = h.snapshot().ranges; + var sum = 0; + for(var i=0;iAddTimer(this); } @@ -539,9 +543,11 @@ nsresult nsTimerImpl::PostTimerEvent() // If this is a repeating precise timer, we need to calculate the time for // the next timer to fire before we make the callback. - if (mType == TYPE_REPEATING_PRECISE) { + if (IsRepeatingPrecisely()) { SetDelayInternal(mDelay); - if (gThread) { + + // But only re-arm REPEATING_PRECISE timers. + if (gThread && mType == TYPE_REPEATING_PRECISE) { nsresult rv = gThread->AddTimer(this); if (NS_FAILED(rv)) return rv; diff --git a/xpcom/threads/nsTimerImpl.h b/xpcom/threads/nsTimerImpl.h index 1b1e3369e2b0..d146d68108e4 100644 --- a/xpcom/threads/nsTimerImpl.h +++ b/xpcom/threads/nsTimerImpl.h @@ -114,6 +114,17 @@ private: NS_RELEASE(mCallback.o); } + bool IsRepeating() const { + PR_STATIC_ASSERT(TYPE_ONE_SHOT < TYPE_REPEATING_SLACK); + PR_STATIC_ASSERT(TYPE_REPEATING_SLACK < TYPE_REPEATING_PRECISE); + PR_STATIC_ASSERT(TYPE_REPEATING_PRECISE < TYPE_REPEATING_PRECISE_CAN_SKIP); + return mType >= TYPE_REPEATING_SLACK; + } + + bool IsRepeatingPrecisely() const { + return mType >= TYPE_REPEATING_PRECISE; + } + nsCOMPtr mEventTarget; void * mClosure;