-
Notifications
You must be signed in to change notification settings - Fork 868
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Remove Greaselion dependency from Rewards service
- Loading branch information
1 parent
7c79b15
commit b650615
Showing
53 changed files
with
2,016 additions
and
1,797 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
173 changes: 173 additions & 0 deletions
173
browser/brave_rewards/creator_detection_script_injector.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,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 |
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,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_ |
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
Oops, something went wrong.