Bug 1147168 - IPC Proxy for Selection, r=tbsaunde
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Wed, 25 Mar 2015 16:19:12 +0200
changeset 266128 cff4597a0bf83e7581cefa39178c028f434766b3
parent 266127 d92c07d1e6df5d28ef1668a2612ea2fc4d8d37f7
child 266129 106f8198c67e5ae377a082924bfbc76aeed382ca
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstbsaunde
bugs1147168
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1147168 - IPC Proxy for Selection, r=tbsaunde
accessible/atk/nsMaiInterfaceSelection.cpp
accessible/ipc/DocAccessibleChild.cpp
accessible/ipc/DocAccessibleChild.h
accessible/ipc/PDocAccessible.ipdl
accessible/ipc/ProxyAccessible.cpp
accessible/ipc/ProxyAccessible.h
--- a/accessible/atk/nsMaiInterfaceSelection.cpp
+++ b/accessible/atk/nsMaiInterfaceSelection.cpp
@@ -4,100 +4,139 @@
  * 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 "InterfaceInitFuncs.h"
 
 #include "Accessible-inl.h"
 #include "AccessibleWrap.h"
 #include "nsMai.h"
+#include "ProxyAccessible.h"
 #include "mozilla/Likely.h"
 
 #include <atk/atk.h>
 
 using namespace mozilla::a11y;
 
 extern "C" {
 
 static gboolean
 addSelectionCB(AtkSelection *aSelection, gint i)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
-  if (!accWrap || !accWrap->IsSelect())
-    return FALSE;
+  if (accWrap && accWrap->IsSelect()) {
+    return accWrap->AddItemToSelection(i);
+  }
 
-  return accWrap->AddItemToSelection(i);
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aSelection))) {
+    return proxy->AddItemToSelection(i);
+  }
+
+  return FALSE;
 }
 
 static gboolean
 clearSelectionCB(AtkSelection *aSelection)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
-  if (!accWrap || !accWrap->IsSelect())
-    return FALSE;
+  if (accWrap && accWrap->IsSelect()) {
+    return accWrap->UnselectAll();
+  }
 
-  return accWrap->UnselectAll();
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aSelection))) {
+    return proxy->UnselectAll();
+  }
+
+  return FALSE;
 }
 
 static AtkObject*
 refSelectionCB(AtkSelection *aSelection, gint i)
 {
+  AtkObject* atkObj = nullptr;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
-  if (!accWrap || !accWrap->IsSelect())
-    return nullptr;
+  if (accWrap && accWrap->IsSelect()) {
+    Accessible* selectedItem = accWrap->GetSelectedItem(i);
+    if (!selectedItem) {
+      return nullptr;
+    }
 
-  Accessible* selectedItem = accWrap->GetSelectedItem(i);
-  if (!selectedItem)
-    return nullptr;
+    atkObj = AccessibleWrap::GetAtkObject(selectedItem);
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aSelection))) {
+    ProxyAccessible* selectedItem = proxy->GetSelectedItem(i);
+    if (selectedItem) {
+      atkObj = GetWrapperFor(selectedItem);
+    }
+  }
 
-  AtkObject* atkObj = AccessibleWrap::GetAtkObject(selectedItem);
-  if (atkObj)
+  if (atkObj) {
     g_object_ref(atkObj);
+  }
 
   return atkObj;
 }
 
 static gint
 getSelectionCountCB(AtkSelection *aSelection)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
-  if (!accWrap || !accWrap->IsSelect())
-    return -1;
+  if (accWrap && accWrap->IsSelect()) {
+    return accWrap->SelectedItemCount();
+  }
 
-  return accWrap->SelectedItemCount();
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aSelection))) {
+    return proxy->SelectedItemCount();
+  }
+
+  return -1;
 }
 
 static gboolean
 isChildSelectedCB(AtkSelection *aSelection, gint i)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
-  if (!accWrap || !accWrap->IsSelect())
-    return FALSE;
+  if (accWrap && accWrap->IsSelect()) {
+    return accWrap->IsItemSelected(i);
+  }
 
-  return accWrap->IsItemSelected(i);
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aSelection))) {
+    return proxy->IsItemSelected(i);
+  }
+
+  return FALSE;
 }
 
 static gboolean
 removeSelectionCB(AtkSelection *aSelection, gint i)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
-  if (!accWrap || !accWrap->IsSelect())
-    return FALSE;
+  if (accWrap && accWrap->IsSelect()) {
+    return accWrap->RemoveItemFromSelection(i);
+  }
 
-  return accWrap->RemoveItemFromSelection(i);
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aSelection))) {
+    return proxy->RemoveItemFromSelection(i);
+  }
+
+  return FALSE;
 }
 
 static gboolean
 selectAllSelectionCB(AtkSelection *aSelection)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
-  if (!accWrap || !accWrap->IsSelect())
-    return FALSE;
+  if (accWrap && accWrap->IsSelect()) {
+    return accWrap->SelectAll();
+  }
 
-  return accWrap->SelectAll();
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aSelection))) {
+    return proxy->SelectAll();
+  }
+
+  return FALSE;
 }
 }
 
 void
 selectionInterfaceInitCB(AtkSelectionIface* aIface)
 {
   NS_ASSERTION(aIface, "Invalid aIface");
   if (MOZ_UNLIKELY(!aIface))
--- a/accessible/ipc/DocAccessibleChild.cpp
+++ b/accessible/ipc/DocAccessibleChild.cpp
@@ -56,16 +56,23 @@ DocAccessibleChild::IdToAccessible(const
 
 Accessible*
 DocAccessibleChild::IdToAccessibleLink(const uint64_t& aID) const
 {
   Accessible* acc = IdToAccessible(aID);
   return acc && acc->IsLink() ? acc : nullptr;
 }
 
+Accessible*
+DocAccessibleChild::IdToAccessibleSelect(const uint64_t& aID) const
+{
+  Accessible* acc = IdToAccessible(aID);
+  return acc && acc->IsSelect() ? acc : nullptr;
+}
+
 HyperTextAccessible*
 DocAccessibleChild::IdToHyperTextAccessible(const uint64_t& aID) const
 {
   Accessible* acc = IdToAccessible(aID);
   return acc && acc->IsHyperText() ? acc->AsHyperText() : nullptr;
 }
 
 ImageAccessible*
@@ -1299,10 +1306,129 @@ DocAccessibleChild::RecvTableIsProbablyF
   TableAccessible* acc = IdToTableAccessible(aID);
   if (acc) {
     *aForLayout = acc->IsProbablyLayoutTable();
   }
 
   return true;
 }
 
+bool
+DocAccessibleChild::RecvSelectedItems(const uint64_t& aID,
+                                      nsTArray<uint64_t>* aSelectedItemIDs)
+{
+  Accessible* acc = IdToAccessibleSelect(aID);
+  if (acc) {
+    nsAutoTArray<Accessible*, 10> selectedItems;
+    acc->SelectedItems(&selectedItems);
+    aSelectedItemIDs->SetCapacity(selectedItems.Length());
+    for (size_t i = 0; i < selectedItems.Length(); ++i) {
+      aSelectedItemIDs->AppendElement(
+        reinterpret_cast<uint64_t>(selectedItems[i]->UniqueID()));
+    }
+  }
+
+  return true;
+}
+
+bool
+DocAccessibleChild::RecvSelectedItemCount(const uint64_t& aID,
+                                          uint32_t* aCount)
+{
+  *aCount = 0;
+  Accessible* acc = IdToAccessibleSelect(aID);
+  if (acc) {
+    *aCount = acc->SelectedItemCount();
+  }
+
+  return true;
+}
+
+bool
+DocAccessibleChild::RecvGetSelectedItem(const uint64_t& aID,
+                                        const uint32_t& aIndex,
+                                        uint64_t* aSelected,
+                                        bool* aOk)
+{
+  *aSelected = 0;
+  *aOk = false;
+  Accessible* acc = IdToAccessibleSelect(aID);
+  if (acc) {
+    Accessible* item = acc->GetSelectedItem(aIndex);
+    if (item) {
+      *aSelected = reinterpret_cast<uint64_t>(item->UniqueID());
+      *aOk = true;
+    }
+  }
+
+  return true;
+}
+
+bool
+DocAccessibleChild::RecvIsItemSelected(const uint64_t& aID,
+                                       const uint32_t& aIndex,
+                                       bool* aSelected)
+{
+  *aSelected = false;
+  Accessible* acc = IdToAccessibleSelect(aID);
+  if (acc) {
+    *aSelected = acc->IsItemSelected(aIndex);
+  }
+
+  return true;
+}
+
+bool
+DocAccessibleChild::RecvAddItemToSelection(const uint64_t& aID,
+                                           const uint32_t& aIndex,
+                                           bool* aSuccess)
+{
+  *aSuccess = false;
+  Accessible* acc = IdToAccessibleSelect(aID);
+  if (acc) {
+    *aSuccess = acc->AddItemToSelection(aIndex);
+  }
+
+  return true;
+}
+
+bool
+DocAccessibleChild::RecvRemoveItemFromSelection(const uint64_t& aID,
+                                                const uint32_t& aIndex,
+                                                bool* aSuccess)
+{
+  *aSuccess = false;
+  Accessible* acc = IdToAccessibleSelect(aID);
+  if (acc) {
+    *aSuccess = acc->RemoveItemFromSelection(aIndex);
+  }
+
+  return true;
+}
+
+bool
+DocAccessibleChild::RecvSelectAll(const uint64_t& aID,
+                                  bool* aSuccess)
+{
+  *aSuccess = false;
+  Accessible* acc = IdToAccessibleSelect(aID);
+  if (acc) {
+    *aSuccess = acc->SelectAll();
+  }
+
+  return true;
+}
+
+bool
+DocAccessibleChild::RecvUnselectAll(const uint64_t& aID,
+                                    bool* aSuccess)
+{
+  *aSuccess = false;
+  Accessible* acc = IdToAccessibleSelect(aID);
+  if (acc) {
+    *aSuccess = acc->UnselectAll();
+  }
+
+  return true;
+}
+
 }
 }
--- a/accessible/ipc/DocAccessibleChild.h
+++ b/accessible/ipc/DocAccessibleChild.h
@@ -317,20 +317,50 @@ public:
   virtual bool RecvTableSelectRow(const uint64_t& aID,
                                   const uint32_t& aRow) override;
   virtual bool RecvTableUnselectColumn(const uint64_t& aID,
                                        const uint32_t& aCol) override;
   virtual bool RecvTableUnselectRow(const uint64_t& aID,
                                     const uint32_t& aRow) override;
   virtual bool RecvTableIsProbablyForLayout(const uint64_t& aID,
                                             bool* aForLayout) override;
+
+  virtual bool RecvSelectedItems(const uint64_t& aID,
+                                 nsTArray<uint64_t>* aSelectedItemIDs) override;
+
+  virtual bool RecvSelectedItemCount(const uint64_t& aID,
+                                     uint32_t* aCount) override;
+
+  virtual bool RecvGetSelectedItem(const uint64_t& aID,
+                                   const uint32_t& aIndex,
+                                   uint64_t* aSelected,
+                                   bool* aOk) override;
+
+  virtual bool RecvIsItemSelected(const uint64_t& aID,
+                                  const uint32_t& aIndex,
+                                  bool* aSelected) override;
+
+  virtual bool RecvAddItemToSelection(const uint64_t& aID,
+                                      const uint32_t& aIndex,
+                                      bool* aSuccess) override;
+
+  virtual bool RecvRemoveItemFromSelection(const uint64_t& aID,
+                                           const uint32_t& aIndex,
+                                           bool* aSuccess) override;
+
+  virtual bool RecvSelectAll(const uint64_t& aID,
+                             bool* aSuccess) override;
+
+  virtual bool RecvUnselectAll(const uint64_t& aID,
+                               bool* aSuccess) override;
 private:
 
   Accessible* IdToAccessible(const uint64_t& aID) const;
   Accessible* IdToAccessibleLink(const uint64_t& aID) const;
+  Accessible* IdToAccessibleSelect(const uint64_t& aID) const;
   HyperTextAccessible* IdToHyperTextAccessible(const uint64_t& aID) const;
   ImageAccessible* IdToImageAccessible(const uint64_t& aID) const;
   TableCellAccessible* IdToTableCellAccessible(const uint64_t& aID) const;
   TableAccessible* IdToTableAccessible(const uint64_t& aID) const;
 
   bool PersistentPropertiesToArray(nsIPersistentProperties* aProps,
                                    nsTArray<Attribute>* aAttributes);
 
--- a/accessible/ipc/PDocAccessible.ipdl
+++ b/accessible/ipc/PDocAccessible.ipdl
@@ -177,12 +177,22 @@ child:
   prio(high) sync TableSelectedCellIndices(uint64_t aID) returns(uint32_t[] aCellIndeces);
   prio(high) sync TableSelectedColumnIndices(uint64_t aID) returns(uint32_t[] aColumnIndeces);
   prio(high) sync TableSelectedRowIndices(uint64_t aID) returns(uint32_t[] aRowIndeces);
   prio(high) sync TableSelectColumn(uint64_t aID, uint32_t aCol);
   prio(high) sync TableSelectRow(uint64_t aID, uint32_t aRow);
   prio(high) sync TableUnselectColumn(uint64_t aID, uint32_t aCol);
   prio(high) sync TableUnselectRow(uint64_t aID, uint32_t aRow);
   prio(high) sync TableIsProbablyForLayout(uint64_t aID) returns(bool aForLayout);
+
+  prio(high) sync SelectedItems(uint64_t aID) returns(uint64_t[] aSelectedItemIDs);
+  prio(high) sync SelectedItemCount(uint64_t aID) returns(uint32_t aCount);
+  prio(high) sync GetSelectedItem(uint64_t aID, uint32_t aIndex) returns(uint64_t aSelected, bool aOk);
+  prio(high) sync IsItemSelected(uint64_t aID, uint32_t aIndex) returns(bool aSelected);
+  prio(high) sync AddItemToSelection(uint64_t aID, uint32_t aIndex) returns(bool aSuccess);
+  prio(high) sync RemoveItemFromSelection(uint64_t aID, uint32_t aIndex) returns(bool aSuccess);
+  prio(high) sync SelectAll(uint64_t aID) returns(bool aSuccess);
+  prio(high) sync UnselectAll(uint64_t aID) returns(bool aSuccess);
+  
 };
 
 }
 }
--- a/accessible/ipc/ProxyAccessible.cpp
+++ b/accessible/ipc/ProxyAccessible.cpp
@@ -726,10 +726,78 @@ ProxyAccessible::TableUnselectRow(uint32
 bool
 ProxyAccessible::TableIsProbablyForLayout()
 {
   bool forLayout = false;
   unused << mDoc->SendTableIsProbablyForLayout(mID, &forLayout);
   return forLayout;
 }
 
+void
+ProxyAccessible::SelectedItems(nsTArray<ProxyAccessible*>* aSelectedItems)
+{
+  nsAutoTArray<uint64_t, 10> itemIDs;
+  unused << mDoc->SendSelectedItems(mID, &itemIDs);
+  aSelectedItems->SetCapacity(itemIDs.Length());
+  for (size_t i = 0; i < itemIDs.Length(); ++i) {
+    aSelectedItems->AppendElement(mDoc->GetAccessible(itemIDs[i]));
+  }
+}
+
+uint32_t
+ProxyAccessible::SelectedItemCount()
+{
+  uint32_t count = 0;
+  unused << mDoc->SendSelectedItemCount(mID, &count);
+  return count;
+}
+
+ProxyAccessible*
+ProxyAccessible::GetSelectedItem(uint32_t aIndex)
+{
+  uint64_t selectedItemID = 0;
+  bool ok = false;
+  unused << mDoc->SendGetSelectedItem(mID, aIndex, &selectedItemID, &ok);
+  return ok ? mDoc->GetAccessible(selectedItemID) : nullptr;
+}
+
+bool
+ProxyAccessible::IsItemSelected(uint32_t aIndex)
+{
+  bool selected = false;
+  unused << mDoc->SendIsItemSelected(mID, aIndex, &selected);
+  return selected;
+}
+ 
+bool
+ProxyAccessible::AddItemToSelection(uint32_t aIndex)
+{
+  bool success = false;
+  unused << mDoc->SendAddItemToSelection(mID, aIndex, &success);
+  return success;
+}
+
+bool
+ProxyAccessible::RemoveItemFromSelection(uint32_t aIndex)
+{
+  bool success = false;
+  unused << mDoc->SendRemoveItemFromSelection(mID, aIndex, &success);
+  return success;
+}
+
+bool
+ProxyAccessible::SelectAll()
+{
+  bool success = false;
+  unused << mDoc->SendSelectAll(mID, &success);
+  return success;
+}
+
+bool
+ProxyAccessible::UnselectAll()
+{
+  bool success = false;
+  unused << mDoc->SendUnselectAll(mID, &success);
+  return success;
+}
+
 }
 }
--- a/accessible/ipc/ProxyAccessible.h
+++ b/accessible/ipc/ProxyAccessible.h
@@ -242,16 +242,25 @@ public:
   void TableSelectedColumnIndices(nsTArray<uint32_t>* aColumnIndices);
   void TableSelectedRowIndices(nsTArray<uint32_t>* aRowIndices);
   void TableSelectColumn(uint32_t aCol);
   void TableSelectRow(uint32_t aRow);
   void TableUnselectColumn(uint32_t aCol);
   void TableUnselectRow(uint32_t aRow);
   bool TableIsProbablyForLayout();
 
+  void SelectedItems(nsTArray<ProxyAccessible*>* aSelectedItems);
+  uint32_t SelectedItemCount();
+  ProxyAccessible* GetSelectedItem(uint32_t aIndex);
+  bool IsItemSelected(uint32_t aIndex);
+  bool AddItemToSelection(uint32_t aIndex);
+  bool RemoveItemFromSelection(uint32_t aIndex);
+  bool SelectAll();
+  bool UnselectAll();
+
   /**
    * Allow the platform to store a pointers worth of data on us.
    */
   uintptr_t GetWrapper() const { return mWrapper; }
   void SetWrapper(uintptr_t aWrapper) { mWrapper = aWrapper; }
 
   /*
    * Return the ID of the accessible being proxied.