Commit 4417ce64 authored by cco3's avatar cco3 Committed by Commit bot

Pass Physical Web metadata through a struct

Currently, we use DictionaryValues in the Physical Web data source.
The problem with this is that we cannot store store longs (timestamps).
This change introduces a metadata struct that can be requested from the
data source, deprecating the DictionaryValue option.

BUG=667722

Review-Url: https://codereview.chromium.org/2561493002
Cr-Commit-Position: refs/heads/master@{#443425}
parent c4bfb0e6
...@@ -283,7 +283,7 @@ class UrlManager { ...@@ -283,7 +283,7 @@ class UrlManager {
PwsResult pwsResult = mPwsResultMap.get(requestUrl); PwsResult pwsResult = mPwsResultMap.get(requestUrl);
if (pwsResult != null) { if (pwsResult != null) {
nativeAppendMetadataItem(nativePhysicalWebCollection, requestUrl, nativeAppendMetadataItem(nativePhysicalWebCollection, requestUrl,
urlInfo.getDistance(), (int) urlInfo.getScanTimestamp(), pwsResult.siteUrl, urlInfo.getDistance(), urlInfo.getScanTimestamp(), pwsResult.siteUrl,
pwsResult.iconUrl, pwsResult.title, pwsResult.description, pwsResult.iconUrl, pwsResult.title, pwsResult.description,
pwsResult.groupId); pwsResult.groupId);
} }
...@@ -825,7 +825,7 @@ class UrlManager { ...@@ -825,7 +825,7 @@ class UrlManager {
private native long nativeInit(); private native long nativeInit();
private native void nativeAppendMetadataItem(long nativePhysicalWebCollection, private native void nativeAppendMetadataItem(long nativePhysicalWebCollection,
String requestUrl, double distanceEstimate, int scanTimestamp, String siteUrl, String requestUrl, double distanceEstimate, long scanTimestamp, String siteUrl,
String iconUrl, String title, String description, String groupId); String iconUrl, String title, String description, String groupId);
private native void nativeOnFound(long nativePhysicalWebDataSourceAndroid, String url); private native void nativeOnFound(long nativePhysicalWebDataSourceAndroid, String url);
private native void nativeOnLost(long nativePhysicalWebDataSourceAndroid, String url); private native void nativeOnLost(long nativePhysicalWebDataSourceAndroid, String url);
......
...@@ -19,7 +19,8 @@ using base::android::JavaParamRef; ...@@ -19,7 +19,8 @@ using base::android::JavaParamRef;
using base::android::ScopedJavaLocalRef; using base::android::ScopedJavaLocalRef;
PhysicalWebCollection::PhysicalWebCollection() PhysicalWebCollection::PhysicalWebCollection()
: metadata_list_(base::MakeUnique<base::ListValue>()), : dictionary_value_list_(base::MakeUnique<base::ListValue>()),
metadata_list_(base::MakeUnique<physical_web::MetadataList>()),
accessed_once_(false) {} accessed_once_(false) {}
PhysicalWebCollection::~PhysicalWebCollection() {} PhysicalWebCollection::~PhysicalWebCollection() {}
...@@ -29,37 +30,56 @@ void PhysicalWebCollection::AppendMetadataItem( ...@@ -29,37 +30,56 @@ void PhysicalWebCollection::AppendMetadataItem(
const JavaParamRef<jobject>& obj, const JavaParamRef<jobject>& obj,
const JavaParamRef<jstring>& j_request_url, const JavaParamRef<jstring>& j_request_url,
jdouble distance_estimate, jdouble distance_estimate,
jint scan_timestamp, jlong scan_timestamp,
const JavaParamRef<jstring>& j_site_url, const JavaParamRef<jstring>& j_site_url,
const JavaParamRef<jstring>& j_icon_url, const JavaParamRef<jstring>& j_icon_url,
const JavaParamRef<jstring>& j_title, const JavaParamRef<jstring>& j_title,
const JavaParamRef<jstring>& j_description, const JavaParamRef<jstring>& j_description,
const JavaParamRef<jstring>& j_group_id) { const JavaParamRef<jstring>& j_group_id) {
auto metadata_item = new base::DictionaryValue(); // Create a DictionaryValue. Notice that we no longer set the timestamp
metadata_item->SetString(physical_web::kScannedUrlKey, // since it is a long and the DictionaryValue can only store ints.
auto dictionary_value = base::MakeUnique<base::DictionaryValue>();
dictionary_value->SetString(physical_web::kScannedUrlKey,
ConvertJavaStringToUTF8(j_request_url)); ConvertJavaStringToUTF8(j_request_url));
metadata_item->SetDouble(physical_web::kDistanceEstimateKey, dictionary_value->SetDouble(physical_web::kDistanceEstimateKey,
distance_estimate); distance_estimate);
metadata_item->SetInteger(physical_web::kScanTimestampKey, scan_timestamp); dictionary_value->SetString(physical_web::kResolvedUrlKey,
metadata_item->SetString(physical_web::kResolvedUrlKey,
ConvertJavaStringToUTF8(j_site_url)); ConvertJavaStringToUTF8(j_site_url));
metadata_item->SetString(physical_web::kIconUrlKey, dictionary_value->SetString(physical_web::kIconUrlKey,
ConvertJavaStringToUTF8(j_icon_url)); ConvertJavaStringToUTF8(j_icon_url));
metadata_item->SetString(physical_web::kTitleKey, dictionary_value->SetString(physical_web::kTitleKey,
ConvertJavaStringToUTF8(j_title)); ConvertJavaStringToUTF8(j_title));
metadata_item->SetString(physical_web::kDescriptionKey, dictionary_value->SetString(physical_web::kDescriptionKey,
ConvertJavaStringToUTF8(j_description)); ConvertJavaStringToUTF8(j_description));
metadata_item->SetString(physical_web::kGroupIdKey, dictionary_value->SetString(physical_web::kGroupIdKey,
ConvertJavaStringToUTF8(j_group_id)); ConvertJavaStringToUTF8(j_group_id));
metadata_list_->Append(std::move(metadata_item)); dictionary_value_list_->Append(std::move(dictionary_value));
physical_web::Metadata metadata;
metadata.scanned_url = GURL(ConvertJavaStringToUTF8(j_request_url));
metadata.resolved_url = GURL(ConvertJavaStringToUTF8(j_site_url));
metadata.icon_url = GURL(ConvertJavaStringToUTF8(j_icon_url));
metadata.title = ConvertJavaStringToUTF8(j_title);
metadata.description = ConvertJavaStringToUTF8(j_description);
metadata.group_id = ConvertJavaStringToUTF8(j_group_id);
metadata.distance_estimate = distance_estimate;
metadata.scan_timestamp = base::Time::FromJavaTime(scan_timestamp);
metadata_list_->push_back(std::move(metadata));
} }
std::unique_ptr<base::ListValue> PhysicalWebCollection::GetMetadataList() { std::unique_ptr<physical_web::MetadataList>
PhysicalWebCollection::GetMetadataList() {
DCHECK(!accessed_once_); DCHECK(!accessed_once_);
accessed_once_ = true; accessed_once_ = true;
return std::move(metadata_list_); return std::move(metadata_list_);
} }
std::unique_ptr<base::ListValue> PhysicalWebCollection::GetMetadata() {
DCHECK(!accessed_once_);
accessed_once_ = true;
return std::move(dictionary_value_list_);
}
PhysicalWebDataSourceAndroid::PhysicalWebDataSourceAndroid() { PhysicalWebDataSourceAndroid::PhysicalWebDataSourceAndroid() {
Initialize(); Initialize();
} }
...@@ -85,16 +105,28 @@ void PhysicalWebDataSourceAndroid::StopDiscovery() { ...@@ -85,16 +105,28 @@ void PhysicalWebDataSourceAndroid::StopDiscovery() {
NOTREACHED(); NOTREACHED();
} }
std::unique_ptr<base::ListValue> PhysicalWebDataSourceAndroid::GetMetadata() { std::unique_ptr<physical_web::MetadataList>
PhysicalWebDataSourceAndroid::GetMetadataList() {
JNIEnv* env = AttachCurrentThread(); JNIEnv* env = AttachCurrentThread();
auto pw_collection = base::MakeUnique<PhysicalWebCollection>(); auto pw_collection = base::MakeUnique<PhysicalWebCollection>();
Java_UrlManager_getPwCollection(env, url_manager_.obj(), Java_UrlManager_getPwCollection(env, url_manager_.obj(),
(long)pw_collection.get()); reinterpret_cast<long>(pw_collection.get()));
return pw_collection->GetMetadataList(); return pw_collection->GetMetadataList();
} }
std::unique_ptr<base::ListValue>
PhysicalWebDataSourceAndroid::GetMetadata() {
JNIEnv* env = AttachCurrentThread();
auto pw_collection = base::MakeUnique<PhysicalWebCollection>();
Java_UrlManager_getPwCollection(env, url_manager_.obj(),
reinterpret_cast<long>(pw_collection.get()));
return pw_collection->GetMetadata();
}
bool PhysicalWebDataSourceAndroid::HasUnresolvedDiscoveries() { bool PhysicalWebDataSourceAndroid::HasUnresolvedDiscoveries() {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
return false; return false;
......
...@@ -27,7 +27,7 @@ class PhysicalWebCollection { ...@@ -27,7 +27,7 @@ class PhysicalWebCollection {
const base::android::JavaParamRef<jobject>& obj, const base::android::JavaParamRef<jobject>& obj,
const base::android::JavaParamRef<jstring>& j_request_url, const base::android::JavaParamRef<jstring>& j_request_url,
jdouble distance_estimate, jdouble distance_estimate,
jint scan_timestamp, jlong scan_timestamp,
const base::android::JavaParamRef<jstring>& j_site_url, const base::android::JavaParamRef<jstring>& j_site_url,
const base::android::JavaParamRef<jstring>& j_icon_url, const base::android::JavaParamRef<jstring>& j_icon_url,
const base::android::JavaParamRef<jstring>& j_title, const base::android::JavaParamRef<jstring>& j_title,
...@@ -36,10 +36,17 @@ class PhysicalWebCollection { ...@@ -36,10 +36,17 @@ class PhysicalWebCollection {
// Returns the metadata list and transfers ownership of the list to the // Returns the metadata list and transfers ownership of the list to the
// caller. Call only once. // caller. Call only once.
std::unique_ptr<base::ListValue> GetMetadataList(); std::unique_ptr<physical_web::MetadataList> GetMetadataList();
// Returns the metadata list and transfers ownership of the list to the
// caller. Call only once.
// DEPRECATED
// TODO(cco3): Remove when we no longer rely on this.
std::unique_ptr<base::ListValue> GetMetadata();
private: private:
std::unique_ptr<base::ListValue> metadata_list_; std::unique_ptr<base::ListValue> dictionary_value_list_;
std::unique_ptr<physical_web::MetadataList> metadata_list_;
bool accessed_once_; bool accessed_once_;
DISALLOW_COPY_AND_ASSIGN(PhysicalWebCollection); DISALLOW_COPY_AND_ASSIGN(PhysicalWebCollection);
...@@ -59,6 +66,7 @@ class PhysicalWebDataSourceAndroid ...@@ -59,6 +66,7 @@ class PhysicalWebDataSourceAndroid
void StopDiscovery() override; void StopDiscovery() override;
std::unique_ptr<base::ListValue> GetMetadata() override; std::unique_ptr<base::ListValue> GetMetadata() override;
std::unique_ptr<physical_web::MetadataList> GetMetadataList() override;
bool HasUnresolvedDiscoveries() override; bool HasUnresolvedDiscoveries() override;
void OnFound(JNIEnv* env, void OnFound(JNIEnv* env,
......
// Copyright 2016 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/android/physical_web/physical_web_data_source_android.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/memory/ptr_util.h"
#include "base/values.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::android::JavaParamRef;
namespace {
const char kRequestUrl[] = "https://awesomesite.us/";
const double kDistanceEstimate = 42.0;
const int64_t kScanTimestamp = 10000000L; // 10M
const char kSiteUrl[] = "https://awesomesite.us/page.html";
const char kIconUrl[] = "https://awesomesite.us/favicon.ico";
const char kTitle[] = "AwesomeSite";
const char kDescription[] = "An awesome site";
const char kGroupId[] = "14a8ef122";
} // namespace
class PhysicalWebCollectionTest : public testing::Test {
public:
PhysicalWebCollectionTest() {}
~PhysicalWebCollectionTest() override {}
void SetUp() override {
collection_ = base::MakeUnique<PhysicalWebCollection>();
env_ = base::android::AttachCurrentThread();
}
void TearDown() override {
collection_.reset();
}
PhysicalWebCollection* Collection();
JNIEnv* Env();
jstring JavaString(const std::string& value);
private:
std::unique_ptr<PhysicalWebCollection> collection_;
JNIEnv* env_;
};
PhysicalWebCollection* PhysicalWebCollectionTest::Collection() {
DCHECK(collection_);
return collection_.get();
}
JNIEnv* PhysicalWebCollectionTest::Env() {
return env_;
}
jstring PhysicalWebCollectionTest::JavaString(const std::string& value) {
return base::android::ConvertUTF8ToJavaString(Env(), value).Release();
}
TEST_F(PhysicalWebCollectionTest, AppendMetadataItem_ListWork) {
Collection()->AppendMetadataItem(
Env(),
JavaParamRef<jobject>(NULL),
JavaParamRef<jstring>(Env(), JavaString(kRequestUrl)),
static_cast<jdouble>(kDistanceEstimate),
static_cast<jlong>(kScanTimestamp),
JavaParamRef<jstring>(Env(), JavaString(kSiteUrl)),
JavaParamRef<jstring>(Env(), JavaString(kIconUrl)),
JavaParamRef<jstring>(Env(), JavaString(kTitle)),
JavaParamRef<jstring>(Env(), JavaString(kDescription)),
JavaParamRef<jstring>(Env(), JavaString(kGroupId)));
std::unique_ptr<physical_web::MetadataList> metadata_list =
Collection()->GetMetadataList();
EXPECT_EQ(1U, metadata_list->size());
auto metadata = (*metadata_list.get())[0];
EXPECT_EQ(kRequestUrl, metadata.scanned_url.spec());
EXPECT_EQ(kDistanceEstimate, metadata.distance_estimate);
EXPECT_EQ(kScanTimestamp, metadata.scan_timestamp.ToJavaTime());
EXPECT_EQ(kSiteUrl, metadata.resolved_url.spec());
EXPECT_EQ(kIconUrl, metadata.icon_url.spec());
EXPECT_EQ(kTitle, metadata.title);
EXPECT_EQ(kDescription, metadata.description);
EXPECT_EQ(kGroupId, metadata.group_id);
}
TEST_F(PhysicalWebCollectionTest, AppendMetadataItem_DictionaryValueWorks) {
Collection()->AppendMetadataItem(
Env(),
JavaParamRef<jobject>(NULL),
JavaParamRef<jstring>(Env(), JavaString(kRequestUrl)),
static_cast<jdouble>(kDistanceEstimate),
static_cast<jlong>(kScanTimestamp),
JavaParamRef<jstring>(Env(), JavaString(kSiteUrl)),
JavaParamRef<jstring>(Env(), JavaString(kIconUrl)),
JavaParamRef<jstring>(Env(), JavaString(kTitle)),
JavaParamRef<jstring>(Env(), JavaString(kDescription)),
JavaParamRef<jstring>(Env(), JavaString(kGroupId)));
std::unique_ptr<base::ListValue> list_value = Collection()->GetMetadata();
EXPECT_EQ(1U, list_value->GetSize());
const base::Value* value;
EXPECT_TRUE(list_value->Get(0, &value));
const base::DictionaryValue* dictionary_value;
EXPECT_TRUE(value->GetAsDictionary(&dictionary_value));
std::string stored_scanned_url;
EXPECT_TRUE(dictionary_value->GetString(physical_web::kScannedUrlKey,
&stored_scanned_url));
EXPECT_EQ(kRequestUrl, stored_scanned_url);
double stored_distance_estimate;
EXPECT_TRUE(dictionary_value->GetDouble(physical_web::kDistanceEstimateKey,
&stored_distance_estimate));
EXPECT_EQ(kDistanceEstimate, stored_distance_estimate);
std::string stored_resolved_url;
EXPECT_TRUE(dictionary_value->GetString(physical_web::kResolvedUrlKey,
&stored_resolved_url));
EXPECT_EQ(kSiteUrl, stored_resolved_url);
std::string stored_icon_url;
EXPECT_TRUE(dictionary_value->GetString(physical_web::kIconUrlKey,
&stored_icon_url));
EXPECT_EQ(kIconUrl, stored_icon_url);
std::string stored_title;
EXPECT_TRUE(dictionary_value->GetString(physical_web::kTitleKey,
&stored_title));
EXPECT_EQ(kTitle, stored_title);
std::string stored_description;
EXPECT_TRUE(dictionary_value->GetString(physical_web::kDescriptionKey,
&stored_description));
EXPECT_EQ(kDescription, stored_description);
std::string stored_group_id;
EXPECT_TRUE(dictionary_value->GetString(physical_web::kGroupIdKey,
&stored_group_id));
EXPECT_EQ(kGroupId, stored_group_id);
}
...@@ -3042,6 +3042,7 @@ test("unit_tests") { ...@@ -3042,6 +3042,7 @@ test("unit_tests") {
"../browser/android/mock_location_settings.cc", "../browser/android/mock_location_settings.cc",
"../browser/android/mock_location_settings.h", "../browser/android/mock_location_settings.h",
"../browser/android/net/external_estimate_provider_android_unittest.cc", "../browser/android/net/external_estimate_provider_android_unittest.cc",
"../browser/android/physical_web/physical_web_data_source_android_unittest.cc",
"../browser/android/preferences/pref_service_bridge_unittest.cc", "../browser/android/preferences/pref_service_bridge_unittest.cc",
"../browser/android/shortcut_info_unittest.cc", "../browser/android/shortcut_info_unittest.cc",
"../browser/android/thumbnail/scoped_ptr_expiring_cache_unittest.cc", "../browser/android/thumbnail/scoped_ptr_expiring_cache_unittest.cc",
......
...@@ -11,8 +11,9 @@ source_set("data_source") { ...@@ -11,8 +11,9 @@ source_set("data_source") {
"physical_web_listener.h", "physical_web_listener.h",
] ]
deps = [ public_deps = [
"//base", "//base",
"//url",
] ]
} }
......
...@@ -73,6 +73,10 @@ std::unique_ptr<base::ListValue> FakePhysicalWebDataSource::GetMetadata() { ...@@ -73,6 +73,10 @@ std::unique_ptr<base::ListValue> FakePhysicalWebDataSource::GetMetadata() {
return metadata_->CreateDeepCopy(); return metadata_->CreateDeepCopy();
} }
std::unique_ptr<MetadataList> FakePhysicalWebDataSource::GetMetadataList() {
return base::MakeUnique<MetadataList>(*metadata_list_.get());
}
bool FakePhysicalWebDataSource::HasUnresolvedDiscoveries() { bool FakePhysicalWebDataSource::HasUnresolvedDiscoveries() {
return false; return false;
} }
...@@ -92,6 +96,11 @@ void FakePhysicalWebDataSource::SetMetadata( ...@@ -92,6 +96,11 @@ void FakePhysicalWebDataSource::SetMetadata(
metadata_ = std::move(metadata); metadata_ = std::move(metadata);
} }
void FakePhysicalWebDataSource::SetMetadataList(
std::unique_ptr<MetadataList> metadata_list) {
metadata_list_ = std::move(metadata_list);
}
void FakePhysicalWebDataSource::NotifyOnFound(const GURL& url) { void FakePhysicalWebDataSource::NotifyOnFound(const GURL& url) {
for (PhysicalWebListener& observer : observer_list_) for (PhysicalWebListener& observer : observer_list_)
observer.OnFound(url); observer.OnFound(url);
......
...@@ -43,6 +43,7 @@ class FakePhysicalWebDataSource : public PhysicalWebDataSource { ...@@ -43,6 +43,7 @@ class FakePhysicalWebDataSource : public PhysicalWebDataSource {
void StopDiscovery() override; void StopDiscovery() override;
std::unique_ptr<base::ListValue> GetMetadata() override; std::unique_ptr<base::ListValue> GetMetadata() override;
std::unique_ptr<MetadataList> GetMetadataList() override;
bool HasUnresolvedDiscoveries() override; bool HasUnresolvedDiscoveries() override;
...@@ -51,12 +52,14 @@ class FakePhysicalWebDataSource : public PhysicalWebDataSource { ...@@ -51,12 +52,14 @@ class FakePhysicalWebDataSource : public PhysicalWebDataSource {
// for testing // for testing
void SetMetadata(std::unique_ptr<base::ListValue> metadata); void SetMetadata(std::unique_ptr<base::ListValue> metadata);
void SetMetadataList(std::unique_ptr<MetadataList> metadata_list);
void NotifyOnFound(const GURL& url); void NotifyOnFound(const GURL& url);
void NotifyOnLost(const GURL& url); void NotifyOnLost(const GURL& url);
void NotifyOnDistanceChanged(const GURL& url, double distance_estimate); void NotifyOnDistanceChanged(const GURL& url, double distance_estimate);
private: private:
std::unique_ptr<base::ListValue> metadata_; std::unique_ptr<base::ListValue> metadata_;
std::unique_ptr<MetadataList> metadata_list_;
base::ObserverList<PhysicalWebListener> observer_list_; base::ObserverList<PhysicalWebListener> observer_list_;
DISALLOW_COPY_AND_ASSIGN(FakePhysicalWebDataSource); DISALLOW_COPY_AND_ASSIGN(FakePhysicalWebDataSource);
......
...@@ -15,4 +15,10 @@ const char kScanTimestampKey[] = "scanTimestamp"; ...@@ -15,4 +15,10 @@ const char kScanTimestampKey[] = "scanTimestamp";
const char kScannedUrlKey[] = "scannedUrl"; const char kScannedUrlKey[] = "scannedUrl";
const char kTitleKey[] = "title"; const char kTitleKey[] = "title";
Metadata::Metadata() {}
Metadata::Metadata(const Metadata& other) = default;
Metadata::~Metadata() {}
} // namespace physical_web } // namespace physical_web
...@@ -6,6 +6,11 @@ ...@@ -6,6 +6,11 @@
#define COMPONENTS_PHYSICAL_WEB_DATA_SOURCE_PHYSICAL_WEB_DATA_SOURCE_H_ #define COMPONENTS_PHYSICAL_WEB_DATA_SOURCE_PHYSICAL_WEB_DATA_SOURCE_H_
#include <memory> #include <memory>
#include <string>
#include <vector>
#include "base/time/time.h"
#include "url/gurl.h"
namespace base { namespace base {
class ListValue; class ListValue;
...@@ -16,6 +21,7 @@ namespace physical_web { ...@@ -16,6 +21,7 @@ namespace physical_web {
class PhysicalWebListener; class PhysicalWebListener;
// Dictionary keys for reading Physical Web URL metadata. // Dictionary keys for reading Physical Web URL metadata.
// TODO(cco3): Remove these when we are no longer dependent.
extern const char kDescriptionKey[]; extern const char kDescriptionKey[];
extern const char kDistanceEstimateKey[]; extern const char kDistanceEstimateKey[];
extern const char kGroupIdKey[]; extern const char kGroupIdKey[];
...@@ -25,6 +31,53 @@ extern const char kScanTimestampKey[]; ...@@ -25,6 +31,53 @@ extern const char kScanTimestampKey[];
extern const char kScannedUrlKey[]; extern const char kScannedUrlKey[];
extern const char kTitleKey[]; extern const char kTitleKey[];
// Metadata struct for associating data with Physical Web URLs.
struct Metadata {
Metadata();
Metadata(const Metadata& other);
~Metadata();
// The URL broadcasted by the beacon and scanned by the client device.
// REQUIRED
GURL scanned_url;
// The URL that the scanned_url redirects to.
// This is the URL that users should be directed to.
// REQUIRED
GURL resolved_url;
// The favicon URL.
// OPTIONAL
GURL icon_url;
// The title of the web page.
// REQUIRED
std::string title;
// The description of the web page.
// OPTIONAL: When the website has not specified a description, the PWS
// generates one based on the initial text of the site, but this is not
// guaranteed behavior.
std::string description;
// An identifier that associates multiple resolved URLs. These URLs will
// most typically be associated because their metadata is near-identical
// (same icon, title, description, URL minus the fragment). e.g.,
// https://mymuseum/exhibits#e1
// https://mymuseum/exhibits#e2
// If two URLs have the same group id, only one should be shown (typically,
// the one with the smallest distance estimate).
// OPTIONAL: Treat the item as its own unique group if this is empty.
std::string group_id;
// The estimated distance between the user and the Physical Web device (e.g.,
// beacon) in meters.
// OPTIONAL: This will be a value <= 0 if no distance estimate has been
// calculated. The distance may not be calculated if we aren't able to
// receive an estimate from the underlying scanning service in time, or if
// (in the future) we begin sourcing Physical Web URLs from a non-BLE
// transport (e.g. mDNS).
double distance_estimate;
// The timestamp corresponding to when this URL was last scanned.
// REQUIRED
base::Time scan_timestamp;
};
using MetadataList = std::vector<Metadata>;
// Helper class for accessing Physical Web metadata and controlling the scanner. // Helper class for accessing Physical Web metadata and controlling the scanner.
class PhysicalWebDataSource { class PhysicalWebDataSource {
public: public:
...@@ -41,6 +94,14 @@ class PhysicalWebDataSource { ...@@ -41,6 +94,14 @@ class PhysicalWebDataSource {
// requests are disabled or if discovery is not active, the list will be // requests are disabled or if discovery is not active, the list will be
// empty. The method can be called at any time to receive the current metadata // empty. The method can be called at any time to receive the current metadata
// list. // list.
virtual std::unique_ptr<MetadataList> GetMetadataList() = 0;
// Returns a list of resolved URLs and associated page metadata. If network
// requests are disabled or if discovery is not active, the list will be
// empty. The method can be called at any time to receive the current metadata
// list.
// DEPRECATED
// TODO(cco3): Remove this when we are no longer dependent on it.
virtual std::unique_ptr<base::ListValue> GetMetadata() = 0; virtual std::unique_ptr<base::ListValue> GetMetadata() = 0;
// Returns boolean |true| if network requests are disabled and there are one // Returns boolean |true| if network requests are disabled and there are one
......
...@@ -23,6 +23,7 @@ class TestPhysicalWebDataSource : public PhysicalWebDataSourceImpl { ...@@ -23,6 +23,7 @@ class TestPhysicalWebDataSource : public PhysicalWebDataSourceImpl {
void StartDiscovery(bool network_request_enabled) override; void StartDiscovery(bool network_request_enabled) override;
void StopDiscovery() override; void StopDiscovery() override;
std::unique_ptr<base::ListValue> GetMetadata() override; std::unique_ptr<base::ListValue> GetMetadata() override;
std::unique_ptr<MetadataList> GetMetadataList() override;
bool HasUnresolvedDiscoveries() override; bool HasUnresolvedDiscoveries() override;
}; };
void TestPhysicalWebDataSource::StartDiscovery(bool network_request_enabled) {} void TestPhysicalWebDataSource::StartDiscovery(bool network_request_enabled) {}
...@@ -33,6 +34,10 @@ std::unique_ptr<base::ListValue> TestPhysicalWebDataSource::GetMetadata() { ...@@ -33,6 +34,10 @@ std::unique_ptr<base::ListValue> TestPhysicalWebDataSource::GetMetadata() {
return NULL; return NULL;
} }
std::unique_ptr<MetadataList> TestPhysicalWebDataSource::GetMetadataList() {
return NULL;
}
bool TestPhysicalWebDataSource::HasUnresolvedDiscoveries() { bool TestPhysicalWebDataSource::HasUnresolvedDiscoveries() {
return false; return false;
} }
......
...@@ -35,6 +35,10 @@ class IOSChromePhysicalWebDataSource ...@@ -35,6 +35,10 @@ class IOSChromePhysicalWebDataSource
// requests are disabled, the list will be empty. // requests are disabled, the list will be empty.
std::unique_ptr<base::ListValue> GetMetadata() override; std::unique_ptr<base::ListValue> GetMetadata() override;
// Returns a list of resolved URLs and associated page metadata. If network
// requests are disabled, the list will be empty.
std::unique_ptr<physical_web::MetadataList> GetMetadataList() override;
// Returns boolean |true| if network requests are disabled and there are one // Returns boolean |true| if network requests are disabled and there are one
// or more discovered URLs that have not been sent to the resolution service. // or more discovered URLs that have not been sent to the resolution service.
bool HasUnresolvedDiscoveries() override; bool HasUnresolvedDiscoveries() override;
......
...@@ -52,6 +52,14 @@ std::unique_ptr<base::ListValue> IOSChromePhysicalWebDataSource::GetMetadata() { ...@@ -52,6 +52,14 @@ std::unique_ptr<base::ListValue> IOSChromePhysicalWebDataSource::GetMetadata() {
return [scanner_ metadata]; return [scanner_ metadata];
} }
std::unique_ptr<physical_web::MetadataList>
IOSChromePhysicalWebDataSource::GetMetadataList() {
if (!scanner_) {
return base::MakeUnique<physical_web::MetadataList>();
}
return [scanner_ metadataList];
}
bool IOSChromePhysicalWebDataSource::HasUnresolvedDiscoveries() { bool IOSChromePhysicalWebDataSource::HasUnresolvedDiscoveries() {
return [scanner_ unresolvedBeaconsCount] > 0; return [scanner_ unresolvedBeaconsCount] > 0;
} }
...@@ -8,11 +8,17 @@ ...@@ -8,11 +8,17 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#include <memory> #include <memory>
#include <vector>
namespace base { namespace base {
class ListValue; class ListValue;
} }
namespace physical_web {
struct Metadata;
using MetadataList = std::vector<Metadata>;
}
@protocol PhysicalWebScannerDelegate; @protocol PhysicalWebScannerDelegate;
// This class will scan for physical web devices. // This class will scan for physical web devices.
...@@ -57,6 +63,11 @@ class ListValue; ...@@ -57,6 +63,11 @@ class ListValue;
// returned. // returned.
- (std::unique_ptr<base::ListValue>)metadata; - (std::unique_ptr<base::ListValue>)metadata;
// Returns the metadata for all resolved physical web URLs. The returned value
// will never be nil; if no metadata has been received then an empty list is
// returned.
- (std::unique_ptr<physical_web::MetadataList>)metadataList;
@end @end
@protocol PhysicalWebScannerDelegate<NSObject> @protocol PhysicalWebScannerDelegate<NSObject>
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#import "ios/chrome/common/physical_web/physical_web_device.h" #import "ios/chrome/common/physical_web/physical_web_device.h"
#import "ios/chrome/common/physical_web/physical_web_request.h" #import "ios/chrome/common/physical_web/physical_web_request.h"
#import "ios/chrome/common/physical_web/physical_web_types.h" #import "ios/chrome/common/physical_web/physical_web_types.h"
#include "url/gurl.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support." #error "This file requires ARC support."
...@@ -185,7 +186,7 @@ enum BeaconType { ...@@ -185,7 +186,7 @@ enum BeaconType {
} }
- (std::unique_ptr<base::ListValue>)metadata { - (std::unique_ptr<base::ListValue>)metadata {
auto metadataList = base::MakeUnique<base::ListValue>(); auto metadataRet = base::MakeUnique<base::ListValue>();
for (PhysicalWebDevice* device in [self devices]) { for (PhysicalWebDevice* device in [self devices]) {
std::string scannedUrl = std::string scannedUrl =
...@@ -202,10 +203,34 @@ enum BeaconType { ...@@ -202,10 +203,34 @@ enum BeaconType {
metadataItem->SetString(physical_web::kIconUrlKey, icon); metadataItem->SetString(physical_web::kIconUrlKey, icon);
metadataItem->SetString(physical_web::kTitleKey, title); metadataItem->SetString(physical_web::kTitleKey, title);
metadataItem->SetString(physical_web::kDescriptionKey, description); metadataItem->SetString(physical_web::kDescriptionKey, description);
metadataList->Append(std::move(metadataItem)); metadataRet->Append(std::move(metadataItem));
} }
return metadataList; return metadataRet;
}
- (std::unique_ptr<physical_web::MetadataList>)metadataList {
auto metadataRet = base::MakeUnique<physical_web::MetadataList>();
for (PhysicalWebDevice* device in [self devices]) {
std::string scannedUrl =
base::SysNSStringToUTF8([[device requestURL] absoluteString]);
std::string resolvedUrl =
base::SysNSStringToUTF8([[device url] absoluteString]);
std::string icon = base::SysNSStringToUTF8([[device icon] absoluteString]);
std::string title = base::SysNSStringToUTF8([device title]);
std::string description = base::SysNSStringToUTF8([device description]);
physical_web::Metadata metadataItem;
metadataItem.scanned_url = GURL(scannedUrl);
metadataItem.resolved_url = GURL(resolvedUrl);
metadataItem.icon_url = GURL(icon);
metadataItem.title = title;
metadataItem.description = description;
metadataRet->push_back(std::move(metadataItem));
}
return metadataRet;
} }
- (void)setNetworkRequestEnabled:(BOOL)enabled { - (void)setNetworkRequestEnabled:(BOOL)enabled {
......
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