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

Speedreader communicate result to tab_helper #9659

Merged
merged 7 commits into from
Sep 3, 2021

Conversation

kkuehlz
Copy link
Contributor

@kkuehlz kkuehlz commented Aug 5, 2021

Resolves brave/brave-browser#17355

Submitter Checklist:

  • I confirm that no security/privacy review is needed, or that I have requested one
  • There is a ticket for my issue
  • Used Github auto-closing keywords in the PR description above
  • Wrote a good PR/commit description
  • 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, npm run lint, 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:

@kkuehlz kkuehlz requested review from iefremov and a team as code owners August 5, 2021 00:03
@kkuehlz kkuehlz force-pushed the speedreader_communicate_result branch from c0c5559 to 0730123 Compare August 5, 2021 06:08
std::string value;
};

} // anonymous namespace
Copy link
Member

Choose a reason for hiding this comment

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

just // namespace

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed


} // anonymous namespace
Copy link
Member

Choose a reason for hiding this comment

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

just // namespace

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

offline_pages::OfflinePageInfoHandler::Register();
#endif

+ RegisterBraveExtendedInfoHandlers();
Copy link
Member

Choose a reason for hiding this comment

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

Can we put this into BraveBrowserMainParts::PreMainMessageLoopRun and don't introduce this patch? ChromeBrowserMainParts::PreMainMessageLoopRun is virtual.

Copy link
Contributor Author

@kkuehlz kkuehlz Aug 5, 2021

Choose a reason for hiding this comment

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

I tried this first.

If I register before, then I miss the call to sessions::ContentSerializedNavigationDriver::SetInstance(..). Happens here.

If I register after calling ChromeBrowserMainParts::PreMainMessageLoopRun, it introduces a very subtle bug where the tabs are restored before we register our handler. So no persisted data ever gets written to the NavigationEntry

Copy link
Member

Choose a reason for hiding this comment

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

What about putting it into PreBrowserStart? It's very close to the current position.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that worked. patch + chromium_src deleted. thanks :)

Copy link
Contributor Author

@kkuehlz kkuehlz Aug 5, 2021

Choose a reason for hiding this comment

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

Would be good if we can DCHECK ensuring Chromium doesn't move this logic around. If the registration happens after any serialized navigation entries are loaded, then it's a no-op. Could introduce a silent bug.

@kkuehlz kkuehlz force-pushed the speedreader_communicate_result branch 2 times, most recently from a2f4d69 to 49d5cdf Compare August 5, 2021 17:16
@kkuehlz kkuehlz requested a review from goodov August 5, 2021 17:19
@kkuehlz kkuehlz force-pushed the speedreader_communicate_result branch 2 times, most recently from 2bb9213 to 47b9a4d Compare August 5, 2021 22:00
void SpeedreaderExtendedInfoHandler::Register() {
auto* handler = new SpeedreaderExtendedInfoHandler();
sessions::ContentSerializedNavigationDriver::GetInstance()
->RegisterExtendedInfoHandler(kSpeedreaderKey, base::WrapUnique(handler));
Copy link
Contributor

Choose a reason for hiding this comment

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

just use make_unique to create the unique_ptr and then std::move to pass it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed


// This class is meant to persist data to a content::NavigationEntry so that
// distilled pages will be recognized on a restored session.
class SpeedreaderExtendedInfoHandler : public sessions::ExtendedInfoHandler {
Copy link
Contributor

Choose a reason for hiding this comment

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

why don't you put this class to components/speedreader?

Copy link
Contributor Author

@kkuehlz kkuehlz Aug 27, 2021

Choose a reason for hiding this comment

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

good idea. moved it there, along with the speedreader::DistillState enum. This will be helpful later when we talk to renderer

SpeedreaderExtendedInfoHandler() = default;
~SpeedreaderExtendedInfoHandler() override = default;

std::string GetExtendedInfo(content::NavigationEntry* entry) const override;
Copy link
Contributor

Choose a reason for hiding this comment

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

pls add // sessions::ExtendedInfoHandler:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

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

SpeedreaderExtendedInfoHandler() = default;
Copy link
Contributor

Choose a reason for hiding this comment

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

commonly, this constructor should be above copy/assignment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

}

// static
bool SpeedreaderExtendedInfoHandler::IsCachedReaderMode(
Copy link
Contributor

Choose a reason for hiding this comment

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

i would rather return some sort of enum instead of making identical methods

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed. good suggestion. this cleaned up a lot of the logic

@kkuehlz kkuehlz force-pushed the speedreader_communicate_result branch from 47b9a4d to 235a851 Compare August 27, 2021 18:46
@kkuehlz kkuehlz requested a review from iefremov August 27, 2021 18:46
@kkuehlz kkuehlz force-pushed the speedreader_communicate_result branch 3 times, most recently from 0f7c734 to 21724ae Compare September 1, 2021 05:34
// When distillation fails we return the original data. Causes this
// throttle to get deleted.
//
// TODO(iefremov): Is it okay to rely on just this, or should the distill
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure, can you please point out when it gets deleted? Probably ok, but I can't quickly find a reference

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i verified heuristically, which is why i was asking. if the throttle returned the original data (distill failed) that function is never reached.

#ifndef BRAVE_COMPONENTS_SPEEDREADER_SPEEDREADER_RESULT_DELEGATE_H_
#define BRAVE_COMPONENTS_SPEEDREADER_SPEEDREADER_RESULT_DELEGATE_H_

#include "content/public/browser/web_contents_user_data.h"
Copy link
Contributor

Choose a reason for hiding this comment

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

not used

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed


#include "content/public/browser/web_contents_user_data.h"

namespace content {
Copy link
Contributor

Choose a reason for hiding this comment

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

not used

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

std::unique_ptr<speedreader::SpeedReaderThrottle> throttle =
speedreader::SpeedReaderThrottle::MaybeCreateThrottleFor(
g_brave_browser_process->speedreader_rewriter_service(),
HostContentSettingsMapFactory::GetForProfile(
Profile::FromBrowserContext(browser_context)),
request.url, state == DistillState::kSpeedreaderMode,
contents, tab_helper, request.url, check_disabled_sites,
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can pass wc_getter and avoid adding the lifetime helper

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@kkuehlz kkuehlz force-pushed the speedreader_communicate_result branch from 21724ae to c548ea0 Compare September 1, 2021 19:14
void SpeedreaderTabHelper::OnDistillComplete() {
// Perform a state transition
auto* entry = web_contents()->GetController().GetLastCommittedEntry();
DCHECK(entry);
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

gotcha, fixed

#include <utility>

#include "base/supports_user_data.h"
#include "components/sessions/content/content_serialized_navigation_driver.h"
Copy link
Contributor

Choose a reason for hiding this comment

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

this should be added to DEPS

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added

distill_state_ = DistillState::kNone;
}
auto* entry = web_contents()->GetController().GetLastCommittedEntry();
DCHECK(entry);
Copy link
Contributor

Choose a reason for hiding this comment

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

I checked other code and it seems we'd better have if

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed and also moved to NavigationEntryCommitted

Kevin Kuehler added 6 commits September 2, 2021 11:37
Uses the webcontents to deliver the result to the correct tab helper. We
might want to follow this up by having the distiller thread return
tuple:

  struct DistillResult {
    bool success;
    std::string buffered_body;
  };

If success is ever false we can abort the loader.
  * Use the DistillState enum in
    SpeedreaderExtendedInfoHandler to de-duplicate logic.
  * Move DistillState to speedreader component
  * Move SpeedreaderExtendedInfoHandler to speedreader component
  * Pass wc_getter to SpeedreaderThrottle instead of creating the
    lifetime helper
Previously we were persisting the SpeedreaderExtendedInfoHandler data to
the NavigationEntry in OnDistillComplete(). Since OnDistillComplete() is
called by the throttle, the navigation entry might not be persisted yet,
so the behavior is not defined. On backward navigations we would
sometimes persist to the previous navigation entry, causing bugs where
pages would incorrectly show up as readable. Since we wait for
DidFinishNavigation, we can safely get the last committed navgiation
entry.
We add two browser test cases for Speedreader. In these tests
Speedreader is enabled.
  (1) Run a readable page through Speedreader. Close the browser and
      open it back up. The page should restore as readable.
  (2) Navigate to a non-readable page, then to a readable page, then do
      a back navigation. The readable state should not "stick".
@kkuehlz kkuehlz force-pushed the speedreader_communicate_result branch from 7f31be1 to b81abfe Compare September 2, 2021 18:38
@kkuehlz kkuehlz force-pushed the speedreader_communicate_result branch from b81abfe to 9b618ed Compare September 2, 2021 21:14
@kkuehlz
Copy link
Contributor Author

kkuehlz commented Sep 2, 2021

CodeQL failure unrelated to the C++ code. It's an HTML blob from the guardian (for testing only) that was already vendored before these changes. I moved the directories around and CI scanned it. Safe to ignore that.

@@ -27,6 +28,11 @@ namespace {
constexpr char kTestProfileName[] = "TestProfile";
} // anonymous namespace

class TestSpeedreaderResultDelegate : public SpeedreaderResultDelegate {
Copy link
Contributor

Choose a reason for hiding this comment

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

also it can go the anonymous namespace above

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

~SpeedreaderTabHelper() override;

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

// Helper function to return a weak pointer
Copy link
Contributor

Choose a reason for hiding this comment

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

IMO the method purpose is pretty obvious, not sure if a comment like this is useful

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sure thing. removed it.

  * Use NavigationEntryCommitted() instead of DidNavigationFinish(). We
    have no guarantees about the next DidNavigationStart() being called
    first.
  * Fix throttle unit test
  * Make several review requests to SpeedreaderBrowserTest
@kkuehlz kkuehlz force-pushed the speedreader_communicate_result branch from 9b618ed to c5677c6 Compare September 3, 2021 17:22
@kkuehlz
Copy link
Contributor Author

kkuehlz commented Sep 3, 2021

AdBlockServiceTest.SubscribeToCustomSubscription failed on Windows but that is a known issue. Merging.

@kkuehlz kkuehlz merged commit c16968e into master Sep 3, 2021
@kkuehlz kkuehlz deleted the speedreader_communicate_result branch September 3, 2021 20:17
@kkuehlz kkuehlz added this to the 1.31.x - Nightly milestone Sep 3, 2021
kkuehlz pushed a commit that referenced this pull request Sep 16, 2021
…esult"

This reverts commit c16968e, reversing
changes made to 5ac6c3b.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Communicate speedreader distill result back to tab helper
3 participants