Bug 1453979 - use ContiguousEnumSerializerInclusive for serializing enums in a11y IPC code; r?MarcoZ draft
authorAlex Gaynor <agaynor@mozilla.com>
Fri, 13 Apr 2018 10:51:43 -0400
changeset 783183 5e69551b150ac4515825df59b3bdff62cebd78ce
parent 782895 6276ec7ebbf33e3484997b189f20fc1511534187
push id106637
push userbmo:agaynor@mozilla.com
push dateMon, 16 Apr 2018 19:31:48 +0000
reviewersMarcoZ
bugs1453979
milestone61.0a1
Bug 1453979 - use ContiguousEnumSerializerInclusive for serializing enums in a11y IPC code; r?MarcoZ MozReview-Commit-ID: 92S42SkSEEP
accessible/ipc/DocAccessibleChildBase.cpp
accessible/ipc/DocAccessibleParent.cpp
accessible/ipc/DocAccessibleParent.h
accessible/ipc/IPCTypes.h
accessible/ipc/other/PDocAccessible.ipdl
accessible/ipc/win/DocAccessibleChild.cpp
accessible/ipc/win/DocAccessibleChild.h
accessible/ipc/win/PDocAccessible.ipdl
--- a/accessible/ipc/DocAccessibleChildBase.cpp
+++ b/accessible/ipc/DocAccessibleChildBase.cpp
@@ -52,17 +52,17 @@ DocAccessibleChildBase::InterfacesFor(Ac
 /* static */ void
 DocAccessibleChildBase::SerializeTree(Accessible* aRoot,
                                       nsTArray<AccessibleData>& aTree)
 {
   uint64_t id = reinterpret_cast<uint64_t>(aRoot->UniqueID());
 #if defined(XP_WIN)
   int32_t msaaId = AccessibleWrap::GetChildIDFor(aRoot);
 #endif
-  uint32_t role = aRoot->Role();
+  a11y::role role = aRoot->Role();
   uint32_t childCount = aRoot->ChildCount();
   uint32_t interfaces = InterfacesFor(aRoot);
 
   // OuterDocAccessibles are special because we don't want to serialize the
   // child doc here, we'll call PDocAccessibleConstructor in
   // NotificationController.
   MOZ_ASSERT(!aRoot->IsDoc(), "documents shouldn't be serialized");
   if (aRoot->IsOuterDoc()) {
--- a/accessible/ipc/DocAccessibleParent.cpp
+++ b/accessible/ipc/DocAccessibleParent.cpp
@@ -108,31 +108,24 @@ DocAccessibleParent::AddSubtree(ProxyAcc
                                 uint32_t aIdx, uint32_t aIdxInParent)
 {
   if (aNewTree.Length() <= aIdx) {
     NS_ERROR("bad index in serialized tree!");
     return 0;
   }
 
   const AccessibleData& newChild = aNewTree[aIdx];
-  if (newChild.Role() > roles::LAST_ROLE) {
-    NS_ERROR("invalid role");
-    return 0;
-  }
 
   if (mAccessibles.Contains(newChild.ID())) {
     NS_ERROR("ID already in use");
     return 0;
   }
 
-  auto role = static_cast<a11y::role>(newChild.Role());
-
-  ProxyAccessible* newProxy =
-    new ProxyAccessible(newChild.ID(), aParent, this, role,
-                        newChild.Interfaces());
+  ProxyAccessible* newProxy = new ProxyAccessible(
+    newChild.ID(), aParent, this, newChild.Role(), newChild.Interfaces());
 
   aParent->AddChildAt(aIdxInParent, newProxy);
   mAccessibles.PutEntry(newChild.ID())->mProxy = newProxy;
   ProxyCreated(newProxy, newChild.Interfaces());
 
 #if defined(XP_WIN)
   WrapperFor(newProxy)->SetID(newChild.MsaaID());
 #endif
@@ -391,28 +384,24 @@ DocAccessibleParent::RecvSelectionEvent(
   RefPtr<xpcAccEvent> event = new xpcAccEvent(aType, xpcTarget, xpcDoc,
                                               nullptr, false);
   nsCoreUtils::DispatchAccEvent(Move(event));
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-DocAccessibleParent::RecvRoleChangedEvent(const uint32_t& aRole)
+DocAccessibleParent::RecvRoleChangedEvent(const a11y::role& aRole)
 {
   if (mShutdown) {
     return IPC_OK();
   }
 
- if (aRole > roles::LAST_ROLE) {
-   return IPC_FAIL(this, "Child sent bad role in RoleChangedEvent");
- }
-
- mRole = static_cast<a11y::role>(aRole);
- return IPC_OK();
+  mRole = aRole;
+  return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 DocAccessibleParent::RecvBindChildDoc(PDocAccessibleParent* aChildDoc, const uint64_t& aID)
 {
   // One document should never directly be the child of another.
   // We should always have at least an outer doc accessible in between.
   MOZ_ASSERT(aID);
--- a/accessible/ipc/DocAccessibleParent.h
+++ b/accessible/ipc/DocAccessibleParent.h
@@ -101,17 +101,17 @@ public:
   virtual mozilla::ipc::IPCResult RecvFocusEvent(const uint64_t& aID,
                                                  const LayoutDeviceIntRect& aCaretRect) override;
 #endif // defined(XP_WIN)
 
   virtual mozilla::ipc::IPCResult RecvSelectionEvent(const uint64_t& aID,
                                                      const uint64_t& aWidgetID,
                                                      const uint32_t& aType) override;
 
-  mozilla::ipc::IPCResult RecvRoleChangedEvent(const uint32_t& aRole) final;
+  mozilla::ipc::IPCResult RecvRoleChangedEvent(const a11y::role& aRole) final;
 
   virtual mozilla::ipc::IPCResult RecvBindChildDoc(PDocAccessibleParent* aChildDoc, const uint64_t& aID) override;
 
   void Unbind()
   {
     if (DocAccessibleParent* parent = ParentDoc()) {
       parent->RemoveChildDoc(this);
     }
--- a/accessible/ipc/IPCTypes.h
+++ b/accessible/ipc/IPCTypes.h
@@ -2,16 +2,29 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=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/. */
 
 #ifndef mozilla_a11y_IPCTypes_h
 #define mozilla_a11y_IPCTypes_h
 
+#include "mozilla/a11y/Role.h"
+
+namespace IPC {
+
+template<>
+struct ParamTraits<mozilla::a11y::role>
+  : public ContiguousEnumSerializerInclusive<mozilla::a11y::role,
+                                             mozilla::a11y::role::NOTHING,
+                                             mozilla::a11y::role::LAST_ROLE>
+{
+};
+};
+
 /**
  * Since IPDL does not support preprocessing, this header file allows us to
  * define types used by PDocAccessible differently depending on platform.
  */
 
 #if defined(XP_WIN) && defined(ACCESSIBILITY)
 
 // So that we don't include a bunch of other Windows junk.
--- a/accessible/ipc/other/PDocAccessible.ipdl
+++ b/accessible/ipc/other/PDocAccessible.ipdl
@@ -5,26 +5,27 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include protocol PFileDescriptorSet;
 include protocol PBrowser;
 
 include "mozilla/GfxMessageUtils.h";
 
 using nsIntRect from "nsRect.h";
+using mozilla::a11y::role from "mozilla/a11y/Role.h";
 using mozilla::gfx::IntSize from "mozilla/gfx/Point.h";
 using mozilla::gfx::IntPoint from "mozilla/gfx/Point.h";
 
 namespace mozilla {
 namespace a11y {
 
 struct AccessibleData
 {
   uint64_t ID;
-  uint32_t Role;
+  role Role;
   uint32_t ChildrenCount;
   uint32_t Interfaces;
 };
 
 struct ShowEventData
 {
   uint64_t ID;
   uint32_t Idx;
@@ -58,17 +59,17 @@ parent:
   async Event(uint64_t aID, uint32_t type);
   async ShowEvent(ShowEventData data, bool aFromuser);
   async HideEvent(uint64_t aRootID, bool aFromUser);
   async StateChangeEvent(uint64_t aID, uint64_t aState, bool aEnabled);
   async CaretMoveEvent(uint64_t aID, int32_t aOffset);
   async TextChangeEvent(uint64_t aID, nsString aStr, int32_t aStart, uint32_t aLen,
                         bool aIsInsert, bool aFromUser);
   async SelectionEvent(uint64_t aID, uint64_t aWidgetID, uint32_t aType);
-  async RoleChangedEvent(uint32_t aRole);
+  async RoleChangedEvent(role aRole);
 
   /*
    * Tell the parent document to bind the existing document as a new child
    * document.
    */
   async BindChildDoc(PDocAccessible aChildDoc, uint64_t aID);
 
 child:
@@ -88,17 +89,17 @@ child:
   nested(inside_sync) sync Help(uint64_t aID) returns(nsString help);
   nested(inside_sync) sync Description(uint64_t aID) returns(nsString desc);
   nested(inside_sync) sync Attributes(uint64_t aID) returns(Attribute[] attributes);
   nested(inside_sync) sync RelationByType(uint64_t aID, uint32_t aRelationType)
     returns(uint64_t[] targets);
   nested(inside_sync) sync Relations(uint64_t aID) returns(RelationTargets[] relations);
   nested(inside_sync) sync IsSearchbox(uint64_t aID) returns(bool retval);
   nested(inside_sync) sync LandmarkRole(uint64_t aID) returns(nsString landmark);
-  nested(inside_sync) sync ARIARoleAtom(uint64_t aID) returns(nsString role);
+  nested(inside_sync) sync ARIARoleAtom(uint64_t aID) returns(nsString ariaRole);
   nested(inside_sync) sync GetLevelInternal(uint64_t aID) returns(int32_t aLevel);
   async ScrollTo(uint64_t aID, uint32_t aScrollType);
   async ScrollToPoint(uint64_t aID, uint32_t aScrollType, int32_t aX,
                       int32_t aY);
 
   // AccessibleText
 
   // TextSubstring is getText in IDL.
--- a/accessible/ipc/win/DocAccessibleChild.cpp
+++ b/accessible/ipc/win/DocAccessibleChild.cpp
@@ -258,17 +258,17 @@ DocAccessibleChild::SendSelectionEvent(c
 
   PushDeferredEvent(MakeUnique<SerializedSelection>(this, aID,
                                                                 aWidgetID,
                                                                 aType));
   return true;
 }
 
 bool
-DocAccessibleChild::SendRoleChangedEvent(const uint32_t& aRole)
+DocAccessibleChild::SendRoleChangedEvent(const a11y::role& aRole)
 {
   if (IsConstructedInParentProcess()) {
     return PDocAccessibleChild::SendRoleChangedEvent(aRole);
   }
 
   PushDeferredEvent(MakeUnique<SerializedRoleChanged>(this, aRole));
   return true;
 }
--- a/accessible/ipc/win/DocAccessibleChild.h
+++ b/accessible/ipc/win/DocAccessibleChild.h
@@ -52,17 +52,17 @@ public:
   bool SendFocusEvent(const uint64_t& aID,
                       const LayoutDeviceIntRect& aCaretRect);
   bool SendTextChangeEvent(const uint64_t& aID, const nsString& aStr,
                            const int32_t& aStart, const uint32_t& aLen,
                            const bool& aIsInsert, const bool& aFromUser,
                            const bool aDoSyncCheck = true);
   bool SendSelectionEvent(const uint64_t& aID, const uint64_t& aWidgetID,
                           const uint32_t& aType);
-  bool SendRoleChangedEvent(const uint32_t& aRole);
+  bool SendRoleChangedEvent(const a11y::role& aRole);
 
   bool ConstructChildDocInParentProcess(DocAccessibleChild* aNewChildDoc,
                                         uint64_t aUniqueID, uint32_t aMsaaID);
 
   bool SendBindChildDoc(DocAccessibleChild* aChildDoc,
                         const uint64_t& aNewParentID);
 
 protected:
@@ -251,27 +251,27 @@ private:
 
     uint64_t  mID;
     uint64_t  mWidgetID;
     uint32_t  mType;
   };
 
   struct SerializedRoleChanged final : public DeferredEvent
   {
-    explicit SerializedRoleChanged(DocAccessibleChild* aTarget, uint32_t aRole)
+    explicit SerializedRoleChanged(DocAccessibleChild* aTarget, a11y::role aRole)
       : DeferredEvent(aTarget)
       , mRole(aRole)
     {}
 
     void Dispatch(DocAccessibleChild* aIPCDoc) override
     {
       Unused << aIPCDoc->SendRoleChangedEvent(mRole);
     }
 
-    uint32_t mRole;
+    a11y::role mRole;
   };
 
   struct SerializedEvent final : public DeferredEvent
   {
     SerializedEvent(DocAccessibleChild* aTarget, uint64_t aID, uint32_t aType)
       : DeferredEvent(aTarget)
       , mID(aID)
       , mType(aType)
--- a/accessible/ipc/win/PDocAccessible.ipdl
+++ b/accessible/ipc/win/PDocAccessible.ipdl
@@ -2,29 +2,30 @@
 /* vim: set ts=2 et sw=2 tw=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/. */
 
 include protocol PFileDescriptorSet;
 include protocol PBrowser;
 
+using mozilla::a11y::role from "mozilla/a11y/Role.h";
 using mozilla::a11y::IAccessibleHolder from "mozilla/a11y/IPCTypes.h";
 using mozilla::a11y::IDispatchHolder from "mozilla/a11y/IPCTypes.h";
 using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h";
 using mozilla::LayoutDeviceIntRect from "Units.h";
 
 namespace mozilla {
 namespace a11y {
 
 struct AccessibleData
 {
   uint64_t ID;
   int32_t MsaaID;
-  uint32_t Role;
+  role Role;
   uint32_t ChildrenCount;
   uint32_t Interfaces;
 };
 
 struct ShowEventData
 {
   uint64_t ID;
   uint32_t Idx;
@@ -55,17 +56,17 @@ parent:
   async StateChangeEvent(uint64_t aID, uint64_t aState, bool aEnabled);
   async CaretMoveEvent(uint64_t aID, LayoutDeviceIntRect aCaretRect,
                        int32_t aOffset);
   async TextChangeEvent(uint64_t aID, nsString aStr, int32_t aStart, uint32_t aLen,
                         bool aIsInsert, bool aFromUser);
   sync SyncTextChangeEvent(uint64_t aID, nsString aStr, int32_t aStart,
                            uint32_t aLen, bool aIsInsert, bool aFromUser);
   async SelectionEvent(uint64_t aID, uint64_t aWidgetID, uint32_t aType);
-  async RoleChangedEvent(uint32_t aRole);
+  async RoleChangedEvent(role aRole);
   async FocusEvent(uint64_t aID, LayoutDeviceIntRect aCaretRect);
 
   /*
    * Tell the parent document to bind the existing document as a new child
    * document.
    */
   async BindChildDoc(PDocAccessible aChildDoc, uint64_t aID);