diff --git a/config/recurse.mk b/config/recurse.mk index 2774445409..b3e8f2e8ca 100644 --- a/config/recurse.mk +++ b/config/recurse.mk @@ -128,7 +128,9 @@ endef $(foreach subtier,$(filter-out compile,$(TIERS)),$(eval $(call CREATE_SUBTIER_TRAVERSAL_RULE,$(subtier)))) ifndef TOPLEVEL_BUILD +ifdef COMPILE_ENVIRONMENT libs:: target host +endif # COMPILE_ENVIRONMENT endif endif # ifeq ($(NO_RECURSE_MAKELEVEL),$(MAKELEVEL)) diff --git a/configure.in b/configure.in index d7e58b150a..5cca6d4cd7 100644 --- a/configure.in +++ b/configure.in @@ -362,6 +362,15 @@ dnl ======================================================== dnl AR_FLAGS set here so HOST_AR_FLAGS can be set correctly (see bug 538269) AR_FLAGS='crs $@' +if test -z "$COMPILE_ENVIRONMENT"; then +if test "$target" != "$host"; then +# Assert that we're cross compiling, but don't require a compile toolchain (as +# MOZ_CROSS_COMPILER does below). +CROSS_COMPILE=1 +AC_DEFINE(CROSS_COMPILE) +fi +fi # !COMPILE_ENVIRONMENT + if test "$COMPILE_ENVIRONMENT"; then if test "$target" != "$host"; then @@ -1925,7 +1934,7 @@ case "$target" in TARGET_COMPILER_ABI="ibmc" CC_VERSION=`lslpp -Lcq vac.C 2>/dev/null | awk -F: '{ print $3 }'` CXX_VERSION=`lslpp -Lcq vacpp.cmp.core 2>/dev/null | awk -F: '{ print $3 }'` - fi + fi # COMPILE_ENVIRONMENT fi case "${target_os}" in aix4.1*) @@ -1934,7 +1943,7 @@ case "$target" in esac if test "$COMPILE_ENVIRONMENT"; then MOZ_CHECK_HEADERS(sys/inttypes.h) - fi + fi # COMPILE_ENVIRONMENT AC_DEFINE(NSCAP_DISABLE_DEBUG_PTR_TYPES) ;; @@ -2061,7 +2070,9 @@ ia64*-hpux*) MOZ_SYNTH_PICO=1 else _PLATFORM_DEFAULT_TOOLKIT=cairo-android - MOZ_LINKER=1 + if test "$COMPILE_ENVIRONMENT"; then + MOZ_LINKER=1 + fi fi TARGET_NSPR_MDCPUCFG='\"md/_linux.cfg\"' @@ -2551,7 +2562,7 @@ if test -z "$COMPILE_ENVIRONMENT"; then SKIP_LIBRARY_CHECKS=1 else MOZ_COMPILER_OPTS -fi +fi # COMPILE_ENVIRONMENT if test -z "$SKIP_COMPILER_CHECKS"; then dnl Checks for typedefs, structures, and compiler characteristics. @@ -3823,7 +3834,9 @@ case "${target}" in NSS_DISABLE_DBM=1 MOZ_THEME_FASTSTRIPE=1 MOZ_TREE_FREETYPE=1 - MOZ_MEMORY=1 + if test "$COMPILE_ENVIRONMENT"; then + MOZ_MEMORY=1 + fi MOZ_RAW=1 ;; @@ -5369,7 +5382,7 @@ if test -n "$MOZ_VPX" -a -z "$MOZ_NATIVE_LIBVPX"; then VPX_ASFLAGS="-f win32 -rnasm -pnasm -DPIC" VPX_X86_ASM=1 dnl The encoder needs obj_int_extract to get asm offsets. - fi + fi # COMPILE_ENVIRONMENT and others ;; *:arm*) if test -n "$GNU_AS" ; then @@ -5398,7 +5411,7 @@ if test -n "$MOZ_VPX" -a -z "$MOZ_NATIVE_LIBVPX"; then if test -n "$COMPILE_ENVIRONMENT" -a -n "$VPX_X86_ASM" -a -z "$VPX_AS"; then AC_MSG_ERROR([yasm is a required build tool for this architecture when webm is enabled. You may either install yasm or --disable-webm (which disables the WebM video format). See https://developer.mozilla.org/en/YASM for more details.]) - fi + fi # COMPILE_ENVIRONMENT and others if test -z "$GNU_CC" -a -z "$INTEL_CC" -a -z "$CLANG_CC" ; then dnl We prefer to get asm offsets using inline assembler, which the above @@ -7047,7 +7060,7 @@ if test -n "$COMPILE_ENVIRONMENT" -a -n "$USE_ELF_HACK"; then USE_ELF_HACK= fi fi -fi +fi # COMPILE_ENVIRONMENT and others. dnl ======================================================== dnl = libstdc++ compatibility hacks @@ -8405,7 +8418,7 @@ AC_SUBST(MOZ_NATIVE_BZ2) AC_SUBST(MOZ_JPEG_CFLAGS) AC_SUBST_LIST(MOZ_JPEG_LIBS) -AC_SUBST(MOZ_BZ2_CFLAGS) +AC_SUBST_LIST(MOZ_BZ2_CFLAGS) AC_SUBST_LIST(MOZ_BZ2_LIBS) AC_SUBST(MOZ_PNG_CFLAGS) AC_SUBST_LIST(MOZ_PNG_LIBS) diff --git a/dom/base/nsIContent.h b/dom/base/nsIContent.h index 4421087dda..078cb1138d 100644 --- a/dom/base/nsIContent.h +++ b/dom/base/nsIContent.h @@ -40,8 +40,8 @@ enum nsLinkState { // IID for the nsIContent interface #define NS_ICONTENT_IID \ -{ 0x52cebfc8, 0x79ba, 0x4e38, \ - { 0x8a, 0x4c, 0x7f, 0x9d, 0xb1, 0xa2, 0xb6, 0x1d } } +{ 0x8e1bab9d, 0x8815, 0x4d2c, \ + { 0xa2, 0x4d, 0x7a, 0xba, 0x52, 0x39, 0xdc, 0x22 } } /** * A node of content in a document's content model. This interface @@ -593,10 +593,12 @@ public: * @param aKeyCausesActivation - if true then element should be activated * @param aIsTrustedEvent - if true then event that is cause of accesskey * execution is trusted. + * @return true if the focus was changed. */ - virtual void PerformAccesskey(bool aKeyCausesActivation, + virtual bool PerformAccesskey(bool aKeyCausesActivation, bool aIsTrustedEvent) { + return false; } /* diff --git a/dom/events/EventListenerManager.cpp b/dom/events/EventListenerManager.cpp index c8d8fa1300..f963eda39d 100644 --- a/dom/events/EventListenerManager.cpp +++ b/dom/events/EventListenerManager.cpp @@ -352,8 +352,8 @@ EventListenerManager::AddEventListenerInternal( if (window && !aFlags.mInSystemGroup) { window->SetHasTouchEventListeners(); } - } else if (aEventMessage >= NS_POINTER_EVENT_START && - aEventMessage <= NS_POINTER_LOST_CAPTURE) { + } else if (aEventMessage >= ePointerEventFirst && + aEventMessage <= ePointerEventLast) { nsPIDOMWindow* window = GetInnerWindowForTarget(); if (aTypeAtom == nsGkAtoms::onpointerenter || aTypeAtom == nsGkAtoms::onpointerleave) { diff --git a/dom/events/EventNameList.h b/dom/events/EventNameList.h index 0e65b0c3f7..88048c081a 100644 --- a/dom/events/EventNameList.h +++ b/dom/events/EventNameList.h @@ -271,11 +271,11 @@ EVENT(mousedown, EventNameType_All, eMouseEventClass) EVENT(mouseenter, - NS_MOUSEENTER, + eMouseEnter, EventNameType_All, eMouseEventClass) EVENT(mouseleave, - NS_MOUSELEAVE, + eMouseLeave, EventNameType_All, eMouseEventClass) EVENT(mousemove, @@ -323,7 +323,7 @@ EVENT(pointerup, EventNameType_All, ePointerEventClass) EVENT(pointercancel, - NS_POINTER_CANCEL, + ePointerCancel, EventNameType_All, ePointerEventClass) EVENT(pointerover, @@ -339,15 +339,15 @@ EVENT(pointerenter, EventNameType_All, ePointerEventClass) EVENT(pointerleave, - NS_POINTER_LEAVE, + ePointerLeave, EventNameType_All, ePointerEventClass) EVENT(gotpointercapture, - NS_POINTER_GOT_CAPTURE, + ePointerGotCapture, EventNameType_All, ePointerEventClass) EVENT(lostpointercapture, - NS_POINTER_LOST_CAPTURE, + ePointerLostCapture, EventNameType_All, ePointerEventClass) EVENT(selectstart, diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index ade602db5e..9ad032f48f 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -638,7 +638,7 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext, } else { if (sPointerEventEnabled) { // We should synthetize corresponding pointer events - GeneratePointerEnterExit(NS_POINTER_LEAVE, mouseEvent); + GeneratePointerEnterExit(ePointerLeave, mouseEvent); } GenerateMouseEnterExit(mouseEvent); //This is a window level mouse exit event and should stop here @@ -3017,7 +3017,7 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext, SetActiveManager(this, activeContent); } break; - case NS_POINTER_CANCEL: { + case ePointerCancel: { if(WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) { GenerateMouseEnterExit(mouseEvent); } @@ -3776,8 +3776,8 @@ EventStateManager::DispatchMouseOrPointerEvent(WidgetMouseEvent* aMouseEvent, // "[When the mouse is locked on an element...e]vents that require the concept // of a mouse cursor must not be dispatched (for example: mouseover, mouseout). if (sIsPointerLocked && - (aMessage == NS_MOUSELEAVE || - aMessage == NS_MOUSEENTER || + (aMessage == eMouseLeave || + aMessage == eMouseEnter || aMessage == eMouseOver || aMessage == eMouseOut)) { mCurrentTargetContent = nullptr; @@ -3891,7 +3891,7 @@ public: ~EnterLeaveDispatcher() { - if (mEventMessage == NS_MOUSEENTER || + if (mEventMessage == eMouseEnter || mEventMessage == NS_POINTER_ENTER) { for (int32_t i = mTargets.Count() - 1; i >= 0; --i) { mESM->DispatchMouseOrPointerEvent(mMouseEvent, mEventMessage, @@ -3962,13 +3962,18 @@ EventStateManager::NotifyMouseOut(WidgetMouseEvent* aMouseEvent, SetContentState(nullptr, NS_EVENT_STATE_HOVER); } + // In case we go out from capturing element (retargetedByPointerCapture is true) + // we should dispatch ePointerLeave event and only for capturing element. + nsRefPtr movingInto = aMouseEvent->retargetedByPointerCapture + ? wrapper->mLastOverElement->GetParent() + : aMovingInto; + EnterLeaveDispatcher leaveDispatcher(this, wrapper->mLastOverElement, - aMovingInto, aMouseEvent, - isPointer ? NS_POINTER_LEAVE : - NS_MOUSELEAVE); + movingInto, aMouseEvent, + isPointer ? ePointerLeave : eMouseLeave); // Fire mouseout - DispatchMouseOrPointerEvent(aMouseEvent, isPointer ? NS_POINTER_OUT : eMouseOut, + DispatchMouseOrPointerEvent(aMouseEvent, isPointer ? ePointerLeave : eMouseOut, wrapper->mLastOverElement, aMovingInto); wrapper->mLastOverFrame = nullptr; @@ -4025,7 +4030,7 @@ EventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent, Maybe enterDispatcher; if (dispatch) { enterDispatcher.emplace(this, aContent, lastOverElement, aMouseEvent, - isPointer ? NS_POINTER_ENTER : NS_MOUSEENTER); + isPointer ? NS_POINTER_ENTER : eMouseEnter); } NotifyMouseOut(aMouseEvent, aContent); @@ -4199,8 +4204,8 @@ EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent) } } break; - case NS_POINTER_LEAVE: - case NS_POINTER_CANCEL: + case ePointerLeave: + case ePointerCancel: case eMouseExitFromWidget: { // This is actually the window mouse exit or pointer leave event. We're not moving diff --git a/dom/html/HTMLLabelElement.cpp b/dom/html/HTMLLabelElement.cpp index 282ee9e6a3..fa4b159a6c 100644 --- a/dom/html/HTMLLabelElement.cpp +++ b/dom/html/HTMLLabelElement.cpp @@ -212,18 +212,20 @@ HTMLLabelElement::SubmitNamesValues(nsFormSubmission* aFormSubmission) return NS_OK; } -void +bool HTMLLabelElement::PerformAccesskey(bool aKeyCausesActivation, bool aIsTrustedEvent) { if (!aKeyCausesActivation) { nsRefPtr element = GetLabeledElement(); - if (element) - element->PerformAccesskey(aKeyCausesActivation, aIsTrustedEvent); + if (element) { + return element->PerformAccesskey(aKeyCausesActivation, aIsTrustedEvent); + } } else { nsPresContext *presContext = GetPresContext(eForUncomposedDoc); - if (!presContext) - return; + if (!presContext) { + return false; + } // Click on it if the users prefs indicate to do so. WidgetMouseEvent event(aIsTrustedEvent, eMouseClick, @@ -236,6 +238,8 @@ HTMLLabelElement::PerformAccesskey(bool aKeyCausesActivation, EventDispatcher::Dispatch(static_cast(this), presContext, &event); } + + return aKeyCausesActivation; } nsGenericHTMLElement* diff --git a/dom/html/HTMLLabelElement.h b/dom/html/HTMLLabelElement.h index 4eb8750efd..12cfa2d46c 100644 --- a/dom/html/HTMLLabelElement.h +++ b/dom/html/HTMLLabelElement.h @@ -67,7 +67,7 @@ public: // nsIContent virtual nsresult PostHandleEvent( EventChainPostVisitor& aVisitor) override; - virtual void PerformAccesskey(bool aKeyCausesActivation, + virtual bool PerformAccesskey(bool aKeyCausesActivation, bool aIsTrustedEvent) override; virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override; diff --git a/dom/html/HTMLLegendElement.cpp b/dom/html/HTMLLegendElement.cpp index e39b54c64d..bb26d4db2f 100644 --- a/dom/html/HTMLLegendElement.cpp +++ b/dom/html/HTMLLegendElement.cpp @@ -128,13 +128,14 @@ HTMLLegendElement::Focus(ErrorResult& aError) getter_AddRefs(result)); } -void +bool HTMLLegendElement::PerformAccesskey(bool aKeyCausesActivation, bool aIsTrustedEvent) { // just use the same behaviour as the focus method ErrorResult rv; Focus(rv); + return NS_SUCCEEDED(rv.StealNSResult()); } already_AddRefed diff --git a/dom/html/HTMLLegendElement.h b/dom/html/HTMLLegendElement.h index cd865d8f16..e2d71d62dd 100644 --- a/dom/html/HTMLLegendElement.h +++ b/dom/html/HTMLLegendElement.h @@ -27,7 +27,7 @@ public: using nsGenericHTMLElement::Focus; virtual void Focus(ErrorResult& aError) override; - virtual void PerformAccesskey(bool aKeyCausesActivation, + virtual bool PerformAccesskey(bool aKeyCausesActivation, bool aIsTrustedEvent) override; // nsIContent diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp index c631bbcd51..0a9b771247 100644 --- a/dom/html/nsGenericHTMLElement.cpp +++ b/dom/html/nsGenericHTMLElement.cpp @@ -2452,13 +2452,13 @@ nsGenericHTMLFormElement::IsElementDisabledForEvents(EventMessage aMessage, case eMouseMove: case eMouseOver: case eMouseOut: - case NS_MOUSEENTER: - case NS_MOUSELEAVE: + case eMouseEnter: + case eMouseLeave: case NS_POINTER_MOVE: case NS_POINTER_OVER: case NS_POINTER_OUT: case NS_POINTER_ENTER: - case NS_POINTER_LEAVE: + case ePointerLeave: case NS_WHEEL_WHEEL: case NS_MOUSE_SCROLL: case NS_MOUSE_PIXEL_SCROLL: @@ -2778,18 +2778,24 @@ nsGenericHTMLElement::RegUnRegAccessKey(bool aDoReg) } } -void +bool nsGenericHTMLElement::PerformAccesskey(bool aKeyCausesActivation, bool aIsTrustedEvent) { nsPresContext* presContext = GetPresContext(eForUncomposedDoc); - if (!presContext) - return; + if (!presContext) { + return false; + } // It's hard to say what HTML4 wants us to do in all cases. - nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + bool focused = true; + nsFocusManager* fm = nsFocusManager::GetFocusManager(); if (fm) { fm->SetFocus(this, nsIFocusManager::FLAG_BYKEY); + + // Return true if the element became the current focus within its window. + nsPIDOMWindow* window = OwnerDoc()->GetWindow(); + focused = (window && window->GetFocusedNode()); } if (aKeyCausesActivation) { @@ -2798,6 +2804,8 @@ nsGenericHTMLElement::PerformAccesskey(bool aKeyCausesActivation, openAllowed : openAbused); DispatchSimulatedClick(this, aIsTrustedEvent, presContext); } + + return focused; } nsresult diff --git a/dom/html/nsGenericHTMLElement.h b/dom/html/nsGenericHTMLElement.h index f92552ffb3..b3a015eaee 100644 --- a/dom/html/nsGenericHTMLElement.h +++ b/dom/html/nsGenericHTMLElement.h @@ -600,7 +600,7 @@ public: virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex); - virtual void PerformAccesskey(bool aKeyCausesActivation, + virtual bool PerformAccesskey(bool aKeyCausesActivation, bool aIsTrustedEvent) override; /** diff --git a/dom/xul/nsXULElement.cpp b/dom/xul/nsXULElement.cpp index ca8bcc374b..7c05acf002 100644 --- a/dom/xul/nsXULElement.cpp +++ b/dom/xul/nsXULElement.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -291,10 +291,6 @@ nsXULElement::Create(nsXULPrototypeElement* aPrototype, nsRefPtr element = Create(aPrototype, nodeInfo, aIsScriptable, aIsRoot); - if (!element) { - return NS_ERROR_OUT_OF_MEMORY; - } - element.forget(aResult); return NS_OK; @@ -623,7 +619,7 @@ nsXULElement::IsFocusableInternal(int32_t *aTabIndex, bool aWithMouse) return shouldFocus; } -void +bool nsXULElement::PerformAccesskey(bool aKeyCausesActivation, bool aIsTrustedEvent) { @@ -646,21 +642,24 @@ nsXULElement::PerformAccesskey(bool aKeyCausesActivation, // |element|, or clear it. content = do_QueryInterface(element); - if (!content) - return; + if (!content) { + return false; + } } nsIFrame* frame = content->GetPrimaryFrame(); - if (!frame || !frame->IsVisibleConsideringAncestors()) - return; + if (!frame || !frame->IsVisibleConsideringAncestors()) { + return false; + } + bool focused = false; nsXULElement* elm = FromContent(content); if (elm) { // Define behavior for each type of XUL element. if (!content->IsXULElement(nsGkAtoms::toolbarbutton)) { nsIFocusManager* fm = nsFocusManager::GetFocusManager(); if (fm) { - nsCOMPtr element; + nsCOMPtr elementToFocus; // for radio buttons, focus the radiogroup instead if (content->IsXULElement(nsGkAtoms::radio)) { nsCOMPtr controlItem(do_QueryInterface(content)); @@ -670,25 +669,30 @@ nsXULElement::PerformAccesskey(bool aKeyCausesActivation, if (!disabled) { nsCOMPtr selectControl; controlItem->GetControl(getter_AddRefs(selectControl)); - element = do_QueryInterface(selectControl); + elementToFocus = do_QueryInterface(selectControl); } } + } else { + elementToFocus = do_QueryInterface(content); } - else { - element = do_QueryInterface(content); + if (elementToFocus) { + fm->SetFocus(elementToFocus, nsIFocusManager::FLAG_BYKEY); + + // Return true if the element became focused. + nsPIDOMWindow* window = OwnerDoc()->GetWindow(); + focused = (window && window->GetFocusedNode()); } - if (element) - fm->SetFocus(element, nsIFocusManager::FLAG_BYKEY); } } if (aKeyCausesActivation && !content->IsAnyOfXULElements(nsGkAtoms::textbox, nsGkAtoms::menulist)) { elm->ClickWithInputSource(nsIDOMMouseEvent::MOZ_SOURCE_KEYBOARD); } + } else { + return content->PerformAccesskey(aKeyCausesActivation, aIsTrustedEvent); } - else { - content->PerformAccesskey(aKeyCausesActivation, aIsTrustedEvent); - } + + return focused; } //---------------------------------------------------------------------- @@ -1050,9 +1054,9 @@ nsXULElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName, if (GetAttr(aNamespaceID, aName, oldValue)) { UnregisterAccessKey(oldValue); } - } - else if (aNamespaceID == kNameSpaceID_None && (aName == - nsGkAtoms::command || aName == nsGkAtoms::observes) && IsInDoc()) { + } else if (aNamespaceID == kNameSpaceID_None && + (aName == nsGkAtoms::command || aName == nsGkAtoms::observes) && + IsInDoc()) { // XXX sXBL/XBL2 issue! Owner or current document? nsAutoString oldValue; GetAttr(kNameSpaceID_None, nsGkAtoms::observes, oldValue); @@ -2277,62 +2281,55 @@ nsXULPrototypeElement::Deserialize(nsIObjectInputStream* aStream, NS_PRECONDITION(aNodeInfos, "missing nodeinfo array"); // Read Node Info - uint32_t number; + uint32_t number = 0; nsresult rv = aStream->Read32(&number); - mNodeInfo = aNodeInfos->ElementAt(number); - if (!mNodeInfo) + if (NS_WARN_IF(NS_FAILED(rv))) return rv; + mNodeInfo = aNodeInfos->SafeElementAt(number, nullptr); + if (!mNodeInfo) { return NS_ERROR_UNEXPECTED; + } // Read Attributes - nsresult tmp = aStream->Read32(&number); - if (NS_FAILED(tmp)) { - rv = tmp; - } + rv = aStream->Read32(&number); + if (NS_WARN_IF(NS_FAILED(rv))) return rv; mNumAttributes = int32_t(number); - uint32_t i; if (mNumAttributes > 0) { - mAttributes = new nsXULPrototypeAttribute[mNumAttributes]; - if (! mAttributes) + mAttributes = new (fallible) nsXULPrototypeAttribute[mNumAttributes]; + if (!mAttributes) { return NS_ERROR_OUT_OF_MEMORY; + } nsAutoString attributeValue; - for (i = 0; i < mNumAttributes; ++i) { - tmp = aStream->Read32(&number); - if (NS_FAILED(tmp)) { - rv = tmp; - } - mozilla::dom::NodeInfo* ni = aNodeInfos->ElementAt(number); - if (!ni) + for (uint32_t i = 0; i < mNumAttributes; ++i) { + rv = aStream->Read32(&number); + if (NS_WARN_IF(NS_FAILED(rv))) return rv; + mozilla::dom::NodeInfo* ni = aNodeInfos->SafeElementAt(number, nullptr); + if (!ni) { return NS_ERROR_UNEXPECTED; + } mAttributes[i].mName.SetTo(ni); - tmp = aStream->ReadString(attributeValue); - if (NS_FAILED(tmp)) { - rv = tmp; - } - tmp = SetAttrAt(i, attributeValue, aDocumentURI); - if (NS_FAILED(tmp)) { - rv = tmp; - } + rv = aStream->ReadString(attributeValue); + if (NS_WARN_IF(NS_FAILED(rv))) return rv; + rv = SetAttrAt(i, attributeValue, aDocumentURI); + if (NS_WARN_IF(NS_FAILED(rv))) return rv; } } - tmp = aStream->Read32(&number); - if (NS_FAILED(tmp)) { - rv = tmp; - } + rv = aStream->Read32(&number); + if (NS_WARN_IF(NS_FAILED(rv))) return rv; uint32_t numChildren = int32_t(number); if (numChildren > 0) { - mChildren.SetCapacity(numChildren); + if (!mChildren.SetCapacity(numChildren, fallible)) { + return NS_ERROR_OUT_OF_MEMORY; + } - for (i = 0; i < numChildren; i++) { - tmp = aStream->Read32(&number); - if (NS_FAILED(tmp)) { - rv = tmp; - } + for (uint32_t i = 0; i < numChildren; i++) { + rv = aStream->Read32(&number); + if (NS_WARN_IF(NS_FAILED(rv))) return rv; Type childType = (Type)number; nsRefPtr child; @@ -2340,79 +2337,52 @@ nsXULPrototypeElement::Deserialize(nsIObjectInputStream* aStream, switch (childType) { case eType_Element: child = new nsXULPrototypeElement(); - if (! child) - return NS_ERROR_OUT_OF_MEMORY; - child->mType = childType; - - tmp = child->Deserialize(aStream, aProtoDoc, aDocumentURI, - aNodeInfos); - if (NS_FAILED(tmp)) { - rv = tmp; - } + rv = child->Deserialize(aStream, aProtoDoc, aDocumentURI, + aNodeInfos); + if (NS_WARN_IF(NS_FAILED(rv))) return rv; break; case eType_Text: child = new nsXULPrototypeText(); - if (! child) - return NS_ERROR_OUT_OF_MEMORY; - child->mType = childType; - - tmp = child->Deserialize(aStream, aProtoDoc, aDocumentURI, - aNodeInfos); - if (NS_FAILED(tmp)) { - rv = tmp; - } + rv = child->Deserialize(aStream, aProtoDoc, aDocumentURI, + aNodeInfos); + if (NS_WARN_IF(NS_FAILED(rv))) return rv; break; case eType_PI: child = new nsXULPrototypePI(); - if (! child) - return NS_ERROR_OUT_OF_MEMORY; - child->mType = childType; - - tmp = child->Deserialize(aStream, aProtoDoc, aDocumentURI, - aNodeInfos); - if (NS_FAILED(tmp)) { - rv = tmp; - } + rv = child->Deserialize(aStream, aProtoDoc, aDocumentURI, + aNodeInfos); + if (NS_WARN_IF(NS_FAILED(rv))) return rv; break; case eType_Script: { // language version/options obtained during deserialization. - nsXULPrototypeScript* script = new nsXULPrototypeScript(0, 0); - if (! script) - return NS_ERROR_OUT_OF_MEMORY; - child = script; - child->mType = childType; + nsRefPtr script = new nsXULPrototypeScript(0, 0); - tmp = aStream->ReadBoolean(&script->mOutOfLine); - if (NS_FAILED(tmp)) { - rv = tmp; - } - if (! script->mOutOfLine) { - tmp = script->Deserialize(aStream, aProtoDoc, aDocumentURI, - aNodeInfos); - if (NS_FAILED(tmp)) { - rv = tmp; - } + rv = aStream->ReadBoolean(&script->mOutOfLine); + if (NS_WARN_IF(NS_FAILED(rv))) return rv; + if (!script->mOutOfLine) { + rv = script->Deserialize(aStream, aProtoDoc, aDocumentURI, + aNodeInfos); + if (NS_WARN_IF(NS_FAILED(rv))) return rv; } else { nsCOMPtr supports; - tmp = aStream->ReadObject(true, getter_AddRefs(supports)); + rv = aStream->ReadObject(true, getter_AddRefs(supports)); + if (NS_WARN_IF(NS_FAILED(rv))) return rv; script->mSrcURI = do_QueryInterface(supports); - if (NS_FAILED(tmp)) { - rv = tmp; - } - tmp = script->DeserializeOutOfLine(aStream, aProtoDoc); - if (NS_FAILED(tmp)) { - rv = tmp; - } + rv = script->DeserializeOutOfLine(aStream, aProtoDoc); + if (NS_WARN_IF(NS_FAILED(rv))) return rv; } - // If we failed to deserialize, consider deleting 'script'? + + child = script.forget(); break; } default: - NS_NOTREACHED("Unexpected child type!"); - rv = NS_ERROR_UNEXPECTED; + MOZ_ASSERT(false, "Unexpected child type!"); + return NS_ERROR_UNEXPECTED; } + MOZ_ASSERT(child, "Don't append null to mChildren"); + MOZ_ASSERT(child->mType == childType); mChildren.AppendElement(child); // Oh dear. Something failed during the deserialization. @@ -2423,7 +2393,7 @@ nsXULPrototypeElement::Deserialize(nsIObjectInputStream* aStream, // death. So, let's just fail now, and propagate that failure // upward so that the ChromeProtocolHandler knows it can't use // a cached chrome channel for this. - if (NS_FAILED(rv)) + if (NS_WARN_IF(NS_FAILED(rv))) return rv; } } @@ -2623,13 +2593,16 @@ nsXULPrototypeScript::Deserialize(nsIObjectInputStream* aStream, nsIURI* aDocumentURI, const nsTArray> *aNodeInfos) { + nsresult rv; NS_ASSERTION(!mSrcLoading || mSrcLoadWaiters != nullptr || !mScriptObject, "prototype script not well-initialized when deserializing?!"); // Read basic prototype data - aStream->Read32(&mLineNo); - aStream->Read32(&mLangVersion); + rv = aStream->Read32(&mLineNo); + if (NS_FAILED(rv)) return rv; + rv = aStream->Read32(&mLangVersion); + if (NS_FAILED(rv)) return rv; AutoSafeJSContext cx; JS::Rooted global(cx, xpc::CompilationScope()); @@ -2637,8 +2610,8 @@ nsXULPrototypeScript::Deserialize(nsIObjectInputStream* aStream, JSAutoCompartment ac(cx, global); JS::Rooted newScriptObject(cx); - nsresult rv = nsContentUtils::XPConnect()->ReadScript(aStream, cx, - newScriptObject.address()); + rv = nsContentUtils::XPConnect()->ReadScript(aStream, cx, + newScriptObject.address()); NS_ENSURE_SUCCESS(rv, rv); Set(newScriptObject); return NS_OK; @@ -2868,11 +2841,11 @@ nsXULPrototypeText::Deserialize(nsIObjectInputStream* aStream, nsIURI* aDocumentURI, const nsTArray> *aNodeInfos) { - nsresult rv; - - rv = aStream->ReadString(mValue); - - return rv; + nsresult rv = aStream->ReadString(mValue); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + return NS_OK; } //---------------------------------------------------------------------- @@ -2911,10 +2884,9 @@ nsXULPrototypePI::Deserialize(nsIObjectInputStream* aStream, nsresult rv; rv = aStream->ReadString(mTarget); - nsresult tmp = aStream->ReadString(mData); - if (NS_FAILED(tmp)) { - rv = tmp; - } + if (NS_FAILED(rv)) return rv; + rv = aStream->ReadString(mData); + if (NS_FAILED(rv)) return rv; return rv; } diff --git a/dom/xul/nsXULElement.h b/dom/xul/nsXULElement.h index cb6a631185..e3fc7b9a50 100644 --- a/dom/xul/nsXULElement.h +++ b/dom/xul/nsXULElement.h @@ -399,7 +399,7 @@ public: } #endif - virtual void PerformAccesskey(bool aKeyCausesActivation, + virtual bool PerformAccesskey(bool aKeyCausesActivation, bool aIsTrustedEvent) override; nsresult ClickWithInputSource(uint16_t aInputSource); diff --git a/dom/xul/nsXULPrototypeCache.cpp b/dom/xul/nsXULPrototypeCache.cpp index 0b405a5bde..d75dc7cd5b 100644 --- a/dom/xul/nsXULPrototypeCache.cpp +++ b/dom/xul/nsXULPrototypeCache.cpp @@ -49,7 +49,7 @@ UpdategDisableXULCache() if (gDisableXULCache) { Telemetry::Accumulate(Telemetry::XUL_CACHE_DISABLED, true); } - + } static void @@ -100,7 +100,7 @@ nsXULPrototypeCache::GetInstance() obsSvc->AddObserver(p, "chrome-flush-caches", false); obsSvc->AddObserver(p, "startupcache-invalidate", false); } - + } return sInstance; } @@ -149,19 +149,19 @@ nsXULPrototypeCache::GetPrototype(nsIURI* aURI) rv = GetInputStream(aURI, getter_AddRefs(ois)); if (NS_FAILED(rv)) return nullptr; - + nsRefPtr newProto; rv = NS_NewXULPrototypeDocument(getter_AddRefs(newProto)); if (NS_FAILED(rv)) return nullptr; - + rv = newProto->Read(ois); if (NS_SUCCEEDED(rv)) { rv = PutPrototype(newProto); } else { newProto = nullptr; } - + mInputStreamTable.Remove(aURI); return newProto; } @@ -347,13 +347,13 @@ nsXULPrototypeCache::WritePrototype(nsXULPrototypeDocument* aPrototypeDocument) } nsresult -nsXULPrototypeCache::GetInputStream(nsIURI* uri, nsIObjectInputStream** stream) +nsXULPrototypeCache::GetInputStream(nsIURI* uri, nsIObjectInputStream** stream) { nsAutoCString spec(kXULCachePrefix); nsresult rv = PathifyURI(uri, spec); - if (NS_FAILED(rv)) + if (NS_FAILED(rv)) return NS_ERROR_NOT_AVAILABLE; - + nsAutoArrayPtr buf; uint32_t len; nsCOMPtr ois; @@ -370,7 +370,7 @@ nsXULPrototypeCache::GetInputStream(nsIURI* uri, nsIObjectInputStream** stream) buf.forget(); mInputStreamTable.Put(uri, ois); - + ois.forget(stream); return NS_OK; } @@ -395,7 +395,7 @@ nsXULPrototypeCache::GetOutputStream(nsIURI* uri, nsIObjectOutputStream** stream = do_QueryInterface(storageStream); objectOutput->SetOutputStream(outputStream); } else { - rv = NewObjectOutputWrappedStorageStream(getter_AddRefs(objectOutput), + rv = NewObjectOutputWrappedStorageStream(getter_AddRefs(objectOutput), getter_AddRefs(storageStream), false); NS_ENSURE_SUCCESS(rv, rv); @@ -406,7 +406,7 @@ nsXULPrototypeCache::GetOutputStream(nsIURI* uri, nsIObjectOutputStream** stream } nsresult -nsXULPrototypeCache::FinishOutputStream(nsIURI* uri) +nsXULPrototypeCache::FinishOutputStream(nsIURI* uri) { nsresult rv; StartupCache* sc = StartupCache::GetSingleton(); @@ -420,10 +420,10 @@ nsXULPrototypeCache::FinishOutputStream(nsIURI* uri) nsCOMPtr outputStream = do_QueryInterface(storageStream); outputStream->Close(); - + nsAutoArrayPtr buf; uint32_t len; - rv = NewBufferFromStorageStream(storageStream, getter_Transfers(buf), + rv = NewBufferFromStorageStream(storageStream, getter_Transfers(buf), &len); NS_ENSURE_SUCCESS(rv, rv); @@ -534,16 +534,16 @@ nsXULPrototypeCache::BeginCaching(nsIURI* aURI) return rv; nsAutoCString fileChromePath, fileLocale; - + nsAutoArrayPtr buf; uint32_t len, amtRead; nsCOMPtr objectInput; - rv = startupCache->GetBuffer(kXULCacheInfoKey, getter_Transfers(buf), + rv = startupCache->GetBuffer(kXULCacheInfoKey, getter_Transfers(buf), &len); if (NS_SUCCEEDED(rv)) rv = NewObjectInputStreamFromBuffer(buf, len, getter_AddRefs(objectInput)); - + if (NS_SUCCEEDED(rv)) { buf.forget(); rv = objectInput->ReadCString(fileLocale); @@ -598,7 +598,7 @@ nsXULPrototypeCache::BeginCaching(nsIURI* aURI) rv = NS_ERROR_FILE_TOO_BIG; } } - + if (NS_SUCCEEDED(rv)) { buf = new char[len]; rv = inputStream->Read(buf, len, &amtRead); diff --git a/gfx/layers/apz/util/APZCCallbackHelper.cpp b/gfx/layers/apz/util/APZCCallbackHelper.cpp index 62ab36611e..b02d920fc2 100644 --- a/gfx/layers/apz/util/APZCCallbackHelper.cpp +++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp @@ -497,7 +497,7 @@ APZCCallbackHelper::DispatchSynthesizedMouseEvent(EventMessage aMsg, nsIWidget* aWidget) { MOZ_ASSERT(aMsg == eMouseMove || aMsg == eMouseDown || - aMsg == eMouseUp || aMsg == NS_MOUSE_MOZLONGTAP); + aMsg == eMouseUp || aMsg == eMouseLongTap); WidgetMouseEvent event(true, aMsg, nullptr, WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal); diff --git a/gfx/layers/apz/util/APZEventState.cpp b/gfx/layers/apz/util/APZEventState.cpp index 1400adc79c..99998929b1 100644 --- a/gfx/layers/apz/util/APZEventState.cpp +++ b/gfx/layers/apz/util/APZEventState.cpp @@ -237,7 +237,9 @@ APZEventState::ProcessLongTap(const nsCOMPtr& aPresShell, * widget->GetDefaultScale(); int time = 0; nsEventStatus status = - APZCCallbackHelper::DispatchSynthesizedMouseEvent(NS_MOUSE_MOZLONGTAP, time, currentPoint, aModifiers, widget); + APZCCallbackHelper::DispatchSynthesizedMouseEvent(eMouseLongTap, time, + currentPoint, + aModifiers, widget); eventHandled = (status == nsEventStatus_eConsumeNoDefault); APZES_LOG("MOZLONGTAP event handled: %d\n", eventHandled); } diff --git a/layout/base/AccessibleCaretEventHub.cpp b/layout/base/AccessibleCaretEventHub.cpp index 05ad183252..6fd3576d87 100644 --- a/layout/base/AccessibleCaretEventHub.cpp +++ b/layout/base/AccessibleCaretEventHub.cpp @@ -516,10 +516,10 @@ AccessibleCaretEventHub::HandleMouseEvent(WidgetMouseEvent* aEvent) rv); break; - case NS_MOUSE_MOZLONGTAP: - AC_LOGV("Before NS_MOUSE_MOZLONGTAP, state: %s", mState->Name()); + case eMouseLongTap: + AC_LOGV("Before eMouseLongTap, state: %s", mState->Name()); rv = mState->OnLongTap(this, point); - AC_LOGV("After NS_MOUSE_MOZLONGTAP, state: %s, consume: %d", mState->Name(), + AC_LOGV("After eMouseLongTap, state: %s, consume: %d", mState->Name(), rv); break; diff --git a/layout/base/SelectionCarets.cpp b/layout/base/SelectionCarets.cpp index 19c884848e..8a1b70578b 100644 --- a/layout/base/SelectionCarets.cpp +++ b/layout/base/SelectionCarets.cpp @@ -264,15 +264,15 @@ SelectionCarets::HandleEvent(WidgetEvent* aEvent) CancelLongTapDetector(); } - } else if (aEvent->mMessage == NS_MOUSE_MOZLONGTAP) { + } else if (aEvent->mMessage == eMouseLongTap) { if (!mVisible || !sSelectionCaretDetectsLongTap) { - SELECTIONCARETS_LOG("SelectWord from NS_MOUSE_MOZLONGTAP"); + SELECTIONCARETS_LOG("SelectWord from eMouseLongTap"); mDownPoint = ptInRoot; nsresult wordSelected = SelectWord(); if (NS_FAILED(wordSelected)) { - SELECTIONCARETS_LOG("SelectWord from NS_MOUSE_MOZLONGTAP failed!"); + SELECTIONCARETS_LOG("SelectWord from eMouseLongTap failed!"); return nsEventStatus_eIgnore; } diff --git a/layout/base/TouchCaret.cpp b/layout/base/TouchCaret.cpp index 6175ffa599..fca14eb105 100644 --- a/layout/base/TouchCaret.cpp +++ b/layout/base/TouchCaret.cpp @@ -795,7 +795,7 @@ TouchCaret::HandleEvent(WidgetEvent* aEvent) TOUCHCARET_LOG("Receive key/wheel event %d", aEvent->mMessage); SetVisibility(false); break; - case NS_MOUSE_MOZLONGTAP: + case eMouseLongTap: if (mState == TOUCHCARET_TOUCHDRAG_ACTIVE) { // Disable long tap event from APZ while dragging the touch caret. status = nsEventStatus_eConsumeNoDefault; diff --git a/layout/base/gtest/TestAccessibleCaretEventHub.cpp b/layout/base/gtest/TestAccessibleCaretEventHub.cpp index 51dca9e25c..39866a64c6 100644 --- a/layout/base/gtest/TestAccessibleCaretEventHub.cpp +++ b/layout/base/gtest/TestAccessibleCaretEventHub.cpp @@ -140,7 +140,7 @@ public: static UniquePtr CreateLongTapEvent(nscoord aX, nscoord aY) { - return CreateMouseEvent(NS_MOUSE_MOZLONGTAP, aX, aY); + return CreateMouseEvent(eMouseLongTap, aX, aY); } static UniquePtr CreateTouchEvent(EventMessage aMessage, diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index b5bbda403a..84dea61875 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -6694,7 +6694,7 @@ DispatchPointerFromMouseOrTouch(PresShell* aShell, pointerMessage = NS_POINTER_DOWN; break; case NS_TOUCH_CANCEL: - pointerMessage = NS_POINTER_CANCEL; + pointerMessage = ePointerCancel; break; default: return NS_OK; @@ -7443,9 +7443,10 @@ PresShell::HandleEvent(nsIFrame* aFrame, } if (pointerEvent->mMessage == NS_POINTER_UP || - pointerEvent->mMessage == NS_POINTER_CANCEL) { + pointerEvent->mMessage == ePointerCancel) { // Implicitly releasing capture for given pointer. - // LOST_POINTER_CAPTURE should be send after NS_POINTER_UP or NS_POINTER_CANCEL. + // ePointerLostCapture should be send after NS_POINTER_UP or + // ePointerCancel. releasePointerCaptureCaller.SetTarget(pointerId, pointerCapturingContent); } } diff --git a/toolkit/mozapps/update/tests/chrome/chrome.ini b/toolkit/mozapps/update/tests/chrome/chrome.ini index 2b1acb2411..e4bd8aef7c 100644 --- a/toolkit/mozapps/update/tests/chrome/chrome.ini +++ b/toolkit/mozapps/update/tests/chrome/chrome.ini @@ -17,8 +17,8 @@ support-files = [test_0015_check_incompat_basic_addons.xul] [test_0016_check_incompat_basic_license_addons.xul] [test_0017_check_staging_basic.xul] -skip-if = os != 'win' -reason = Bug 918029 and bug 1164560 - timeout caused by copying too many files. +skip-if = asan +reason = Bug 1168003 [test_0021_check_billboard.xul] [test_0022_check_billboard_license.xul] [test_0023_check_incompat_billboard.xul] @@ -59,11 +59,15 @@ reason = Bug 918029 and bug 1164560 - timeout caused by copying too many files. [test_0094_restartNotification_remote.xul] [test_0095_restartNotification_remoteInvalidNumber.xul] [test_0096_restartNotification_stagedBackground.xul] +skip-if = asan +reason = Bug 1168003 [test_0097_restartNotification_stagedServiceBackground.xul] +skip-if = os != 'win' +reason = only Windows has the maintenance service. [test_0101_background_restartNotification.xul] [test_0102_background_restartNotification_staging.xul] -skip-if = os == 'linux' -reason = Bug 918029 - timeout caused by copying too many files. +skip-if = asan +reason = Bug 1168003 [test_0103_background_restartNotification_stagingService.xul] skip-if = os != 'win' reason = only Windows has the maintenance service. diff --git a/toolkit/mozapps/update/tests/chrome/test_0017_check_staging_basic.xul b/toolkit/mozapps/update/tests/chrome/test_0017_check_staging_basic.xul index ab08cb83f2..a20966a28e 100644 --- a/toolkit/mozapps/update/tests/chrome/test_0017_check_staging_basic.xul +++ b/toolkit/mozapps/update/tests/chrome/test_0017_check_staging_basic.xul @@ -31,6 +31,8 @@ const TESTS = [ { buttonClick: "extra1" } ]; +gUseTestUpdater = true; + function runTest() { debugDump("entering"); diff --git a/toolkit/mozapps/update/tests/chrome/test_0096_restartNotification_stagedBackground.xul b/toolkit/mozapps/update/tests/chrome/test_0096_restartNotification_stagedBackground.xul index ba43af8c4c..b86861012c 100644 --- a/toolkit/mozapps/update/tests/chrome/test_0096_restartNotification_stagedBackground.xul +++ b/toolkit/mozapps/update/tests/chrome/test_0096_restartNotification_stagedBackground.xul @@ -24,6 +24,8 @@ const TESTS = [ { buttonClick: "extra1" } ]; +gUseTestUpdater = true; + function runTest() { debugDump("entering"); diff --git a/toolkit/mozapps/update/tests/chrome/test_0097_restartNotification_stagedServiceBackground.xul b/toolkit/mozapps/update/tests/chrome/test_0097_restartNotification_stagedServiceBackground.xul index 852a16f2ba..9f7a602c4f 100644 --- a/toolkit/mozapps/update/tests/chrome/test_0097_restartNotification_stagedServiceBackground.xul +++ b/toolkit/mozapps/update/tests/chrome/test_0097_restartNotification_stagedServiceBackground.xul @@ -24,6 +24,8 @@ const TESTS = [ { buttonClick: "extra1" } ]; +gUseTestUpdater = true; + function runTest() { debugDump("entering"); diff --git a/toolkit/mozapps/update/tests/chrome/test_0102_background_restartNotification_staging.xul b/toolkit/mozapps/update/tests/chrome/test_0102_background_restartNotification_staging.xul index 25e96a7e28..7491d3f61f 100644 --- a/toolkit/mozapps/update/tests/chrome/test_0102_background_restartNotification_staging.xul +++ b/toolkit/mozapps/update/tests/chrome/test_0102_background_restartNotification_staging.xul @@ -24,6 +24,8 @@ const TESTS = [ { buttonClick: "extra1" } ]; +gUseTestUpdater = true; + function runTest() { debugDump("entering"); diff --git a/toolkit/mozapps/update/tests/chrome/test_0103_background_restartNotification_stagingService.xul b/toolkit/mozapps/update/tests/chrome/test_0103_background_restartNotification_stagingService.xul index fb04ea069d..c007b81348 100644 --- a/toolkit/mozapps/update/tests/chrome/test_0103_background_restartNotification_stagingService.xul +++ b/toolkit/mozapps/update/tests/chrome/test_0103_background_restartNotification_stagingService.xul @@ -24,6 +24,8 @@ const TESTS = [ { buttonClick: "extra1" } ]; +gUseTestUpdater = true; + function runTest() { debugDump("entering"); diff --git a/toolkit/mozapps/update/tests/chrome/test_9999_cleanup.xul b/toolkit/mozapps/update/tests/chrome/test_9999_cleanup.xul index 2c5fd34945..54792b02b7 100644 --- a/toolkit/mozapps/update/tests/chrome/test_9999_cleanup.xul +++ b/toolkit/mozapps/update/tests/chrome/test_9999_cleanup.xul @@ -81,7 +81,29 @@ function runTest() { ", Exception: " + e); } - resetAddons(finishTest); + resetAddons(cleanupRestoreUpdaterBackup); +} + +/** + * After all tests finish this will repeatedly attempt to restore the real + * updater if it exists and then call finishTest after the restore is + * successful. + */ +function cleanupRestoreUpdaterBackup() { + debugDump("entering"); + + try { + // Windows debug builds keep the updater file in use for a short period of + // time after the updater process exits. + restoreUpdaterBackup(); + } catch (e) { + logTestInfo("Attempt to restore the backed up updater failed... " + + "will try again, Exception: " + e); + SimpleTest.executeSoon(cleanupRestoreUpdaterBackup); + return; + } + + SimpleTest.executeSoon(finishTest); } function finishTest() { diff --git a/toolkit/mozapps/update/tests/chrome/utils.js b/toolkit/mozapps/update/tests/chrome/utils.js index ca3fa544da..7178ad128f 100644 --- a/toolkit/mozapps/update/tests/chrome/utils.js +++ b/toolkit/mozapps/update/tests/chrome/utils.js @@ -129,6 +129,7 @@ Cu.import("resource://gre/modules/AddonManager.jsm", this); Cu.import("resource://gre/modules/Services.jsm", this); const IS_MACOSX = ("nsILocalFileMac" in Ci); +const IS_WIN = ("@mozilla.org/windows-registry-key;1" in Cc); // The tests have to use the pageid instead of the pageIndex due to the // app update wizard's access method being random. @@ -182,6 +183,10 @@ const TEST_ADDONS = [ "appdisabled_1", "appdisabled_2", const LOG_FUNCTION = info; +const BIN_SUFFIX = (IS_WIN ? ".exe" : ""); +const FILE_UPDATER_BIN = "updater" + (IS_MACOSX ? ".app" : BIN_SUFFIX); +const FILE_UPDATER_BIN_BAK = FILE_UPDATER_BIN + ".bak"; + var gURLData = URL_HOST + "/" + REL_PATH_DATA + "/"; var gTestTimeout = 240000; // 4 minutes @@ -210,6 +215,7 @@ var gPrefToCheck; var gDisableNoUpdateAddon = false; var gDisableUpdateCompatibilityAddon = false; var gDisableUpdateVersionAddon = false; +var gUseTestUpdater = false; // Set to true to log additional information for debugging. To log additional // information for an individual test set DEBUG_AUS_TEST to true in the test's @@ -324,9 +330,10 @@ function runTestDefaultWaitForWindowClosed() { setupFiles(); setupPrefs(); + gEnv.set("MOZ_TEST_SKIP_UPDATE_STAGE", "1"); removeUpdateDirsAndFiles(); reloadUpdateManagerData(); - setupAddons(runTest); + setupAddons(setupTestUpdater); } } @@ -352,6 +359,7 @@ function finishTestDefault() { verifyTestsRan(); resetPrefs(); + gEnv.set("MOZ_TEST_SKIP_UPDATE_STAGE", ""); resetFiles(); removeUpdateDirsAndFiles(); reloadUpdateManagerData(); @@ -361,7 +369,7 @@ function finishTestDefault() { gDocElem.removeEventListener("pageshow", onPageShowDefault, false); } - finishTestDefaultWaitForWindowClosed(); + finishTestRestoreUpdaterBackup(); } /** @@ -384,6 +392,28 @@ function finishTestTimeout(aTimer) { } } +/** + * When a test finishes this will repeatedly attempt to restore the real updater + * for tests that use the test updater and then call + * finishTestDefaultWaitForWindowClosed after the restore is successful. + */ +function finishTestRestoreUpdaterBackup() { + if (gUseTestUpdater) { + try { + // Windows debug builds keep the updater file in use for a short period of + // time after the updater process exits. + restoreUpdaterBackup(); + } catch (e) { + logTestInfo("Attempt to restore the backed up updater failed... " + + "will try again, Exception: " + e); + SimpleTest.executeSoon(finishTestRestoreUpdaterBackup); + return; + } + } + + finishTestDefaultWaitForWindowClosed(); +} + /** * If an update window is found SimpleTest.executeSoon can callback before the * update window is fully closed especially with debug builds. If an update @@ -394,6 +424,7 @@ function finishTestTimeout(aTimer) { function finishTestDefaultWaitForWindowClosed() { gCloseWindowTimeoutCounter++; if (gCloseWindowTimeoutCounter > CLOSE_WINDOW_TIMEOUT_MAXCOUNT) { + SimpleTest.requestCompleteLog(); SimpleTest.finish(); return; } @@ -746,7 +777,7 @@ function checkIncompatbleList() { for (let i = 0; i < gIncompatibleListbox.itemCount; i++) { let label = gIncompatibleListbox.getItemAtIndex(i).label; // Use indexOf since locales can change the text displayed - ok(label.indexOf("noupdate") != -1, "Checking that only incompatible " + + ok(label.indexOf("noupdate") != -1, "Checking that only incompatible " + "add-ons that don't have an update are listed in the incompatible list"); } } @@ -886,6 +917,102 @@ function setupFiles() { writeFile(updateSettingsIni, UPDATE_SETTINGS_CONTENTS); } +/** + * For tests that use the test updater restores the backed up real updater if + * it exists and tries again on failure since Windows debug builds at times + * leave the file in use. After success moveRealUpdater is called to continue + * the setup of the test updater. For tests that don't use the test updater + * runTest will be called. + */ +function setupTestUpdater() { + if (!gUseTestUpdater) { + runTest(); + return; + } + + try { + restoreUpdaterBackup(); + } catch (e) { + logTestInfo("Attempt to restore the backed up updater failed... " + + "will try again, Exception: " + e); + SimpleTest.executeSoon(setupTestUpdater); + return; + } + moveRealUpdater(); +} + +/** + * Backs up the real updater and tries again on failure since Windows debug + * builds at times leave the file in use. After success it will call + * copyTestUpdater to continue the setup of the test updater. + */ +function moveRealUpdater() { + try { + // Move away the real updater + let baseAppDir = getAppBaseDir(); + let updater = baseAppDir.clone(); + updater.append(FILE_UPDATER_BIN); + updater.moveTo(baseAppDir, FILE_UPDATER_BIN_BAK); + } catch (e) { + logTestInfo("Attempt to move the real updater out of the way failed... " + + "will try again, Exception: " + e); + SimpleTest.executeSoon(moveRealUpdater); + return; + } + + copyTestUpdater(); +} + +/** + * Copies the test updater so it can be used by tests and tries again on failure + * since Windows debug builds at times leave the file in use. After success it + * will call runTest to continue the test. + */ +function copyTestUpdater() { + try { + // Copy the test updater + let baseAppDir = getAppBaseDir(); + let testUpdaterDir = Services.dirsvc.get("CurWorkD", Ci.nsILocalFile); + let relPath = REL_PATH_DATA; + let pathParts = relPath.split("/"); + for (let i = 0; i < pathParts.length; ++i) { + testUpdaterDir.append(pathParts[i]); + } + + let testUpdater = testUpdaterDir.clone(); + testUpdater.append(FILE_UPDATER_BIN); + testUpdater.copyToFollowingLinks(baseAppDir, FILE_UPDATER_BIN); + } catch (e) { + logTestInfo("Attempt to copy the test updater failed... " + + "will try again, Exception: " + e); + SimpleTest.executeSoon(copyTestUpdater); + return; + } + + runTest(); +} + +/** + * Restores the updater that was backed up. This is called in setupTestUpdater + * before the backup of the real updater is done in case the previous test + * failed to restore the updater, in finishTestDefaultWaitForWindowClosed when + * the test has finished, and in test_9999_cleanup.xul after all tests have + * finished. + */ +function restoreUpdaterBackup() { + let baseAppDir = getAppBaseDir(); + let updater = baseAppDir.clone(); + let updaterBackup = baseAppDir.clone(); + updater.append(FILE_UPDATER_BIN); + updaterBackup.append(FILE_UPDATER_BIN_BAK); + if (updaterBackup.exists()) { + if (updater.exists()) { + updater.remove(true); + } + updaterBackup.moveTo(baseAppDir, FILE_UPDATER_BIN); + } +} + /** * Sets the most common preferences used by tests to values used by the majority * of the tests and when necessary saves the preference's original values if diff --git a/toolkit/mozapps/update/tests/data/shared.js b/toolkit/mozapps/update/tests/data/shared.js index d9ff348135..c3d8a64e95 100644 --- a/toolkit/mozapps/update/tests/data/shared.js +++ b/toolkit/mozapps/update/tests/data/shared.js @@ -131,6 +131,10 @@ XPCOMUtils.defineLazyGetter(this, "gPrefRoot", function test_gPR() { return Services.prefs.getBranch(null); }); +XPCOMUtils.defineLazyServiceGetter(this, "gEnv", + "@mozilla.org/process/environment;1", + "nsIEnvironment"); + XPCOMUtils.defineLazyGetter(this, "gZipW", function test_gZipW() { return Cc["@mozilla.org/zipwriter;1"]. createInstance(Ci.nsIZipWriter); diff --git a/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js b/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js index e710087b18..b95261f91e 100644 --- a/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js +++ b/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js @@ -1181,12 +1181,15 @@ function getTestDirPath() { * The relative path to the file or directory to get from the root of * the test's data directory. If not specified the test's data * directory will be returned. + * @param aAllowNonExists (optional) + * Whether or not to throw an error if the path exists. + * If not specified, then false is used. * @return The nsIFile for the file in the test data directory. * @throws If the file or directory does not exist. */ -function getTestDirFile(aRelPath) { +function getTestDirFile(aRelPath, aAllowNonExists) { let relpath = getTestDirPath() + (aRelPath ? aRelPath : ""); - return do_get_file(relpath, false); + return do_get_file(relpath, !!aAllowNonExists); } /** @@ -1484,8 +1487,7 @@ function runUpdate(aExpectedExitValue, aExpectedStatus, aCallback) { let updater = binDir.clone(); updater.append("updater.app"); if (!updater.exists()) { - updater = binDir.clone(); - updater.append(FILE_UPDATER_BIN); + updater = getTestDirFile(FILE_UPDATER_BIN); if (!updater.exists()) { do_throw("Unable to find updater binary!"); } @@ -1759,8 +1761,6 @@ function setupAppFiles() { // dependentlibs.list file. let appFiles = [ { relPath : FILE_APP_BIN, inGreDir : false }, - { relPath : FILE_UPDATER_BIN, - inGreDir : false }, { relPath : FILE_APPLICATION_INI, inGreDir : true }, { relPath : "dependentlibs.list", @@ -1795,8 +1795,19 @@ function setupAppFiles() { copyFileToTestAppDir(aAppFile.relPath, aAppFile.inGreDir); }); - logTestInfo("finish - copying or creating symlinks to application files " + - "for the test"); + // Copy the xpcshell updater binary + let updater = getTestDirFile("updater.app", true); + if (!updater.exists()) { + updater = getTestDirFile(FILE_UPDATER_BIN); + if (!updater.exists()) { + do_throw("Unable to find the updater binary!"); + } + } + let testBinDir = getGREBinDir(); + updater.copyToFollowingLinks(testBinDir, updater.leafName); + + debugDump("finish - copying or creating symlinks to application files " + + "for the test"); } /** @@ -2094,10 +2105,13 @@ function runUpdateUsingService(aInitialStatus, aExpectedStatus, aCheckSvcLog) { setEnvironment(); - // There is a security check done by the service to make sure the updater - // we are executing is the same as the one in the apply-to dir. - // To make sure they match from tests we copy updater.exe to the apply-to dir. - copyFileToTestAppDir(FILE_UPDATER_BIN, false); + let updater = getTestDirFile(FILE_UPDATER_BIN); + if (!updater.exists()) { + do_throw("Unable to find updater binary!"); + } + let testBinDir = getGREBinDir() + updater.copyToFollowingLinks(testBinDir, updater.leafName); + updater.copyToFollowingLinks(updatesDir, updater.leafName); // The service will execute maintenanceservice_installer.exe and // will copy maintenanceservice.exe out of the same directory from diff --git a/toolkit/mozapps/update/tests/unit_base_updater/xpcshell.ini b/toolkit/mozapps/update/tests/unit_base_updater/xpcshell.ini index 45812133ad..3e44621f08 100644 --- a/toolkit/mozapps/update/tests/unit_base_updater/xpcshell.ini +++ b/toolkit/mozapps/update/tests/unit_base_updater/xpcshell.ini @@ -18,9 +18,9 @@ skip-if = toolkit == 'gonk' reason = bug 820380 [marStageSuccessPartial.js] [marVersionDowngrade.js] -run-if = os == 'win' +skip-if = os != 'win' && os != 'mac' && os != 'linux' [marWrongChannel.js] -run-if = os == 'win' +skip-if = os != 'win' && os != 'mac' && os != 'linux' [marStageFailurePartial.js] [marCallbackAppSuccessComplete_win.js] run-if = os == 'win' diff --git a/toolkit/mozapps/update/tests/unit_service_updater/bootstrapSvc.js b/toolkit/mozapps/update/tests/unit_service_updater/bootstrapSvc.js new file mode 100644 index 0000000000..ffa207ebbe --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/bootstrapSvc.js @@ -0,0 +1,33 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* Bootstrap the tests using the service by installing our own version of the service */ + +function run_test() { + if (!shouldRunServiceTest(true)) { + return; + } + + setupTestCommon(); + // We don't actually care if the MAR has any data, we only care about the + // application return code and update.status result. + gTestFiles = gTestFilesCommon; + gTestDirs = []; + setupUpdaterTest(FILE_COMPLETE_MAR); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_SUCCEEDED, false); +} + +function checkUpdateFinished() { + checkFilesAfterUpdateSuccess(getApplyDirFile, false, false); + + // We need to check the service log even though this is a bootstrap + // because the app bin could be in use by this test by the time the next + // test runs. + checkCallbackServiceLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/checkUpdaterSigSvc.js b/toolkit/mozapps/update/tests/unit_service_updater/checkUpdaterSigSvc.js new file mode 100644 index 0000000000..99f0a5da9e --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/checkUpdaterSigSvc.js @@ -0,0 +1,41 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/** + * We skip authenticode cert checks from the service udpates + * so that we can use updater-xpcshell with the wrong certs for testing. + * This tests that code path. */ + +function run_test() { + if (!IS_AUTHENTICODE_CHECK_ENABLED) { + return; + } + + let binDir = getGREBinDir(); + let maintenanceServiceBin = binDir.clone(); + maintenanceServiceBin.append(FILE_MAINTENANCE_SERVICE_BIN); + + let updaterBin = binDir.clone(); + updaterBin.append(FILE_UPDATER_BIN); + + debugDump("Launching maintenance service bin: " + + maintenanceServiceBin.path + " to check updater: " + + updaterBin.path + " signature."); + + // Bypass the manifest and run as invoker + let env = Cc["@mozilla.org/process/environment;1"]. + getService(Ci.nsIEnvironment); + env.set("__COMPAT_LAYER", "RunAsInvoker"); + + let dummyInstallPath = "---"; + let maintenanceServiceBinArgs = ["check-cert", dummyInstallPath, + updaterBin.path]; + let maintenanceServiceBinProcess = Cc["@mozilla.org/process/util;1"]. + createInstance(Ci.nsIProcess); + maintenanceServiceBinProcess.init(maintenanceServiceBin); + maintenanceServiceBinProcess.run(true, maintenanceServiceBinArgs, + maintenanceServiceBinArgs.length); + Assert.equal(maintenanceServiceBinProcess.exitValue, 0, + "the maintenance service exit value should be 0"); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyDirLockedStageFailureSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyDirLockedStageFailureSvc_win.js new file mode 100644 index 0000000000..7aeb47cdca --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyDirLockedStageFailureSvc_win.js @@ -0,0 +1,89 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/** + * Test applying an update by staging an update and launching an application to + * apply it. + */ + +const START_STATE = STATE_PENDING_SVC; +const END_STATE = STATE_PENDING; + +function run_test() { + if (MOZ_APP_NAME == "xulrunner") { + logTestInfo("Unable to run this test on xulrunner"); + return; + } + + if (!shouldRunServiceTest()) { + return; + } + + setupTestCommon(); + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + setupUpdaterTest(FILE_COMPLETE_MAR); + + createUpdaterINI(false); + + if (IS_WIN) { + Services.prefs.setBoolPref(PREF_APP_UPDATE_SERVICE_ENABLED, true); + } + + let channel = Services.prefs.getCharPref(PREF_APP_UPDATE_CHANNEL); + let patches = getLocalPatchString(null, null, null, null, null, "true", + START_STATE); + let updates = getLocalUpdateString(patches, null, null, null, null, null, + null, null, null, null, null, null, + null, "true", channel); + writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true); + writeVersionFile(getAppVersion()); + writeStatusFile(START_STATE); + + reloadUpdateManagerData(); + Assert.ok(!!gUpdateManager.activeUpdate, + "the active update should be defined"); + + lockDirectory(getAppBaseDir()); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + stageUpdate(); +} + +function end_test() { + resetEnvironment(); +} + +/** + * Checks if staging the update has failed. + */ +function checkUpdateApplied() { + // Don't proceed until the update has failed, and reset to pending. + if (gUpdateManager.activeUpdate.state != END_STATE) { + if (++gTimeoutRuns > MAX_TIMEOUT_RUNS) { + do_throw("Exceeded MAX_TIMEOUT_RUNS while waiting for the " + + "active update status state to equal: " + + END_STATE + + ", current state: " + gUpdateManager.activeUpdate.state); + } + do_timeout(TEST_CHECK_TIMEOUT, checkUpdateApplied); + return; + } + + do_timeout(TEST_CHECK_TIMEOUT, finishTest); +} + +function finishTest() { + checkPostUpdateRunningFile(false); + Assert.equal(readStatusState(), END_STATE, + "the status state" + MSG_SHOULD_EQUAL); + checkFilesAfterUpdateFailure(getApplyDirFile, false, false); + unlockDirectory(getAppBaseDir()); + standardInit(); + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateAppBinInUseStageSuccessSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateAppBinInUseStageSuccessSvc_win.js new file mode 100644 index 0000000000..96d566dffc --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateAppBinInUseStageSuccessSvc_win.js @@ -0,0 +1,254 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/** + * Test applying an update by staging an update and launching an application to + * apply it. + */ + +const START_STATE = STATE_PENDING_SVC; +const END_STATE = STATE_APPLIED_SVC; + +function run_test() { + if (MOZ_APP_NAME == "xulrunner") { + logTestInfo("Unable to run this test on xulrunner"); + return; + } + + if (!shouldRunServiceTest()) { + return; + } + + setupTestCommon(); + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setupUpdaterTest(FILE_COMPLETE_MAR); + + createUpdaterINI(true); + + if (IS_WIN) { + Services.prefs.setBoolPref(PREF_APP_UPDATE_SERVICE_ENABLED, true); + } + + let channel = Services.prefs.getCharPref(PREF_APP_UPDATE_CHANNEL); + let patches = getLocalPatchString(null, null, null, null, null, "true", + START_STATE); + let updates = getLocalUpdateString(patches, null, null, null, null, null, + null, null, null, null, null, null, + null, "true", channel); + writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true); + writeVersionFile(getAppVersion()); + writeStatusFile(START_STATE); + + reloadUpdateManagerData(); + Assert.ok(!!gUpdateManager.activeUpdate, + "the active update should be defined"); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + setAppBundleModTime(); + stageUpdate(); +} + +function customLaunchAppToApplyUpdate() { + debugDump("start - locking installation directory"); + const LPCWSTR = ctypes.char16_t.ptr; + const DWORD = ctypes.uint32_t; + const LPVOID = ctypes.voidptr_t; + const GENERIC_READ = 0x80000000; + const FILE_SHARE_READ = 1; + const FILE_SHARE_WRITE = 2; + const OPEN_EXISTING = 3; + const FILE_FLAG_BACKUP_SEMANTICS = 0x02000000; + const INVALID_HANDLE_VALUE = LPVOID(0xffffffff); + let kernel32 = ctypes.open("kernel32"); + let CreateFile = kernel32.declare("CreateFileW", ctypes.default_abi, + LPVOID, LPCWSTR, DWORD, DWORD, + LPVOID, DWORD, DWORD, LPVOID); + gHandle = CreateFile(getAppBaseDir().path, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, LPVOID(0), + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, LPVOID(0)); + Assert.notEqual(gHandle.toString(), INVALID_HANDLE_VALUE.toString(), + "the handle should not equal INVALID_HANDLE_VALUE"); + kernel32.close(); + debugDump("finish - locking installation directory"); +} + +/** + * Checks if the update has finished being staged. + */ +function checkUpdateApplied() { + gTimeoutRuns++; + // Don't proceed until the active update's state is the expected value. + if (gUpdateManager.activeUpdate.state != END_STATE) { + if (gTimeoutRuns > MAX_TIMEOUT_RUNS) { + do_throw("Exceeded MAX_TIMEOUT_RUNS while waiting for the " + + "active update status state to equal: " + + END_STATE + + ", current state: " + gUpdateManager.activeUpdate.state); + } + do_timeout(TEST_CHECK_TIMEOUT, checkUpdateApplied); + return; + } + + // Don't proceed until the update's status state is the expected value. + let state = readStatusState(); + if (state != END_STATE) { + if (gTimeoutRuns > MAX_TIMEOUT_RUNS) { + do_throw("Exceeded MAX_TIMEOUT_RUNS while waiting for the update" + + "status file state to equal: " + + END_STATE + + ", current status state: " + state); + } + do_timeout(TEST_CHECK_TIMEOUT, checkUpdateApplied); + return; + } + + // Don't proceed until the last update log has been created. + let log; + if (IS_WIN || IS_MACOSX) { + log = getUpdatesDir(); + } else { + log = getStageDirFile(null, true); + log.append(DIR_UPDATES); + } + log.append(FILE_LAST_LOG); + if (!log.exists()) { + if (gTimeoutRuns > MAX_TIMEOUT_RUNS) { + do_throw("Exceeded MAX_TIMEOUT_RUNS while waiting for the update log " + + "to be created. Path: " + log.path); + } + do_timeout(TEST_CHECK_TIMEOUT, checkUpdateApplied); + return; + } + + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateSuccess(getStageDirFile, true, false); + + log = getUpdatesPatchDir(); + log.append(FILE_UPDATE_LOG); + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST); + + log = getUpdatesDir(); + log.append(FILE_LAST_LOG); + if (IS_WIN || IS_MACOSX) { + Assert.ok(log.exists(), MSG_SHOULD_EXIST); + } else { + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST); + } + + log = getUpdatesDir(); + log.append(FILE_BACKUP_LOG); + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST); + + let updatesDir = getStageDirFile(DIR_UPDATES + "/" + DIR_PATCH, true); + Assert.ok(!updatesDir.exists(), MSG_SHOULD_NOT_EXIST); + + log = getStageDirFile(DIR_UPDATES + "/" + FILE_LAST_LOG, true); + if (IS_WIN || IS_MACOSX) { + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST); + } else { + Assert.ok(log.exists(), MSG_SHOULD_EXIST); + } + + log = getStageDirFile(DIR_UPDATES + "/" + FILE_BACKUP_LOG, true); + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST); + + // Switch the application to the staged application that was updated by + // launching the application. + do_timeout(TEST_CHECK_TIMEOUT, launchAppToApplyUpdate); +} + +/** + * Checks if the post update binary was properly launched for the platforms that + * support launching post update process. + */ +function checkUpdateFinished() { + if (IS_WIN || IS_MACOSX) { + gCheckFunc = finishCheckUpdateFinished; + checkPostUpdateAppLog(); + } else { + finishCheckUpdateFinished(); + } +} + +/** + * Checks if the update has finished and if it has finished performs checks for + * the test. + */ +function finishCheckUpdateFinished() { + gTimeoutRuns++; + // Don't proceed until the update's status state is the expected value. + let state = readStatusState(); + if (state != STATE_SUCCEEDED) { + if (gTimeoutRuns > MAX_TIMEOUT_RUNS) { + do_throw("Exceeded MAX_TIMEOUT_RUNS while waiting for the " + + "update status file state to equal: " + + STATE_SUCCEEDED + + ", current status state: " + state); + } + do_timeout(TEST_CHECK_TIMEOUT, checkUpdateFinished); + return; + } + + // Don't proceed until the application was switched out with the staged update + // successfully. + let updatedDir = getStageDirFile(null, true); + if (updatedDir.exists()) { + if (gTimeoutRuns > MAX_TIMEOUT_RUNS) { + do_throw("Exceeded MAX_TIMEOUT_RUNS while waiting for the updated " + + "directory to not exist. Path: " + updatedDir.path); + } + do_timeout(TEST_CHECK_TIMEOUT, checkUpdateFinished); + return; + } + + if (IS_WIN) { + // Don't proceed until the updater binary is no longer in use. + let updater = getUpdatesPatchDir(); + updater.append(FILE_UPDATER_BIN); + if (updater.exists()) { + if (gTimeoutRuns > MAX_TIMEOUT_RUNS) { + do_throw("Exceeded MAX_TIMEOUT_RUNS while waiting for the " + + "updater binary to no longer be in use"); + } + try { + updater.remove(false); + } catch (e) { + do_timeout(TEST_CHECK_TIMEOUT, checkUpdateFinished); + return; + } + } + } + + checkPostUpdateRunningFile(true); + checkAppBundleModTime(); + checkFilesAfterUpdateSuccess(getApplyDirFile, false, false); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS); + + standardInit(); + + let update = gUpdateManager.getUpdateAt(0); + Assert.equal(update.state, STATE_SUCCEEDED, + "the update state" + MSG_SHOULD_EQUAL); + + let updatesDir = getUpdatesPatchDir(); + Assert.ok(updatesDir.exists(), MSG_SHOULD_EXIST); + + let log = getUpdatesPatchDir(); + log.append(FILE_UPDATE_LOG); + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST); + + log = getUpdatesDir(); + log.append(FILE_LAST_LOG); + Assert.ok(log.exists(), MSG_SHOULD_EXIST); + + log = getUpdatesDir(); + log.append(FILE_BACKUP_LOG); + Assert.ok(log.exists(), MSG_SHOULD_EXIST); + + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateStageSuccessSvc.js b/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateStageSuccessSvc.js new file mode 100644 index 0000000000..b6a0f9f258 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateStageSuccessSvc.js @@ -0,0 +1,236 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/** + * Test applying an update by staging an update and launching an application to + * apply it. + */ + +const START_STATE = STATE_PENDING_SVC; +const END_STATE = STATE_APPLIED_SVC; + +function run_test() { + if (MOZ_APP_NAME == "xulrunner") { + logTestInfo("Unable to run this test on xulrunner"); + return; + } + + if (!shouldRunServiceTest()) { + return; + } + + setupTestCommon(); + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setupUpdaterTest(FILE_COMPLETE_MAR); + + createUpdaterINI(false); + + if (IS_WIN) { + Services.prefs.setBoolPref(PREF_APP_UPDATE_SERVICE_ENABLED, true); + } + + let channel = Services.prefs.getCharPref(PREF_APP_UPDATE_CHANNEL); + let patches = getLocalPatchString(null, null, null, null, null, "true", + START_STATE); + let updates = getLocalUpdateString(patches, null, null, null, null, null, + null, null, null, null, null, null, + null, "true", channel); + writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true); + writeVersionFile(getAppVersion()); + writeStatusFile(START_STATE); + + reloadUpdateManagerData(); + Assert.ok(!!gUpdateManager.activeUpdate, + "the active update should be defined"); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + setAppBundleModTime(); + stageUpdate(); +} + +/** + * Checks if the update has finished being staged. + */ +function checkUpdateApplied() { + gTimeoutRuns++; + // Don't proceed until the active update's state is the expected value. + if (gUpdateManager.activeUpdate.state != END_STATE) { + if (gTimeoutRuns > MAX_TIMEOUT_RUNS) { + do_throw("Exceeded MAX_TIMEOUT_RUNS while waiting for the " + + "active update status state to equal: " + + END_STATE + + ", current state: " + gUpdateManager.activeUpdate.state); + } + do_timeout(TEST_CHECK_TIMEOUT, checkUpdateApplied); + return; + } + + // Don't proceed until the update's status state is the expected value. + let state = readStatusState(); + if (state != END_STATE) { + if (gTimeoutRuns > MAX_TIMEOUT_RUNS) { + do_throw("Exceeded MAX_TIMEOUT_RUNS while waiting for the update " + + "status state to equal: " + + END_STATE + + ", current status state: " + state); + } + do_timeout(TEST_CHECK_TIMEOUT, checkUpdateApplied); + return; + } + + // Don't proceed until the last update log has been created. + let log; + if (IS_WIN || IS_MACOSX) { + log = getUpdatesDir(); + } else { + log = getStageDirFile(null, true); + log.append(DIR_UPDATES); + } + log.append(FILE_LAST_LOG); + if (!log.exists()) { + if (gTimeoutRuns > MAX_TIMEOUT_RUNS) { + do_throw("Exceeded MAX_TIMEOUT_RUNS while waiting for the update log " + + "to be created. Path: " + log.path); + } + do_timeout(TEST_CHECK_TIMEOUT, checkUpdateApplied); + return; + } + + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateSuccess(getStageDirFile, true, false); + + log = getUpdatesPatchDir(); + log.append(FILE_UPDATE_LOG); + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST); + + log = getUpdatesDir(); + log.append(FILE_LAST_LOG); + if (IS_WIN || IS_MACOSX) { + Assert.ok(log.exists(), MSG_SHOULD_EXIST); + } else { + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST); + } + + log = getUpdatesDir(); + log.append(FILE_BACKUP_LOG); + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST); + + let updatesDir = getStageDirFile(DIR_UPDATES + "/" + DIR_PATCH, true); + Assert.ok(!updatesDir.exists(), MSG_SHOULD_NOT_EXIST); + + log = getStageDirFile(DIR_UPDATES + "/" + FILE_LAST_LOG, true); + if (IS_WIN || IS_MACOSX) { + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST); + } else { + Assert.ok(log.exists(), MSG_SHOULD_EXIST); + } + + log = getStageDirFile(DIR_UPDATES + "/" + FILE_BACKUP_LOG, true); + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST); + + // Switch the application to the staged application that was updated by + // launching the application. + do_timeout(TEST_CHECK_TIMEOUT, launchAppToApplyUpdate); +} + +/** + * Checks if the post update binary was properly launched for the platforms that + * support launching post update process. + */ +function checkUpdateFinished() { + if (IS_WIN || IS_MACOSX) { + gCheckFunc = finishCheckUpdateApplied; + checkPostUpdateAppLog(); + } else { + finishCheckUpdateApplied(); + } +} + +/** + * Checks if the update has finished and if it has finished performs checks for + * the test. + */ +function finishCheckUpdateApplied() { + gTimeoutRuns++; + // Don't proceed until the update's status state is the expected value. + let state = readStatusState(); + if (state != STATE_SUCCEEDED) { + if (gTimeoutRuns > MAX_TIMEOUT_RUNS) { + do_throw("Exceeded MAX_TIMEOUT_RUNS while waiting for the " + + "update status file state to equal: " + + STATE_SUCCEEDED + + ", current status state: " + state); + } + do_timeout(TEST_CHECK_TIMEOUT, checkUpdateFinished); + return; + } + + // Don't proceed until the application was switched out with the staged update + // successfully. + let updatedDir = getStageDirFile(null, true); + if (updatedDir.exists()) { + if (gTimeoutRuns > MAX_TIMEOUT_RUNS) { + do_throw("Exceeded MAX_TIMEOUT_RUNS while waiting for the updated " + + "directory to not exist. Path: " + updatedDir.path); + } + do_timeout(TEST_CHECK_TIMEOUT, checkUpdateFinished); + return; + } + + if (IS_WIN) { + // Don't proceed until the updater binary is no longer in use. + let updater = getUpdatesPatchDir(); + updater.append(FILE_UPDATER_BIN); + if (updater.exists()) { + if (gTimeoutRuns > MAX_TIMEOUT_RUNS) { + do_throw("Exceeded MAX_TIMEOUT_RUNS while waiting for the " + + "updater binary to no longer be in use"); + } + try { + updater.remove(false); + } catch (e) { + do_timeout(TEST_CHECK_TIMEOUT, checkUpdateFinished); + return; + } + } + } + + checkPostUpdateRunningFile(true); + checkAppBundleModTime(); + checkFilesAfterUpdateSuccess(getApplyDirFile, false, true); + gSwitchApp = true; + checkUpdateLogContents(); + gSwitchApp = false; + + standardInit(); + + let update = gUpdateManager.getUpdateAt(0); + Assert.equal(update.state, STATE_SUCCEEDED, + "the update state" + MSG_SHOULD_EQUAL); + + let updatesDir = getUpdatesPatchDir(); + Assert.ok(updatesDir.exists(), MSG_SHOULD_EXIST); + + let log = getUpdatesPatchDir(); + log.append(FILE_UPDATE_LOG); + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST); + + log = getUpdatesDir(); + log.append(FILE_LAST_LOG); + Assert.ok(log.exists(), MSG_SHOULD_EXIST); + + log = getUpdatesDir(); + log.append(FILE_BACKUP_LOG); + if (IS_WIN || IS_MACOSX) { + Assert.ok(log.exists(), MSG_SHOULD_EXIST); + } else { + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST); + } + + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateSuccessSvc.js b/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateSuccessSvc.js new file mode 100644 index 0000000000..6ed5adaf67 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateSuccessSvc.js @@ -0,0 +1,136 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/** + * Test applying an update by staging an update and launching an application to + * apply it. + */ + +const START_STATE = STATE_PENDING_SVC; +const END_STATE = STATE_SUCCEEDED; + +function run_test() { + if (MOZ_APP_NAME == "xulrunner") { + logTestInfo("Unable to run this test on xulrunner"); + return; + } + + if (!shouldRunServiceTest()) { + return; + } + + setupTestCommon(); + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setupUpdaterTest(FILE_COMPLETE_MAR); + + createUpdaterINI(); + setAppBundleModTime(); + + let channel = Services.prefs.getCharPref(PREF_APP_UPDATE_CHANNEL); + let patches = getLocalPatchString(null, null, null, null, null, "true", + START_STATE); + let updates = getLocalUpdateString(patches, null, null, null, null, null, + null, null, null, null, null, null, + null, "true", channel); + writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true); + writeVersionFile(getAppVersion()); + writeStatusFile(START_STATE); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + runUpdateUsingService(START_STATE, END_STATE); +} + +/** + * Checks if the post update binary was properly launched for the platforms that + * support launching post update process. + */ +function checkUpdateFinished() { + if (IS_WIN || IS_MACOSX) { + gCheckFunc = finishCheckUpdateFinished; + checkPostUpdateAppLog(); + } else { + finishCheckUpdateFinished(); + } +} + +/** + * Checks if the update has finished and if it has finished performs checks for + * the test. + */ +function finishCheckUpdateFinished() { + gTimeoutRuns++; + // Don't proceed until the update's status state is the expected value. + let state = readStatusState(); + if (state != END_STATE) { + if (gTimeoutRuns > MAX_TIMEOUT_RUNS) { + do_throw("Exceeded MAX_TIMEOUT_RUNS while waiting for the update " + + "status state to equal: " + END_STATE + + ", current status state: " + state); + } else { + do_timeout(TEST_CHECK_TIMEOUT, checkUpdateFinished); + } + return; + } + + // Don't proceed until the update log has been created. + let log = getUpdatesPatchDir(); + log.append(FILE_UPDATE_LOG); + if (!log.exists()) { + if (gTimeoutRuns > MAX_TIMEOUT_RUNS) { + do_throw("Exceeded MAX_TIMEOUT_RUNS while waiting for the update log " + + "to be created. Path: " + log.path); + } + do_timeout(TEST_CHECK_TIMEOUT, checkUpdateFinished); + return; + } + + if (IS_WIN) { + // Don't proceed until the updater binary is no longer in use. + let updater = getUpdatesPatchDir(); + updater.append(FILE_UPDATER_BIN); + if (updater.exists()) { + if (gTimeoutRuns > MAX_TIMEOUT_RUNS) { + do_throw("Exceeded while waiting for updater binary to no longer be " + + "in use"); + } + try { + updater.remove(false); + } catch (e) { + do_timeout(TEST_CHECK_TIMEOUT, checkUpdateFinished); + return; + } + } + } + + checkAppBundleModTime(); + checkFilesAfterUpdateSuccess(getApplyDirFile, false, false); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS); + + standardInit(); + + let update = gUpdateManager.getUpdateAt(0); + Assert.equal(update.state, END_STATE, + "the update state" + MSG_SHOULD_EQUAL); + + let updatesDir = getUpdatesPatchDir(); + Assert.ok(updatesDir.exists(), MSG_SHOULD_EXIST); + + log = getUpdatesPatchDir(); + log.append(FILE_UPDATE_LOG); + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST); + + log = getUpdatesDir(); + log.append(FILE_LAST_LOG); + Assert.ok(log.exists(), MSG_SHOULD_EXIST); + + log = getUpdatesDir(); + log.append(FILE_BACKUP_LOG); + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST); + + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marAppInUseStageFailureCompleteSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marAppInUseStageFailureCompleteSvc_win.js new file mode 100644 index 0000000000..0a5e86187c --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppInUseStageFailureCompleteSvc_win.js @@ -0,0 +1,59 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* Application in use complete MAR file staged patch apply failure test */ + +const START_STATE = STATE_PENDING_SVC; +const END_STATE = STATE_PENDING; + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + gStageUpdate = true; + setupTestCommon(); + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + setupUpdaterTest(FILE_COMPLETE_MAR); + + // Launch the callback helper application so it is in use during the update. + let callbackApp = getApplyDirFile(DIR_RESOURCES + gCallbackBinFile); + let args = [getApplyDirPath() + DIR_RESOURCES, "input", "output", "-s", + HELPER_SLEEP_TIMEOUT]; + let callbackAppProcess = Cc["@mozilla.org/process/util;1"]. + createInstance(Ci.nsIProcess); + callbackAppProcess.init(callbackApp); + callbackAppProcess.run(false, args, args.length); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep); +} + +function doUpdate() { + runUpdateUsingService(START_STATE, STATE_APPLIED); +} + +function checkUpdateFinished() { + // Switch the application to the staged application that was updated. + gStageUpdate = false; + gSwitchApp = true; + runUpdate(1, END_STATE, checkUpdateApplied); +} + +function checkUpdateApplied() { + setupHelperFinish(); +} + +function checkUpdate() { + checkFilesAfterUpdateFailure(getApplyDirFile, false, false); + checkUpdateLogContains(ERR_RENAME_FILE); + checkUpdateLogContains(ERR_MOVE_DESTDIR_7); + standardInit(); + checkCallbackAppLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marAppInUseSuccessCompleteSvc.js b/toolkit/mozapps/update/tests/unit_service_updater/marAppInUseSuccessCompleteSvc.js new file mode 100644 index 0000000000..bb82d3f1f2 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppInUseSuccessCompleteSvc.js @@ -0,0 +1,49 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* Application in use complete MAR file patch apply success test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + setupTestCommon(); + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setupUpdaterTest(FILE_COMPLETE_MAR); + + // Launch the callback helper application so it is in use during the update. + let callbackApp = getApplyDirFile(DIR_RESOURCES + gCallbackBinFile); + callbackApp.permissions = PERMS_DIRECTORY; + let args = [getApplyDirPath() + DIR_RESOURCES, "input", "output", "-s", + HELPER_SLEEP_TIMEOUT]; + let callbackAppProcess = Cc["@mozilla.org/process/util;1"]. + createInstance(Ci.nsIProcess); + callbackAppProcess.init(callbackApp); + callbackAppProcess.run(false, args, args.length); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep); +} + +function doUpdate() { + setAppBundleModTime(); + runUpdateUsingService(STATE_PENDING_SVC, STATE_SUCCEEDED); +} + +function checkUpdateFinished() { + setupHelperFinish(); +} + +function checkUpdate() { + checkAppBundleModTime(); + checkFilesAfterUpdateSuccess(getApplyDirFile, false, false); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS); + standardInit(); + checkCallbackServiceLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessCompleteSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessCompleteSvc_win.js new file mode 100644 index 0000000000..aaee1adea7 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessCompleteSvc_win.js @@ -0,0 +1,38 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* Replace app binary complete MAR file staged patch apply success test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + gStageUpdate = true; + setupTestCommon(); + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setupUpdaterTest(FILE_COMPLETE_MAR); + + gCallbackBinFile = "exe0.exe"; + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_APPLIED); +} + +function checkUpdateFinished() { + // Switch the application to the staged application that was updated. + gStageUpdate = false; + gSwitchApp = true; + runUpdate(0, STATE_SUCCEEDED, checkUpdateApplied); +} + +function checkUpdateApplied() { + checkFilesAfterUpdateSuccess(getApplyDirFile, false, false); + standardInit(); + checkCallbackAppLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessPartialSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessPartialSvc_win.js new file mode 100644 index 0000000000..451cbd4b8d --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessPartialSvc_win.js @@ -0,0 +1,38 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* Patch app binary partial MAR file staged patch apply success test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + gStageUpdate = true; + setupTestCommon(); + gTestFiles = gTestFilesPartialSuccess; + gTestDirs = gTestDirsPartialSuccess; + setupUpdaterTest(FILE_PARTIAL_MAR); + + gCallbackBinFile = "exe0.exe"; + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_APPLIED); +} + +function checkUpdateFinished() { + // Switch the application to the staged application that was updated. + gStageUpdate = false; + gSwitchApp = true; + runUpdate(0, STATE_SUCCEEDED, checkUpdateApplied); +} + +function checkUpdateApplied() { + checkFilesAfterUpdateSuccess(getApplyDirFile, false, false); + standardInit(); + checkCallbackAppLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppSuccessCompleteSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppSuccessCompleteSvc_win.js new file mode 100644 index 0000000000..a06d49078c --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppSuccessCompleteSvc_win.js @@ -0,0 +1,30 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* Replace app binary complete MAR file patch apply success test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + setupTestCommon(); + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setupUpdaterTest(FILE_COMPLETE_MAR); + + gCallbackBinFile = "exe0.exe"; + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_SUCCEEDED); +} + +function checkUpdateFinished() { + checkFilesAfterUpdateSuccess(getApplyDirFile, false, false); + standardInit(); + checkCallbackServiceLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppSuccessPartialSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppSuccessPartialSvc_win.js new file mode 100644 index 0000000000..d8cbf8a310 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppSuccessPartialSvc_win.js @@ -0,0 +1,30 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* Patch app binary partial MAR file patch apply success test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + setupTestCommon(); + gTestFiles = gTestFilesPartialSuccess; + gTestDirs = gTestDirsPartialSuccess; + setupUpdaterTest(FILE_PARTIAL_MAR); + + gCallbackBinFile = "exe0.exe"; + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_SUCCEEDED); +} + +function checkUpdateFinished() { + checkFilesAfterUpdateSuccess(getApplyDirFile, false, false); + standardInit(); + checkCallbackServiceLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marFailurePartialSvc.js b/toolkit/mozapps/update/tests/unit_service_updater/marFailurePartialSvc.js new file mode 100644 index 0000000000..d87a1c50a8 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marFailurePartialSvc.js @@ -0,0 +1,42 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* General Partial MAR File Patch Apply Failure Test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + setupTestCommon(); + gTestFiles = gTestFilesPartialSuccess; + gTestFiles[11].originalFile = "partial.png"; + gTestDirs = gTestDirsPartialSuccess; + setTestFilesAndDirsForFailure(); + setupUpdaterTest(FILE_PARTIAL_MAR); + + createUpdaterINI(); + setAppBundleModTime(); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + runUpdateUsingService(STATE_PENDING_SVC, + STATE_FAILED_LOADSOURCE_ERROR_WRONG_SIZE); +} + +/** + * Checks if the update has finished and if it has finished performs checks for + * the test. + */ +function checkUpdateFinished() { + checkPostUpdateRunningFile(false); + checkAppBundleModTime(); + checkFilesAfterUpdateFailure(getApplyDirFile, false, false); + checkUpdateLogContents(LOG_PARTIAL_FAILURE); + standardInit(); + checkCallbackServiceLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailureCompleteSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailureCompleteSvc_win.js new file mode 100644 index 0000000000..4c9ab7e60f --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailureCompleteSvc_win.js @@ -0,0 +1,57 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File in use complete MAR file staged patch apply failure test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + gStageUpdate = true; + setupTestCommon(); + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + setupUpdaterTest(FILE_COMPLETE_MAR); + + // Launch an existing file so it is in use during the update. + let fileInUseBin = getApplyDirFile(gTestFiles[13].relPathDir + + gTestFiles[13].fileName); + let args = [getApplyDirPath() + DIR_RESOURCES, "input", "output", "-s", + HELPER_SLEEP_TIMEOUT]; + let fileInUseProcess = Cc["@mozilla.org/process/util;1"]. + createInstance(Ci.nsIProcess); + fileInUseProcess.init(fileInUseBin); + fileInUseProcess.run(false, args, args.length); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep); +} + +function doUpdate() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_APPLIED); +} + +function checkUpdateFinished() { + // Switch the application to the staged application that was updated. + gStageUpdate = false; + gSwitchApp = true; + runUpdate(1, STATE_PENDING, checkUpdateApplied); +} + +function checkUpdateApplied() { + setupHelperFinish(); +} + +function checkUpdate() { + checkFilesAfterUpdateFailure(getApplyDirFile, false, false); + checkUpdateLogContains(ERR_RENAME_FILE); + checkUpdateLogContains(ERR_MOVE_DESTDIR_7); + standardInit(); + checkCallbackAppLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailurePartialSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailurePartialSvc_win.js new file mode 100644 index 0000000000..a3f09b4a6f --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailurePartialSvc_win.js @@ -0,0 +1,57 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File in use partial MAR file staged patch apply failure test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + gStageUpdate = true; + setupTestCommon(); + gTestFiles = gTestFilesPartialSuccess; + gTestDirs = gTestDirsPartialSuccess; + setTestFilesAndDirsForFailure(); + setupUpdaterTest(FILE_PARTIAL_MAR); + + // Launch an existing file so it is in use during the update. + let fileInUseBin = getApplyDirFile(gTestFiles[11].relPathDir + + gTestFiles[11].fileName); + let args = [getApplyDirPath() + DIR_RESOURCES, "input", "output", "-s", + HELPER_SLEEP_TIMEOUT]; + let fileInUseProcess = Cc["@mozilla.org/process/util;1"]. + createInstance(Ci.nsIProcess); + fileInUseProcess.init(fileInUseBin); + fileInUseProcess.run(false, args, args.length); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep); +} + +function doUpdate() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_APPLIED); +} + +function checkUpdateFinished() { + // Switch the application to the staged application that was updated. + gStageUpdate = false; + gSwitchApp = true; + runUpdate(1, STATE_PENDING, checkUpdateApplied); +} + +function checkUpdateApplied() { + setupHelperFinish(); +} + +function checkUpdate() { + checkFilesAfterUpdateFailure(getApplyDirFile, false, false); + checkUpdateLogContains(ERR_RENAME_FILE); + checkUpdateLogContains(ERR_MOVE_DESTDIR_7); + standardInit(); + checkCallbackAppLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseSuccessCompleteSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseSuccessCompleteSvc_win.js new file mode 100644 index 0000000000..d35d6dbb99 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseSuccessCompleteSvc_win.js @@ -0,0 +1,47 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File in use complete MAR file patch apply success test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + setupTestCommon(); + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setupUpdaterTest(FILE_COMPLETE_MAR); + + // Launch an existing file so it is in use during the update. + let fileInUseBin = getApplyDirFile(gTestFiles[13].relPathDir + + gTestFiles[13].fileName); + let args = [getApplyDirPath() + DIR_RESOURCES, "input", "output", "-s", + HELPER_SLEEP_TIMEOUT]; + let fileInUseProcess = Cc["@mozilla.org/process/util;1"]. + createInstance(Ci.nsIProcess); + fileInUseProcess.init(fileInUseBin); + fileInUseProcess.run(false, args, args.length); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep); +} + +function doUpdate() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_SUCCEEDED); +} + +function checkUpdateFinished() { + setupHelperFinish(); +} + +function checkUpdate() { + checkFilesAfterUpdateSuccess(getApplyDirFile, false, true); + checkUpdateLogContains(ERR_BACKUP_DISCARD); + standardInit(); + checkCallbackServiceLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseSuccessPartialSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseSuccessPartialSvc_win.js new file mode 100644 index 0000000000..ae34168f10 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseSuccessPartialSvc_win.js @@ -0,0 +1,47 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File in use partial MAR file patch apply success test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + setupTestCommon(); + gTestFiles = gTestFilesPartialSuccess; + gTestDirs = gTestDirsPartialSuccess; + setupUpdaterTest(FILE_PARTIAL_MAR); + + // Launch an existing file so it is in use during the update. + let fileInUseBin = getApplyDirFile(gTestFiles[11].relPathDir + + gTestFiles[11].fileName); + let args = [getApplyDirPath() + DIR_RESOURCES, "input", "output", "-s", + HELPER_SLEEP_TIMEOUT]; + let fileInUseProcess = Cc["@mozilla.org/process/util;1"]. + createInstance(Ci.nsIProcess); + fileInUseProcess.init(fileInUseBin); + fileInUseProcess.run(false, args, args.length); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep); +} + +function doUpdate() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_SUCCEEDED); +} + +function checkUpdateFinished() { + setupHelperFinish(); +} + +function checkUpdate() { + checkFilesAfterUpdateSuccess(getApplyDirFile, false, true); + checkUpdateLogContains(ERR_BACKUP_DISCARD); + standardInit(); + checkCallbackServiceLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFailureCompleteSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFailureCompleteSvc_win.js new file mode 100644 index 0000000000..77afda1026 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFailureCompleteSvc_win.js @@ -0,0 +1,57 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File locked complete MAR file patch apply failure test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + setupTestCommon(); + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + setupUpdaterTest(FILE_COMPLETE_MAR); + + // Exclusively lock an existing file so it is in use during the update. + let helperBin = getTestDirFile(FILE_HELPER_BIN); + let helperDestDir = getApplyDirFile(DIR_RESOURCES); + helperBin.copyTo(helperDestDir, FILE_HELPER_BIN); + helperBin = getApplyDirFile(DIR_RESOURCES + FILE_HELPER_BIN); + // Strip off the first two directories so the path has to be from the helper's + // working directory. + let lockFileRelPath = gTestFiles[3].relPathDir.split("/"); + if (IS_MACOSX) { + lockFileRelPath = lockFileRelPath.slice(2); + } + lockFileRelPath = lockFileRelPath.join("/") + "/" + gTestFiles[3].fileName; + let args = [getApplyDirPath() + DIR_RESOURCES, "input", "output", "-s", + HELPER_SLEEP_TIMEOUT, lockFileRelPath]; + let lockFileProcess = Cc["@mozilla.org/process/util;1"]. + createInstance(Ci.nsIProcess); + lockFileProcess.init(helperBin); + lockFileProcess.run(false, args, args.length); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep); +} + +function doUpdate() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_FAILED_WRITE_ERROR); +} + +function checkUpdateFinished() { + setupHelperFinish(); +} + +function checkUpdate() { + checkFilesAfterUpdateFailure(getApplyDirFile, false, false); + checkUpdateLogContains(ERR_RENAME_FILE); + standardInit(); + checkCallbackServiceLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFailurePartialSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFailurePartialSvc_win.js new file mode 100644 index 0000000000..9a2fac7518 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFailurePartialSvc_win.js @@ -0,0 +1,57 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File locked partial MAR file patch apply failure test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + setupTestCommon(); + gTestFiles = gTestFilesPartialSuccess; + gTestDirs = gTestDirsPartialSuccess; + setTestFilesAndDirsForFailure(); + setupUpdaterTest(FILE_PARTIAL_MAR); + + // Exclusively lock an existing file so it is in use during the update. + let helperBin = getTestDirFile(FILE_HELPER_BIN); + let helperDestDir = getApplyDirFile(DIR_RESOURCES); + helperBin.copyTo(helperDestDir, FILE_HELPER_BIN); + helperBin = getApplyDirFile(DIR_RESOURCES + FILE_HELPER_BIN); + // Strip off the first two directories so the path has to be from the helper's + // working directory. + let lockFileRelPath = gTestFiles[2].relPathDir.split("/"); + if (IS_MACOSX) { + lockFileRelPath = lockFileRelPath.slice(2); + } + lockFileRelPath = lockFileRelPath.join("/") + "/" + gTestFiles[2].fileName; + let args = [getApplyDirPath() + DIR_RESOURCES, "input", "output", "-s", + HELPER_SLEEP_TIMEOUT, lockFileRelPath]; + let lockFileProcess = Cc["@mozilla.org/process/util;1"]. + createInstance(Ci.nsIProcess); + lockFileProcess.init(helperBin); + lockFileProcess.run(false, args, args.length); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep); +} + +function doUpdate() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_FAILED_READ_ERROR); +} + +function checkUpdateFinished() { + setupHelperFinish(); +} + +function checkUpdate() { + checkFilesAfterUpdateFailure(getApplyDirFile, false, false); + checkUpdateLogContains(ERR_UNABLE_OPEN_DEST); + standardInit(); + checkCallbackServiceLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailureCompleteSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailureCompleteSvc_win.js new file mode 100644 index 0000000000..9e4bb658d1 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailureCompleteSvc_win.js @@ -0,0 +1,66 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File locked complete MAR file staged patch apply failure test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + gStageUpdate = true; + setupTestCommon(); + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + setupUpdaterTest(FILE_COMPLETE_MAR); + + // Exclusively lock an existing file so it is in use during the update. + let helperBin = getTestDirFile(FILE_HELPER_BIN); + let helperDestDir = getApplyDirFile(DIR_RESOURCES); + helperBin.copyTo(helperDestDir, FILE_HELPER_BIN); + helperBin = getApplyDirFile(DIR_RESOURCES + FILE_HELPER_BIN); + // Strip off the first two directories so the path has to be from the helper's + // working directory. + let lockFileRelPath = gTestFiles[3].relPathDir.split("/"); + if (IS_MACOSX) { + lockFileRelPath = lockFileRelPath.slice(2); + } + lockFileRelPath = lockFileRelPath.join("/") + "/" + gTestFiles[3].fileName; + let args = [getApplyDirPath() + DIR_RESOURCES, "input", "output", "-s", + HELPER_SLEEP_TIMEOUT, lockFileRelPath]; + let lockFileProcess = Cc["@mozilla.org/process/util;1"]. + createInstance(Ci.nsIProcess); + lockFileProcess.init(helperBin); + lockFileProcess.run(false, args, args.length); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep); +} + +function doUpdate() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_FAILED_WRITE_ERROR_FILE_COPY); +} + +function checkUpdateFinished() { + // Switch the application to the staged application that was updated. + gStageUpdate = false; + gSwitchApp = true; + runUpdate(1, STATE_PENDING, checkUpdateApplied); +} + +function checkUpdateApplied() { + setupHelperFinish(); +} + +function checkUpdate() { + checkFilesAfterUpdateFailure(getApplyDirFile, false, false); + checkUpdateLogContains(ERR_RENAME_FILE); + checkUpdateLogContains(ERR_MOVE_DESTDIR_7); + standardInit(); + checkCallbackAppLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailurePartialSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailurePartialSvc_win.js new file mode 100644 index 0000000000..e6dad52831 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailurePartialSvc_win.js @@ -0,0 +1,66 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File locked partial MAR file staged patch apply failure test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + gStageUpdate = true; + setupTestCommon(); + gTestFiles = gTestFilesPartialSuccess; + gTestDirs = gTestDirsPartialSuccess; + setTestFilesAndDirsForFailure(); + setupUpdaterTest(FILE_PARTIAL_MAR); + + // Exclusively lock an existing file so it is in use during the update. + let helperBin = getTestDirFile(FILE_HELPER_BIN); + let helperDestDir = getApplyDirFile(DIR_RESOURCES); + helperBin.copyTo(helperDestDir, FILE_HELPER_BIN); + helperBin = getApplyDirFile(DIR_RESOURCES + FILE_HELPER_BIN); + // Strip off the first two directories so the path has to be from the helper's + // working directory. + let lockFileRelPath = gTestFiles[2].relPathDir.split("/"); + if (IS_MACOSX) { + lockFileRelPath = lockFileRelPath.slice(2); + } + lockFileRelPath = lockFileRelPath.join("/") + "/" + gTestFiles[2].fileName; + let args = [getApplyDirPath() + DIR_RESOURCES, "input", "output", "-s", + HELPER_SLEEP_TIMEOUT, lockFileRelPath]; + let lockFileProcess = Cc["@mozilla.org/process/util;1"]. + createInstance(Ci.nsIProcess); + lockFileProcess.init(helperBin); + lockFileProcess.run(false, args, args.length); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep); +} + +function doUpdate() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_FAILED_WRITE_ERROR_FILE_COPY); +} + +function checkUpdateFinished() { + // Switch the application to the staged application that was updated. + gStageUpdate = false; + gSwitchApp = true; + runUpdate(1, STATE_PENDING, checkUpdateApplied); +} + +function checkUpdateApplied() { + setupHelperFinish(); +} + +function checkUpdate() { + checkFilesAfterUpdateFailure(getApplyDirFile, false, false); + checkUpdateLogContains(ERR_RENAME_FILE); + checkUpdateLogContains(ERR_MOVE_DESTDIR_7); + standardInit(); + checkCallbackAppLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailureCompleteSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailureCompleteSvc_win.js new file mode 100644 index 0000000000..1d840e703a --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailureCompleteSvc_win.js @@ -0,0 +1,68 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File in use inside removed dir complete MAR file staged patch apply failure + test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + gStageUpdate = true; + setupTestCommon(); + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + setupUpdaterTest(FILE_COMPLETE_MAR); + + let fileInUseBin = getApplyDirFile(gTestDirs[4].relPathDir + + gTestDirs[4].subDirs[0] + + gTestDirs[4].subDirFiles[0]); + // Remove the empty file created for the test so the helper application can + // replace it. + fileInUseBin.remove(false); + + let helperBin = getTestDirFile(FILE_HELPER_BIN); + let fileInUseDir = getApplyDirFile(gTestDirs[4].relPathDir + + gTestDirs[4].subDirs[0]); + helperBin.copyTo(fileInUseDir, gTestDirs[4].subDirFiles[0]); + + // Launch an existing file so it is in use during the update. + let args = [getApplyDirPath() + DIR_RESOURCES, "input", "output", "-s", + HELPER_SLEEP_TIMEOUT]; + let fileInUseProcess = Cc["@mozilla.org/process/util;1"]. + createInstance(Ci.nsIProcess); + fileInUseProcess.init(fileInUseBin); + fileInUseProcess.run(false, args, args.length); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep); +} + +function doUpdate() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_APPLIED); +} + +function checkUpdateFinished() { + // Switch the application to the staged application that was updated. + gStageUpdate = false; + gSwitchApp = true; + runUpdate(1, STATE_PENDING, checkUpdateApplied); +} + +function checkUpdateApplied() { + setupHelperFinish(); +} + +function checkUpdate() { + checkFilesAfterUpdateFailure(getApplyDirFile, false, false); + checkUpdateLogContains(ERR_RENAME_FILE); + checkUpdateLogContains(ERR_MOVE_DESTDIR_7); + standardInit(); + checkCallbackAppLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailurePartialSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailurePartialSvc_win.js new file mode 100644 index 0000000000..4073410eb5 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailurePartialSvc_win.js @@ -0,0 +1,66 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File in use inside removed dir partial MAR file staged patch apply failure + test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + gStageUpdate = true; + setupTestCommon(); + gTestFiles = gTestFilesPartialSuccess; + gTestDirs = gTestDirsPartialSuccess; + setTestFilesAndDirsForFailure(); + setupUpdaterTest(FILE_PARTIAL_MAR); + + let fileInUseBin = getApplyDirFile(gTestDirs[2].relPathDir + + gTestDirs[2].files[0]); + // Remove the empty file created for the test so the helper application can + // replace it. + fileInUseBin.remove(false); + + let helperBin = getTestDirFile(FILE_HELPER_BIN); + let fileInUseDir = getApplyDirFile(gTestDirs[2].relPathDir); + helperBin.copyTo(fileInUseDir, gTestDirs[2].files[0]); + + // Launch an existing file so it is in use during the update. + let args = [getApplyDirPath() + DIR_RESOURCES, "input", "output", "-s", + HELPER_SLEEP_TIMEOUT]; + let fileInUseProcess = Cc["@mozilla.org/process/util;1"]. + createInstance(Ci.nsIProcess); + fileInUseProcess.init(fileInUseBin); + fileInUseProcess.run(false, args, args.length); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep); +} + +function doUpdate() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_APPLIED); +} + +function checkUpdateFinished() { + // Switch the application to the staged application that was updated. + gStageUpdate = false; + gSwitchApp = true; + runUpdate(1, STATE_PENDING, checkUpdateApplied); +} + +function checkUpdateApplied() { + setupHelperFinish(); +} + +function checkUpdate() { + checkFilesAfterUpdateFailure(getApplyDirFile, false, false); + checkUpdateLogContains(ERR_RENAME_FILE); + checkUpdateLogContains(ERR_MOVE_DESTDIR_7); + standardInit(); + checkCallbackAppLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseSuccessCompleteSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseSuccessCompleteSvc_win.js new file mode 100644 index 0000000000..a46caeca7d --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseSuccessCompleteSvc_win.js @@ -0,0 +1,57 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File in use inside removed dir complete MAR file patch apply success test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + setupTestCommon(); + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setupUpdaterTest(FILE_COMPLETE_MAR); + + let fileInUseBin = getApplyDirFile(gTestDirs[4].relPathDir + + gTestDirs[4].subDirs[0] + + gTestDirs[4].subDirFiles[0]); + // Remove the empty file created for the test so the helper application can + // replace it. + fileInUseBin.remove(false); + + let helperBin = getTestDirFile(FILE_HELPER_BIN); + let fileInUseDir = getApplyDirFile(gTestDirs[4].relPathDir + + gTestDirs[4].subDirs[0]); + helperBin.copyTo(fileInUseDir, gTestDirs[4].subDirFiles[0]); + + // Launch an existing file so it is in use during the update. + let args = [getApplyDirPath() + DIR_RESOURCES, "input", "output", "-s", + HELPER_SLEEP_TIMEOUT]; + let fileInUseProcess = Cc["@mozilla.org/process/util;1"]. + createInstance(Ci.nsIProcess); + fileInUseProcess.init(fileInUseBin); + fileInUseProcess.run(false, args, args.length); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep); +} + +function doUpdate() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_SUCCEEDED); +} + +function checkUpdateFinished() { + setupHelperFinish(); +} + +function checkUpdate() { + checkFilesAfterUpdateSuccess(getApplyDirFile, false, true); + checkUpdateLogContains(ERR_BACKUP_DISCARD); + standardInit(); + checkCallbackServiceLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseSuccessPartialSvc_win.js b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseSuccessPartialSvc_win.js new file mode 100644 index 0000000000..04f71aab19 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseSuccessPartialSvc_win.js @@ -0,0 +1,55 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File in use inside removed dir partial MAR file patch apply success test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + setupTestCommon(); + gTestFiles = gTestFilesPartialSuccess; + gTestDirs = gTestDirsPartialSuccess; + setupUpdaterTest(FILE_PARTIAL_MAR); + + let fileInUseBin = getApplyDirFile(gTestDirs[2].relPathDir + + gTestDirs[2].files[0]); + // Remove the empty file created for the test so the helper application can + // replace it. + fileInUseBin.remove(false); + + let helperBin = getTestDirFile(FILE_HELPER_BIN); + let fileInUseDir = getApplyDirFile(gTestDirs[2].relPathDir); + helperBin.copyTo(fileInUseDir, gTestDirs[2].files[0]); + + // Launch an existing file so it is in use during the update. + let args = [getApplyDirPath() + DIR_RESOURCES, "input", "output", "-s", + HELPER_SLEEP_TIMEOUT]; + let fileInUseProcess = Cc["@mozilla.org/process/util;1"]. + createInstance(Ci.nsIProcess); + fileInUseProcess.init(fileInUseBin); + fileInUseProcess.run(false, args, args.length); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + do_timeout(TEST_HELPER_TIMEOUT, waitForHelperSleep); +} + +function doUpdate() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_SUCCEEDED); +} + +function checkUpdateFinished() { + setupHelperFinish(); +} + +function checkUpdate() { + checkFilesAfterUpdateSuccess(getApplyDirFile, false, true); + checkUpdateLogContains(ERR_BACKUP_DISCARD); + standardInit(); + checkCallbackServiceLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marStageFailurePartialSvc.js b/toolkit/mozapps/update/tests/unit_service_updater/marStageFailurePartialSvc.js new file mode 100644 index 0000000000..20e15da779 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marStageFailurePartialSvc.js @@ -0,0 +1,41 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* General Partial MAR File Staged Patch Apply Failure Test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + gStageUpdate = true; + setupTestCommon(); + gTestFiles = gTestFilesPartialSuccess; + gTestFiles[11].originalFile = "partial.png"; + gTestDirs = gTestDirsPartialSuccess; + setTestFilesAndDirsForFailure(); + setupUpdaterTest(FILE_PARTIAL_MAR); + + createUpdaterINI(true); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + runUpdateUsingService(STATE_PENDING_SVC, + STATE_FAILED_LOADSOURCE_ERROR_WRONG_SIZE); +} + +/** + * Checks if the update has finished and if it has finished performs checks for + * the test. + */ +function checkUpdateFinished() { + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile, true, false); + checkUpdateLogContents(LOG_PARTIAL_FAILURE); + standardInit(); + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessCompleteSvc.js b/toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessCompleteSvc.js new file mode 100644 index 0000000000..d7306b862e --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessCompleteSvc.js @@ -0,0 +1,147 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* General Complete MAR File Staged Patch Apply Test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + gStageUpdate = true; + setupTestCommon(); + gTestFiles = gTestFilesCompleteSuccess; + gTestFiles[gTestFiles.length - 1].originalContents = null; + gTestFiles[gTestFiles.length - 1].compareContents = "FromComplete\n"; + gTestFiles[gTestFiles.length - 1].comparePerms = 0o644; + gTestDirs = gTestDirsCompleteSuccess; + setupUpdaterTest(FILE_COMPLETE_MAR); + if (IS_MACOSX) { + // Create files in the old distribution directory location to verify that + // the directory and its contents are removed when there is a distribution + // directory in the new location. + let testFile = getApplyDirFile(DIR_MACOS + "distribution/testFile", true); + writeFile(testFile, "test\n"); + testFile = getApplyDirFile(DIR_MACOS + "distribution/test1/testFile", true); + writeFile(testFile, "test\n"); + } + + createUpdaterINI(false); + setAppBundleModTime(); + + // Don't test symlinks on Mac OS X in this test since it tends to timeout. + // It is tested on Mac OS X in marAppInUseStageSuccessComplete_unix.js + // The tests don't support symlinks on gonk. + if (IS_UNIX && !IS_MACOSX && !IS_TOOLKIT_GONK) { + removeSymlink(); + createSymlink(); + do_register_cleanup(removeSymlink); + gTestFiles.splice(gTestFiles.length - 3, 0, + { + description : "Readable symlink", + fileName : "link", + relPathDir : DIR_RESOURCES, + originalContents : "test", + compareContents : "test", + originalFile : null, + compareFile : null, + originalPerms : 0o666, + comparePerms : 0o666 + }); + } + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_APPLIED); +} + +function checkUpdateFinished() { + checkFilesAfterUpdateSuccess(getStageDirFile, true, false); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS); + checkPostUpdateRunningFile(false); + + // Switch the application to the staged application that was updated. + gStageUpdate = false; + gSwitchApp = true; + do_timeout(TEST_CHECK_TIMEOUT, function() { + runUpdate(0, STATE_SUCCEEDED, checkUpdateApplied); + }); +} + +/** + * Checks if the post update binary was properly launched for the platforms that + * support launching post update process. + */ +function checkUpdateApplied() { + if (IS_WIN || IS_MACOSX) { + gCheckFunc = finishCheckUpdateApplied; + checkPostUpdateAppLog(); + } else { + finishCheckUpdateApplied(); + } +} + +/** + * Checks if the update has finished and if it has finished performs checks for + * the test. + */ +function finishCheckUpdateApplied() { + checkPostUpdateRunningFile(true); + + if (IS_MACOSX) { + let distributionDir = getApplyDirFile(DIR_MACOS + "distribution", true); + Assert.ok(!distributionDir.exists(), MSG_SHOULD_NOT_EXIST); + checkUpdateLogContains("removing old distribution directory"); + } + + // The tests don't support symlinks on gonk. + if (IS_UNIX && !IS_MACOSX && !IS_TOOLKIT_GONK) { + checkSymlink(); + } + checkAppBundleModTime(); + checkFilesAfterUpdateSuccess(getApplyDirFile, false, false); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS); + standardInit(); + checkCallbackAppLog(); +} + +function runHelperProcess(args) { + let helperBin = getTestDirFile(FILE_HELPER_BIN); + let process = Cc["@mozilla.org/process/util;1"]. + createInstance(Ci.nsIProcess); + process.init(helperBin); + debugDump("Running " + helperBin.path + " " + args.join(" ")); + process.run(true, args, args.length); + Assert.equal(process.exitValue, 0, + "the helper process exit value should be 0"); +} + +function createSymlink() { + let args = ["setup-symlink", "moz-foo", "moz-bar", "target", + getApplyDirFile().path + "/" + DIR_RESOURCES + "link"]; + runHelperProcess(args); + getApplyDirFile(DIR_RESOURCES + "link", false).permissions = 0o666; + + args = ["setup-symlink", "moz-foo2", "moz-bar2", "target2", + getApplyDirFile().path + "/" + DIR_RESOURCES + "link2", "change-perm"]; + runHelperProcess(args); +} + +function removeSymlink() { + let args = ["remove-symlink", "moz-foo", "moz-bar", "target", + getApplyDirFile().path + "/" + DIR_RESOURCES + "link"]; + runHelperProcess(args); + args = ["remove-symlink", "moz-foo2", "moz-bar2", "target2", + getApplyDirFile().path + "/" + DIR_RESOURCES + "link2"]; + runHelperProcess(args); +} + +function checkSymlink() { + let args = ["check-symlink", + getApplyDirFile().path + "/" + DIR_RESOURCES + "link"]; + runHelperProcess(args); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessPartialSvc.js b/toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessPartialSvc.js new file mode 100644 index 0000000000..db867ac535 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessPartialSvc.js @@ -0,0 +1,99 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* General Partial MAR File Staged Patch Apply Test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + gStageUpdate = true; + setupTestCommon(); + gTestFiles = gTestFilesPartialSuccess; + gTestFiles[gTestFiles.length - 2].originalContents = null; + gTestFiles[gTestFiles.length - 2].compareContents = "FromPartial\n"; + gTestFiles[gTestFiles.length - 2].comparePerms = 0o644; + gTestDirs = gTestDirsPartialSuccess; + preventDistributionFiles(); + setupUpdaterTest(FILE_PARTIAL_MAR); + if (IS_MACOSX) { + // Create files in the old distribution directory location to verify that + // the directory and its contents are moved to the new location on update. + let testFile = getApplyDirFile(DIR_MACOS + "distribution/testFile", true); + writeFile(testFile, "test\n"); + testFile = getApplyDirFile(DIR_MACOS + "distribution/test/testFile", true); + writeFile(testFile, "test\n"); + } + + createUpdaterINI(false); + setAppBundleModTime(); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_APPLIED); +} + +function checkUpdateFinished() { + checkFilesAfterUpdateSuccess(getStageDirFile, true, false); + checkUpdateLogContents(LOG_PARTIAL_SUCCESS, true); + checkPostUpdateRunningFile(false); + + // Switch the application to the staged application that was updated. + gStageUpdate = false; + gSwitchApp = true; + do_timeout(TEST_CHECK_TIMEOUT, function() { + runUpdate(0, STATE_SUCCEEDED, checkUpdateApplied); + }); +} + +/** + * Checks if the post update binary was properly launched for the platforms that + * support launching post update process. + */ +function checkUpdateApplied() { + if (IS_WIN || IS_MACOSX) { + gCheckFunc = finishCheckUpdateApplied; + checkPostUpdateAppLog(); + } else { + finishCheckUpdateApplied(); + } +} + +/** + * Checks if the update has finished and if it has finished performs checks for + * the test. + */ +function finishCheckUpdateApplied() { + checkPostUpdateRunningFile(true); + + let distributionDir = getApplyDirFile(DIR_RESOURCES + "distribution", true); + if (IS_MACOSX) { + Assert.ok(distributionDir.exists(), MSG_SHOULD_EXIST); + + let testFile = getApplyDirFile(DIR_RESOURCES + "distribution/testFile", true); + Assert.ok(testFile.exists(), MSG_SHOULD_EXIST); + + testFile = getApplyDirFile(DIR_RESOURCES + "distribution/test/testFile", true); + Assert.ok(testFile.exists(), MSG_SHOULD_EXIST); + + distributionDir = getApplyDirFile(DIR_MACOS + "distribution", true); + Assert.ok(!distributionDir.exists(), MSG_SHOULD_NOT_EXIST); + + checkUpdateLogContains("Moving old distribution directory to new location"); + } else { + debugDump("testing that files aren't added with an add-if instruction " + + "when the file's destination directory doesn't exist"); + Assert.ok(!distributionDir.exists(), MSG_SHOULD_NOT_EXIST); + } + + checkAppBundleModTime(); + checkFilesAfterUpdateSuccess(getApplyDirFile, false, false); + checkUpdateLogContents(LOG_PARTIAL_SUCCESS, true); + standardInit(); + checkCallbackAppLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marSuccessCompleteSvc.js b/toolkit/mozapps/update/tests/unit_service_updater/marSuccessCompleteSvc.js new file mode 100644 index 0000000000..8fb4f169fe --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marSuccessCompleteSvc.js @@ -0,0 +1,80 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* General Complete MAR File Patch Apply Test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + setupTestCommon(); + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + preventDistributionFiles(); + setupUpdaterTest(FILE_COMPLETE_MAR); + if (IS_MACOSX) { + // Create files in the old distribution directory location to verify that + // the directory and its contents are moved to the new location on update. + let testFile = getApplyDirFile(DIR_MACOS + "distribution/testFile", true); + writeFile(testFile, "test\n"); + testFile = getApplyDirFile(DIR_MACOS + "distribution/test/testFile", true); + writeFile(testFile, "test\n"); + } + + createUpdaterINI(); + setAppBundleModTime(); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_SUCCEEDED); +} + +/** + * Checks if the post update binary was properly launched for the platforms that + * support launching post update process. + */ +function checkUpdateFinished() { + if (IS_WIN || IS_MACOSX) { + gCheckFunc = finishCheckUpdateFinished; + checkPostUpdateAppLog(); + } else { + finishCheckUpdateFinished(); + } +} + +/** + * Checks if the update has finished and if it has finished performs checks for + * the test. + */ +function finishCheckUpdateFinished() { + let distributionDir = getApplyDirFile(DIR_RESOURCES + "distribution", true); + if (IS_MACOSX) { + Assert.ok(distributionDir.exists(), MSG_SHOULD_EXIST); + + let testFile = getApplyDirFile(DIR_RESOURCES + "distribution/testFile", true); + Assert.ok(testFile.exists(), MSG_SHOULD_EXIST); + + testFile = getApplyDirFile(DIR_RESOURCES + "distribution/test/testFile", true); + Assert.ok(testFile.exists(), MSG_SHOULD_EXIST); + + distributionDir = getApplyDirFile(DIR_MACOS + "distribution", true); + Assert.ok(!distributionDir.exists(), MSG_SHOULD_NOT_EXIST); + + checkUpdateLogContains("Moving old distribution directory to new location"); + } else { + debugDump("testing that files aren't added with an add-if instruction " + + "when the file's destination directory doesn't exist"); + Assert.ok(!distributionDir.exists(), MSG_SHOULD_NOT_EXIST); + } + + checkAppBundleModTime(); + checkFilesAfterUpdateSuccess(getApplyDirFile, false, false); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true); + standardInit(); + checkCallbackServiceLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/marSuccessPartialSvc.js b/toolkit/mozapps/update/tests/unit_service_updater/marSuccessPartialSvc.js new file mode 100644 index 0000000000..56e7e1ea5a --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/marSuccessPartialSvc.js @@ -0,0 +1,72 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* General Partial MAR File Patch Apply Test */ + +function run_test() { + if (!shouldRunServiceTest()) { + return; + } + + setupTestCommon(); + gTestFiles = gTestFilesPartialSuccess; + gTestFiles[gTestFiles.length - 1].originalContents = null; + gTestFiles[gTestFiles.length - 1].compareContents = "FromPartial\n"; + gTestFiles[gTestFiles.length - 1].comparePerms = 0o644; + gTestFiles[gTestFiles.length - 2].originalContents = null; + gTestFiles[gTestFiles.length - 2].compareContents = "FromPartial\n"; + gTestFiles[gTestFiles.length - 2].comparePerms = 0o644; + gTestDirs = gTestDirsPartialSuccess; + setupUpdaterTest(FILE_PARTIAL_MAR); + if (IS_MACOSX) { + // Create files in the old distribution directory location to verify that + // the directory and its contents are removed when there is a distribution + // directory in the new location. + let testFile = getApplyDirFile(DIR_MACOS + "distribution/testFile", true); + writeFile(testFile, "test\n"); + testFile = getApplyDirFile(DIR_MACOS + "distribution/test/testFile", true); + writeFile(testFile, "test\n"); + } + + createUpdaterINI(true); + setAppBundleModTime(); + + setupAppFilesAsync(); +} + +function setupAppFilesFinished() { + runUpdateUsingService(STATE_PENDING_SVC, STATE_SUCCEEDED); +} + +/** + * Checks if the post update binary was properly launched for the platforms that + * support launching post update process. + */ +function checkUpdateFinished() { + if (IS_WIN || IS_MACOSX) { + gCheckFunc = finishCheckUpdateFinished; + checkPostUpdateAppLog(); + } else { + finishCheckUpdateFinished(); + } +} + +/** + * Checks if the update has finished and if it has finished performs checks for + * the test. + */ +function finishCheckUpdateFinished() { + if (IS_MACOSX) { + let distributionDir = getApplyDirFile(DIR_MACOS + "distribution", true); + Assert.ok(!distributionDir.exists(), MSG_SHOULD_NOT_EXIST); + checkUpdateLogContains("removing old distribution directory"); + } + + checkAppBundleModTime(); + checkFilesAfterUpdateSuccess(getApplyDirFile, false, false); + checkUpdateLogContents(LOG_PARTIAL_SUCCESS); + standardInit(); + checkCallbackServiceLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_service_updater/xpcshell.ini b/toolkit/mozapps/update/tests/unit_service_updater/xpcshell.ini new file mode 100644 index 0000000000..c9ce29b053 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_service_updater/xpcshell.ini @@ -0,0 +1,70 @@ +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, You can obtain one at http://mozilla.org/MPL/2.0/. + +; Tests that require the updater binary and the maintenance service. + +[DEFAULT] +tags = appupdate +head = head_update.js +tail = + +[bootstrapSvc.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marSuccessCompleteSvc.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marSuccessPartialSvc.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marFailurePartialSvc.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marStageSuccessCompleteSvc.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marStageSuccessPartialSvc.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marStageFailurePartialSvc.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marCallbackAppSuccessCompleteSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marCallbackAppSuccessPartialSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marCallbackAppStageSuccessCompleteSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marCallbackAppStageSuccessPartialSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marAppInUseSuccessCompleteSvc.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marAppInUseStageFailureCompleteSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marFileLockedFailureCompleteSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marFileLockedFailurePartialSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marFileLockedStageFailureCompleteSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marFileLockedStageFailurePartialSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marFileInUseSuccessCompleteSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marFileInUseSuccessPartialSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marRMRFDirFileInUseSuccessCompleteSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marRMRFDirFileInUseSuccessPartialSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marFileInUseStageFailureCompleteSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marFileInUseStageFailurePartialSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marRMRFDirFileInUseStageFailureCompleteSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marRMRFDirFileInUseStageFailurePartialSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marAppApplyDirLockedStageFailureSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marAppApplyUpdateAppBinInUseStageSuccessSvc_win.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marAppApplyUpdateSuccessSvc.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[marAppApplyUpdateStageSuccessSvc.js] +run-sequentially = Uses the Mozilla Maintenance Service. +[checkUpdaterSigSvc.js] diff --git a/toolkit/mozapps/update/updater/Makefile.in b/toolkit/mozapps/update/updater/Makefile.in index f334119b3c..732371dc20 100644 --- a/toolkit/mozapps/update/updater/Makefile.in +++ b/toolkit/mozapps/update/updater/Makefile.in @@ -3,6 +3,8 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +# For changes here, also consider ./updater-xpcshell/Makefile.in + ifndef MOZ_WINCONSOLE ifdef MOZ_DEBUG MOZ_WINCONSOLE = 1 @@ -43,5 +45,3 @@ libs:: $(NSINSTALL) $(DIST)/bin/updater $(DIST)/bin/updater.app/Contents/MacOS rm -f $(DIST)/bin/updater endif - -CXXFLAGS += $(MOZ_BZ2_CFLAGS) diff --git a/toolkit/mozapps/update/updater/archivereader.cpp b/toolkit/mozapps/update/updater/archivereader.cpp index cb8f7736b3..90cf45c3db 100644 --- a/toolkit/mozapps/update/updater/archivereader.cpp +++ b/toolkit/mozapps/update/updater/archivereader.cpp @@ -17,9 +17,14 @@ // These are generated at compile time based on the DER file for the channel // being used +#ifdef MOZ_VERIFY_MAR_SIGNATURE +#ifdef TEST_UPDATER +#include "../xpcshellCert.h" +#else #include "primaryCert.h" #include "secondaryCert.h" -#include "xpcshellCert.h" +#endif +#endif #define UPDATER_NO_STRING_GLUE_STL #include "nsVersionComparator.cpp" @@ -77,21 +82,19 @@ ArchiveReader::VerifySignature() return ARCHIVE_NOT_OPEN; } - // If the fallback key exists we're running an XPCShell test and we should - // use the XPCShell specific cert for the signed MAR. - int rv = OK; -#ifdef XP_WIN - if (DoesFallbackKeyExist()) { - rv = VerifyLoadedCert(mArchive, xpcshellCertData); - } else -#endif - { - rv = VerifyLoadedCert(mArchive, primaryCertData); - if (rv != OK) { - rv = VerifyLoadedCert(mArchive, secondaryCertData); - } +#ifndef MOZ_VERIFY_MAR_SIGNATURE + return OK; +#else +#ifdef TEST_UPDATER + int rv = VerifyLoadedCert(mArchive, xpcshellCertData); +#else + int rv = VerifyLoadedCert(mArchive, primaryCertData); + if (rv != OK) { + rv = VerifyLoadedCert(mArchive, secondaryCertData); } +#endif return rv; +#endif } /** diff --git a/toolkit/mozapps/update/updater/moz.build b/toolkit/mozapps/update/updater/moz.build index fde296df65..f9123c557c 100644 --- a/toolkit/mozapps/update/updater/moz.build +++ b/toolkit/mozapps/update/updater/moz.build @@ -6,123 +6,9 @@ Program('updater') -SOURCES += [ - 'archivereader.cpp', - 'bspatch.cpp', - 'updater.cpp', -] +updater_rel_path = '' +include('updater-common.build') +if CONFIG['ENABLE_TESTS']: + DIRS += ['updater-xpcshell'] -have_progressui = 0 - -if CONFIG['MOZ_VERIFY_MAR_SIGNATURE']: - USE_LIBS += [ - 'verifymar', - ] - -if CONFIG['OS_ARCH'] == 'WINNT': - have_progressui = 1 - SOURCES += [ - 'loaddlls.cpp', - 'progressui_win.cpp', - 'win_dirent.cpp', - ] - RCINCLUDE = 'updater.rc' - DEFINES['UNICODE'] = True - DEFINES['_UNICODE'] = True - DEFINES['NOMINMAX'] = True - USE_STATIC_LIBS = True - - # Pick up nsWindowsRestart.cpp - LOCAL_INCLUDES += [ - '/toolkit/xre', - ] - USE_LIBS += [ - 'updatecommon-standalone', - ] - OS_LIBS += [ - 'comctl32', - 'ws2_32', - 'shell32', - 'shlwapi', - 'crypt32', - 'advapi32', - ] -elif CONFIG['OS_ARCH'] == 'Linux': - USE_LIBS += [ - 'updatecommon', - '/modules/libmar/sign/signmar', - '/security/nss/lib/nss/nss3', - '/security/nss/lib/util/nssutil3', - ] - OS_LIBS += CONFIG['NSPR_LIBS'] -else: - USE_LIBS += [ - 'updatecommon', - ] - -USE_LIBS += [ - 'mar', -] - -if CONFIG['MOZ_NATIVE_BZ2']: - OS_LIBS += CONFIG['MOZ_BZ2_LIBS'] -else: - USE_LIBS += [ - 'bz2', - ] - -if CONFIG['MOZ_ENABLE_GTK']: - have_progressui = 1 - SOURCES += [ - 'progressui_gtk.cpp', - ] - -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': - have_progressui = 1 - SOURCES += [ - 'launchchild_osx.mm', - 'progressui_osx.mm', - ] - OS_LIBS += ['-framework Cocoa -framework Security'] -elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - have_progressui = 1 - SOURCES += [ - 'automounter_gonk.cpp', - 'progressui_gonk.cpp', - ] - DISABLE_STL_WRAPPING = True - OS_LIBS += [ - 'cutils', - 'sysutils', - ] - -if have_progressui == 0: - SOURCES += [ - 'progressui_null.cpp', - ] - -DEFINES['NS_NO_XPCOM'] = True -DISABLE_STL_WRAPPING = True -for var in ('MAR_CHANNEL_ID', 'MOZ_APP_VERSION'): - DEFINES[var] = '"%s"' % CONFIG[var] - -LOCAL_INCLUDES += [ - '../common', - '/xpcom/glue', -] - -DELAYLOAD_DLLS += [ - 'crypt32.dll', - 'comctl32.dll', - 'userenv.dll', - 'wsock32.dll', -] - -if CONFIG['_MSC_VER']: - WIN32_EXE_LDFLAGS += ['-ENTRY:wmainCRTStartup'] -elif CONFIG['OS_ARCH'] == 'WINNT': - WIN32_EXE_LDFLAGS += ['-municode'] - -if CONFIG['MOZ_WIDGET_GTK']: - CXXFLAGS += CONFIG['TK_CFLAGS'] - OS_LIBS += CONFIG['TK_LIBS'] +CXXFLAGS += CONFIG['MOZ_BZ2_CFLAGS'] diff --git a/toolkit/mozapps/update/updater/updater-common.build b/toolkit/mozapps/update/updater/updater-common.build new file mode 100644 index 0000000000..c7df7269ab --- /dev/null +++ b/toolkit/mozapps/update/updater/updater-common.build @@ -0,0 +1,130 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +srcs = [ + 'archivereader.cpp', + 'bspatch.cpp', + 'updater.cpp', +] + +have_progressui = 0 + +if CONFIG['MOZ_VERIFY_MAR_SIGNATURE']: + USE_LIBS += [ + 'verifymar', + ] + +if CONFIG['OS_ARCH'] == 'WINNT': + have_progressui = 1 + srcs += [ + 'loaddlls.cpp', + 'progressui_win.cpp', + 'win_dirent.cpp', + ] + RCINCLUDE = '%supdater.rc' % updater_rel_path + DEFINES['UNICODE'] = True + DEFINES['_UNICODE'] = True + DEFINES['NOMINMAX'] = True + USE_STATIC_LIBS = True + + # Pick up nsWindowsRestart.cpp + LOCAL_INCLUDES += [ + '/toolkit/xre', + ] + USE_LIBS += [ + 'updatecommon-standalone', + ] + OS_LIBS += [ + 'comctl32', + 'ws2_32', + 'shell32', + 'shlwapi', + 'crypt32', + 'advapi32', + ] +elif CONFIG['OS_ARCH'] == 'Linux' and CONFIG['MOZ_VERIFY_MAR_SIGNATURE']: + USE_LIBS += [ + 'nss', + 'signmar', + 'updatecommon', + ] + OS_LIBS += CONFIG['nspr'] +else: + USE_LIBS += [ + 'updatecommon', + ] + +USE_LIBS += [ + 'mar', +] + +if CONFIG['MOZ_NATIVE_BZ2']: + OS_LIBS += CONFIG['MOZ_BZ2_LIBS'] +else: + USE_LIBS += [ + 'bz2', + ] + +if CONFIG['MOZ_ENABLE_GTK']: + have_progressui = 1 + srcs += [ + 'progressui_gtk.cpp', + ] + +if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': + have_progressui = 1 + srcs += [ + 'launchchild_osx.mm', + 'progressui_osx.mm', + ] + OS_LIBS += [ + '-framework Cocoa', + '-framework Security', + ] +elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': + have_progressui = 1 + srcs += [ + 'automounter_gonk.cpp', + 'progressui_gonk.cpp', + ] + DISABLE_STL_WRAPPING = True + OS_LIBS += [ + 'cutils', + 'sysutils', + ] + +if have_progressui == 0: + srcs += [ + 'progressui_null.cpp', + ] + +SOURCES += ['%s%s' % (updater_rel_path, f) for f in sorted(srcs)] + +DEFINES['NS_NO_XPCOM'] = True +DISABLE_STL_WRAPPING = True +for var in ('MAR_CHANNEL_ID', 'MOZ_APP_VERSION'): + DEFINES[var] = '"%s"' % CONFIG[var] + +LOCAL_INCLUDES += [ + '/toolkit/mozapps/update/common', + '/xpcom/glue', +] + +DELAYLOAD_DLLS += [ + 'crypt32.dll', + 'comctl32.dll', + 'userenv.dll', + 'wsock32.dll', +] + +if CONFIG['_MSC_VER']: + WIN32_EXE_LDFLAGS += ['-ENTRY:wmainCRTStartup'] +elif CONFIG['OS_ARCH'] == 'WINNT': + WIN32_EXE_LDFLAGS += ['-municode'] + +if CONFIG['MOZ_WIDGET_GTK']: + CXXFLAGS += CONFIG['TK_CFLAGS'] + OS_LIBS += CONFIG['TK_LIBS'] diff --git a/toolkit/mozapps/update/updater/updater-xpcshell/Makefile.in b/toolkit/mozapps/update/updater/updater-xpcshell/Makefile.in new file mode 100644 index 0000000000..4631874dcb --- /dev/null +++ b/toolkit/mozapps/update/updater/updater-xpcshell/Makefile.in @@ -0,0 +1,40 @@ +# vim:set ts=8 sw=8 sts=8 noet: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# For changes here, also consider ../Makefile.in + +XPCSHELLTESTROOT = $(abspath $(DEPTH))/_tests/xpcshell/toolkit/mozapps/update/tests +MOCHITESTROOT = $(abspath $(DEPTH))/_tests/testing/mochitest/chrome/toolkit/mozapps/update/tests + +include $(topsrcdir)/config/rules.mk + +ifndef MOZ_WINCONSOLE +ifdef MOZ_DEBUG +MOZ_WINCONSOLE = 1 +else +MOZ_WINCONSOLE = 0 +endif +endif + +libs:: +ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) + # Copy for xpcshell tests + $(NSINSTALL) -D $(XPCSHELLTESTROOT)/data/updater-xpcshell.app + rsync -a -C --exclude '*.in' $(srcdir)/../macbuild/Contents $(XPCSHELLTESTROOT)/data/updater-xpcshell.app + sed -e 's/%APP_NAME%/$(MOZ_APP_DISPLAYNAME)/' $(srcdir)/../macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | \ + iconv -f UTF-8 -t UTF-16 > $(XPCSHELLTESTROOT)/data/updater-xpcshell.app/Contents/Resources/English.lproj/InfoPlist.strings + $(NSINSTALL) -D $(XPCSHELLTESTROOT)/data/updater-xpcshell.app/Contents/MacOS/updater-xpcshell + $(NSINSTALL) $(PROGRAM) $(XPCSHELLTESTROOT)/data/updater-xpcshell.app/Contents/MacOS + rm -f $(PROGRAM) + rm -Rf $(XPCSHELLTESTROOT)/data/updater.app + mv $(XPCSHELLTESTROOT)/data/updater-xpcshell.app $(XPCSHELLTESTROOT)/data/updater.app + mv $(XPCSHELLTESTROOT)/data/updater.app/Contents/MacOS/updater-xpcshell $(XPCSHELLTESTROOT)/data/updater.app/Contents/MacOS/updater + + # Copy for mochitest chrome tests + rsync -a -C $(XPCSHELLTESTROOT)/data/updater.app $(MOCHITESTROOT)/data/updater.app +else + cp $(PROGRAM) $(XPCSHELLTESTROOT)/data/updater$(BIN_SUFFIX) + cp $(PROGRAM) $(MOCHITESTROOT)/data/updater$(BIN_SUFFIX) +endif diff --git a/toolkit/mozapps/update/updater/updater-xpcshell/moz.build b/toolkit/mozapps/update/updater/updater-xpcshell/moz.build new file mode 100644 index 0000000000..8ff85dfd49 --- /dev/null +++ b/toolkit/mozapps/update/updater/updater-xpcshell/moz.build @@ -0,0 +1,14 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +Program('updater-xpcshell') + +updater_rel_path = '../' +DIST_INSTALL = False +DEFINES['TEST_UPDATER'] = True +include('../updater-common.build') + +CXXFLAGS += CONFIG['MOZ_BZ2_CFLAGS'] diff --git a/toolkit/mozapps/update/updater/updater.cpp b/toolkit/mozapps/update/updater/updater.cpp index 155896d83e..0d8a4a94a5 100644 --- a/toolkit/mozapps/update/updater/updater.cpp +++ b/toolkit/mozapps/update/updater/updater.cpp @@ -2342,7 +2342,12 @@ UpdateThreadFunc(void *param) NS_tchar updateSettingsPath[MAX_TEXT_LEN]; NS_tsnprintf(updateSettingsPath, sizeof(updateSettingsPath) / sizeof(updateSettingsPath[0]), - NS_T("%s/update-settings.ini"), gWorkingDirPath); +#ifdef XP_MACOSX + NS_T("%s/Contents/Resources/update-settings.ini"), +#else + NS_T("%s/update-settings.ini"), +#endif + gWorkingDirPath); MARChannelStringTable MARStrings; if (ReadMARChannelIDs(updateSettingsPath, &MARStrings) != OK) { // If we can't read from update-settings.ini then we shouldn't impose @@ -2357,7 +2362,18 @@ UpdateThreadFunc(void *param) #endif if (rv == OK && sStagedUpdate && !sIsOSUpdate) { +#ifdef TEST_UPDATER + // The MOZ_TEST_SKIP_UPDATE_STAGE environment variable prevents copying + // the files in dist/bin in the test updater when staging an update since + // this can cause tests to timeout. + if (getenv("MOZ_TEST_SKIP_UPDATE_STAGE")) { + rv = OK; + } else { + rv = CopyInstallDirToDestDir(); + } +#else rv = CopyInstallDirToDestDir(); +#endif } if (rv == OK) { diff --git a/toolkit/mozapps/update/updater/updater.rc b/toolkit/mozapps/update/updater/updater.rc index ceddf51e55..7603eecb64 100644 --- a/toolkit/mozapps/update/updater/updater.rc +++ b/toolkit/mozapps/update/updater/updater.rc @@ -4,7 +4,17 @@ // Microsoft Visual C++ generated resource script. // +#ifdef TEST_UPDATER +#include "../resource.h" +#define MANIFEST_PATH "../updater.exe.manifest" +#define COMCTL32_MANIFEST_PATH "../updater.exe.comctl32.manifest" +#define ICON_PATH "../updater.ico" +#else #include "resource.h" +#define MANIFEST_PATH "updater.exe.manifest" +#define COMCTL32_MANIFEST_PATH "updater.exe.comctl32.manifest" +#define ICON_PATH "updater.ico" +#endif #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// @@ -30,15 +40,15 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // RT_MANIFEST // -1 RT_MANIFEST "updater.exe.manifest" -IDR_COMCTL32_MANIFEST RT_MANIFEST "updater.exe.comctl32.manifest" +1 RT_MANIFEST MANIFEST_PATH +IDR_COMCTL32_MANIFEST RT_MANIFEST COMCTL32_MANIFEST_PATH ///////////////////////////////////////////////////////////////////////////// // // Icon // -IDI_DIALOG ICON "updater.ico" +IDI_DIALOG ICON ICON_PATH ///////////////////////////////////////////////////////////////////////////// diff --git a/widget/EventMessageList.h b/widget/EventMessageList.h index 5496fdb5de..7a19ddeb68 100644 --- a/widget/EventMessageList.h +++ b/widget/EventMessageList.h @@ -58,22 +58,23 @@ NS_EVENT_MESSAGE(eMouseActivate, eMouseEventFirst + 30) NS_EVENT_MESSAGE(eMouseOver, eMouseEventFirst + 31) NS_EVENT_MESSAGE(eMouseOut, eMouseEventFirst + 32) NS_EVENT_MESSAGE(eMouseHitTest, eMouseEventFirst + 33) -NS_EVENT_MESSAGE(NS_MOUSEENTER, eMouseEventFirst + 34) -NS_EVENT_MESSAGE(NS_MOUSELEAVE, eMouseEventFirst + 35) -NS_EVENT_MESSAGE(NS_MOUSE_MOZLONGTAP, eMouseEventFirst + 36) +NS_EVENT_MESSAGE(eMouseEnter, eMouseEventFirst + 34) +NS_EVENT_MESSAGE(eMouseLeave, eMouseEventFirst + 35) +NS_EVENT_MESSAGE(eMouseLongTap, eMouseEventFirst + 36) // Pointer spec events -NS_EVENT_MESSAGE(NS_POINTER_EVENT_START, 4400) -NS_EVENT_MESSAGE(NS_POINTER_MOVE, NS_POINTER_EVENT_START) -NS_EVENT_MESSAGE(NS_POINTER_UP, NS_POINTER_EVENT_START + 1) -NS_EVENT_MESSAGE(NS_POINTER_DOWN, NS_POINTER_EVENT_START + 2) -NS_EVENT_MESSAGE(NS_POINTER_OVER, NS_POINTER_EVENT_START + 22) -NS_EVENT_MESSAGE(NS_POINTER_OUT, NS_POINTER_EVENT_START + 23) -NS_EVENT_MESSAGE(NS_POINTER_ENTER, NS_POINTER_EVENT_START + 24) -NS_EVENT_MESSAGE(NS_POINTER_LEAVE, NS_POINTER_EVENT_START + 25) -NS_EVENT_MESSAGE(NS_POINTER_CANCEL, NS_POINTER_EVENT_START + 26) -NS_EVENT_MESSAGE(NS_POINTER_GOT_CAPTURE, NS_POINTER_EVENT_START + 27) -NS_EVENT_MESSAGE(NS_POINTER_LOST_CAPTURE, NS_POINTER_EVENT_START + 28) +NS_EVENT_MESSAGE(ePointerEventFirst, 4400) +NS_EVENT_MESSAGE(NS_POINTER_MOVE, ePointerEventFirst) +NS_EVENT_MESSAGE(NS_POINTER_UP, ePointerEventFirst + 1) +NS_EVENT_MESSAGE(NS_POINTER_DOWN, ePointerEventFirst + 2) +NS_EVENT_MESSAGE(NS_POINTER_OVER, ePointerEventFirst + 22) +NS_EVENT_MESSAGE(NS_POINTER_OUT, ePointerEventFirst + 23) +NS_EVENT_MESSAGE(NS_POINTER_ENTER, ePointerEventFirst + 24) +NS_EVENT_MESSAGE(ePointerLeave, ePointerEventFirst + 25) +NS_EVENT_MESSAGE(ePointerCancel, ePointerEventFirst + 26) +NS_EVENT_MESSAGE(ePointerGotCapture, ePointerEventFirst + 27) +NS_EVENT_MESSAGE(ePointerLostCapture, ePointerEventFirst + 28) +NS_EVENT_MESSAGE(ePointerEventLast, ePointerLostCapture) NS_EVENT_MESSAGE(NS_CONTEXTMENU_MESSAGE_START, 500) NS_EVENT_MESSAGE(NS_CONTEXTMENU, NS_CONTEXTMENU_MESSAGE_START) diff --git a/widget/MouseEvents.h b/widget/MouseEvents.h index b8c6c7a15f..0186f1c6ea 100644 --- a/widget/MouseEvents.h +++ b/widget/MouseEvents.h @@ -204,8 +204,8 @@ protected: , clickCount(0) { switch (aMessage) { - case NS_MOUSEENTER: - case NS_MOUSELEAVE: + case eMouseEnter: + case eMouseLeave: mFlags.mBubbles = false; mFlags.mCancelable = false; break; @@ -224,8 +224,8 @@ public: reason(aReason), context(aContext), exit(eChild), clickCount(0) { switch (aMessage) { - case NS_MOUSEENTER: - case NS_MOUSELEAVE: + case eMouseEnter: + case eMouseLeave: mFlags.mBubbles = false; mFlags.mCancelable = false; break; @@ -626,13 +626,13 @@ public: { switch (mMessage) { case NS_POINTER_ENTER: - case NS_POINTER_LEAVE: + case ePointerLeave: mFlags.mBubbles = false; mFlags.mCancelable = false; break; - case NS_POINTER_CANCEL: - case NS_POINTER_GOT_CAPTURE: - case NS_POINTER_LOST_CAPTURE: + case ePointerCancel: + case ePointerGotCapture: + case ePointerLostCapture: mFlags.mCancelable = false; break; default: