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); |
} |