Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix handler unregistration in C++ channels (#16794)
MethodChannel and BasicMessageChannel in the C++ wrapper didn't have the expected semantics that passing a null handler would remove any existing handler. This was inconsistent with other platforms and with the lower-level object APIs in this wrapper, and made unregistration in cases where that's desirable more difficult due to needing to keep other object references. Adds tests for this functionality, and some backfill of missing tests for basic handler behavior. See #51207
- Loading branch information
1 parent
d590e98
commit 52070e3
Showing
7 changed files
with
247 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
shell/platform/common/cpp/client_wrapper/basic_message_channel_unittests.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/basic_message_channel.h" | ||
|
||
#include <memory> | ||
#include <string> | ||
|
||
#include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/binary_messenger.h" | ||
#include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/standard_message_codec.h" | ||
#include "gtest/gtest.h" | ||
|
||
namespace flutter { | ||
|
||
namespace { | ||
|
||
class TestBinaryMessenger : public BinaryMessenger { | ||
public: | ||
void Send(const std::string& channel, | ||
const uint8_t* message, | ||
const size_t message_size) const override {} | ||
|
||
void Send(const std::string& channel, | ||
const uint8_t* message, | ||
const size_t message_size, | ||
BinaryReply reply) const override {} | ||
|
||
void SetMessageHandler(const std::string& channel, | ||
BinaryMessageHandler handler) override { | ||
last_message_handler_channel_ = channel; | ||
last_message_handler_ = handler; | ||
} | ||
|
||
std::string last_message_handler_channel() { | ||
return last_message_handler_channel_; | ||
} | ||
|
||
BinaryMessageHandler last_message_handler() { return last_message_handler_; } | ||
|
||
private: | ||
std::string last_message_handler_channel_; | ||
BinaryMessageHandler last_message_handler_; | ||
}; | ||
|
||
} // namespace | ||
|
||
// Tests that SetMessageHandler sets a handler that correctly interacts with | ||
// the binary messenger. | ||
TEST(BasicMessageChannelTest, Registration) { | ||
TestBinaryMessenger messenger; | ||
const std::string channel_name("some_channel"); | ||
const StandardMessageCodec& codec = StandardMessageCodec::GetInstance(); | ||
BasicMessageChannel channel(&messenger, channel_name, &codec); | ||
|
||
bool callback_called = false; | ||
const std::string message_value("hello"); | ||
channel.SetMessageHandler( | ||
[&callback_called, message_value](const auto& message, auto reply) { | ||
callback_called = true; | ||
// Ensure that the wrapper recieved a correctly decoded message and a | ||
// reply. | ||
EXPECT_EQ(message.StringValue(), message_value); | ||
EXPECT_NE(reply, nullptr); | ||
}); | ||
EXPECT_EQ(messenger.last_message_handler_channel(), channel_name); | ||
EXPECT_NE(messenger.last_message_handler(), nullptr); | ||
// Send a test message to trigger the handler test assertions. | ||
auto message = codec.EncodeMessage(EncodableValue(message_value)); | ||
|
||
messenger.last_message_handler()( | ||
message->data(), message->size(), | ||
[](const uint8_t* reply, const size_t reply_size) {}); | ||
EXPECT_EQ(callback_called, true); | ||
} | ||
|
||
// Tests that SetMessageHandler with a null handler unregisters the handler. | ||
TEST(BasicMessageChannelTest, Unregistration) { | ||
TestBinaryMessenger messenger; | ||
const std::string channel_name("some_channel"); | ||
BasicMessageChannel channel(&messenger, channel_name, | ||
&flutter::StandardMessageCodec::GetInstance()); | ||
|
||
channel.SetMessageHandler([](const auto& message, auto reply) {}); | ||
EXPECT_EQ(messenger.last_message_handler_channel(), channel_name); | ||
EXPECT_NE(messenger.last_message_handler(), nullptr); | ||
|
||
channel.SetMessageHandler(nullptr); | ||
EXPECT_EQ(messenger.last_message_handler_channel(), channel_name); | ||
EXPECT_EQ(messenger.last_message_handler(), nullptr); | ||
} | ||
|
||
} // namespace flutter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 94 additions & 0 deletions
94
shell/platform/common/cpp/client_wrapper/method_channel_unittests.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/method_channel.h" | ||
|
||
#include <memory> | ||
#include <string> | ||
|
||
#include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/binary_messenger.h" | ||
#include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/standard_method_codec.h" | ||
#include "gtest/gtest.h" | ||
|
||
namespace flutter { | ||
|
||
namespace { | ||
|
||
class TestBinaryMessenger : public BinaryMessenger { | ||
public: | ||
void Send(const std::string& channel, | ||
const uint8_t* message, | ||
const size_t message_size) const override {} | ||
|
||
void Send(const std::string& channel, | ||
const uint8_t* message, | ||
const size_t message_size, | ||
BinaryReply reply) const override {} | ||
|
||
void SetMessageHandler(const std::string& channel, | ||
BinaryMessageHandler handler) override { | ||
last_message_handler_channel_ = channel; | ||
last_message_handler_ = handler; | ||
} | ||
|
||
std::string last_message_handler_channel() { | ||
return last_message_handler_channel_; | ||
} | ||
|
||
BinaryMessageHandler last_message_handler() { return last_message_handler_; } | ||
|
||
private: | ||
std::string last_message_handler_channel_; | ||
BinaryMessageHandler last_message_handler_; | ||
}; | ||
|
||
} // namespace | ||
|
||
// Tests that SetMethodCallHandler sets a handler that correctly interacts with | ||
// the binary messenger. | ||
TEST(MethodChannelTest, Registration) { | ||
TestBinaryMessenger messenger; | ||
const std::string channel_name("some_channel"); | ||
const StandardMethodCodec& codec = StandardMethodCodec::GetInstance(); | ||
MethodChannel channel(&messenger, channel_name, &codec); | ||
|
||
bool callback_called = false; | ||
const std::string method_name("hello"); | ||
channel.SetMethodCallHandler( | ||
[&callback_called, method_name](const auto& call, auto result) { | ||
callback_called = true; | ||
// Ensure that the wrapper recieved a correctly decoded call and a | ||
// result. | ||
EXPECT_EQ(call.method_name(), method_name); | ||
EXPECT_NE(result, nullptr); | ||
}); | ||
EXPECT_EQ(messenger.last_message_handler_channel(), channel_name); | ||
EXPECT_NE(messenger.last_message_handler(), nullptr); | ||
// Send a test message to trigger the handler test assertions. | ||
MethodCall<EncodableValue> call(method_name, nullptr); | ||
auto message = codec.EncodeMethodCall(call); | ||
|
||
messenger.last_message_handler()( | ||
message->data(), message->size(), | ||
[](const uint8_t* reply, const size_t reply_size) {}); | ||
EXPECT_EQ(callback_called, true); | ||
} | ||
|
||
// Tests that SetMethodCallHandler with a null handler unregisters the handler. | ||
TEST(MethodChannelTest, Unregistration) { | ||
TestBinaryMessenger messenger; | ||
const std::string channel_name("some_channel"); | ||
MethodChannel channel(&messenger, channel_name, | ||
&flutter::StandardMethodCodec::GetInstance()); | ||
|
||
channel.SetMethodCallHandler([](const auto& call, auto result) {}); | ||
EXPECT_EQ(messenger.last_message_handler_channel(), channel_name); | ||
EXPECT_NE(messenger.last_message_handler(), nullptr); | ||
|
||
channel.SetMethodCallHandler(nullptr); | ||
EXPECT_EQ(messenger.last_message_handler_channel(), channel_name); | ||
EXPECT_EQ(messenger.last_message_handler(), nullptr); | ||
} | ||
|
||
} // namespace flutter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters