Skip to content

Commit

Permalink
Remove Greaselion dependency from Rewards service
Browse files Browse the repository at this point in the history
  • Loading branch information
zenparsing committed Oct 24, 2024
1 parent 4bfe3aa commit cd73dc4
Show file tree
Hide file tree
Showing 53 changed files with 2,016 additions and 1,797 deletions.
8 changes: 8 additions & 0 deletions browser/about_flags.cc
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,14 @@
FEATURE_VALUE_TYPE( \
brave_rewards::features::kAnimatedBackgroundFeature), \
}, \
{ \
"brave-rewards-platform-creator-detection", \
"Detect Brave Creators on media platform sites", \
"Enables detection of Brave Creator pages on media platform sites.", \
kOsDesktop | kOsAndroid, \
FEATURE_VALUE_TYPE( \
brave_rewards::features::kPlatformCreatorDetectionFeature), \
}, \
{ \
"brave-ads-should-launch-brave-ads-as-an-in-process-service", \
"Launch Brave Ads as an in-process service", \
Expand Down
11 changes: 5 additions & 6 deletions browser/brave_rewards/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@
# 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/. */

import("//brave/components/greaselion/browser/buildflags/buildflags.gni")
import("//extensions/buildflags/buildflags.gni")
import("//testing/test.gni")

source_set("brave_rewards") {
sources = [
"creator_detection_script_injector.h",
"rewards_service_factory.h",
"rewards_tab_helper.h",
]

deps = [
"//base",
"//brave/components/brave_rewards/browser",
"//brave/components/script_injector/common/mojom",
"//chrome/browser/profiles",
"//components/keyed_service/content",
"//components/sessions",
Expand All @@ -25,6 +26,7 @@ source_set("brave_rewards") {

source_set("brave_rewards_impl") {
sources = [
"creator_detection_script_injector.cc",
"rewards_prefs_util.cc",
"rewards_prefs_util.h",
"rewards_service_factory.cc",
Expand All @@ -40,7 +42,8 @@ source_set("brave_rewards_impl") {
"//brave/browser/ui:brave_rewards_source",
"//brave/components/brave_rewards/browser",
"//brave/components/brave_rewards/common",
"//brave/components/greaselion/browser/buildflags",
"//brave/components/brave_rewards/common:features",
"//brave/components/brave_rewards/resources/creator_detection:creator_detection_generated_grit",
"//chrome/browser/bitmap_fetcher",
"//chrome/browser/favicon",
"//chrome/browser/profiles",
Expand All @@ -61,10 +64,6 @@ source_set("brave_rewards_impl") {

deps += [ "//extensions/browser" ]
}

if (enable_greaselion) {
deps += [ "//brave/browser/greaselion" ]
}
}

source_set("util") {
Expand Down
173 changes: 173 additions & 0 deletions browser/brave_rewards/creator_detection_script_injector.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
// Copyright (c) 2024 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 https://mozilla.org/MPL/2.0/.

#include "brave/browser/brave_rewards/creator_detection_script_injector.h"

#include <utility>

#include "base/containers/fixed_flat_map.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/strings/strcat.h"
#include "base/strings/utf_string_conversions.h"
#include "brave/browser/brave_rewards/rewards_util.h"
#include "brave/components/brave_rewards/common/features.h"
#include "brave/components/brave_rewards/common/pref_names.h"
#include "brave/components/brave_rewards/common/publisher_utils.h"
#include "brave/components/brave_rewards/resources/grit/creator_detection_generated.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_isolated_world_ids.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/content_client.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "ui/base/resource/resource_bundle.h"

namespace brave_rewards {

namespace {

constexpr auto kScriptMap = base::MakeFixedFlatMap<std::string_view, int>(
{{"github.com", IDR_CREATOR_DETECTION_GITHUB_BUNDLE_JS},
{"www.github.com", IDR_CREATOR_DETECTION_GITHUB_BUNDLE_JS},
{"gist.github.com", IDR_CREATOR_DETECTION_GITHUB_BUNDLE_JS},
{"reddit.com", IDR_CREATOR_DETECTION_REDDIT_BUNDLE_JS},
{"www.reddit.com", IDR_CREATOR_DETECTION_REDDIT_BUNDLE_JS},
{"twitch.tv", IDR_CREATOR_DETECTION_TWITCH_BUNDLE_JS},
{"www.twitch.tv", IDR_CREATOR_DETECTION_TWITCH_BUNDLE_JS},
{"twitter.com", IDR_CREATOR_DETECTION_TWITTER_BUNDLE_JS},
{"x.com", IDR_CREATOR_DETECTION_TWITTER_BUNDLE_JS},
{"vimeo.com", IDR_CREATOR_DETECTION_VIMEO_BUNDLE_JS},
{"www.youtube.com", IDR_CREATOR_DETECTION_YOUTUBE_BUNDLE_JS},
{"m.youtube.com", IDR_CREATOR_DETECTION_YOUTUBE_BUNDLE_JS}});

std::string LoadScriptResource(int id) {
auto& bundle = ui::ResourceBundle::GetSharedInstance();
if (bundle.IsGzipped(id)) {
return bundle.LoadDataResourceString(id);
}
return std::string(bundle.GetRawDataResource(id));
}

std::optional<std::string> GetDetectionScript(content::RenderFrameHost* rfh) {
// Only run scripts for the main frame.
if (!rfh || !rfh->IsInPrimaryMainFrame()) {
return std::nullopt;
}

// Only run scripts if the creator detection feature is enabled.
if (!base::FeatureList::IsEnabled(
features::kPlatformCreatorDetectionFeature)) {
return std::nullopt;
}

auto* profile = Profile::FromBrowserContext(rfh->GetBrowserContext());

// Only run scripts if the Rewards service is available for this profile.
if (!IsSupportedForProfile(profile)) {
return std::nullopt;
}

// Only run scripts if the user has enabled Brave Rewards.
if (!profile || !profile->GetPrefs()->GetBoolean(prefs::kEnabled)) {
return std::nullopt;
}

// Only run scripts for known "media platform" sites.
GURL url = rfh->GetLastCommittedURL();
if (!IsMediaPlatformURL(url)) {
return std::nullopt;
}

// Only run scripts when there is an exact hostname match.
auto iter = kScriptMap.find(url.host_piece());
if (iter == kScriptMap.end()) {
return std::nullopt;
}

return LoadScriptResource(iter->second);
}

} // namespace

CreatorDetectionScriptInjector::CreatorDetectionScriptInjector() = default;
CreatorDetectionScriptInjector::~CreatorDetectionScriptInjector() = default;

void CreatorDetectionScriptInjector::MaybeInjectScript(
content::RenderFrameHost* rfh) {
injector_.reset();
injector_host_token_ = content::GlobalRenderFrameHostToken();

if (!rfh) {
return;
}

auto script_source = GetDetectionScript(rfh);
if (!script_source) {
return;
}

injector_host_token_ = rfh->GetGlobalFrameToken();
rfh->GetRemoteAssociatedInterfaces()->GetInterface(&injector_);

// Execute the detection script. It must set `braveRewards.detectCreator` to a
// function. That function will be called by `DetectCreator`.
ExecuteScript(script_source.value(), base::DoNothing());
}

void CreatorDetectionScriptInjector::DetectCreator(
content::RenderFrameHost* rfh,
DetectCreatorCallback callback) {
if (!rfh || rfh->GetGlobalFrameToken() != injector_host_token_ ||
!injector_.is_bound()) {
std::move(callback).Run(std::nullopt);
return;
}

// Call the detection function set up by the detection script.
ExecuteScript(
"braveRewards.detectCreator()",
base::BindOnce(&CreatorDetectionScriptInjector::OnCreatorDetected,
weak_factory_.GetWeakPtr(), std::move(callback)));
}

void CreatorDetectionScriptInjector::ExecuteScript(
std::string_view script,
ExecuteScriptCallback callback) {
CHECK(injector_.is_bound());
injector_->RequestAsyncExecuteScript(
ISOLATED_WORLD_ID_BRAVE_INTERNAL, base::UTF8ToUTF16(script),
blink::mojom::UserActivationOption::kDoNotActivate,
blink::mojom::PromiseResultOption::kAwait, std::move(callback));
}

void CreatorDetectionScriptInjector::OnCreatorDetected(
DetectCreatorCallback callback,
base::Value value) {
Result result;
if (auto* dict = value.GetIfDict()) {
if (auto* id = dict->FindString("id")) {
result.id = *id;
}
if (auto* name = dict->FindString("name")) {
result.name = *name;
}
if (auto* url = dict->FindString("url")) {
result.url = *url;
}
if (auto* image_url = dict->FindString("imageURL")) {
result.image_url = *image_url;
}
}
std::move(callback).Run(std::move(result));
}

CreatorDetectionScriptInjector::Result::Result() = default;
CreatorDetectionScriptInjector::Result::~Result() = default;
CreatorDetectionScriptInjector::Result::Result(const Result&) = default;
CreatorDetectionScriptInjector::Result&
CreatorDetectionScriptInjector::Result::operator=(const Result&) = default;

} // namespace brave_rewards
81 changes: 81 additions & 0 deletions browser/brave_rewards/creator_detection_script_injector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright (c) 2024 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 https://mozilla.org/MPL/2.0/.

#ifndef BRAVE_BROWSER_BRAVE_REWARDS_CREATOR_DETECTION_SCRIPT_INJECTOR_H_
#define BRAVE_BROWSER_BRAVE_REWARDS_CREATOR_DETECTION_SCRIPT_INJECTOR_H_

#include <optional>
#include <string>
#include <string_view>

#include "base/functional/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/values.h"
#include "brave/components/script_injector/common/mojom/script_injector.mojom.h"
#include "content/public/browser/global_routing_id.h"
#include "mojo/public/cpp/bindings/associated_remote.h"

namespace content {
class RenderFrameHost;
}

namespace brave_rewards {

// Responsible for detecting Brave creator information associated with media
// platform pages, using JS scripts that are injected into an isolated world.
class CreatorDetectionScriptInjector {
public:
CreatorDetectionScriptInjector();
~CreatorDetectionScriptInjector();

CreatorDetectionScriptInjector(const CreatorDetectionScriptInjector&) =
delete;
CreatorDetectionScriptInjector& operator=(
const CreatorDetectionScriptInjector&) = delete;

// Injects creator detection scripts (if appropriate) into an isolated world
// associated with the specified render frame host. The scripts are expected
// to set up a JS function that will later be called by `DetectCreator`.
void MaybeInjectScript(content::RenderFrameHost* rfh);

struct Result {
Result();
~Result();
Result(const Result&);
Result& operator=(const Result&);

std::string id;
std::string name;
std::string url;
std::string image_url;
};

using DetectCreatorCallback = base::OnceCallback<void(std::optional<Result>)>;

// Runs the creator detection routine initialized by `MaybeInjectScript` and
// asynchrounously returns the detection result. Return `nullopt` if the
// detection routine was not invoked (e.g. because Rewards is not enabled or
// because there is no script for this page). Returns a `Result` with empty
// fields if there is not creator associated with the current page. Note that
// any of the `Result` fields may be empty if the detection script was unable
// to gather that information from the page.
void DetectCreator(content::RenderFrameHost* rfh,
DetectCreatorCallback callback);

private:
using ExecuteScriptCallback = base::OnceCallback<void(base::Value)>;

void ExecuteScript(std::string_view script, ExecuteScriptCallback callback);

void OnCreatorDetected(DetectCreatorCallback callback, base::Value value);

mojo::AssociatedRemote<script_injector::mojom::ScriptInjector> injector_;
content::GlobalRenderFrameHostToken injector_host_token_;
base::WeakPtrFactory<CreatorDetectionScriptInjector> weak_factory_{this};
};

} // namespace brave_rewards

#endif // BRAVE_BROWSER_BRAVE_REWARDS_CREATOR_DETECTION_SCRIPT_INJECTOR_H_
11 changes: 0 additions & 11 deletions browser/brave_rewards/rewards_service_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "brave/components/brave_rewards/browser/rewards_service.h"
#include "brave/components/brave_rewards/browser/rewards_service_impl.h"
#include "brave/components/brave_rewards/browser/rewards_service_observer.h"
#include "brave/components/greaselion/browser/buildflags/buildflags.h"
#include "chrome/browser/bitmap_fetcher/bitmap_fetcher_service_factory.h"
#include "chrome/browser/favicon/favicon_service_factory.h"
#include "chrome/browser/profiles/incognito_helpers.h"
Expand All @@ -31,10 +30,6 @@
#include "extensions/browser/event_router_factory.h"
#endif

#if BUILDFLAG(ENABLE_GREASELION)
#include "brave/browser/greaselion/greaselion_service_factory.h"
#endif

namespace brave_rewards {

RewardsService* testing_service_ = nullptr;
Expand Down Expand Up @@ -65,9 +60,6 @@ RewardsServiceFactory::RewardsServiceFactory()
BrowserContextDependencyManager::GetInstance()) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
DependsOn(extensions::EventRouterFactory::GetInstance());
#endif
#if BUILDFLAG(ENABLE_GREASELION)
DependsOn(greaselion::GreaselionServiceFactory::GetInstance());
#endif
DependsOn(brave_wallet::BraveWalletServiceFactory::GetInstance());
}
Expand Down Expand Up @@ -123,9 +115,6 @@ RewardsServiceFactory::BuildServiceInstanceForBrowserContext(
profile, ServiceAccessType::EXPLICIT_ACCESS),
request_image_callback, cancel_request_image_callback,
profile->GetDefaultStoragePartition(),
#if BUILDFLAG(ENABLE_GREASELION)
greaselion::GreaselionServiceFactory::GetForBrowserContext(context),
#endif
brave_wallet::BraveWalletServiceFactory::GetServiceForContext(
context));
rewards_service->Init(std::move(extension_observer),
Expand Down
Loading

0 comments on commit cd73dc4

Please sign in to comment.