| Index: chrome/browser/webshare/share_service_impl.cc
|
| diff --git a/chrome/browser/webshare/share_service_impl.cc b/chrome/browser/webshare/share_service_impl.cc
|
| index 7d2ddc1d20529ceb0aa3eeef01b413a88107a297..eadfe7e49a8ee73678f1dc3f722ac2ae6497731a 100644
|
| --- a/chrome/browser/webshare/share_service_impl.cc
|
| +++ b/chrome/browser/webshare/share_service_impl.cc
|
| @@ -10,12 +10,15 @@
|
|
|
| #include "base/strings/string_util.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| -#include "chrome/browser/ui/browser.h"
|
| +#include "chrome/browser/engagement/site_engagement_service.h"
|
| +#include "chrome/browser/profiles/profile.h"
|
| #include "chrome/browser/ui/browser_commands.h"
|
| #include "chrome/browser/ui/browser_dialogs.h"
|
| #include "chrome/browser/ui/browser_list.h"
|
| #include "chrome/browser/ui/browser_tabstrip.h"
|
| #include "chrome/browser/ui/tabs/tab_strip_model.h"
|
| +#include "chrome/common/pref_names.h"
|
| +#include "components/prefs/pref_service.h"
|
| #include "mojo/public/cpp/bindings/strong_binding.h"
|
| #include "net/base/escape.h"
|
|
|
| @@ -45,6 +48,9 @@ std::string JoinString(const std::vector<base::StringPiece>& pieces) {
|
|
|
| } // namespace
|
|
|
| +ShareServiceImpl::ShareServiceImpl() = default;
|
| +ShareServiceImpl::~ShareServiceImpl() = default;
|
| +
|
| // static
|
| void ShareServiceImpl::Create(blink::mojom::ShareServiceRequest request) {
|
| mojo::MakeStrongBinding(base::MakeUnique<ShareServiceImpl>(),
|
| @@ -116,7 +122,7 @@ bool ShareServiceImpl::ReplacePlaceholders(base::StringPiece url_template,
|
| void ShareServiceImpl::ShowPickerDialog(
|
| const std::vector<std::pair<base::string16, GURL>>& targets,
|
| const base::Callback<void(base::Optional<std::string>)>& callback) {
|
| - // TODO(mgiuca): Get the browser window as |parent_window|.
|
| +// TODO(mgiuca): Get the browser window as |parent_window|.
|
| #if defined(OS_LINUX) || defined(OS_WIN)
|
| chrome::ShowWebShareTargetPickerDialog(nullptr /* parent_window */, targets,
|
| callback);
|
| @@ -125,65 +131,145 @@ void ShareServiceImpl::ShowPickerDialog(
|
| #endif
|
| }
|
|
|
| +Browser* ShareServiceImpl::GetBrowser() {
|
| +// TODO(constantina): Prevent this code from being run/compiled in android.
|
| +#if defined(OS_LINUX) || defined(OS_WIN)
|
| + return BrowserList::GetInstance()->GetLastActive();
|
| +#else
|
| + return nullptr;
|
| +#endif
|
| +}
|
| +
|
| void ShareServiceImpl::OpenTargetURL(const GURL& target_url) {
|
| // TODO(constantina): Prevent this code from being run/compiled in android.
|
| #if defined(OS_LINUX) || defined(OS_WIN)
|
| - Browser* browser = BrowserList::GetInstance()->GetLastActive();
|
| + Browser* browser = GetBrowser();
|
| chrome::AddTabAt(browser, target_url,
|
| browser->tab_strip_model()->active_index() + 1, true);
|
| #endif
|
| }
|
|
|
| +std::string ShareServiceImpl::GetTargetTemplate(
|
| + const std::string& target_url,
|
| + const base::DictionaryValue& share_targets) {
|
| + const base::DictionaryValue* share_target_info_dict = nullptr;
|
| + share_targets.GetDictionaryWithoutPathExpansion(target_url,
|
| + &share_target_info_dict);
|
| +
|
| + std::string url_template;
|
| + share_target_info_dict->GetString("url_template", &url_template);
|
| + return url_template;
|
| +}
|
| +
|
| +PrefService* ShareServiceImpl::GetPrefService() {
|
| +// TODO(constantina): Prevent this code from being run/compiled in android.
|
| +#if defined(OS_LINUX) || defined(OS_WIN)
|
| + return GetBrowser()->profile()->GetPrefs();
|
| +#else
|
| + return nullptr;
|
| +#endif
|
| +}
|
| +
|
| +blink::mojom::EngagementLevel ShareServiceImpl::GetEngagementLevel(
|
| + const GURL& url) {
|
| +// TODO(constantina): Prevent this code from being run/compiled in android.
|
| +#if defined(OS_LINUX) || defined(OS_WIN)
|
| + SiteEngagementService* site_engagement_service =
|
| + SiteEngagementService::Get(GetBrowser()->profile());
|
| + return site_engagement_service->GetEngagementLevel(url);
|
| +#else
|
| + return blink::mojom::EngagementLevel::NONE;
|
| +#endif
|
| +}
|
| +
|
| +// static
|
| +std::vector<std::pair<base::string16, GURL>>
|
| +ShareServiceImpl::GetTargetsWithSufficientEngagement(
|
| + const base::DictionaryValue& share_targets) {
|
| + constexpr blink::mojom::EngagementLevel kMinimumEngagementLevel =
|
| + blink::mojom::EngagementLevel::LOW;
|
| +
|
| + std::vector<std::pair<base::string16, GURL>> sufficiently_engaged_targets;
|
| +
|
| + for (base::DictionaryValue::Iterator it(share_targets); !it.IsAtEnd();
|
| + it.Advance()) {
|
| + GURL manifest_url(it.key());
|
| + if (GetEngagementLevel(manifest_url) >= kMinimumEngagementLevel) {
|
| + const base::DictionaryValue* share_target_dict;
|
| + bool result = it.value().GetAsDictionary(&share_target_dict);
|
| + DCHECK(result);
|
| +
|
| + std::string name;
|
| + share_target_dict->GetString("name", &name);
|
| +
|
| + sufficiently_engaged_targets.push_back(
|
| + make_pair(base::UTF8ToUTF16(name), manifest_url));
|
| + }
|
| + }
|
| +
|
| + return sufficiently_engaged_targets;
|
| +}
|
| +
|
| void ShareServiceImpl::Share(const std::string& title,
|
| const std::string& text,
|
| const GURL& share_url,
|
| const ShareCallback& callback) {
|
| - // TODO(constantina): Replace hard-coded name and manifest URL with the list
|
| - // of registered targets' manifest URLs.
|
| - constexpr char kTargetName[] = "Web Share Target Test App";
|
| - constexpr char kManifestURL[] =
|
| - "https://wicg.github.io/web-share-target/demos/manifest.json";
|
| - // TODO(constantina): Pass vector of pairs of target names and manifest URLs
|
| - // to picker.
|
| - std::vector<std::pair<base::string16, GURL>> targets{make_pair(
|
| - base::ASCIIToUTF16(kTargetName), GURL(kManifestURL))};
|
| -
|
| - ShowPickerDialog(targets, base::Bind(&ShareServiceImpl::OnPickerClosed,
|
| - base::Unretained(this), title, text,
|
| - share_url, callback));
|
| + std::unique_ptr<base::DictionaryValue> share_targets;
|
| +
|
| +// TODO(constantina): Prevent this code from being run/compiled in android.
|
| +#if defined(OS_LINUX) || defined(OS_WIN)
|
| + share_targets = GetPrefService()
|
| + ->GetDictionary(prefs::kWebShareVisitedTargets)
|
| + ->CreateDeepCopy();
|
| +#else
|
| + return;
|
| +#endif
|
| +
|
| + std::vector<std::pair<base::string16, GURL>> sufficiently_engaged_targets =
|
| + GetTargetsWithSufficientEngagement(*share_targets);
|
| +
|
| + ShowPickerDialog(
|
| + sufficiently_engaged_targets,
|
| + base::Bind(&ShareServiceImpl::OnPickerClosed, base::Unretained(this),
|
| + base::Passed(&share_targets), title, text, share_url,
|
| + callback));
|
| }
|
|
|
| -void ShareServiceImpl::OnPickerClosed(const std::string& title,
|
| - const std::string& text,
|
| - const GURL& share_url,
|
| - const ShareCallback& callback,
|
| - base::Optional<std::string> result) {
|
| +void ShareServiceImpl::OnPickerClosed(
|
| + std::unique_ptr<base::DictionaryValue> share_targets,
|
| + const std::string& title,
|
| + const std::string& text,
|
| + const GURL& share_url,
|
| + const ShareCallback& callback,
|
| + base::Optional<std::string> result) {
|
| if (!result.has_value()) {
|
| callback.Run(base::Optional<std::string>("Share was cancelled"));
|
| return;
|
| }
|
|
|
| - // TODO(constantina): use manifest URL in result to look up corresponding URL
|
| - // template.
|
| - constexpr char kUrlTemplate[] =
|
| - "https://wicg.github.io/web-share-target/demos/"
|
| - "sharetarget.html?title={title}&text={text}&url={url}";
|
| + std::string chosen_target = result.value();
|
|
|
| + std::string url_template = GetTargetTemplate(chosen_target, *share_targets);
|
| std::string url_template_filled;
|
| - if (!ReplacePlaceholders(kUrlTemplate, title, text, share_url,
|
| + if (!ReplacePlaceholders(url_template, title, text, share_url,
|
| &url_template_filled)) {
|
| callback.Run(base::Optional<std::string>(
|
| "Error: unable to replace placeholders in url template"));
|
| return;
|
| }
|
|
|
| - GURL target_url(url_template_filled);
|
| - if (!target_url.is_valid()) {
|
| + // The template is relative to the manifest URL (minus the filename).
|
| + // Concatenate to make an absolute URL.
|
| + base::StringPiece url_base(
|
| + chosen_target.data(),
|
| + chosen_target.size() - GURL(chosen_target).ExtractFileName().size());
|
| + const GURL target(url_base.as_string() + url_template_filled);
|
| + if (!target.is_valid()) {
|
| callback.Run(base::Optional<std::string>(
|
| "Error: url of share target is not a valid url."));
|
| return;
|
| }
|
| - OpenTargetURL(target_url);
|
| + OpenTargetURL(target);
|
|
|
| callback.Run(base::nullopt);
|
| }
|
|
|