Skip to content

Re-add support for Chromecast #2493

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

Merged
merged 1 commit into from
Jul 23, 2019
Merged

Re-add support for Chromecast #2493

merged 1 commit into from
Jul 23, 2019

Conversation

bsclifton
Copy link
Member

@bsclifton bsclifton commented May 24, 2019

Fixes brave/brave-browser#209
Related brave/brave-browser#4631


Revert "Merge pull request #2119 from brave/revert_enabling_chromecast"
This reverts commit 29ea1df, reversing
changes made to c08710a.

Submitter Checklist:

Test Plan:

First Launch

  1. Launch Brave with a new profile
  2. Verify that Cast option is not available in the hamburger menu
  3. Open wireshark, filter traffic for udp.port == 1900 and verify that no traffic is generated by Brave.

Settings Page

  1. Open brave://settings and verify that Extensions > Media Router is disabled
  2. Toggle the switch, relaunch.
  3. Navigate to the hamburger menu and check Cast is available
  4. Click Cast, and verify if you're able to cast your screen to a Chrome-cast device (Note: that signature verification takes some time on first try, so wait for ~10-20 secs before trying this)
  5. Toggle the switch back off, relaunch and verify Cast is not available in the hamburger menu.

Upgrade

  1. Open Brave-Browser without this change
  2. Navigate to brave://flags and enable media router
  3. Relaunch and verify that ChromeCast doesn't work
  4. Open Brave-Browser (use the same profile) with the change
  5. Navigate to brave://settings and confirm Media Router preference is enabled
  6. Verify Cast works as expected.

Settings UI

  1. Navigate to brave://settings
  2. Toggle the Media Router Setting
  3. Verify that a fixed bottom bar requesting a relaunch.
  4. Toggle the Media Router Setting and verify that the bar disappears
  5. Toggle it back on, and navigate to a different page. The bar should disappear
  6. Navigate to brave://settings and the bar should re-appear.

Sync with brave://flags

  1. Navigate to brave flags, set Load Media Router Component Extension to enabled
  2. Verify that Media Router setting in, brave://settings is also enabled
  3. Navigate to brave flags, set Load Media Router Component Extension to disabled
  4. Verify that Media Router setting in, brave://settings is also disabled

  1. Navigate to brave flags, set Media Router Setting to enabled
  2. Verify that the Media Router Flag, in brave://flags is enabled
  3. Navigate to brave flags, set Media Router Setting to disabled
  4. Verify that the Media Router Flag, in brave://flags is disabled

Reviewer Checklist:

  • New files have MPL-2.0 license header.
  • Request a security/privacy review as needed.
  • Adequate test coverage exists to prevent regressions
  • Verify test plan is specified in PR before merging to source

After-merge Checklist:

  • The associated issue milestone is set to the smallest version that the
    changes has landed on.
  • All relevant documentation has been updated.

@bsclifton bsclifton self-assigned this May 24, 2019
@bsclifton
Copy link
Member Author

Errors from prior merge attempt:

12:53:51  NETWORK AUDIT FAIL: https://clients2.google.com/service/update2/crx?os=linux&arch=x64&os_arch=x86_64&nacl_arch=x86-64&prod=chromiumcrx&prodchannel=unknown&prodversion=73.0.64.26&lang=en-US&acceptformat=crx2,crx3&x=id%3Dpkedcjkdefgpdelpbcmbmeomcjbeemfm%26v%3D0.0.0.0%26installedby%3Dother%26uc%26ping%3Dr%253D-1%2526e%253D1
12:53:51  NETWORK AUDIT FAIL: https://clients2.google.com/service/update2/crx?os=linux&arch=x64&os_arch=x86_64&nacl_arch=x86-64&prod=chromiumcrx&prodchannel=unknown&prodversion=73.0.64.26&lang=en-US&acceptformat=crx2,crx3&x=id%3Dpkedcjkdefgpdelpbcmbmeomcjbeemfm%26v%3D0.0.0.0%26installedby%3Dother%26uc%26ping%3Dr%253D-1%2526e%253D1
12:53:51  NETWORK AUDIT FAIL: https://extensionupdater.brave.com/service/update2/crx?os=linux&arch=x64&os_arch=x86_64&nacl_arch=x86-64&prod=chromiumcrx&prodchannel=unknown&prodversion=73.0.64.26&lang=en-US&acceptformat=crx2,crx3&x=id%3Dpkedcjkdefgpdelpbcmbmeomcjbeemfm%26v%3D0.0.0.0%26installedby%3Dother%26uc%26ping%3Dr%253D-1%2526e%253D1
12:53:51  NETWORK AUDIT FAIL: http://redirector.gvt1.com/edgedl/chromewebstore/L2Nocm9tZV9leHRlbnNpb24vYmxvYnMvMjJlQUFXRC12Ny1ldUFnMXF3SDlXZDlFZw/7319.128.0.1_pkedcjkdefgpdelpbcmbmeomcjbeemfm.crx
12:53:51  NETWORK AUDIT FAIL: http://redirector.gvt1.com/edgedl/chromewebstore/L2Nocm9tZV9leHRlbnNpb24vYmxvYnMvMjJlQUFXRC12Ny1ldUFnMXF3SDlXZDlFZw/7319.128.0.1_pkedcjkdefgpdelpbcmbmeomcjbeemfm.crx
12:53:51  NETWORK AUDIT FAIL: http://r6---sn-nx5e6ne6.gvt1.com/edgedl/chromewebstore/L2Nocm9tZV9leHRlbnNpb24vYmxvYnMvMjJlQUFXRC12Ny1ldUFnMXF3SDlXZDlFZw/7319.128.0.1_pkedcjkdefgpdelpbcmbmeomcjbeemfm.crx?cms_redirect=yes&mip=34.219.185.75&mm=28&mn=sn-nx5e6ne6&ms=nvh&mt=1553863827&mv=m&pl=12&shardbypass=yes

@bsclifton bsclifton requested a review from jumde May 28, 2019 23:16
@bsclifton bsclifton added this to the 0.67.x - Nightly milestone May 28, 2019
@jumde jumde force-pushed the readd-chromecast branch 2 times, most recently from 24f1944 to 63cea2e Compare June 10, 2019 21:37
@simonhong
Copy link
Member

simonhong commented Jun 18, 2019

As @jumde mentioned, case is still not working due to Disabling extension pkedcjkdefgpdelpbcmbmeomcjbeemfm ('Chrome Media Router') due to install verification failure.

and @jumde tested it is enabled with below patch.

index 32b499da4..9672b8987 100644
--- a/browser/extensions/brave_extension_management.cc
+++ b/browser/extensions/brave_extension_management.cc
@@ -16,6 +16,7 @@
 #include "brave/browser/extensions/brave_tor_client_updater.h"
 #include "chrome/browser/extensions/external_policy_loader.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/extensions/install_verifier.h"
 #include "components/prefs/pref_service.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/common/extension.h"
@@ -41,6 +42,9 @@ void BraveExtensionManagement::RegisterBraveExtensions() {
       *base::CommandLine::ForCurrentProcess();
   if (!command_line.HasSwitch(switches::kDisableTorClientUpdaterExtension))
     g_brave_browser_process->tor_client_updater()->Register();
+  std::set<std::string> ids;
+  ids.insert("pkedcjkdefgpdelpbcmbmeomcjbeemfm");
+  InstallVerifier::Get(profile_)->AddProvisional(ids);
 }

With above patch, Disabling extension pkedcjkdefgpdelpbcmbmeomcjbeemfm ('Chrome Media Router') due to install verification failure. is not visible but still can't get available device list. Works with clean profile.

@jumde
Copy link
Contributor

jumde commented Jun 18, 2019

As @jumde mentioned, case is still not working due to Disabling extension pkedcjkdefgpdelpbcmbmeomcjbeemfm ('Chrome Media Router') due to install verification failure.

and @jumde tested it is enabled with below patch.

index 32b499da4..9672b8987 100644
--- a/browser/extensions/brave_extension_management.cc
+++ b/browser/extensions/brave_extension_management.cc
@@ -16,6 +16,7 @@
 #include "brave/browser/extensions/brave_tor_client_updater.h"
 #include "chrome/browser/extensions/external_policy_loader.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/extensions/install_verifier.h"
 #include "components/prefs/pref_service.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/common/extension.h"
@@ -41,6 +42,9 @@ void BraveExtensionManagement::RegisterBraveExtensions() {
       *base::CommandLine::ForCurrentProcess();
   if (!command_line.HasSwitch(switches::kDisableTorClientUpdaterExtension))
     g_brave_browser_process->tor_client_updater()->Register();
+  std::set<std::string> ids;
+  ids.insert("pkedcjkdefgpdelpbcmbmeomcjbeemfm");
+  InstallVerifier::Get(profile_)->AddProvisional(ids);
 }

With above patch, Disabling extension pkedcjkdefgpdelpbcmbmeomcjbeemfm ('Chrome Media Router') due to install verification failure. is not visible but still can't get available device list.

@simonhong - With this patch I checked that the signature check fails in https://cs.chromium.org/chromium/src/chrome/browser/extensions/install_verifier.cc?l=631. I'm not sure if we're okay with that.

@simonhong
Copy link
Member

@jumde I edited right before your last comment :)
Device list is fetched properly with clean profile.

@simonhong simonhong changed the title WIP: Re-add support for Chromecast Re-add support for Chromecast Jun 18, 2019
@simonhong simonhong marked this pull request as ready for review June 18, 2019 11:45
@bsclifton bsclifton added CI/skip-android Do not run CI builds for Android CI/skip-ios Do not run CI builds for iOS labels Jun 18, 2019
@@ -38,6 +42,9 @@ const char kCRLSetPrefix3[] =
const char kCRLSetPrefix4[] =
"*://storage.googleapis.com/update-delta/hfnkpimlhhgieaddgfemjhofmfblmnib"
"/*crxd";
const char kGoogleAPIPrefix[] = "https://www.googleapis.com/";
Copy link
Member

Choose a reason for hiding this comment

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

out of curiosity, why https instead of * here?

Copy link
Contributor

Choose a reason for hiding this comment

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

it was not connecting over http but I agree, using * would help if the code fallsback to the non-secure url

@jumde jumde force-pushed the readd-chromecast branch 4 times, most recently from 9ec2881 to 1b13d24 Compare June 24, 2019 22:23
@simonhong simonhong requested a review from bridiver June 25, 2019 00:34
@simonhong
Copy link
Member

@bridiver added cause this PR adds new patch file.

@jumde jumde force-pushed the readd-chromecast branch from ea15f56 to 1b16b5b Compare June 25, 2019 21:54
@bsclifton bsclifton requested a review from bbondy June 25, 2019 22:23
@jumde jumde requested a review from diracdeltas June 25, 2019 22:30
Copy link
Member

@petemill petemill left a comment

Choose a reason for hiding this comment

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

Thanks for making the restart notification persistent. Minor changes requested to the JS api

@@ -63,10 +64,29 @@ void BraveDefaultExtensionsHandler::RegisterMessages() {
flags_ui::kRestartBrowser,
base::BindRepeating(&BraveDefaultExtensionsHandler::HandleRestartBrowser,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"showRelaunchToast",
Copy link
Member

Choose a reason for hiding this comment

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

👍 on the pattern but please can we call the command getRestartNeeded so that:

  • it's about the data, not the UI implementation (toast)
  • it's specific about getting data, and not performing an action


/** @override */
created: function() {
this.browserProxy_ = settings.BraveDefaultExtensionsBrowserProxyImpl.getInstance();
this.browserProxy_.showRelaunchToast().then(show => {
this.hideRestartToast = !show;
this.$.needsRestart.hidden = this.hideRestartToast;
Copy link
Member

Choose a reason for hiding this comment

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

This may be a micro-optimization, so consider it a nit: I'd feel more comfortable if this didn't require a DOM change on 99.9% of all Settings page loads (i.e. page loads which don't have the toast showing).
This can be achieved by either:

  • Preferred: Wrap the element in an <if which tests hideRestartToast (though positive variable name is better, e.g. showRestartToast
  • Similar pattern to what you have: Create a css class called something like pageNeedsRestart, and only add this class if the variable comes back true.


bool IsExtensionInstalled(const std::string& extension_id) const;
void OnInstallResult(const std::string& pref_name,
bool success, const std::string& error,
extensions::webstore_install::Result result);

Profile* profile_ = nullptr;
bool restartNeeded = false;
Copy link
Member

Choose a reason for hiding this comment

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

nit: restart_needed_ is the chromium style.

args->GetBoolean(0, &enabled);

restartNeeded = !restartNeeded;
if (enabled) {
Copy link
Member

Choose a reason for hiding this comment

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

It would be good to add some comments why this is needed.

Copy link
Contributor

Choose a reason for hiding this comment

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

done!

@jumde jumde force-pushed the readd-chromecast branch 2 times, most recently from c6c6a27 to 10047e1 Compare July 13, 2019 19:26
disable_reason::DisableReason* reason,
base::string16* error) const {
CHECK(extension);
+ ReturnFalseIfExtensionShouldSkipSignatureChecking(extension->id())
Copy link
Contributor

Choose a reason for hiding this comment

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

This happens because for Media Router the signature fetch and check happens out of order. This is likely a chromium bug, but not seen because chromium uses ENFORCE instead of ENFORCE_STRICT by default.(https://cs.chromium.org/chromium/src/chrome/browser/extensions/chrome_content_verifier_delegate.cc?l=110)

But, ENFORCE_STRICT (https://cs.chromium.org/chromium/src/extensions/browser/content_verifier_delegate.h?g=0&l=42) is better for security.

We have multiple options here:

  1. Use ENFORCE over ENFORCE_STRICT similar to chromium.
  2. SkipSignatureVerification for MediaRouter as seen in this PR.
  3. RedoSignature check after the fetch is complete.

Thoughts? @bridiver @diracdeltas @tomlowenthal

cc: @bsclifton @simonhong

Copy link
Member Author

Choose a reason for hiding this comment

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

Option 2 or 3 sound great to me- I'd vote for option 2 as my choice 😄

Copy link
Member

Choose a reason for hiding this comment

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

i prefer 3 since Google Chrome uses ENFORCE_STRICT (https://cs.chromium.org/chromium/src/chrome/browser/extensions/chrome_content_verifier_delegate.cc?l=68); so IIUC, 3 is the only option that gives us parity with Google Chrome security-wise.

Copy link
Contributor

Choose a reason for hiding this comment

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

@diracdeltas - ENFORCE_STRICT is only used when field trials are enabled, I don't think Chrome has field trials enabled for release builds. Let me know if I'm missing something.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@diracdeltas I thought it was the other way around? Chromium uses ENFORCE so my preference is to follow that and not patch here

Copy link
Contributor

Choose a reason for hiding this comment

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

@diracdeltas @bridiver - ENFORCE_STRICT works well for the extensions I have tested, but I understand the concern that we might run into web-compat issues with an experimental feature.

I have a patch for 3 but, I'm okay with 1 to avoid any web-compat risk we might run into.

@jumde jumde force-pushed the readd-chromecast branch from f5da576 to 969710f Compare July 15, 2019 18:52
!args->GetString(1, &enable_str))
return;

+ SyncFeatureFlagWithBravePrefs(entry_internal_name, Profile::FromWebUI(web_ui()));
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm confused, I thought we were doing a lazy check to sync with the pref?

Copy link
Collaborator

Choose a reason for hiding this comment

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

if we need notification at the time this changes then we should add a pref observer for kEnabledLabsExperiments

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 I could have named it better, the intention of this call is to update the temporary pref kBraveEnabledMediaRouter that we use in brave://settings when flags are toggled. So toggling the flag correctly toggles the Media Router switch in brave://settings.

Copy link
Collaborator

Choose a reason for hiding this comment

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

this can be done without a patch using a chromium_src override for SetFeatureEntryEnabled which I thought is what we had before and maybe this is why I'm confused here

@@ -45,13 +45,42 @@ int OnBeforeURLRequest_CommonStaticRedirectWork(
const ResponseCallback& next_callback,
std::shared_ptr<BraveRequestInfo> ctx) {
GURL::Replacements replacements;
static URLPattern googleapis_pattern(
URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS, kGoogleAPIPrefix);
Copy link
Collaborator

Choose a reason for hiding this comment

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

lint 4 spaces

base::Value(restart_needed_));
}

void BraveDefaultExtensionsHandler::HandleRestartBrowser(
Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe the correct way to handle this is to just link to kChromeUIRestartURL

Copy link
Contributor

Choose a reason for hiding this comment

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

Navigation to kChromeUIRestartURL internally calls chrome::AttemptRestart: https://cs.chromium.org/chromium/src/chrome/browser/browser_about_handler.cc?l=98.

We can link to kChromeUIRestartURL in javascript directly but I was just trying to avoid chances of regression if kChromeUIRestartURL changes in future.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it is better to use kChromeUIRestartURL than to duplicate the logic here. Not sure why kChromeUIRestartURL would change in the future

Copy link
Member

Choose a reason for hiding this comment

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

@bridiver just noting that the same functionality in chrome://flags does not link to kChromeUIRestartUI but sends a message to a message handler via chrome.send too and calls AttemptRestart. I wonder what would happen to session restore if the tab was navigated away from the settings page to kChromeUIRestartURL. The settings page may not restore, which would be unfortunate. Although I did spot comments around this being a non-navigation url, so maybe it would restore... Still, I wonder why the Flags page doesn't use it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@petemill because a lot of other things happen in FlagsDOMHandler::HandleRestartBrowser before the restart. The only thing we're doing here is calling AttemptRestart so it's functionally equivalent

Copy link
Collaborator

Choose a reason for hiding this comment

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

  DCHECK(flags_storage_);
#if defined(OS_CHROMEOS)
  // On ChromeOS be less intrusive and restart inside the user session after
  // we apply the newly selected flags.
  base::CommandLine user_flags(base::CommandLine::NO_PROGRAM);
  about_flags::ConvertFlagsToSwitches(flags_storage_.get(),
                                      &user_flags,
                                      flags_ui::kAddSentinels);

  // Apply additional switches from policy that should not be dropped when
  // applying flags..
  chromeos::UserSessionManager::MaybeAppendPolicySwitches(
      Profile::FromWebUI(web_ui())->GetPrefs(), &user_flags);

  base::CommandLine::StringVector flags;
  // argv[0] is the program name |base::CommandLine::NO_PROGRAM|.
  flags.assign(user_flags.argv().begin() + 1, user_flags.argv().end());
  VLOG(1) << "Restarting to apply per-session flags...";
  AccountId account_id =
      user_manager::UserManager::Get()->GetActiveUser()->GetAccountId();
  chromeos::UserSessionManager::GetInstance()->SetSwitchesForUser(
      account_id,
      chromeos::UserSessionManager::CommandLineSwitchesType::
          kPolicyAndFlagsAndKioskControl,
      flags);
#endif
  chrome::AttemptRestart();
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

they need all of that code to run on chromeos before attempting the restart



AllowJavascript();
ResolveJavascriptCallback(args->GetList()[0].Clone(),
Copy link
Collaborator

@bridiver bridiver Jul 15, 2019

Choose a reason for hiding this comment

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

why are you cloning this? Also args->GetList()[0] is not the correct or safe way to get this value.

std::string callback_id;
args->GetString(0, &callback_id);

and then pass in base::Value(callback_id)

// Adding the media router extension on explicit toggle to prevent
// any suprise connections on upgrade
if (enabled) {
extensions::ExtensionPrefs::Get(profile_)->SetExtensionEnabled(
Copy link
Collaborator

Choose a reason for hiding this comment

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

we shouldn't be directly calling ExtensionPrefs::SetExtensionEnabled. You should enable/disable using the ExtensionRegistry

@jumde jumde force-pushed the readd-chromecast branch 2 times, most recently from 9bde2f6 to 40ccf3d Compare July 17, 2019 06:28
TEST_F(BraveCommonStaticRedirectNetworkDelegateHelperTest,
RedirectChromecastDownload) {
net::TestDelegate test_delegate;
GURL url(
Copy link
Collaborator

Choose a reason for hiding this comment

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

how do we know this still works if the extension version changes?

Copy link
Contributor

@jumde jumde Jul 18, 2019

Choose a reason for hiding this comment

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

changed to random_hash and random_version, the pattern https://github.com/brave/brave-core/pull/2493/files#diff-6337bc2627a3b8782b369e66dc193cb9R47 should catch all changes to hash and version

@jumde jumde force-pushed the readd-chromecast branch from 302d3a0 to 6a45e60 Compare July 18, 2019 23:14
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#define SetFeatureEntryEnabled SetFeatureEntryEnabled_ChromiumImpl
#include "../../../../chrome/browser/about_flags.cc" // NOLINT
Copy link
Contributor

Choose a reason for hiding this comment

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

Needed because SetFeatureEntryEnabled in about_flags.cc calls, SetFeatureEnabled in flags_state.cc

bridiver
bridiver previously approved these changes Jul 22, 2019
Copy link
Member

@petemill petemill left a comment

Choose a reason for hiding this comment

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

Found a minor issue with the restart prompt. Since I've already provided feedback about that which may have led to this issue, I've implemented a proposed change in #2974. Apart from that it all looks good.

@jumde jumde force-pushed the readd-chromecast branch from 931087a to e0ed3de Compare July 23, 2019 15:38
Copy link
Member

@petemill petemill left a comment

Choose a reason for hiding this comment

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

Cast off! ⚓️

@bsclifton bsclifton merged commit f56db6d into master Jul 23, 2019
@bsclifton bsclifton deleted the readd-chromecast branch August 6, 2019 17:58
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.

Enable Chromecast support
7 participants