-
Notifications
You must be signed in to change notification settings - Fork 871
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
Include component versions in webcompat reports #25688
Include component versions in webcompat reports #25688
Conversation
9a6a930
to
dc56223
Compare
ea63de7
to
b54f416
Compare
@@ -50,12 +52,14 @@ namespace { | |||
constexpr char kUISourceHistogramName[] = "Brave.Webcompat.UISource"; | |||
constexpr int kMaxScreenshotPixelCount = 1280 * 720; | |||
|
|||
const std::string BoolToString(bool value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const std::string BoolToString(bool value) { | |
std::string BoolToString(bool value) { |
content::BrowserContext* | ||
WebcompatReporterServiceFactory::GetBrowserContextToUse( | ||
content::BrowserContext* context) const { | ||
return chrome::GetBrowserContextRedirectedInIncognito(context); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls use ProfileKeyedServiceFactory
configured for incognito appropriately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now that you have ProfileKeyedServiceFactory
, you need to remove GetBrowserContextToUse
override.
@@ -63,7 +63,8 @@ class WebcompatReporterDOMHandler : public content::WebUIMessageHandler { | |||
|
|||
raw_ptr<content::RenderWidgetHostView> render_widget_host_view_; | |||
scoped_refptr<base::SequencedTaskRunner> ui_task_runner_; | |||
std::unique_ptr<webcompat_reporter::WebcompatReportUploader> uploader_; | |||
std::unique_ptr<webcompat_reporter::WebcompatReporterService> | |||
reporter_service_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this variable used somehow or is it a leftover? It looks wrong, because you should never own a KeyedService
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it was leftover
|
||
private: | ||
raw_ptr<component_updater::ComponentUpdateService> component_update_service_; | ||
raw_ptr<brave_shields::AdBlockService> adblock_service_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const raw_ptr<...>
both members.
|
||
// static | ||
mojo::PendingRemote<mojom::WebcompatReporterHandler> | ||
WebcompatReporterServiceFactory::GetForContext( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GetMojoReportHandlerForContext
format: "%@ (%@)", | ||
AppInfo.appVersion, | ||
AppInfo.buildNumber | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
channel is missing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, channel has separate property: "channel": "developer"
mentioned code helps to combine version value. ex: "version": "1.73 (0)"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, I see it's filled later in WebcompatReporter.swift
. Not sure why those are separated.. maybe everything can be filled in one place?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I removed WebcompatReporter.swift
, so now all things are in the same place
] | ||
|
||
deps = [ | ||
":webcompat_reporter_mojom_wrappers", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this be a public_deps
instead?
std::optional<std::vector<ComponentInfo>> GetComponentInfos() const override; | ||
|
||
private: | ||
raw_ptr<component_updater::ComponentUpdateService> component_update_service_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const
ios/browser/api/webcompat_reporter/webcompat_reporter_service_delegate.mm
Show resolved
Hide resolved
return std::nullopt; | ||
} | ||
|
||
return result; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like this exact code is duplicated. Pls create a base delegate impl that will be shared on iOS and desktop/android.
...oid/java/org/chromium/chrome/browser/webcompat_reporter/WebcompatReporterServiceFactory.java
Outdated
Show resolved
Hide resolved
public WebcompatReporterHandler getWebcompatReporterHandler( | ||
ConnectionErrorHandler connectionErrorHandler) { | ||
Profile profile = Utils.getProfile(false); // Always use regular profile | ||
if (profile == null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Utils.getProfile
is marked as @NonNull
and it tries to get the profile in several different ways, so I would not use the null check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Android Java code lgtm.
These imports look strange:
import org.chromium.chrome.browser.crypto_wallet.util.Utils;
at src/brave/android/java/org/chromium/chrome/browser/webcompat_reporter/WebcompatReporterServiceFactory.java
and
import org.chromium.chrome.browser.BraveRewardsHelper;
import org.chromium.chrome.browser.BraveRewardsNativeWorker;
at src/brave/android/java/org/chromium/chrome/browser/shields/BraveShieldsHandler.java
And this is an issue beyond the current PR, crypto_wallet.util.Utils
and BraveRewardsHelper
are widely used beyond rewards/wallet.
Follow-up issues:
brave/brave-browser#41689
brave/brave-browser#41690
auto service = | ||
webcompat_reporter::WebcompatReporterServiceFactory::GetForBrowserState( | ||
browserState); | ||
if (!service) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a mojo interface, not a keyed service.
I think the variable and the method name GetForBrowserState
should be renamed accordingly to not confuse people.
content::BrowserContext* | ||
WebcompatReporterServiceFactory::GetBrowserContextToUse( | ||
content::BrowserContext* context) const { | ||
return chrome::GetBrowserContextRedirectedInIncognito(context); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now that you have ProfileKeyedServiceFactory
, you need to remove GetBrowserContextToUse
override.
if (!is_ios) { | ||
deps += [ | ||
"//brave/components/brave_shields/content/browser", | ||
"//chrome/test:test_support", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is it for? you shouldn't have //chrome
in components
.
std::optional<std::string> brave_vpn_connected; | ||
std::optional<std::string> details; | ||
std::optional<std::string> contact; | ||
std::optional<base::Value> ad_block_components; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you added a mojo structure that's just similar to this one. Do we really need to have both? Why not just use mojo structure everywhere from now on? Seems like the right thing to do.
ConvertCompsToValue(report_info->ad_block_components_version.value()); | ||
if (components) { | ||
report_details_dict.Set(kAdBlockComponentsVersionField, | ||
components->Clone()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can let ConvertCompsToValue
always return a value and simplify things here a bit:
if (report_info->ad_block_components_version && !report_info->ad_block_components_version->empty()) {
report_details_dict.Set(kAdBlockComponentsVersionField,
ConvertCompsToValue(report_info->ad_block_components_version.value()));
}
std::unique_ptr<WebcompatReportUploader> webcompat_report_uploader_; | ||
network::TestURLLoaderFactory url_loader_factory_; | ||
scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_; | ||
base::test::TaskEnvironment task_environment_{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
task environment should go first, otherwise you might hit uaf on test destruction.
std::move(delegate), nullptr); | ||
|
||
webcompat_reporter_service_->SetReportUploaderForTest( | ||
std::unique_ptr<WebcompatReportUploader>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not pass this directly into constructor and remove SetReportUploaderForTest
?
also std::make_unique<>
.
+ (nullable id)serviceForBrowserState:(ChromeBrowserState*)browserState { | ||
auto service = webcompat_reporter::WebcompatReporterServiceFactory:: | ||
GetMojoReportHandlerForContext(browserState); | ||
if (!service) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
handler
#include "ios/chrome/browser/shared/model/profile/profile_ios.h" | ||
|
||
@implementation WebcompatReporterServiceFactory | ||
+ (nullable id)serviceForBrowserState:(ChromeBrowserState*)browserState { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this be handlerForBrowserState
?
Logger.module.error( | ||
"Failed to setup webcompat request payload: \(error.localizedDescription)" | ||
public static func send( | ||
braveVersion: String?, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why this function should list all these parameters? Can it just receive the mojo struct type?
namespace webcompat_reporter { | ||
|
||
bool NeedsToGetComponentInfo(const std::string& component_id) { | ||
static const base::NoDestructor<base::flat_set<std::string>> kComponentIds({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can it just be base::MakeFixedFlatSet<std::string_view>{...}
? everything here should be constexpr.
the function can also receive std::string_view
instead of std::string
.
|
||
// static | ||
mojo::PendingRemote<mojom::WebcompatReporterHandler> | ||
WebcompatReporterServiceFactory::GetMojoReportHandlerForContext( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm.. let's actually call it GetHandlerForContext
.
format: "%@ (%@)", | ||
AppInfo.appVersion, | ||
AppInfo.buildNumber | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, I see it's filled later in WebcompatReporter.swift
. Not sure why those are separated.. maybe everything can be filled in one place?
private static var currentLanguageCode: String? { | ||
return Locale.current.language.languageCode?.identifier | ||
} | ||
public class WebcompatReporterUploader { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need this class at all? can't we just call
privateMode: false
)!
webcompatReporterAPI.submitWebcompatReport
in the frontend?
ios/brave-ios/Sources/Brave/Frontend/Shields/SubmitReportView.swift
Outdated
Show resolved
Hide resolved
ios/browser/api/webcompat_reporter/webcompat_reporter_service_factory_wrapper.mm
Outdated
Show resolved
Hide resolved
ios/browser/api/webcompat_reporter/webcompat_reporter_service_factory.mm
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
iOS just needs a format for presubmit check, but lgtm 👍.
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
…d to add unittests Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: vadym <vadym@vadyms-iMac-Pro.local>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
Signed-off-by: Vadym Struts <vstruts@brave.com>
45ae0dd
to
396c47c
Compare
[puLL-Merge] - brave/brave-core@25688 DescriptionThis pull request implements a new WebcompatReporterService for reporting web compatibility issues in Brave browser. It adds functionality to submit reports about website issues, including details about the browser's configuration and any user-provided information. The implementation spans across Android, iOS, and desktop platforms. ChangesChanges
Possible Issues
Security Hotspots
This PR significantly refactors the web compatibility reporting system in Brave, centralizing the functionality and making it more consistent across platforms. It also introduces a more modular and maintainable architecture for handling these reports. |
Signed-off-by: Vadym Struts <vstruts@brave.com>
Released in v1.73.31 |
KeyedService* WebcompatReporterServiceFactory::BuildServiceInstanceFor( | ||
content::BrowserContext* context) const { | ||
auto* default_storage_partition = context->GetDefaultStoragePartition(); | ||
if (!default_storage_partition) { | ||
return nullptr; | ||
} | ||
|
||
auto report_uploader = std::make_unique<WebcompatReportUploader>( | ||
default_storage_partition->GetURLLoaderFactoryForBrowserProcess()); | ||
return new WebcompatReporterService( | ||
std::make_unique<WebcompatReporterServiceDelegateImpl>( | ||
g_browser_process->component_updater(), | ||
g_brave_browser_process->ad_block_service()), | ||
std::move(report_uploader)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BuildServiceInstanceFor
has been deprecated for a while now, and all instances of it in brave have been removed in the past. This PR has introduced a new case though. Leaving a comment to as a PSA.
Resolves brave/brave-browser#35674
Submitter Checklist:
QA/Yes
orQA/No
;release-notes/include
orrelease-notes/exclude
;OS/...
) to the associated issuenpm run test -- brave_browser_tests
,npm run test -- brave_unit_tests
wikinpm run presubmit
wiki,npm run gn_check
,npm run tslint
git rebase master
(if needed)Reviewer Checklist:
gn
After-merge Checklist:
changes has landed on
Test Plan:
Make sure that Webcompat Report contains the
component versions
information.Steps:
component versions
information.