Skip to content
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

Element Picker on Android #26725

Merged
merged 8 commits into from
Dec 16, 2024
Merged

Element Picker on Android #26725

merged 8 commits into from
Dec 16, 2024

Conversation

vadimstruts
Copy link
Collaborator

@vadimstruts vadimstruts commented Nov 25, 2024

Resolves brave/brave-browser#33241

  • Enabled Element picker for Android
  • Enhanced Element Picker's UI
  • Added Feature flag which is enabled by default for Desktop and disabled by default for Android
2024-12-04.13-44-36.mp4

Submitter Checklist:

  • I confirm that no security/privacy review is needed and no other type of reviews are needed, or that I have requested them
  • There is a ticket for my issue
  • Used Github auto-closing keywords in the PR description above
  • Wrote a good PR/commit description
  • Squashed any review feedback or "fixup" commits before merge, so that history is a record of what happened in the repo, not your PR
  • Added appropriate labels (QA/Yes or QA/No; release-notes/include or release-notes/exclude; OS/...) to the associated issue
  • Checked the PR locally:
    • npm run test -- brave_browser_tests, npm run test -- brave_unit_tests wiki
    • npm run presubmit wiki, npm run gn_check, npm run tslint
  • Ran git rebase master (if needed)

Reviewer Checklist:

  • A security review is not needed, or a link to one is included in the PR description
  • New files have MPL-2.0 license header
  • Adequate test coverage exists to prevent regressions
  • Major classes, functions and non-trivial code blocks are well-commented
  • Changes in component dependencies are properly reflected in gn
  • Code follows the style guide
  • Test plan is specified in PR before merging

After-merge Checklist:

Test Plan:

  1. Open Android Brave browser
  2. Open any webpage you want to block any HTML element
  3. Open Brave Shields menu -> Advanced controls
  4. Make sure that Block elements item is absent (It means that brave://flags/#block-element-feature flag is disabled)
  5. If it was disabled, (It was not enabled with Griffin), enable it and make sure that Block elements item is present in the Brave Shields menu -> Advanced controls menu
  6. Click Block elements and make sure that Element Picker appears
  7. Click any HTML element you want to block and press button Block Element, and make sure element blocked
  8. Change Android Theme (Dark/Light) and make sure that Element picker has the same color

@vadimstruts vadimstruts linked an issue Nov 25, 2024 that may be closed by this pull request
@github-actions github-actions bot added the CI/storybook-url Deploy storybook and provide a unique URL for each build label Nov 25, 2024
@brave-builds
Copy link
Collaborator

A Storybook has been deployed to preview UI for the latest push

Copy link
Contributor

github-actions bot commented Dec 3, 2024

Chromium major version is behind target branch (131.0.6778.69 vs 132.0.6834.15). Please rebase.

@github-actions github-actions bot added the chromium-version-mismatch The Chromium version on the PR branch does not match the version on the target branch label Dec 3, 2024
@vadimstruts vadimstruts force-pushed the 33241-element-picker-on-android branch from 0b29960 to 50b3c88 Compare December 3, 2024 00:07
@github-actions github-actions bot removed the chromium-version-mismatch The Chromium version on the PR branch does not match the version on the target branch label Dec 3, 2024
@vadimstruts vadimstruts marked this pull request as ready for review December 4, 2024 12:42
@vadimstruts vadimstruts requested review from deeppandya and a team as code owners December 4, 2024 12:42
android:id="@+id/brave_shields_block_element_text"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:paddingStart="16dp"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as paddingStart and paddingEnd are the same, so it is possible to use a single android:paddingHorizontal

</div>
</section>
</section>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably the last line should be empty

Copy link
Contributor

@AlexeyBarabash AlexeyBarabash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Android and native changes lgtm

Copy link
Contributor

@deeppandya deeppandya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lgtm

@@ -1620,6 +1622,20 @@ public void openBraveContentFilteringSettings() {
settingsLauncher.startSettings(this, ContentFilteringFragment.class);
}

public boolean isNightlyModeEnabled() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: NightlyMode sounds like it has to do with the release channel, maybe NightMode instead?

}

@CalledByNative
public static boolean isNightlyModeEnabled() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

@@ -6,23 +6,18 @@ const NSSVG = 'http://www.w3.org/2000/svg'

let pickerDiv: HTMLDivElement | null
let shadowRoot: ShadowRoot | null
const isAndroid = /(android)/i.test(navigator.userAgent)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this best practice? Not a big deal, just a bit suprising, imo

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to use initialization call which returns the platform

Comment on lines 617 to 619
if (isAndroid) {
return
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it's as easy as removing early returns, I'd leave this kind of mouse-specific logic in on Android since some folks would e.g. use a keyboard/mouse combo on a tablet

Perhaps it's worth using pointer/hover media queries rather than UA inspection? ref

blink::WebLocalFrame* web_frame = render_frame_->GetWebFrame();
std::string new_selectors_script = base::StringPrintf(
kSePickerThemeInfoScript, is_dark_mode_enabled, background_color);
web_frame->ExecuteScriptInIsolatedWorld(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is possible to pass the result via getElementPickerThemeInfo(callback) instead of using ExecuteScriptInIsolatedWorld()?


mojo::AssociatedRemote<cosmetic_filters::mojom::CosmeticFiltersHandler>&
CosmeticFiltersJSHandler::GetElementPickerRemoteHandler() {
if (!element_picker_actions_handler_ ||
Copy link
Collaborator

@atuchin-m atuchin-m Dec 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

int OnEventBegin(const std::string& event_name);
void OnEventEnd(const std::string& event_name, int);

void InjectStylesheet(const std::string& stylesheet);

bool generichide_ = false;

mojo::AssociatedRemote<cosmetic_filters::mojom::CosmeticFiltersHandler>&
GetElementPickerRemoteHandler();
void OnRemoteHandlerDisconnect();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: move the methods above.

Copy link
Collaborator

@mkarolin mkarolin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strings++

@vadimstruts vadimstruts requested a review from a team as a code owner December 10, 2024 14:39
@github-actions github-actions bot added CI/run-upstream-tests Run upstream unit and browser tests on Linux and Windows (otherwise only on Linux) puLL-Merge labels Dec 10, 2024
@vadimstruts vadimstruts force-pushed the 33241-element-picker-on-android branch from d83dbdf to 064dbbf Compare December 10, 2024 18:50
#if !BUILDFLAG(IS_ANDROID)
mojom::RunningPlatform::kDesktop
#else // !BUILDFLAG(IS_ANDROID)
mojom::RunningPlatform::kAndroid
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks a bit unusual. You should know at compile time that you're on Android. I don't think mojom::RunningPlatform is necessary. Just check BUILDFLAG(IS_ANDROID) where you need to.

declare_args() {
enable_block_elements_feature =
(brave_channel == "development" || brave_channel == "nightly" ||
brave_channel == "beta" || (is_official_build && !is_android)) && !is_ios
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls don't introduce a buildflag that's configured like this (a combination of channel, platform and official_build). This may lead to a broken build when the branch migration happens, because the flag in false state is never checked on android builds until we start building release builds in the branch with these changes.

Instead pls make the feature DISABLED by default on Android and enable it via Griffin on beta/nightly. Everything will be simpler this way. You can add it into brave://flags so anyone can enable it manually in any branch.


bool IsDarkModeEnabled() {
JNIEnv* env = base::android::AttachCurrentThread();
return Java_BraveCosmeticFiltersUtils_isNightModeEnabled(env);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there really no existing way to check if dark mode is enabled on Android from C++ code?

what about GetDarkModeState() from chrome/browser/flags/android/chrome_session_state.h?

if you really need these values from BraveActivity, please consider making it as browser-wide util, not bound to cosmetic_filters.

@@ -128,6 +129,14 @@ BASE_FEATURE(kCosmeticFilteringSyncLoad,
BASE_FEATURE(kBlockAllCookiesToggle,
"BlockAllCookiesToggle",
base::FEATURE_DISABLED_BY_DEFAULT);
// when enabled, allow to select and block HTML elements
BASE_FEATURE(kBlockElementFeature,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe BraveShieldsElementPicker?

}

const active = document.getElementById('brave-element-picker')
if (!active) {
launchElementPicker(attachElementPicker())
api.initElementPicker((platform: number) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd go something like platform: 'desktop' | 'android'

@@ -24,6 +24,9 @@ interface CosmeticFiltersHandler {

// Opens the custom filter section in Shields settings .
ManageCustomFilters();

GetElementPickerThemeInfo() => (
bool is_nightly_mode_enabled, int32 background_color);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_nightly_mode_enabled -> is_dark_mode_enabled

color_provider.GetColor(kColorSidePanelBadgeBackground));
#else // !BUILDFLAG(IS_ANDROID)
std::move(callback).Run(chrome::android::GetDarkModeState() ==
chrome::android::DarkModeState::kDarkModeSystem,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should check both kDarkModeSystem and kDarkModeApp.

Signed-off-by: Vadym Struts <[email protected]>
Signed-off-by: Vadym Struts <[email protected]>
Signed-off-by: Vadym Struts <[email protected]>
Signed-off-by: Vadym Struts <[email protected]>
Signed-off-by: Vadym Struts <[email protected]>
@vadimstruts vadimstruts force-pushed the 33241-element-picker-on-android branch from 382878a to 828afc3 Compare December 16, 2024 16:47
Copy link
Contributor

[puLL-Merge] - brave/brave-core@26725

Description

This PR introduces a new feature for element picking and blocking in the Brave browser, primarily focusing on the Android platform. It adds functionality to select and block specific HTML elements on web pages, enhancing the user's ability to customize their browsing experience.

Changes

Changes

  1. android/brave_java_sources.gni:

    • Added a new Java source file for cosmetic filters utilities.
  2. android/java/org/chromium/base/BraveFeatureList.java:

    • Introduced a new feature flag BRAVE_SHIELDS_ELEMENT_PICKER.
  3. android/java/org/chromium/chrome/browser/app/BraveActivity.java:

    • Added methods to support the new element picker feature, including opening custom filter settings and getting theme background color.
  4. android/java/org/chromium/chrome/browser/cosmetic_filters/BraveCosmeticFiltersUtils.java:

    • New file implementing utility functions for cosmetic filters, including launching the content picker and handling theme-related information.
  5. android/java/org/chromium/chrome/browser/shields/BraveShieldsHandler.java:

    • Updated to include the new element picker feature in the Brave Shields menu.
  6. android/java/res/layout/brave_shields_secondary_layout.xml:

    • Added a new text view for the "Block element" option.
  7. browser/about_flags.cc:

    • Added a new flag for the block element feature.
  8. browser/android/cosmetic_filters/cosmetic_filters_utils.cc and .h:

    • New files implementing the native side of cosmetic filters utilities.
  9. browser/cosmetic_filters/cosmetic_filters_tab_helper.cc and .h:

    • Updated to support the new element picker feature, including theme handling.
  10. browser/ui/android/strings/android_brave_strings.grd:

    • Added a new string for the "Block element" text.
  11. components/cosmetic_filters/resources/data/element_picker.html and .ts:

    • Significantly updated the element picker UI and functionality, including support for Android.
  12. Various build and configuration files were updated to include the new components.

sequenceDiagram
    participant User
    participant BraveShieldsUI
    participant CosmeticFiltersUtils
    participant ElementPicker
    participant WebContent

    User->>BraveShieldsUI: Tap "Block element"
    BraveShieldsUI->>CosmeticFiltersUtils: launchContentPickerForWebContent()
    CosmeticFiltersUtils->>ElementPicker: Inject and initialize
    ElementPicker->>WebContent: Attach to DOM
    User->>ElementPicker: Select element
    ElementPicker->>CosmeticFiltersUtils: Create filter
    CosmeticFiltersUtils->>WebContent: Apply filter
    ElementPicker->>User: Show confirmation
    User->>ElementPicker: Confirm or cancel
    ElementPicker->>CosmeticFiltersUtils: Save or discard filter
    CosmeticFiltersUtils->>BraveShieldsUI: Update UI
Loading

Possible Issues

  1. The element picker functionality might not work correctly on all websites, especially those with complex DOM structures or dynamic content.
  2. Performance impact on lower-end Android devices when using the element picker feature.

Security Hotspots

  1. The element picker injects JavaScript into web pages, which could potentially be exploited if not properly sandboxed.
  2. The use of XPath selectors in Android might lead to overly broad selections if not carefully implemented.

@vadimstruts vadimstruts merged commit 4be896e into master Dec 16, 2024
18 checks passed
@vadimstruts vadimstruts deleted the 33241-element-picker-on-android branch December 16, 2024 21:54
@github-actions github-actions bot added this to the 1.75.x - Nightly milestone Dec 16, 2024
@brave-builds
Copy link
Collaborator

Released in v1.75.104

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI/run-upstream-tests Run upstream unit and browser tests on Linux and Windows (otherwise only on Linux) CI/storybook-url Deploy storybook and provide a unique URL for each build needs-security-review puLL-Merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Element Picker on Android
10 participants