Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(uplift to 1.32.x) Signing transactions and messages with Trezor accounts (#10902 #10903) #11035

Merged
merged 2 commits into from
Nov 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion browser/brave_wallet/brave_wallet_tab_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ BraveWalletTabHelper::~BraveWalletTabHelper() {
}

#if !defined(OS_ANDROID) && !defined(OS_IOS)
void BraveWalletTabHelper::ClosePanelOnDeactivate(bool close) {
void BraveWalletTabHelper::SetCloseOnDeactivate(bool close) {
if (wallet_bubble_manager_delegate_)
wallet_bubble_manager_delegate_->CloseOnDeactivate(close);
close_on_deactivate_for_testing_ = close;
Expand Down Expand Up @@ -125,6 +125,10 @@ content::WebContents* BraveWalletTabHelper::GetBubbleWebContentsForTesting() {
return wallet_bubble_manager_delegate_->GetWebContentsForTesting();
}

const std::vector<int32_t>& BraveWalletTabHelper::GetPopupIdsForTesting() {
return wallet_bubble_manager_delegate_->GetPopupIdsForTesting();
}

GURL BraveWalletTabHelper::GetApproveBubbleURL() {
GURL webui_url = GURL(kBraveUIWalletPanelURL);
url::Replacements<char> replacements;
Expand Down
4 changes: 3 additions & 1 deletion browser/brave_wallet/brave_wallet_tab_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <memory>
#include <utility>
#include <vector>

#include "content/public/browser/web_contents_user_data.h"
#include "url/gurl.h"
Expand All @@ -33,9 +34,10 @@ class BraveWalletTabHelper
void ShowApproveWalletBubble();
void CloseBubble();
bool IsShowingBubble();
void ClosePanelOnDeactivate(bool close);
void SetCloseOnDeactivate(bool close);
bool IsBubbleClosedForTesting();
content::WebContents* GetBubbleWebContentsForTesting();
const std::vector<int32_t>& GetPopupIdsForTesting();
void SetShowBubbleCallbackForTesting(base::OnceClosure callback) {
show_bubble_callback_for_testing_ = std::move(callback);
}
Expand Down
128 changes: 128 additions & 0 deletions browser/brave_wallet/brave_wallet_tab_helper_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "base/test/thread_test_helper.h"
#include "brave/browser/brave_wallet/brave_wallet_tab_helper.h"
#include "brave/browser/brave_wallet/rpc_controller_factory.h"
#include "brave/browser/ui/webui/brave_wallet/wallet_common_ui.h"
#include "brave/common/brave_paths.h"
#include "brave/common/webui_url_constants.h"
#include "brave/components/brave_wallet/common/features.h"
Expand All @@ -22,9 +23,11 @@
#include "chrome/test/base/ui_test_utils.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "components/permissions/fake_usb_chooser_controller.h"
#include "components/sessions/content/session_tab_helper.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/web_contents_tester.h"
#include "net/dns/mock_host_resolver.h"

Expand All @@ -39,6 +42,50 @@ base::OnceClosure ShowChooserBubble(
std::move(controller));
}

void ExecuteScriptToOpenPopup(content::WebContents* web_contents,
const GURL& url) {
content::TestNavigationObserver popup_waiter(nullptr, 1);
popup_waiter.StartWatchingNewWebContents();
bool result = false;
CHECK(content::ExecuteScriptAndExtractBool(
web_contents,
content::JsReplace(
"window.domAutomationController.send(!!window.open($1));", url),
&result));
ASSERT_TRUE(result);
popup_waiter.Wait();
}

int32_t OpenNonPanelPopup(const GURL& url,
Browser* browser,
content::WebContents* web_contents) {
EXPECT_EQ(1, browser->tab_strip_model()->count());
content::TestNavigationObserver popup_waiter(nullptr, 1);
popup_waiter.StartWatchingNewWebContents();
ExecuteScriptToOpenPopup(web_contents, url);
popup_waiter.Wait();
EXPECT_EQ(2, browser->tab_strip_model()->count());
content::WebContents* popup =
browser->tab_strip_model()->GetActiveWebContents();
auto popup_id = sessions::SessionTabHelper::IdForTab(popup).id();
auto* child_popup = brave_wallet::GetWebContentsFromTabId(nullptr, popup_id);
EXPECT_EQ(child_popup->GetVisibleURL(), url);
return popup_id;
}

int32_t OpenPanelPopup(const GURL& url,
content::WebContents* panel_contents,
brave_wallet::BraveWalletTabHelper* tab_helper) {
auto current_size = tab_helper->GetPopupIdsForTesting().size();
ExecuteScriptToOpenPopup(panel_contents, url);
auto popup_ids = tab_helper->GetPopupIdsForTesting();
EXPECT_EQ(popup_ids.size(), current_size + 1);
auto popup_id = popup_ids.back();
auto* child_popup = brave_wallet::GetWebContentsFromTabId(nullptr, popup_id);
EXPECT_EQ(child_popup->GetVisibleURL(), url);
return popup_id;
}

} // namespace

class BraveWalletTabHelperBrowserTest : public InProcessBrowserTest {
Expand Down Expand Up @@ -126,3 +173,84 @@ IN_PROC_BROWSER_TEST_F(BraveWalletTabHelperBrowserTest,
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(tab_helper->IsShowingBubble());
}

IN_PROC_BROWSER_TEST_F(BraveWalletTabHelperBrowserTest,
ClosePopupsWhenSwitchTabs) {
auto blank_url = https_server()->GetURL("c.com", "/popup.html");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), blank_url));
content::WebContents* active_contents =
browser()->tab_strip_model()->GetActiveWebContents();
WaitForLoadStop(active_contents);
auto non_panel_popup_id =
OpenNonPanelPopup(blank_url, browser(), active_contents);
browser()->tab_strip_model()->ActivateTabAt(0);
auto* tab_helper =
brave_wallet::BraveWalletTabHelper::FromWebContents(active_contents);
ASSERT_TRUE(
brave_wallet::GetWebContentsFromTabId(nullptr, non_panel_popup_id));
tab_helper->ShowApproveWalletBubble();
EXPECT_TRUE(tab_helper->IsShowingBubble());
auto* panel_contents = tab_helper->GetBubbleWebContentsForTesting();
WaitForLoadStop(panel_contents);
tab_helper->SetCloseOnDeactivate(false);
auto popup1_id =
OpenPanelPopup(https_server()->GetURL("a.com", "/popup.html"),
panel_contents, tab_helper);
auto popup2_id =
OpenPanelPopup(https_server()->GetURL("b.com", "/popup.html"),
panel_contents, tab_helper);
EXPECT_TRUE(tab_helper->IsShowingBubble());
chrome::NewTab(browser());
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(tab_helper->IsShowingBubble());
Browser* target_browser = nullptr;
ASSERT_FALSE(
brave_wallet::GetWebContentsFromTabId(&target_browser, popup1_id));
EXPECT_EQ(target_browser, nullptr);
target_browser = nullptr;
ASSERT_FALSE(
brave_wallet::GetWebContentsFromTabId(&target_browser, popup2_id));
EXPECT_EQ(target_browser, nullptr);
EXPECT_EQ(tab_helper->GetPopupIdsForTesting().size(), 0u);
target_browser = nullptr;
ASSERT_TRUE(brave_wallet::GetWebContentsFromTabId(&target_browser,
non_panel_popup_id));
EXPECT_EQ(target_browser, browser());
}

IN_PROC_BROWSER_TEST_F(BraveWalletTabHelperBrowserTest, ClosePopupsWithBubble) {
auto blank_url = https_server()->GetURL("c.com", "/popup.html");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), blank_url));
content::WebContents* active_contents =
browser()->tab_strip_model()->GetActiveWebContents();
WaitForLoadStop(active_contents);
auto non_panel_popup_id =
OpenNonPanelPopup(blank_url, browser(), active_contents);
browser()->tab_strip_model()->ActivateTabAt(0);
auto* tab_helper =
brave_wallet::BraveWalletTabHelper::FromWebContents(active_contents);
Browser* target_browser = nullptr;
ASSERT_TRUE(brave_wallet::GetWebContentsFromTabId(&target_browser,
non_panel_popup_id));
EXPECT_EQ(browser(), target_browser);
tab_helper->ShowApproveWalletBubble();
EXPECT_TRUE(tab_helper->IsShowingBubble());
auto* panel_contents = tab_helper->GetBubbleWebContentsForTesting();
WaitForLoadStop(panel_contents);
tab_helper->SetCloseOnDeactivate(false);
auto popup1_id =
OpenPanelPopup(https_server()->GetURL("a.com", "/popup.html"),
panel_contents, tab_helper);
auto popup2_id =
OpenPanelPopup(https_server()->GetURL("b.com", "/popup.html"),
panel_contents, tab_helper);
EXPECT_TRUE(tab_helper->IsShowingBubble());
tab_helper->CloseBubble();
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(tab_helper->IsShowingBubble());
ASSERT_FALSE(brave_wallet::GetWebContentsFromTabId(nullptr, popup1_id));
ASSERT_FALSE(brave_wallet::GetWebContentsFromTabId(nullptr, popup2_id));
EXPECT_EQ(tab_helper->GetPopupIdsForTesting().size(), 0u);
ASSERT_TRUE(
brave_wallet::GetWebContentsFromTabId(nullptr, non_panel_popup_id));
}
2 changes: 2 additions & 0 deletions browser/ui/brave_wallet/wallet_bubble_manager_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define BRAVE_BROWSER_UI_BRAVE_WALLET_WALLET_BUBBLE_MANAGER_DELEGATE_H_

#include <memory>
#include <vector>

class GURL;

Expand All @@ -33,6 +34,7 @@ class WalletBubbleManagerDelegate {
virtual bool IsShowingBubble() = 0;
virtual bool IsBubbleClosedForTesting() = 0;
virtual content::WebContents* GetWebContentsForTesting() = 0;
virtual const std::vector<int32_t>& GetPopupIdsForTesting() = 0;
virtual void CloseOnDeactivate(bool close) = 0;

protected:
Expand Down
79 changes: 74 additions & 5 deletions browser/ui/wallet_bubble_manager_delegate_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
#include "brave/browser/ui/wallet_bubble_manager_delegate_impl.h"

#include <utility>
#include <vector>

#include "base/callback.h"
#include "brave/browser/ui/views/frame/brave_browser_view.h"
#include "brave/browser/ui/webui/brave_wallet/wallet_common_ui.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
Expand Down Expand Up @@ -35,22 +38,81 @@ template <typename T>
class BraveWebUIBubbleManagerT : public WebUIBubbleManagerT<T> {
public:
BraveWebUIBubbleManagerT(views::View* anchor_view,
Profile* profile,
Browser* browser,
const GURL& webui_url,
int task_manager_string_id,
bool enable_extension_apis = false)
: WebUIBubbleManagerT<T>(anchor_view,
profile,
browser->profile(),
webui_url,
task_manager_string_id,
enable_extension_apis) {}
enable_extension_apis),
browser_(browser) {}
base::WeakPtr<WebUIBubbleDialogView> CreateWebUIBubbleDialog() override {
auto bubble_view = WebUIBubbleManagerT<T>::CreateWebUIBubbleDialog();
bubble_view_ = bubble_view.get();
web_ui_contents_for_testing_ = bubble_view_->web_view()->GetWebContents();
// Checking if we create WalletPanelUI instance of WebUI and
// extracting BubbleContentsWrapper class to pass real browser delegate
// into it to redirect popups to be opened as separate windows.
// Set a callback to be possible to activate/deactivate wallet panel from
// typescript side
auto contents_wrapper = WebUIBubbleManagerT<T>::cached_contents_wrapper();
if (!contents_wrapper || !contents_wrapper->web_contents()) {
return std::move(bubble_view);
}
content::WebUI* const webui = contents_wrapper->web_contents()->GetWebUI();
if (!webui || !webui->GetController()) {
return std::move(bubble_view);
}
WalletPanelUI* wallet_panel =
webui->GetController()->template GetAs<WalletPanelUI>();
if (!wallet_panel || !browser_ || !browser_->GetDelegateWeakPtr()) {
return std::move(bubble_view);
}
// Set Browser delegate to redirect popups to be opened as Popup window
contents_wrapper->SetWebContentsAddNewContentsDelegate(
browser_->GetDelegateWeakPtr());
// Pass deactivation callback for wallet panel api calls
// The bubble disappears by default when Trezor opens a popup window
// from the wallet panel bubble. In order to prevent it we set a callback
// to modify panel deactivation flag from api calls in SetCloseOnDeactivate
// inside wallet_panel_handler.cc when necessary.
wallet_panel->SetDeactivationCallback(
base::BindRepeating(&BraveWebUIBubbleManagerT<T>::SetCloseOnDeactivate,
weak_factory_.GetWeakPtr()));

return std::move(bubble_view);
}

void CloseOpenedPopups() {
auto contents_wrapper = WebUIBubbleManagerT<T>::cached_contents_wrapper();
if (!contents_wrapper)
return;
for (auto tab_id : contents_wrapper->GetPopupIds()) {
Browser* popup_browser = nullptr;
content::WebContents* popup_contents =
brave_wallet::GetWebContentsFromTabId(&popup_browser, tab_id);
if (!popup_contents || !popup_browser)
continue;
auto delegate = popup_browser->GetDelegateWeakPtr();
if (!delegate)
continue;
delegate->CloseContents(popup_contents);
}
contents_wrapper->GetPopupIds().clear();
}

const std::vector<int32_t>& GetPopupIdsForTesting() {
auto contents_wrapper = WebUIBubbleManagerT<T>::cached_contents_wrapper();
return contents_wrapper->GetPopupIds();
}

void OnWidgetDestroying(views::Widget* widget) override {
CloseOpenedPopups();
WebUIBubbleManagerT<T>::OnWidgetDestroying(widget);
}

void SetCloseOnDeactivate(bool close) {
if (bubble_view_) {
bubble_view_->set_close_on_deactivate(close);
Expand All @@ -62,8 +124,10 @@ class BraveWebUIBubbleManagerT : public WebUIBubbleManagerT<T> {
}

private:
Browser* browser_ = nullptr;
WebUIBubbleDialogView* bubble_view_ = nullptr;
content::WebContents* web_ui_contents_for_testing_ = nullptr;
base::WeakPtrFactory<BraveWebUIBubbleManagerT<T>> weak_factory_{this};
};

// static
Expand All @@ -87,8 +151,8 @@ WalletBubbleManagerDelegateImpl::WalletBubbleManagerDelegateImpl(

webui_bubble_manager_ =
std::make_unique<BraveWebUIBubbleManagerT<WalletPanelUI>>(
anchor_view, browser->profile(), webui_url_,
IDS_ACCNAME_BRAVE_WALLET_BUTTON, true);
anchor_view, browser, webui_url_, IDS_ACCNAME_BRAVE_WALLET_BUTTON,
true);
}

WalletBubbleManagerDelegateImpl::~WalletBubbleManagerDelegateImpl() {
Expand All @@ -112,6 +176,11 @@ content::WebContents*
WalletBubbleManagerDelegateImpl::GetWebContentsForTesting() {
return webui_bubble_manager_->GetWebContentsForTesting();
}

const std::vector<int32_t>&
WalletBubbleManagerDelegateImpl::GetPopupIdsForTesting() {
return webui_bubble_manager_->GetPopupIdsForTesting();
}
void WalletBubbleManagerDelegateImpl::CloseBubble() {
webui_bubble_manager_->CloseBubble();
}
Expand Down
2 changes: 2 additions & 0 deletions browser/ui/wallet_bubble_manager_delegate_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "brave/browser/ui/brave_wallet/wallet_bubble_manager_delegate.h"

#include <memory>
#include <vector>

#include "brave/browser/ui/webui/brave_wallet/wallet_panel_ui.h"
#include "chrome/browser/ui/views/bubble/webui_bubble_manager.h"
Expand All @@ -35,6 +36,7 @@ class WalletBubbleManagerDelegateImpl : public WalletBubbleManagerDelegate {
void CloseOnDeactivate(bool close) override;
bool IsBubbleClosedForTesting() override;
content::WebContents* GetWebContentsForTesting() override;
const std::vector<int32_t>& GetPopupIdsForTesting() override;

private:
content::WebContents* web_contents_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@

#include <utility>

#include "base/callback.h"
#include "brave/components/permissions/contexts/brave_ethereum_permission_context.h"

WalletPanelHandler::WalletPanelHandler(
mojo::PendingReceiver<brave_wallet::mojom::PanelHandler> receiver,
ui::MojoBubbleWebUIController* webui_controller,
GetWebContentsForTabCallback get_web_contents_for_tab)
GetWebContentsForTabCallback get_web_contents_for_tab,
PanelCloseOnDeactivationCallback close_on_deactivation)
: receiver_(this, std::move(receiver)),
webui_controller_(webui_controller),
get_web_contents_for_tab_(std::move(get_web_contents_for_tab)) {}
get_web_contents_for_tab_(std::move(get_web_contents_for_tab)),
close_on_deactivation_(std::move(close_on_deactivation)) {}

WalletPanelHandler::~WalletPanelHandler() {}

Expand Down Expand Up @@ -52,3 +55,8 @@ void WalletPanelHandler::CancelConnectToSite(const std::string& origin,

permissions::BraveEthereumPermissionContext::Cancel(contents);
}

void WalletPanelHandler::SetCloseOnDeactivate(bool close) {
if (close_on_deactivation_)
close_on_deactivation_.Run(close);
}
Loading