Skip to content

Commit

Permalink
Merge pull request #11026 from brave/pr10902_sign_trezor_transactions…
Browse files Browse the repository at this point in the history
…_to_33

(uplift to 1.33.x) Signing transactions and messages with Trezor accounts (#10902 #10903)
  • Loading branch information
kjozwiak authored Nov 12, 2021
2 parents 8639214 + 4901c56 commit 5ae00f4
Show file tree
Hide file tree
Showing 45 changed files with 1,293 additions and 562 deletions.
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

0 comments on commit 5ae00f4

Please sign in to comment.