summaryrefslogtreecommitdiff
path: root/dali
diff options
context:
space:
mode:
authorBowon Ryu <bowon.ryu@samsung.com>2024-06-11 01:21:45 +0000
committerGerrit Code Review <gerrit@review>2024-06-11 01:21:45 +0000
commit4d862848b094ca088c6c89e32d6747d0a933ae21 (patch)
tree41039ad92d4a736dce99532492f3f9ee8da97302 /dali
parentf73721bd2e951ccf02eb35acbc500ab54d01882f (diff)
parent5d222bd5fb39c6afabba14be32486df95e90e3f5 (diff)
downloaddali-adaptor-4d862848b094ca088c6c89e32d6747d0a933ae21.tar.gz
dali-adaptor-4d862848b094ca088c6c89e32d6747d0a933ae21.tar.bz2
dali-adaptor-4d862848b094ca088c6c89e32d6747d0a933ae21.zip
Merge "Implement multi-type copy support for the clipboard" into devel/master
Diffstat (limited to 'dali')
-rw-r--r--dali/internal/clipboard/common/clipboard-impl.h6
-rw-r--r--dali/internal/clipboard/generic/clipboard-impl-generic.cpp5
-rw-r--r--dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp264
-rw-r--r--dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp104
4 files changed, 308 insertions, 71 deletions
diff --git a/dali/internal/clipboard/common/clipboard-impl.h b/dali/internal/clipboard/common/clipboard-impl.h
index cf508ea36..a7a2eea1a 100644
--- a/dali/internal/clipboard/common/clipboard-impl.h
+++ b/dali/internal/clipboard/common/clipboard-impl.h
@@ -119,6 +119,12 @@ public:
*/
bool OnReceiveData();
+ /**
+ * This is called after a timeout when no new data set.
+ * @return will return false; one-shot timer.
+ */
+ bool OnMultiSelectionTimeout();
+
private:
// Undefined
Clipboard(const Clipboard&);
diff --git a/dali/internal/clipboard/generic/clipboard-impl-generic.cpp b/dali/internal/clipboard/generic/clipboard-impl-generic.cpp
index ce788bd87..b5732405c 100644
--- a/dali/internal/clipboard/generic/clipboard-impl-generic.cpp
+++ b/dali/internal/clipboard/generic/clipboard-impl-generic.cpp
@@ -135,6 +135,11 @@ bool Clipboard::OnReceiveData()
return false;
}
+bool Clipboard::OnMultiSelectionTimeout()
+{
+ return false;
+}
+
} // namespace Adaptor
} // namespace Internal
diff --git a/dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp b/dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp
index 0dc294958..19b1163da 100644
--- a/dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp
+++ b/dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp
@@ -19,11 +19,13 @@
#include <dali/internal/clipboard/common/clipboard-impl.h>
// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/environment-variable.h>
#include <dali/devel-api/common/singleton-service.h>
#include <dali/internal/adaptor/tizen-wayland/dali-ecore-wl2.h>
#include <dali/integration-api/debug.h>
+#include <dali/public-api/adaptor-framework/timer.h>
+#include <map>
#include <unistd.h>
-#include <unordered_map>
namespace Dali
{
@@ -31,6 +33,12 @@ namespace Internal
{
namespace Adaptor
{
+namespace
+{
+const char* DALI_CLIPBOARD_MULTI_SELECTION_TIMEOUT("DALI_CLIPBOARD_MULTI_SELECTION_TIMEOUT");
+const uint32_t DEFAULT_MULTI_SELECTION_TIMEOUT = 500u;
+}
+
static Eina_Bool EcoreEventDataSend(void* data, int type, void* event);
static Eina_Bool EcoreEventOfferDataReady(void* data, int type, void* event);
static Eina_Bool EcoreEventSelectionOffer(void* data, int type, void* event);
@@ -78,23 +86,78 @@ struct Clipboard::Impl
bool SetData(const Dali::Clipboard::ClipData& clipData)
{
- mMimeType = clipData.GetMimeType();
- mData = clipData.GetData();
+ std::string mimeType = clipData.GetMimeType();
+ std::string data = clipData.GetData();
- if(mData.empty())
+ if(data.empty())
{
DALI_LOG_ERROR("ClipData is empty, return false.\n");
return false;
}
const char* mimeTypes[2];
- mimeTypes[0] = mMimeType.c_str();
+ mimeTypes[0] = mimeType.c_str();
mimeTypes[1] = nullptr;
+ mSetDatas[mimeType] = data;
+
Ecore_Wl2_Display* display = ecore_wl2_connected_display_get(NULL);
Ecore_Wl2_Input* input = ecore_wl2_input_default_input_get(display);
- mSerial = ecore_wl2_dnd_selection_set(input, mimeTypes);
- DALI_LOG_RELEASE_INFO("selection_set success, serial:%u, type:%s, data:%s\n", mSerial, mMimeType.c_str(), mData.c_str());
+
+ uint32_t serial = ecore_wl2_dnd_selection_set(input, mimeTypes);
+ DALI_LOG_RELEASE_INFO("selection_set success, serial:%u, type:%s, data:%s\n", serial, mimeType.c_str(), data.c_str());
+
+ // If the serial is the same, it is the same source.
+ // If the type is the same, it is a separate copy.
+ if(mSerial == serial && mLastType != mimeType && !mMultiSelectionTimeout)
+ {
+ // Checks whether there is an identical type requested from one source.
+ bool typeExists = false;
+ for (const auto& type : mSetTypes)
+ {
+ if (type == mimeType)
+ {
+ typeExists = true;
+ break;
+ }
+ }
+
+ if(!typeExists) // Same copy.
+ {
+ // It requests all types of copies requested from one source at once.
+ // EcoreEventDataSend callback is called as many as the number of requested types.
+ mSetTypes.push_back(mimeType);
+
+ size_t typeCount = mSetTypes.size();
+ const char* types[typeCount + 1];
+ for(size_t i = 0; i < typeCount; i++)
+ {
+ types[i] = mSetTypes[i].c_str();
+ DALI_LOG_RELEASE_INFO("selection_set multi types, serial:%u, type:%s\n", serial, types[i]);
+ }
+ types[typeCount] = nullptr;
+
+ // TODO : At this point, it is impossible to avoid duplicate calls,
+ // because we cannot know how many more times the copy will be called for the same source.
+ serial = ecore_wl2_dnd_selection_set(input, types);
+ }
+ else // Separate copy.
+ {
+ mSetTypes.clear();
+ mSetTypes.push_back(mimeType);
+ }
+ }
+ else
+ {
+ mSetTypes.clear();
+ mSetTypes.push_back(mimeType);
+ }
+
+ // Store the last serial and type.
+ mSerial = serial;
+ mLastType = mimeType;
+
+ SetMultiSelectionTimeout();
return true;
}
@@ -115,6 +178,7 @@ struct Clipboard::Impl
if(!offer)
{
DALI_LOG_ERROR("selection_get fail, request type:%s\n", mimeType.c_str());
+ mLastOffer = nullptr;
return 0u;
}
@@ -142,13 +206,33 @@ struct Clipboard::Impl
return 0u;
}
+ uint32_t lastDataId = mDataId;
mDataId++;
mDataRequestIds.push_back(mDataId);
mDataRequestItems[mDataId] = std::make_pair(mimeType, offer);
- DALI_LOG_RELEASE_INFO("offer_receive, id:%u, request type:%s\n", mDataId, mimeType.c_str());
- ecore_wl2_offer_receive(offer, const_cast<char*>(type));
- ecore_wl2_display_flush(ecore_wl2_input_display_get(input));
+ // Not yet received a callback for the recent offer receive.
+ if(mLastOffer == offer && mDataRequestItems.count(lastDataId))
+ {
+ // A receive request for the same offer and type is made only once.
+ if(std::find(mGetTypes.begin(), mGetTypes.end(), mimeType) == mGetTypes.end())
+ {
+ mGetTypes.push_back(mimeType);
+ mReservedOfferReceives[lastDataId] = mDataId;
+ } // else do nothing.
+ }
+ else
+ {
+ mGetTypes.clear();
+ mGetTypes.push_back(mimeType);
+
+ DALI_LOG_RELEASE_INFO("offer_receive, id:%u, request type:%s\n", mDataId, mimeType.c_str());
+ ecore_wl2_offer_receive(offer, const_cast<char*>(type));
+ ecore_wl2_display_flush(ecore_wl2_input_display_get(input));
+ }
+
+ mLastOffer = offer;
+
return mDataId;
}
@@ -158,37 +242,20 @@ struct Clipboard::Impl
if(ev->serial != mSerial)
{
+ DALI_LOG_ERROR("ev->serial:%u, mSerial:%u, type:%s\n", ev->serial, mSerial, ev->type);
return;
}
- // no matching mime type.
- if(mMimeType.compare(ev->type))
+ // Check whether the hash has data of the requested type.
+ // If there is no data of the requested type, something has already gone wrong.
+ std::string type = ev->type;
+ std::string data = "";
+ if(mSetDatas.count(type))
{
- auto it = mDataRequestIds.begin();
- while(it != mDataRequestIds.end())
- {
- uint32_t dataRequestId = *it;
- auto item = mDataRequestItems.find(dataRequestId);
- if(item != mDataRequestItems.end())
- {
- std::string mimeType = static_cast<std::string>(item->second.first);
- if(!mimeType.compare(ev->type))
- {
- mDataRequestItems.erase(dataRequestId);
- it = mDataRequestIds.erase(it);
- DALI_LOG_ERROR("no matching type, empty signal emit, request type:%s, available type:%s\n", ev->type, mMimeType.c_str());
- mDataReceivedSignal.Emit(dataRequestId, "", "");
- }
- else
- {
- ++it;
- }
- }
- }
- return;
+ data = mSetDatas[type];
}
- size_t dataLength = strlen(mData.c_str());
+ size_t dataLength = strlen(data.c_str());
size_t bufferSize = dataLength + 1u;
char* buffer = new char[bufferSize];
@@ -197,7 +264,7 @@ struct Clipboard::Impl
return;
}
- memcpy(buffer, mData.c_str(), dataLength);
+ memcpy(buffer, data.c_str(), dataLength);
buffer[dataLength] = '\0';
auto ret = write(ev->fd, buffer, bufferSize);
@@ -209,8 +276,8 @@ struct Clipboard::Impl
close(ev->fd);
delete[] buffer;
- DALI_LOG_RELEASE_INFO("send data, type:%s, data:%s \n", mMimeType.c_str(), mData.c_str());
- mDataSentSignal.Emit(ev->type, mData.c_str());
+ DALI_LOG_RELEASE_INFO("send data, type:%s, data:%s \n", ev->type, data.c_str());
+ mDataSentSignal.Emit(ev->type, data.c_str());
}
void ReceiveData(void* event)
@@ -244,27 +311,72 @@ struct Clipboard::Impl
DALI_LOG_RELEASE_INFO("receive data, type:%s, data:%s\n", ev->mimetype, content.c_str());
- auto it = mDataRequestIds.begin();
- while(it != mDataRequestIds.end())
+ // Retrieve request id list.
+ for(auto it = mDataRequestIds.begin(); it != mDataRequestIds.end();)
{
uint32_t dataRequestId = *it;
- auto item = mDataRequestItems.find(dataRequestId);
- if(item != mDataRequestItems.end())
+ if(mDataRequestItems.count(dataRequestId))
{
- Ecore_Wl2_Offer* offer = static_cast<Ecore_Wl2_Offer*>(item->second.second);
- if(offer == ev->offer)
+ auto item = mDataRequestItems[dataRequestId];
+ std::string mimeType = static_cast<std::string>(item.first);
+ Ecore_Wl2_Offer* offer = static_cast<Ecore_Wl2_Offer*>(item.second);
+
+ // Processes all the same types stored in the request list.
+ if(!mimeType.compare(ev->mimetype))
{
- std::string mimeType = static_cast<std::string>(item->second.first);
mDataRequestItems.erase(dataRequestId);
it = mDataRequestIds.erase(it);
- DALI_LOG_RELEASE_INFO("receive data, success signal emit, id:%u, type:%s\n", dataRequestId, mimeType.c_str());
- mDataReceivedSignal.Emit(dataRequestId, mimeType.c_str(), content.c_str());
+
+ // A change in an offer means a change in the clipboard's data.
+ // Old offers are not always invalid, but at least in Dali it is unknown whether they are valid or not.
+ // For safe processing, old offers are considered invalid offers.
+ if(offer && offer == ev->offer && mLastOffer == offer)
+ {
+ DALI_LOG_RELEASE_INFO("receive data, success signal emit, id:%u, type:%s\n", dataRequestId, mimeType.c_str());
+ mDataReceivedSignal.Emit(dataRequestId, mimeType.c_str(), content.c_str());
+
+ if(mReservedOfferReceives.count(dataRequestId))
+ {
+ uint32_t reservedId = mReservedOfferReceives[dataRequestId];
+ if(mDataRequestItems.count(reservedId))
+ {
+ auto reservedItem = mDataRequestItems[reservedId];
+ std::string reservedType = static_cast<std::string>(reservedItem.first);
+ Ecore_Wl2_Offer* reservedOffer = static_cast<Ecore_Wl2_Offer*>(reservedItem.second);
+
+ if(reservedOffer)
+ {
+ Ecore_Wl2_Display* display = ecore_wl2_connected_display_get(NULL);
+ Ecore_Wl2_Input* input = ecore_wl2_input_default_input_get(display);
+
+ DALI_LOG_RELEASE_INFO("offer_receive, id:%u, request type:%s\n", reservedId, reservedType.c_str());
+ ecore_wl2_offer_receive(reservedOffer, const_cast<char*>(reservedType.c_str()));
+ ecore_wl2_display_flush(ecore_wl2_input_display_get(input));
+ }
+ }
+ mReservedOfferReceives.erase(dataRequestId);
+ }
+ }
+ else // null or invalid offer.
+ {
+ DALI_LOG_RELEASE_INFO("invalid offer, id:%u, request type:%s\n", dataRequestId, mimeType.c_str());
+ mDataReceivedSignal.Emit(dataRequestId, "", "");
+
+ if(mReservedOfferReceives.count(dataRequestId))
+ {
+ mReservedOfferReceives.erase(dataRequestId);
+ }
+ }
}
- else
+ else // item's type and event data's type are different.
{
++it;
}
}
+ else // There is no id in request items.
+ {
+ it = mDataRequestIds.erase(it);
+ }
}
}
@@ -295,16 +407,15 @@ struct Clipboard::Impl
for(int i = 0; i < ev->num_types; i++)
{
- DALI_LOG_RELEASE_INFO("mime type(%s)", ev->types[i]);
if(!formatMarkup.compare(ev->types[i]))
{
+ // Ignore elementary markup from efl.
continue;
}
- if(!selectedType)
- {
- selectedType = ev->types[i];
- }
+ selectedType = ev->types[i];
+ DALI_LOG_RELEASE_INFO("data selected signal emit, type:%s\n", selectedType);
+ mDataSelectedSignal.Emit(selectedType);
}
if(!selectedType)
@@ -312,14 +423,29 @@ struct Clipboard::Impl
DALI_LOG_ERROR("mime type is invalid.\n");
return;
}
+ }
+
+ void SetMultiSelectionTimeout()
+ {
+ mMultiSelectionTimeout = false;
+ if(mMultiSelectionTimeoutTimer.IsRunning())
+ {
+ mMultiSelectionTimeoutTimer.Stop();
+ }
+ mMultiSelectionTimeoutTimer.Start();
+ }
- DALI_LOG_RELEASE_INFO("data selected signal emit, type:%s\n", selectedType);
- mDataSelectedSignal.Emit(selectedType);
+ bool OnMultiSelectionTimeout()
+ {
+ DALI_LOG_RELEASE_INFO("multi-selection end\n");
+ mMultiSelectionTimeout = true;
+ return false;
}
- uint32_t mSerial{std::numeric_limits<uint32_t>::max()};
- std::string mMimeType;
- std::string mData;
+ uint32_t mSerial{std::numeric_limits<uint32_t>::max()};
+ std::string mLastType; // mime type used in last copy.
+ Ecore_Wl2_Offer* mLastOffer; // offer used in last paste.
+
Ecore_Event_Handler* mSendHandler{nullptr};
Ecore_Event_Handler* mReceiveHandler{nullptr};
Ecore_Event_Handler* mSelectionHanlder{nullptr};
@@ -330,7 +456,15 @@ struct Clipboard::Impl
uint32_t mDataId{0};
std::vector<uint32_t> mDataRequestIds;
- std::unordered_map<uint32_t, std::pair<std::string, Ecore_Wl2_Offer*>> mDataRequestItems;
+ std::map<uint32_t, std::pair<std::string, Ecore_Wl2_Offer*>> mDataRequestItems;
+
+ std::vector<std::string> mSetTypes; // types for the same source (one user copy).
+ std::map<std::string, std::string> mSetDatas; // datas for the same source (one user copy), key is mime type, value is data.
+ std::vector<std::string> mGetTypes; // types requested to receive for the same offer.
+ std::map<uint32_t, uint32_t> mReservedOfferReceives; // in order to process offer receive sequentially, key is current id, value is reserved id.
+
+ Dali::Timer mMultiSelectionTimeoutTimer;
+ bool mMultiSelectionTimeout{false};
};
static Eina_Bool EcoreEventDataSend(void* data, int type, void* event)
@@ -360,6 +494,13 @@ static Eina_Bool EcoreEventSelectionOffer(void* data, int type, void* event)
Clipboard::Clipboard(Impl* impl)
: mImpl(impl)
{
+ // Check environment variable for DALI_CLIPBOARD_MULTI_SELECTION_TIMEOUT
+ auto timeoutString = Dali::EnvironmentVariable::GetEnvironmentVariable(DALI_CLIPBOARD_MULTI_SELECTION_TIMEOUT);
+ uint32_t multiSelectionTimeout = timeoutString ? static_cast<uint32_t>(std::atoi(timeoutString)) : DEFAULT_MULTI_SELECTION_TIMEOUT;
+
+ DALI_LOG_RELEASE_INFO("multi-selection timeout set:%u\n", multiSelectionTimeout);
+ mImpl->mMultiSelectionTimeoutTimer = Dali::Timer::New(multiSelectionTimeout);
+ mImpl->mMultiSelectionTimeoutTimer.TickSignal().Connect(this, &Clipboard::OnMultiSelectionTimeout);
}
Clipboard::~Clipboard()
@@ -460,6 +601,11 @@ bool Clipboard::OnReceiveData()
return false;
}
+bool Clipboard::OnMultiSelectionTimeout()
+{
+ return mImpl->OnMultiSelectionTimeout();
+}
+
} // namespace Adaptor
} // namespace Internal
diff --git a/dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp b/dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp
index 9c15021c3..4780e04a1 100644
--- a/dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp
+++ b/dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp
@@ -29,6 +29,8 @@
#include <dali/devel-api/common/singleton-service.h>
#include <dali/internal/adaptor/common/adaptor-impl.h>
#include <dali/internal/window-system/ubuntu-x11/window-interface-ecore-x.h>
+#include <map>
+#include <queue>
namespace Dali
{
@@ -45,30 +47,64 @@ struct Clipboard::Impl
bool HasType(const std::string& mimeType)
{
- return mMimeType == mimeType ? true : false;
+ for(const auto& type : mMimeTypes)
+ {
+ if (type == mimeType)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void UpdateData(std::string& mimeType, std::string& data, bool clearBuffer)
+ {
+ if(clearBuffer)
+ {
+ mMimeTypes.clear();
+ mDatas.clear();
+ }
+ mMimeTypes.push_back(mimeType);
+ mDatas[mimeType] = data;
}
bool SetData(const Dali::Clipboard::ClipData& clipData)
{
- mMimeType = clipData.GetMimeType();
- mData = clipData.GetData();
+ std::string mimeType = clipData.GetMimeType();
+ std::string data = clipData.GetData();
- if(mData.empty())
+ if(mimeType.empty() || data.empty())
{
return false;
}
- mDataSentSignal.Emit(mMimeType.c_str(), mData.c_str());
- mDataSelectedSignal.Emit(mMimeType.c_str());
+ if(mLastType != mimeType && !mMultiSelectionTimeout)
+ {
+ bool clearBuffer = HasType(mimeType);
+ UpdateData(mimeType, data, clearBuffer);
+ }
+ else
+ {
+ UpdateData(mimeType, data, true);
+ }
+
+ mLastType = mimeType;
+
+ mDataSentSignal.Emit(mimeType.c_str(), data.c_str());
+ mDataSelectedSignal.Emit(mimeType.c_str());
+
+ SetMultiSelectionTimeout();
return true;
}
uint32_t GetData(const std::string &mimeType)
{
- if(!mMimeType.compare(mimeType.c_str()))
+ if(mDatas.count(mimeType))
{
mDataId++;
+ mDataReceiveQueue.push(std::make_pair(mDataId, mimeType));
+
// For consistency of operation with tizen Wl2, a fake callback is occurs using a timer.
if(mDataReceiveTimer.IsRunning())
{
@@ -83,28 +119,67 @@ struct Clipboard::Impl
bool OnReceiveData()
{
- DALI_LOG_RELEASE_INFO("receive data, success signal emit, id:%u, type:%s, data:%s\n", mDataId, mMimeType.c_str(), mData.c_str());
- mDataReceivedSignal.Emit(mDataId, mMimeType.c_str(), mData.c_str());
+ while(!mDataReceiveQueue.empty())
+ {
+ auto item = mDataReceiveQueue.front();
+ mDataReceiveQueue.pop();
+
+ uint32_t requestId = item.first;
+ std::string requestType = item.second;
+ std::string data = "";
+
+ if(mDatas.count(requestType))
+ {
+ data = mDatas[requestType];
+ }
+
+ DALI_LOG_RELEASE_INFO("receive data, success signal emit, id:%u, type:%s, data:%s\n", requestId, requestType.c_str(), data.c_str());
+ mDataReceivedSignal.Emit(requestId, requestType.c_str(), data.c_str());
+ }
+ return false;
+ }
+
+ void SetMultiSelectionTimeout()
+ {
+ mMultiSelectionTimeout = false;
+ if(mMultiSelectionTimeoutTimer.IsRunning())
+ {
+ mMultiSelectionTimeoutTimer.Stop();
+ }
+ mMultiSelectionTimeoutTimer.Start();
+ }
+
+ bool OnMultiSelectionTimeout()
+ {
+ mMultiSelectionTimeout = true;
return false;
}
Ecore_X_Window mApplicationWindow;
- std::string mMimeType;
- std::string mData;
uint32_t mDataId{0};
+ std::string mLastType;
+
+ std::vector<std::string> mMimeTypes;
+ std::map<std::string, std::string> mDatas; // type, data
+ std::queue<std::pair<uint32_t, std::string>> mDataReceiveQueue; // id, type
Dali::Clipboard::DataSentSignalType mDataSentSignal;
Dali::Clipboard::DataReceivedSignalType mDataReceivedSignal;
Dali::Clipboard::DataSelectedSignalType mDataSelectedSignal;
Dali::Timer mDataReceiveTimer;
+ Dali::Timer mMultiSelectionTimeoutTimer;
+ bool mMultiSelectionTimeout{false};
};
Clipboard::Clipboard(Impl* impl)
: mImpl(impl)
{
- mImpl->mDataReceiveTimer = Dali::Timer::New(10);
+ mImpl->mDataReceiveTimer = Dali::Timer::New(10u);
mImpl->mDataReceiveTimer.TickSignal().Connect(this, &Clipboard::OnReceiveData);
+
+ mImpl->mMultiSelectionTimeoutTimer = Dali::Timer::New(500u);
+ mImpl->mMultiSelectionTimeoutTimer.TickSignal().Connect(this, &Clipboard::OnMultiSelectionTimeout);
}
Clipboard::~Clipboard()
@@ -217,6 +292,11 @@ bool Clipboard::OnReceiveData()
return mImpl->OnReceiveData();
}
+bool Clipboard::OnMultiSelectionTimeout()
+{
+ return mImpl->OnMultiSelectionTimeout();
+}
+
} // namespace Adaptor
} // namespace Internal