Skip to content

Commit

Permalink
Add dapp detection
Browse files Browse the repository at this point in the history
contents script in brave extension detects whether window.web3 is accessed or not
from current tab and sends a message to background script to notify to browser.
When browser gets "braveShields.dappAvailable", it shows wallet extension install
guide when dapp detection pref is enabled.
  • Loading branch information
simonhong committed Jun 17, 2019
1 parent 739bc85 commit dddde19
Show file tree
Hide file tree
Showing 19 changed files with 281 additions and 2 deletions.
3 changes: 3 additions & 0 deletions app/brave_generated_resources.grd
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@
<message name="IDS_WIDEVINE_PERMISSION_REQUEST_TEXT_FRAGMENT" desc="Text fragment for Widevine permission request. 'Widevine' is the name of a plugin and should not be translated.">
Install and run Widevine
</message>
<message name="IDS_WALLET_PERMISSION_REQUEST_TEXT_FRAGMENT" desc="Text fragment for wallet installation permission request.">
Install cryptocurrency wallet
</message>
<if expr="is_linux">
<message name="IDS_WIDEVINE_PERMISSION_REQUEST_TEXT_FRAGMENT_INSTALL" desc="Text fragment for Widevine permission request. 'Widevine' is the name of a plugin and should not be translated.">
Install Widevine
Expand Down
4 changes: 4 additions & 0 deletions browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ source_set("browser_process") {
"brave_rewards/rewards_tab_helper.h",
"brave_rewards/tip_dialog.cc",
"brave_rewards/tip_dialog.h",
"dapp/dapp_utils.cc",
"dapp/dapp_utils.h",
"dapp/wallet_installation_permission_request.cc",
"dapp/wallet_installation_permission_request.h",
]

deps += [
Expand Down
3 changes: 3 additions & 0 deletions browser/brave_profile_prefs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {

// IPFS companion extension
registry->RegisterBooleanPref(kIPFSCompanionEnabled, false);

// Dapp detection
registry->RegisterBooleanPref(kDappDetectionEnabled, true);
}

} // namespace brave
23 changes: 23 additions & 0 deletions browser/dapp/dapp_utils.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* Copyright (c) 2019 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* 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 "brave/browser/dapp/dapp_utils.h"

#include "brave/browser/dapp/wallet_installation_permission_request.h"
#include "brave/common/pref_names.h"
#include "chrome/browser/permissions/permission_request_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "components/prefs/pref_service.h"

bool DappDetectionEnabled(content::BrowserContext* browser_context) {
Profile* profile = Profile::FromBrowserContext(browser_context);
return profile->GetPrefs()->GetBoolean(kDappDetectionEnabled);
}

void RequestWallInstallationPermission(content::WebContents* web_contents) {
DCHECK(web_contents);
PermissionRequestManager::FromWebContents(web_contents)->AddRequest(
new WalletInstallationPermissionRequest(web_contents));
}
17 changes: 17 additions & 0 deletions browser/dapp/dapp_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* Copyright (c) 2019 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */

#ifndef BRAVE_BROWSER_DAPP_DAPP_UTILS_H_
#define BRAVE_BROWSER_DAPP_DAPP_UTILS_H_

namespace content {
class BrowserContext;
class WebContents;
}

bool DappDetectionEnabled(content::BrowserContext* browser_context);
void RequestWallInstallationPermission(content::WebContents* web_contents);

#endif // BRAVE_BROWSER_DAPP_DAPP_UTILS_H_
57 changes: 57 additions & 0 deletions browser/dapp/wallet_installation_permission_request.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* Copyright (c) 2019 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* 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 "brave/browser/dapp/wallet_installation_permission_request.h"

#include "brave/grit/brave_generated_resources.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"

WalletInstallationPermissionRequest::WalletInstallationPermissionRequest(
content::WebContents* web_contents)
: web_contents_(web_contents) {
}

WalletInstallationPermissionRequest::~WalletInstallationPermissionRequest() {
}

PermissionRequest::IconId
WalletInstallationPermissionRequest::GetIconId() const {
return kExtensionIcon;
}

base::string16
WalletInstallationPermissionRequest::GetMessageTextFragment() const {
return l10n_util::GetStringUTF16(
IDS_WALLET_PERMISSION_REQUEST_TEXT_FRAGMENT);
}

GURL WalletInstallationPermissionRequest::GetOrigin() const {
return web_contents_->GetVisibleURL();
}

void WalletInstallationPermissionRequest::PermissionGranted() {
// TODO(shong): Install wallet.
NOTIMPLEMENTED();
}

void WalletInstallationPermissionRequest::PermissionDenied() {
// Do nothing.
}

void WalletInstallationPermissionRequest::Cancelled() {
// Do nothing.
}

void WalletInstallationPermissionRequest::RequestFinished() {
delete this;
}

PermissionRequestType
WalletInstallationPermissionRequest::GetPermissionRequestType() const {
return PermissionRequestType::PERMISSION_WALLET;
}
41 changes: 41 additions & 0 deletions browser/dapp/wallet_installation_permission_request.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* Copyright (c) 2019 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */

#ifndef BRAVE_BROWSER_DAPP_WALLET_INSTALLATION_PERMISSION_REQUEST_H_
#define BRAVE_BROWSER_DAPP_WALLET_INSTALLATION_PERMISSION_REQUEST_H_

#include "chrome/browser/permissions/permission_request.h"

namespace content {
class WebContents;
}

class GURL;

class WalletInstallationPermissionRequest : public PermissionRequest {
public:
explicit WalletInstallationPermissionRequest(
content::WebContents* web_contents);
~WalletInstallationPermissionRequest() override;

private:
// PermissionRequest overrides:
PermissionRequest::IconId GetIconId() const override;
base::string16 GetMessageTextFragment() const override;
GURL GetOrigin() const override;
void PermissionGranted() override;
void PermissionDenied() override;
void Cancelled() override;
void RequestFinished() override;
PermissionRequestType GetPermissionRequestType() const override;

// It's safe to use this raw |web_contents_| because this request is deleted
// by PermissionManager that is tied with this |web_contents_|.
content::WebContents* web_contents_;

DISALLOW_COPY_AND_ASSIGN(WalletInstallationPermissionRequest);
};

#endif // BRAVE_BROWSER_DAPP_WALLET_INSTALLATION_PERMISSION_REQUEST_H_
29 changes: 29 additions & 0 deletions browser/extensions/api/brave_shields_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <utility>

#include "base/strings/string_number_conversions.h"
#include "brave/browser/dapp/dapp_utils.h"
#include "brave/common/extensions/api/brave_shields.h"
#include "brave/common/extensions/extension_constants.h"
#include "brave/components/brave_shields/browser/brave_shields_web_contents_observer.h"
Expand Down Expand Up @@ -82,6 +83,34 @@ ExtensionFunction::ResponseAction BraveShieldsAllowScriptsOnceFunction::Run() {
return RespondNow(NoArguments());
}

ExtensionFunction::ResponseAction
BraveShieldsDappAvailableFunction::Run() {
std::unique_ptr<brave_shields::DappAvailable::Params> params(
brave_shields::DappAvailable::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());

if (!DappDetectionEnabled(browser_context()))
return RespondNow(NoArguments());

// Get web contents for this tab
content::WebContents* contents = nullptr;
if (!ExtensionTabUtil::GetTabById(
params->tab_id,
Profile::FromBrowserContext(browser_context()),
include_incognito_information(),
nullptr,
nullptr,
&contents,
nullptr)) {
return RespondNow(Error(tabs_constants::kTabNotFoundError,
base::NumberToString(params->tab_id)));
}

RequestWallInstallationPermission(contents);

return RespondNow(NoArguments());
}

ExtensionFunction::ResponseAction
BraveShieldsContentSettingGetFunction::Run() {
ContentSettingsType content_type;
Expand Down
10 changes: 10 additions & 0 deletions browser/extensions/api/brave_shields_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ class BraveShieldsAllowScriptsOnceFunction : public UIThreadExtensionFunction {
ResponseAction Run() override;
};

class BraveShieldsDappAvailableFunction : public UIThreadExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("braveShields.dappAvailable", UNKNOWN)

protected:
~BraveShieldsDappAvailableFunction() override {}

ResponseAction Run() override;
};

class BraveShieldsContentSettingGetFunction
: public UIThreadExtensionFunction {
public:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ std::string GetPermissionRequestString(PermissionRequestType type) {
return "Autoplay";
if (type == PermissionRequestType::PERMISSION_WIDEVINE)
return "Widevine";
if (type == PermissionRequestType::PERMISSION_WALLET)
return "Wallet";
return GetPermissionRequestString_ChromiumImpl(type);
}

Expand Down
18 changes: 18 additions & 0 deletions common/extensions/api/brave_shields.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,24 @@
"parameters": []
}
]
},
{
"name": "dappAvailable",
"type": "function",
"description": "Called when website is dapp",
"parameters": [
{
"name": "tabID",
"type": "integer"
},
{
"type": "function",
"name": "callback",
"optional": true,
"parameters": [
]
}
]
}
],
"types": [
Expand Down
1 change: 1 addition & 0 deletions common/pref_names.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,4 @@ const char kWebTorrentEnabled[] = "brave.webtorrent_enabled";
const char kHangoutsEnabled[] = "brave.hangouts_enabled";
const char kHideBraveRewardsButton[] = "brave.hide_brave_rewards_button";
const char kIPFSCompanionEnabled[] = "brave.ipfs_companion_enabled";
const char kDappDetectionEnabled[] = "brave.dapp_detection_enabled";
1 change: 1 addition & 0 deletions common/pref_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,6 @@ extern const char kWebTorrentEnabled[];
extern const char kHangoutsEnabled[];
extern const char kHideBraveRewardsButton[];
extern const char kIPFSCompanionEnabled[];
extern const char kDappDetectionEnabled[];

#endif // BRAVE_COMMON_PREF_NAMES_H_
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ require('./events/shieldsEvents')
require('./events/runtimeEvents')
require('./events/webNavigationEvents')
require('./events/cosmeticFilterEvents')
require('./events/dappDetectionEvents')
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* Copyright (c) 2019 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */

// content script listener for dapp detection.
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
const action = typeof msg === 'string' ? msg : msg.type
switch (action) {
case 'dappAvailable': {
chrome.tabs.query({active: true, currentWindow: true}, function (tabs: chrome.tabs.Tab[]) {
// Only notify when this message is comes from active tab.
if (msg.location === tabs[0].url) {
chrome.braveShields.dappAvailable(tabs[0].id)
}
});
break
}
}
})
45 changes: 45 additions & 0 deletions components/brave_extension/extension/brave_extension/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,48 @@ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
}
}
})

// For dapp detection.
const script =
`
function __insertWeb3Installed() {
if (!window.alreadyInserted) {
const meta = document.createElement('meta')
meta.name = 'web3-installed'
document.head.appendChild(meta)
window.alreadyInserted = true
}
}
if (window.web3) {
if (!window.web3.currentProvider || !window.web3.currentProvider.isMetaMask) {
__insertWeb3Installed()
}
} else {
var oldWeb3 = window.web3
Object.defineProperty(window, 'web3', {
configurable: true,
set: function (val) {
__insertWeb3Installed()
oldWeb3 = val
},
get: function () {
__insertWeb3Installed()
return oldWeb3
}
})
}`

let script_el = document.createElement('script');
script_el.textContent = script;
(document.head||document.documentElement).appendChild(script_el);

setTimeout(function () {
const isDapp = document.querySelector('meta[name="web3-installed"]')
if (isDapp) {
chrome.runtime.sendMessage({
type: 'dappAvailable',
location: window.location.href
})
script_el.remove()
}
}, 3000)
1 change: 1 addition & 0 deletions components/definitions/chromel.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ declare namespace chrome.braveShields {
}

const allowScriptsOnce: any
const dappAvailable: (tabId: number | undefined) => void
const javascript: any
const plugins: any
}
Expand Down
2 changes: 2 additions & 0 deletions components/definitions/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,7 @@ declare global {
sync_ui_exports: {
initialize: () => void
}
alreadyInserted: boolean
web3: any
}
}
5 changes: 3 additions & 2 deletions patches/chrome-browser-permissions-permission_request.h.patch
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
diff --git a/chrome/browser/permissions/permission_request.h b/chrome/browser/permissions/permission_request.h
index 5aeadb23de307cacfc3c192696dcdaaad2217685..925a3b170f36cac7f4acd056070779b8ff9c5083 100644
index 5aeadb23de307cacfc3c192696dcdaaad2217685..6012c3ac7d754d67f12729d27f1055dfb794b042 100644
--- a/chrome/browser/permissions/permission_request.h
+++ b/chrome/browser/permissions/permission_request.h
@@ -45,6 +45,10 @@ enum class PermissionRequestType {
@@ -45,6 +45,11 @@ enum class PermissionRequestType {
PERMISSION_CLIPBOARD_READ = 16,
PERMISSION_SECURITY_KEY_ATTESTATION = 17,
PERMISSION_PAYMENT_HANDLER = 18,
+#if defined(BRAVE_CHROMIUM_BUILD)
+ PERMISSION_AUTOPLAY = 19,
+ PERMISSION_WIDEVINE = 20,
+ PERMISSION_WALLET = 21,
+#endif
// NUM must be the last value in the enum.
NUM
Expand Down

0 comments on commit dddde19

Please sign in to comment.