Commit d89f6ff4 authored by Becca Hughes's avatar Becca Hughes Committed by Commit Bot

Media Engagement: Bundle MEI Preload as a component

Bundle MEI preload data as a component and include a default
version of that component with Chrome. The component
updater is behind the PreloadMediaEngagementData feature
flag.

BUG=787464

Change-Id: Icfc07296caf48e663c9ed7de864f3a1ae6a513d0
Reviewed-on: https://chromium-review.googlesource.com/784892
Commit-Queue: Becca Hughes <beccahughes@chromium.org>
Reviewed-by: default avatarMichael Moss <mmoss@chromium.org>
Reviewed-by: default avatarGreg Thompson <grt@chromium.org>
Reviewed-by: default avatarJochen Eisinger <jochen@chromium.org>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Reviewed-by: default avatarJoshua Pawlicki <waffles@chromium.org>
Cr-Commit-Position: refs/heads/master@{#523760}
parent 4a0b4d14
......@@ -301,7 +301,10 @@ if (!is_android && !is_mac) {
deps += [ "//third_party/adobe/flash:flapper_binaries" ]
}
data_deps += [ "//third_party/widevine/cdm:widevinecdmadapter" ]
data_deps += [
"//chrome/browser/resources/media/mei_preload:component",
"//third_party/widevine/cdm:widevinecdmadapter",
]
if (is_multi_dll_chrome) {
defines += [ "CHROME_MULTIPLE_DLL" ]
......@@ -649,7 +652,9 @@ if (is_win) {
}
foreach(locale, locales_as_mac_outputs) {
outputs += [ "$target_gen_dir/app_infoplist_strings/$locale.lproj/InfoPlist.strings" ]
outputs += [
"$target_gen_dir/app_infoplist_strings/$locale.lproj/InfoPlist.strings",
]
}
args =
......@@ -1207,10 +1212,8 @@ if (is_win) {
if (enable_nacl) {
framework_contents += [ "Internet Plug-Ins" ]
}
if (_should_bundle_widevine) {
framework_contents += [ "Libraries" ]
}
}
configs += [ "//build/config/compiler:wexit_time_destructors" ]
......@@ -1233,6 +1236,7 @@ if (is_win) {
":widevine_cdm_library",
"//build/config:exe_and_shlib_deps",
"//chrome/app/nibs:chrome_xibs",
"//chrome/browser/resources/media/mei_preload:component_bundle",
]
if (is_chrome_branded) {
......
......@@ -273,6 +273,8 @@ split_static_library("browser") {
"component_updater/crl_set_component_installer.h",
"component_updater/file_type_policies_component_installer.cc",
"component_updater/file_type_policies_component_installer.h",
"component_updater/mei_preload_component_installer.cc",
"component_updater/mei_preload_component_installer.h",
"component_updater/optimization_hints_component_installer.cc",
"component_updater/optimization_hints_component_installer.h",
"component_updater/origin_trials_component_installer.cc",
......
......@@ -57,6 +57,7 @@
#include "chrome/browser/component_updater/crl_set_component_installer.h"
#include "chrome/browser/component_updater/downloadable_strings_component_installer.h"
#include "chrome/browser/component_updater/file_type_policies_component_installer.h"
#include "chrome/browser/component_updater/mei_preload_component_installer.h"
#include "chrome/browser/component_updater/optimization_hints_component_installer.h"
#include "chrome/browser/component_updater/origin_trials_component_installer.h"
#include "chrome/browser/component_updater/pepper_flash_component_installer.h"
......@@ -534,6 +535,8 @@ void RegisterComponentsForUpdate(PrefService* profile_prefs) {
#endif
}
RegisterMediaEngagementPreloadComponent(cus, base::OnceClosure());
#if defined(OS_WIN)
#if defined(GOOGLE_CHROME_BUILD)
RegisterSwReporterComponent(cus);
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/component_updater/mei_preload_component_installer.h"
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/path_service.h"
#include "base/task_scheduler/post_task.h"
#include "base/version.h"
#include "chrome/browser/media/media_engagement_preloaded_list.h"
#include "components/component_updater/component_updater_paths.h"
#include "media/base/media_switches.h"
using component_updater::ComponentUpdateService;
namespace {
constexpr base::FilePath::CharType kMediaEngagementPreloadBinaryPbFileName[] =
FILE_PATH_LITERAL("preloaded_data.pb");
// The extension id is: aemomkdncapdnfajjbbcbdebjljbpmpj
constexpr uint8_t kPublicKeySHA256[32] = {
0x04, 0xce, 0xca, 0x3d, 0x20, 0xf3, 0xd5, 0x09, 0x91, 0x12, 0x13,
0x41, 0x9b, 0x91, 0xfc, 0xf9, 0x19, 0xc4, 0x94, 0x6a, 0xb9, 0x9a,
0xe1, 0xaf, 0x3b, 0x9a, 0x95, 0x85, 0x5b, 0x9e, 0x99, 0xed};
constexpr char kMediaEngagementPreloadManifestName[] = "MEI Preload";
void LoadPreloadedDataFromDisk(const base::FilePath& pb_path) {
DCHECK(!pb_path.empty());
MediaEngagementPreloadedList::GetInstance()->LoadFromFile(pb_path);
}
} // namespace
namespace component_updater {
MediaEngagementPreloadComponentInstallerPolicy::
MediaEngagementPreloadComponentInstallerPolicy(
base::OnceClosure on_load_closure)
: on_load_closure_(std::move(on_load_closure)) {}
MediaEngagementPreloadComponentInstallerPolicy::
~MediaEngagementPreloadComponentInstallerPolicy() = default;
bool MediaEngagementPreloadComponentInstallerPolicy::
SupportsGroupPolicyEnabledComponentUpdates() const {
return false;
}
bool MediaEngagementPreloadComponentInstallerPolicy::RequiresNetworkEncryption()
const {
return false;
}
update_client::CrxInstaller::Result
MediaEngagementPreloadComponentInstallerPolicy::OnCustomInstall(
const base::DictionaryValue& manifest,
const base::FilePath& install_dir) {
return update_client::CrxInstaller::Result(0); // Nothing custom here.
}
void MediaEngagementPreloadComponentInstallerPolicy::OnCustomUninstall() {}
base::FilePath MediaEngagementPreloadComponentInstallerPolicy::GetInstalledPath(
const base::FilePath& base) {
return base.Append(kMediaEngagementPreloadBinaryPbFileName);
}
void MediaEngagementPreloadComponentInstallerPolicy::ComponentReady(
const base::Version& version,
const base::FilePath& install_dir,
std::unique_ptr<base::DictionaryValue> manifest) {
base::TaskTraits task_traits = {
base::MayBlock(), base::TaskPriority::BACKGROUND,
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN};
base::OnceClosure task =
base::BindOnce(&LoadPreloadedDataFromDisk, GetInstalledPath(install_dir));
if (!on_load_closure_) {
base::PostTaskWithTraits(FROM_HERE, task_traits, std::move(task));
} else {
base::PostTaskWithTraitsAndReply(FROM_HERE, task_traits, std::move(task),
std::move(on_load_closure_));
}
}
// Called during startup and installation before ComponentReady().
bool MediaEngagementPreloadComponentInstallerPolicy::VerifyInstallation(
const base::DictionaryValue& manifest,
const base::FilePath& install_dir) const {
// No need to actually validate the proto here, since we'll do the checking
// in LoadFromFile().
return base::PathExists(GetInstalledPath(install_dir));
}
base::FilePath
MediaEngagementPreloadComponentInstallerPolicy::GetRelativeInstallDir() const {
return base::FilePath(FILE_PATH_LITERAL("MEIPreload"));
}
void MediaEngagementPreloadComponentInstallerPolicy::GetHash(
std::vector<uint8_t>* hash) const {
hash->assign(kPublicKeySHA256,
kPublicKeySHA256 + arraysize(kPublicKeySHA256));
}
std::string MediaEngagementPreloadComponentInstallerPolicy::GetName() const {
return kMediaEngagementPreloadManifestName;
}
update_client::InstallerAttributes
MediaEngagementPreloadComponentInstallerPolicy::GetInstallerAttributes() const {
return update_client::InstallerAttributes();
}
std::vector<std::string>
MediaEngagementPreloadComponentInstallerPolicy::GetMimeTypes() const {
return std::vector<std::string>();
}
void RegisterMediaEngagementPreloadComponent(ComponentUpdateService* cus,
base::OnceClosure on_load) {
if (!base::FeatureList::IsEnabled(media::kPreloadMediaEngagementData))
return;
auto installer = base::MakeRefCounted<ComponentInstaller>(
std::make_unique<MediaEngagementPreloadComponentInstallerPolicy>(
std::move(on_load)));
installer->Register(cus, base::OnceClosure());
}
} // namespace component_updater
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_COMPONENT_UPDATER_MEI_PRELOAD_COMPONENT_INSTALLER_H_
#define CHROME_BROWSER_COMPONENT_UPDATER_MEI_PRELOAD_COMPONENT_INSTALLER_H_
#include <stdint.h>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/values.h"
#include "components/component_updater/component_installer.h"
namespace base {
class FilePath;
} // namespace base
namespace component_updater {
class ComponentUpdateService;
class MediaEngagementPreloadComponentInstallerPolicy
: public ComponentInstallerPolicy {
public:
explicit MediaEngagementPreloadComponentInstallerPolicy(
base::OnceClosure on_load_closure);
~MediaEngagementPreloadComponentInstallerPolicy() override;
private:
// The following methods override ComponentInstallerPolicy.
bool SupportsGroupPolicyEnabledComponentUpdates() const override;
bool RequiresNetworkEncryption() const override;
update_client::CrxInstaller::Result OnCustomInstall(
const base::DictionaryValue& manifest,
const base::FilePath& install_dir) override;
void OnCustomUninstall() override;
bool VerifyInstallation(const base::DictionaryValue& manifest,
const base::FilePath& install_dir) const override;
void ComponentReady(const base::Version& version,
const base::FilePath& install_dir,
std::unique_ptr<base::DictionaryValue> manifest) override;
base::FilePath GetRelativeInstallDir() const override;
void GetHash(std::vector<uint8_t>* hash) const override;
std::string GetName() const override;
update_client::InstallerAttributes GetInstallerAttributes() const override;
std::vector<std::string> GetMimeTypes() const override;
static base::FilePath GetInstalledPath(const base::FilePath& base);
// Called when the data is loaded into the preloaded list.
base::OnceClosure on_load_closure_;
DISALLOW_COPY_AND_ASSIGN(MediaEngagementPreloadComponentInstallerPolicy);
};
// Call once during startup to make the component update service aware of
// the MEI Preload component.
void RegisterMediaEngagementPreloadComponent(ComponentUpdateService* cus,
base::OnceClosure on_load);
} // namespace component_updater
#endif // CHROME_BROWSER_COMPONENT_UPDATER_MEI_PRELOAD_COMPONENT_INSTALLER_H_
......@@ -9,12 +9,16 @@
#include "base/test/simple_test_clock.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/time/time.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/component_updater/mei_preload_component_installer.h"
#include "chrome/browser/media/media_engagement_contents_observer.h"
#include "chrome/browser/media/media_engagement_preloaded_list.h"
#include "chrome/browser/media/media_engagement_service.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/component_updater/component_updater_service.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/test/browser_test_utils.h"
#include "media/base/media_switches.h"
......@@ -34,7 +38,7 @@ class WasRecentlyAudibleWatcher {
// |web_contents| must be non-NULL and needs to stay alive for the
// entire lifetime of |this|.
explicit WasRecentlyAudibleWatcher(content::WebContents* web_contents)
: web_contents_(web_contents), timer_(new base::Timer(true, true)){};
: web_contents_(web_contents), timer_(new base::Timer(true, true)) {}
~WasRecentlyAudibleWatcher() = default;
// Waits until WasRecentlyAudible is true.
......@@ -47,7 +51,7 @@ class WasRecentlyAudibleWatcher {
run_loop_.reset(new base::RunLoop());
run_loop_->Run();
}
};
}
private:
void TestWasRecentlyAudible() {
......@@ -55,7 +59,7 @@ class WasRecentlyAudibleWatcher {
run_loop_->Quit();
timer_->Stop();
}
};
}
content::WebContents* web_contents_;
......@@ -69,7 +73,7 @@ class WasRecentlyAudibleWatcher {
// Class used to test the Media Engagement service.
class MediaEngagementBrowserTest : public InProcessBrowserTest {
public:
protected:
MediaEngagementBrowserTest()
: task_runner_(new base::TestMockTimeTaskRunner()) {
http_server_.ServeFilesFromSourceDirectory(kMediaEngagementTestDataPath);
......@@ -89,7 +93,7 @@ class MediaEngagementBrowserTest : public InProcessBrowserTest {
InProcessBrowserTest::SetUp();
injected_clock_ = false;
};
}
void LoadTestPage(const GURL& url) {
// We can't do this in SetUp as the browser isn't ready yet and we
......@@ -97,7 +101,7 @@ class MediaEngagementBrowserTest : public InProcessBrowserTest {
InjectTimerTaskRunner();
ui_test_utils::NavigateToURL(browser(), url);
};
}
void LoadTestPageAndWaitForPlay(const GURL& url, bool web_contents_muted) {
LoadTestPage(url);
......@@ -110,13 +114,13 @@ class MediaEngagementBrowserTest : public InProcessBrowserTest {
bool web_contents_muted) {
LoadTestPageAndWaitForPlayAndAudible(http_server_.GetURL("/" + page),
web_contents_muted);
};
}
void LoadTestPageAndWaitForPlayAndAudible(const GURL& url,
bool web_contents_muted) {
LoadTestPageAndWaitForPlay(url, web_contents_muted);
WaitForWasRecentlyAudible();
};
}
void OpenTab(const GURL& url) {
NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
......@@ -262,6 +266,23 @@ class MediaEngagementBrowserTest : public InProcessBrowserTest {
base::TimeDelta::FromSeconds(2);
};
// Class used to test the MEI preload component.
class MediaEngagementPreloadBrowserTest : public InProcessBrowserTest {
public:
MediaEngagementPreloadBrowserTest() = default;
~MediaEngagementPreloadBrowserTest() override = default;
void SetUp() override {
scoped_feature_list_.InitWithFeatures({media::kPreloadMediaEngagementData},
{});
InProcessBrowserTest::SetUp();
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
};
IN_PROC_BROWSER_TEST_F(MediaEngagementBrowserTest, RecordEngagement) {
LoadTestPageAndWaitForPlayAndAudible("engagement_test.html", false);
AdvanceMeaningfulPlaybackTime();
......@@ -568,3 +589,14 @@ IN_PROC_BROWSER_TEST_F(MediaEngagementBrowserTest,
ExpectScores(1, 1, 3, 3);
}
IN_PROC_BROWSER_TEST_F(MediaEngagementPreloadBrowserTest,
EnsureSingletonListIsLoaded) {
base::RunLoop run_loop;
component_updater::RegisterMediaEngagementPreloadComponent(
g_browser_process->component_updater(), run_loop.QuitClosure());
run_loop.Run();
// The list should be loaded now.
EXPECT_TRUE(MediaEngagementPreloadedList::GetInstance()->loaded());
}
# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
mei_preload_sources = [
"manifest.json",
"preloaded_data.pb",
]
mei_preload_out_dir = "MEIPreload"
copy("component") {
sources = mei_preload_sources
outputs = [
"$root_out_dir/$mei_preload_out_dir/{{source_file_part}}",
]
}
bundle_data("component_bundle") {
sources = mei_preload_sources
outputs = [
"{{bundle_contents_dir}}/Libraries/$mei_preload_out_dir/{{source_file_part}}",
]
}
{
"update_url": "https://clients2.google.com/service/update2/crx",
"name": "MEI Preload",
"description": "Contains preloaded data for Media Engagement",
"version": "0.0.0.1",
"manifest_version": 2,
"icons": {}
}
......@@ -61,6 +61,8 @@ packaging_files = packaging_files_binaries + [
"$root_out_dir/xdg-mime",
"$root_out_dir/xdg-settings",
"$root_out_dir/locales/en-US.pak",
"$root_out_dir/MEIPreload/manifest.json",
"$root_out_dir/MEIPreload/preloaded_data.pb",
]
action_foreach("calculate_deb_dependencies") {
......@@ -348,6 +350,7 @@ group("installer_deps") {
":theme_files",
"//chrome",
"//chrome:packed_resources",
"//chrome/browser/resources/media/mei_preload:component",
"//sandbox/linux:chrome_sandbox",
]
if (enable_nacl) {
......
......@@ -185,6 +185,13 @@ stage_install_common() {
cp -a '{}' "${STAGEDIR}/${INSTALLDIR}/locales/" \;
find "${STAGEDIR}/${INSTALLDIR}/locales" -type f -exec chmod 644 '{}' \;
# MEI Preload
if [ -f "${BUILDDIR}/MEIPreload/manifest.json" ]; then
install -m 755 -d "${STAGEDIR}/${INSTALLDIR}/MEIPreload/"
install -m 644 "${BUILDDIR}/MEIPreload/manifest.json" "${STAGEDIR}/${INSTALLDIR}/MEIPreload/"
install -m 644 "${BUILDDIR}/MEIPreload/preloaded_data.pb" "${STAGEDIR}/${INSTALLDIR}/MEIPreload/"
fi
# Widevine CDM.
if [ -f "${BUILDDIR}/libwidevinecdmadapter.so" ]; then
install -m ${SHLIB_PERMS} -s "${BUILDDIR}/libwidevinecdmadapter.so" "${STAGEDIR}/${INSTALLDIR}/"
......
......@@ -83,3 +83,9 @@ WidevineCdm\_platform_specific\win_x86\widevinecdmadapter.dll: %(VersionDir)s\Wi
WidevineCdm\_platform_specific\win_x64\widevinecdm.dll: %(VersionDir)s\WidevineCdm\_platform_specific\win_x64\
WidevineCdm\_platform_specific\win_x64\widevinecdm.dll.sig: %(VersionDir)s\WidevineCdm\_platform_specific\win_x64\
WidevineCdm\_platform_specific\win_x64\widevinecdmadapter.dll: %(VersionDir)s\WidevineCdm\_platform_specific\win_x64\
#
# MEI Preload sub dir
#
MEIPreload\manifest.json: %(VersionDir)s\MEIPreload\
MEIPreload\preloaded_data.pb: %(VersionDir)s\MEIPreload\
......@@ -1982,6 +1982,10 @@ test("browser_tests") {
if (is_chromeos || (is_linux && use_dbus)) {
sources += [ "../browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc" ]
}
if (!is_android && !is_mac) {
data_deps += [ "//chrome/browser/resources/media/mei_preload:component" ]
}
}
}
......
......@@ -123,4 +123,13 @@ FILES = [
'filename': 'nacl_helper_nonsfi',
'buildtype': ['dev', 'official'],
},
# MEI Preload files:
{
'filename': 'MEIPreload/manifest.json',
'buildtype': ['dev', 'official'],
},
{
'filename': 'MEIPreload/preloaded_data.pb',
'buildtype': ['dev', 'official'],
},
]
......@@ -300,4 +300,13 @@ FILES = [
'archive': 'content-shell.zip',
'optional': ['dev'],
},
]
# MEI Preload files:
{
'filename': 'MEIPreload/manifest.json',
'buildtype': ['dev', 'official'],
},
{
'filename': 'MEIPreload/preloaded_data.pb',
'buildtype': ['dev', 'official'],
},
]
......@@ -862,4 +862,13 @@ FILES = [
'archive': 'metrics-metadata.zip',
'optional': ['dev', 'official'],
},
# MEI Preload files:
{
'filename': 'MEIPreload/manifest.json',
'buildtype': ['dev', 'official'],
},
{
'filename': 'MEIPreload/preloaded_data.pb',
'buildtype': ['dev', 'official'],
},
]
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment