Commit f4b37cb6 authored by Viviane Yang's avatar Viviane Yang Committed by Commit Bot

[Push] Pass expirationTime attribute from PushMessagingService

to PushManager

This CL adds the capability to pass an expirationTime attribute from
PushMessagingServiceImpl down to PushManager, when PushManager::get
Subscription is called. It is an optional parameter specified in
milliseconds from 1st January 1970 UTC according to the standard.

https://w3c.github.io/push-api/#dfn-subscription-expiration-time

When PushManager::getSubscription is called, expiration_time should be
retrieved in PushMessagingServiceImpl from the app_identifier and sent
back as a callback to PushMessagingManager, which sents it to PushPro-
vider, converts it from a mojom::blink::PushSubscriptionPtr to a
PushSubscription object and returned to PushManager.

The expiration time will be stored in PushMessagingAppIdentifier, which
is currently not implemented yet but WIP. It will then call
PushMessagingServiceImpl::SubscribeEnd with a non-null value for expir-
ation_time and pass the expiration time in SubscriptionInfoCallback.

WIP Issue: 2302610

Change-Id: I1e6c69a930def902cd6f08813de5856ae08729fc
Bug: 1104215
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2302192Reviewed-by: default avatarRayan Kanso <rayankans@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarRichard Knoll <knollr@chromium.org>
Commit-Queue: Viviane Yang <viviy@google.com>
Cr-Commit-Position: refs/heads/master@{#789889}
parent f4a062fd
......@@ -127,6 +127,7 @@ void LegacyRegisterCallback(const base::Closure& done_callback,
void DidRegister(base::Closure done_callback,
const std::string& registration_id,
const GURL& endpoint,
const base::Optional<base::Time>& expiration_time,
const std::vector<uint8_t>& p256dh,
const std::vector<uint8_t>& auth,
blink::mojom::PushRegistrationStatus status) {
......
......@@ -717,7 +717,9 @@ void PushMessagingServiceImpl::SubscribeEnd(
const std::vector<uint8_t>& p256dh,
const std::vector<uint8_t>& auth,
blink::mojom::PushRegistrationStatus status) {
std::move(callback).Run(subscription_id, endpoint, p256dh, auth, status);
std::move(callback).Run(subscription_id, endpoint,
base::nullopt /* expiration_time*/, p256dh, auth,
status);
}
void PushMessagingServiceImpl::SubscribeEndWithError(
......@@ -798,6 +800,8 @@ void PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo(
// GetSubscriptionInfo methods -------------------------------------------------
// TODO(crbug.com/1104215): Get |expiration_time| from |app_identifier|, where
// it is stored in profile preferences
void PushMessagingServiceImpl::GetSubscriptionInfo(
const GURL& origin,
int64_t service_worker_registration_id,
......@@ -811,6 +815,7 @@ void PushMessagingServiceImpl::GetSubscriptionInfo(
if (app_identifier.is_null()) {
std::move(callback).Run(
false /* is_valid */, GURL::EmptyGURL() /*endpoint*/,
base::nullopt /* expiration_time */,
std::vector<uint8_t>() /* p256dh */, std::vector<uint8_t>() /* auth */);
return;
}
......@@ -842,6 +847,7 @@ void PushMessagingServiceImpl::DidValidateSubscription(
if (!is_valid) {
std::move(callback).Run(
false /* is_valid */, GURL::EmptyGURL() /* endpoint */,
base::nullopt /* expiration_time */,
std::vector<uint8_t>() /* p256dh */, std::vector<uint8_t>() /* auth */);
return;
}
......@@ -861,7 +867,8 @@ void PushMessagingServiceImpl::DidGetEncryptionInfo(
// I/O errors might prevent the GCM Driver from retrieving a key-pair.
bool is_valid = !p256dh.empty();
std::move(callback).Run(
is_valid, endpoint, std::vector<uint8_t>(p256dh.begin(), p256dh.end()),
is_valid, endpoint, base::nullopt /* expiration_time */,
std::vector<uint8_t>(p256dh.begin(), p256dh.end()),
std::vector<uint8_t>(auth_secret.begin(), auth_secret.end()));
}
......
......@@ -11,9 +11,11 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/gcm/gcm_profile_service_factory.h"
#include "chrome/browser/permissions/permission_manager_factory.h"
......@@ -105,11 +107,13 @@ class PushMessagingServiceTest : public ::testing::Test {
// Callback to use when the subscription may have been subscribed.
void DidRegister(std::string* subscription_id_out,
GURL* endpoint_out,
base::Optional<base::Time>* expiration_time_out,
std::vector<uint8_t>* p256dh_out,
std::vector<uint8_t>* auth_out,
base::Closure done_callback,
const std::string& registration_id,
const GURL& endpoint,
const base::Optional<base::Time>& expiration_time,
const std::vector<uint8_t>& p256dh,
const std::vector<uint8_t>& auth,
blink::mojom::PushRegistrationStatus status) {
......@@ -117,6 +121,7 @@ class PushMessagingServiceTest : public ::testing::Test {
status);
*subscription_id_out = registration_id;
*expiration_time_out = expiration_time;
*endpoint_out = endpoint;
*p256dh_out = p256dh;
*auth_out = auth;
......@@ -164,6 +169,7 @@ TEST_F(PushMessagingServiceTest, PayloadEncryptionTest) {
std::string subscription_id;
GURL endpoint;
base::Optional<base::Time> expiration_time;
std::vector<uint8_t> p256dh, auth;
base::RunLoop run_loop;
......@@ -179,7 +185,7 @@ TEST_F(PushMessagingServiceTest, PayloadEncryptionTest) {
origin, kTestServiceWorkerId, std::move(options),
base::BindOnce(&PushMessagingServiceTest::DidRegister,
base::Unretained(this), &subscription_id, &endpoint,
&p256dh, &auth, run_loop.QuitClosure()));
&expiration_time, &p256dh, &auth, run_loop.QuitClosure()));
EXPECT_EQ(0u, subscription_id.size()); // this must be asynchronous
......@@ -190,6 +196,7 @@ TEST_F(PushMessagingServiceTest, PayloadEncryptionTest) {
ASSERT_GT(endpoint.spec().size(), 0u);
ASSERT_GT(p256dh.size(), 0u);
ASSERT_GT(auth.size(), 0u);
ASSERT_EQ(expiration_time, base::nullopt);
// (3) Encrypt a message using the public key and authentication secret that
// are associated with the subscription.
......
......@@ -18,6 +18,7 @@
#include "base/optional.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/post_task.h"
#include "base/time/time.h"
#include "content/browser/permissions/permission_controller_impl.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/service_worker/service_worker_context_core.h"
......@@ -167,14 +168,16 @@ class PushMessagingManager::Core {
// Public GetSubscription methods on UI thread -------------------------------
// Callback called on UI thread.
void GetSubscriptionDidGetInfoOnUI(GetSubscriptionCallback callback,
const GURL& origin,
int64_t service_worker_registration_id,
const std::string& application_server_key,
bool is_valid,
const GURL& endpoint,
const std::vector<uint8_t>& p256dh,
const std::vector<uint8_t>& auth);
void GetSubscriptionDidGetInfoOnUI(
GetSubscriptionCallback callback,
const GURL& origin,
int64_t service_worker_registration_id,
const std::string& application_server_key,
bool is_valid,
const GURL& endpoint,
const base::Optional<base::Time>& expiration_time,
const std::vector<uint8_t>& p256dh,
const std::vector<uint8_t>& auth);
// Callback called on UI thread.
void GetSubscriptionDidUnsubscribe(
......@@ -216,6 +219,7 @@ class PushMessagingManager::Core {
void DidRegister(RegisterData data,
const std::string& push_subscription_id,
const GURL& endpoint,
const base::Optional<base::Time>& expiration_time,
const std::vector<uint8_t>& p256dh,
const std::vector<uint8_t>& auth,
blink::mojom::PushRegistrationStatus status);
......@@ -505,10 +509,14 @@ void PushMessagingManager::Core::DidRequestPermissionInIncognito(
blink::mojom::PushRegistrationStatus::INCOGNITO_PERMISSION_DENIED));
}
// TODO(crbug.com/1104215): Handle expiration_time that is passed from push
// service check if |expiration_time| is valid before saving it in |data| and
// passing it back in SendSubscriptionSuccess
void PushMessagingManager::Core::DidRegister(
RegisterData data,
const std::string& push_subscription_id,
const GURL& endpoint,
const base::Optional<base::Time>& expiration_time,
const std::vector<uint8_t>& p256dh,
const std::vector<uint8_t>& auth,
blink::mojom::PushRegistrationStatus status) {
......@@ -534,6 +542,8 @@ void PushMessagingManager::Core::DidRegister(
: blink::mojom::PushRegistrationStatus::
SUCCESS_FROM_PUSH_SERVICE));
} else {
// TODO(crbug.com/646721): for invalid |expiration_time| send a subscription
// error with a new PushRegistrationStatus
RunOrPostTaskOnThread(
FROM_HERE, ServiceWorkerContext::GetCoreThreadId(),
base::BindOnce(&PushMessagingManager::SendSubscriptionError, sw_parent_,
......@@ -844,6 +854,7 @@ void PushMessagingManager::Core::GetSubscriptionDidGetInfoOnUI(
const std::string& application_server_key,
bool is_valid,
const GURL& endpoint,
const base::Optional<base::Time>& expiration_time,
const std::vector<uint8_t>& p256dh,
const std::vector<uint8_t>& auth) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
......@@ -861,14 +872,12 @@ void PushMessagingManager::Core::GetSubscriptionDidGetInfoOnUI(
blink::mojom::PushGetRegistrationStatus status =
blink::mojom::PushGetRegistrationStatus::SUCCESS;
// TODO(crbug.com/1104215): Get expiration_time from push_service in
// Core::GetSubscriptionInfoOnUI
RunOrPostTaskOnThread(
FROM_HERE, ServiceWorkerContext::GetCoreThreadId(),
base::BindOnce(std::move(callback), status,
blink::mojom::PushSubscription::New(
endpoint, base::nullopt /* expiration_time */,
std::move(options), p256dh, auth)));
base::BindOnce(
std::move(callback), status,
blink::mojom::PushSubscription::New(
endpoint, expiration_time, std::move(options), p256dh, auth)));
RecordGetRegistrationStatus(status);
} else {
......@@ -930,6 +939,7 @@ void PushMessagingManager::Core::GetSubscriptionInfoOnUI(
if (!push_service) {
std::move(callback).Run(
false /* is_valid */, GURL::EmptyGURL() /* endpoint */,
base::nullopt /* expiration_time */,
std::vector<uint8_t>() /* p256dh */, std::vector<uint8_t>() /* auth */);
return;
}
......
......@@ -10,6 +10,8 @@
#include <vector>
#include "base/callback_forward.h"
#include "base/optional.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
#include "third_party/blink/public/mojom/push_messaging/push_messaging.mojom.h"
#include "url/gurl.h"
......@@ -34,6 +36,7 @@ class CONTENT_EXPORT PushMessagingService {
using RegisterCallback =
base::OnceCallback<void(const std::string& registration_id,
const GURL& endpoint,
const base::Optional<base::Time>& expiration_time,
const std::vector<uint8_t>& p256dh,
const std::vector<uint8_t>& auth,
blink::mojom::PushRegistrationStatus status)>;
......@@ -42,6 +45,7 @@ class CONTENT_EXPORT PushMessagingService {
using SubscriptionInfoCallback =
base::OnceCallback<void(bool is_valid,
const GURL& endpoint,
const base::Optional<base::Time>& expiration_time,
const std::vector<uint8_t>& p256dh,
const std::vector<uint8_t>& auth)>;
using StringCallback = base::OnceCallback<
......
......@@ -6,7 +6,9 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/optional.h"
#include "base/stl_util.h"
#include "base/time/time.h"
#include "content/public/browser/permission_type.h"
#include "content/shell/browser/web_test/web_test_browser_context.h"
#include "content/shell/browser/web_test/web_test_content_browser_client.h"
......@@ -38,6 +40,10 @@ const uint8_t kAuthentication[] = {0xA5, 0xD9, 0x3C, 0x43, 0x0C, 0x00,
static_assert(sizeof(kAuthentication) == 12,
"The fake authentication key must be at least 12 bytes in size.");
base::Time GetFutureTime() {
return base::Time::Now() + base::TimeDelta::FromDays(100);
}
} // anonymous namespace
WebTestPushMessagingService::WebTestPushMessagingService()
......@@ -79,17 +85,17 @@ void WebTestPushMessagingService::SubscribeFromWorker(
kTestP256Key + base::size(kTestP256Key));
std::vector<uint8_t> auth(kAuthentication,
kAuthentication + base::size(kAuthentication));
const std::string subscription_id = "layoutTestRegistrationId";
const GURL endpoint = CreateEndpoint(subscription_id);
subscribed_service_worker_registration_ = service_worker_registration_id;
std::move(callback).Run(
subscription_id, endpoint, p256dh, auth,
subscription_id, endpoint, GetFutureTime(), p256dh, auth,
blink::mojom::PushRegistrationStatus::SUCCESS_FROM_PUSH_SERVICE);
} else {
std::move(callback).Run(
"registration_id", GURL::EmptyGURL() /* endpoint */,
base::nullopt /* expiration_time */,
std::vector<uint8_t>() /* p256dh */, std::vector<uint8_t>() /* auth */,
blink::mojom::PushRegistrationStatus::PERMISSION_DENIED);
}
......@@ -105,9 +111,9 @@ void WebTestPushMessagingService::GetSubscriptionInfo(
kTestP256Key + base::size(kTestP256Key));
std::vector<uint8_t> auth(kAuthentication,
kAuthentication + base::size(kAuthentication));
const GURL endpoint = CreateEndpoint(subscription_id);
std::move(callback).Run(true /* is_valid */, endpoint, p256dh, auth);
std::move(callback).Run(true /* is_valid */, endpoint, GetFutureTime(),
p256dh, auth);
}
bool WebTestPushMessagingService::SupportNonVisibleMessages() {
......
......@@ -18,8 +18,6 @@ blink_modules_sources("push_messaging") {
"push_messaging_bridge.h",
"push_messaging_client.cc",
"push_messaging_client.h",
"push_messaging_type_converter.cc",
"push_messaging_type_converter.h",
"push_messaging_utils.cc",
"push_messaging_utils.h",
"push_provider.cc",
......@@ -32,6 +30,8 @@ blink_modules_sources("push_messaging") {
"push_subscription_change_event.h",
"push_subscription_options.cc",
"push_subscription_options.h",
"push_type_converter.cc",
"push_type_converter.h",
"service_worker_global_scope_push.h",
"service_worker_registration_push.cc",
"service_worker_registration_push.h",
......
......@@ -17,10 +17,10 @@
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/modules/manifest/manifest_manager.h"
#include "third_party/blink/renderer/modules/push_messaging/push_error.h"
#include "third_party/blink/renderer/modules/push_messaging/push_messaging_type_converter.h"
#include "third_party/blink/renderer/modules/push_messaging/push_messaging_utils.h"
#include "third_party/blink/renderer/modules/push_messaging/push_subscription.h"
#include "third_party/blink/renderer/modules/push_messaging/push_subscription_options.h"
#include "third_party/blink/renderer/modules/push_messaging/push_type_converter.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
......
......@@ -10,10 +10,10 @@
#include "third_party/blink/public/mojom/push_messaging/push_messaging_status.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/modules/push_messaging/push_error.h"
#include "third_party/blink/renderer/modules/push_messaging/push_messaging_type_converter.h"
#include "third_party/blink/renderer/modules/push_messaging/push_messaging_utils.h"
#include "third_party/blink/renderer/modules/push_messaging/push_subscription.h"
#include "third_party/blink/renderer/modules/push_messaging/push_subscription_options.h"
#include "third_party/blink/renderer/modules/push_messaging/push_type_converter.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
......
......@@ -49,6 +49,19 @@ String ToBase64URLWithoutPadding(DOMArrayBuffer* buffer) {
return value;
}
// Converts a {base::Optional<base::Time>} into a
// {base::Optional<base::DOMTimeStamp>} object.
// base::Time is in milliseconds from Windows epoch (1601-01-01 00:00:00 UTC)
// while blink::DOMTimeStamp is in milliseconds from UNIX epoch (1970-01-01
// 00:00:00 UTC)
base::Optional<blink::DOMTimeStamp> ToDOMTimeStamp(
const base::Optional<base::Time>& time) {
if (time)
return ConvertSecondsToDOMTimeStamp(time->ToDoubleT());
return base::nullopt;
}
} // namespace
// static
......@@ -58,7 +71,8 @@ PushSubscription* PushSubscription::Create(
return MakeGarbageCollected<PushSubscription>(
subscription->endpoint, subscription->options->user_visible_only,
subscription->options->application_server_key, subscription->p256dh,
subscription->auth, service_worker_registration);
subscription->auth, ToDOMTimeStamp(subscription->expirationTime),
service_worker_registration);
}
PushSubscription::PushSubscription(
......@@ -67,8 +81,8 @@ PushSubscription::PushSubscription(
const WTF::Vector<uint8_t>& application_server_key,
const WTF::Vector<unsigned char>& p256dh,
const WTF::Vector<unsigned char>& auth,
ServiceWorkerRegistration* service_worker_registration,
const base::Optional<DOMTimeStamp> expiration_time)
const base::Optional<DOMTimeStamp>& expiration_time,
ServiceWorkerRegistration* service_worker_registration)
: endpoint_(endpoint),
options_(MakeGarbageCollected<PushSubscriptionOptions>(
user_visible_only,
......@@ -77,8 +91,8 @@ PushSubscription::PushSubscription(
SafeCast<unsigned>(p256dh.size()))),
auth_(
DOMArrayBuffer::Create(auth.data(), SafeCast<unsigned>(auth.size()))),
service_worker_registration_(service_worker_registration),
expiration_time_(expiration_time) {}
expiration_time_(expiration_time),
service_worker_registration_(service_worker_registration) {}
PushSubscription::~PushSubscription() = default;
......
......@@ -34,14 +34,13 @@ class MODULES_EXPORT PushSubscription final : public ScriptWrappable {
mojom::blink::PushSubscriptionPtr subscription,
ServiceWorkerRegistration* service_worker_registration);
PushSubscription(
const KURL& endpoint,
bool user_visible_only,
const WTF::Vector<uint8_t>& application_server_key,
const WTF::Vector<unsigned char>& p256dh,
const WTF::Vector<unsigned char>& auth,
ServiceWorkerRegistration* service_worker_registration,
const base::Optional<DOMTimeStamp> expiration_time = base::nullopt);
PushSubscription(const KURL& endpoint,
bool user_visible_only,
const WTF::Vector<uint8_t>& application_server_key,
const WTF::Vector<unsigned char>& p256dh,
const WTF::Vector<unsigned char>& auth,
const base::Optional<DOMTimeStamp>& expiration_time,
ServiceWorkerRegistration* service_worker_registration);
~PushSubscription() override;
......@@ -68,9 +67,9 @@ class MODULES_EXPORT PushSubscription final : public ScriptWrappable {
Member<DOMArrayBuffer> p256dh_;
Member<DOMArrayBuffer> auth_;
Member<ServiceWorkerRegistration> service_worker_registration_;
base::Optional<DOMTimeStamp> expiration_time_;
Member<ServiceWorkerRegistration> service_worker_registration_;
};
} // namespace blink
......
......@@ -37,6 +37,7 @@ TEST(PushSubscriptionTest, SerializesToBase64URLWithoutPadding) {
PushSubscription subscription(
KURL() /* endpoint */, true /* user_visible_only */,
Vector<uint8_t>() /* application_server_key */, kP256DH, kAuthSecret,
base::nullopt /* expiration_time */,
nullptr /* service_worker_registration */);
ScriptValue json_object =
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/push_messaging/push_messaging_type_converter.h"
#include "third_party/blink/renderer/modules/push_messaging/push_type_converter.h"
#include "base/numerics/safe_conversions.h"
#include "third_party/blink/renderer/modules/push_messaging/push_subscription.h"
......
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PUSH_MESSAGING_PUSH_MESSAGING_TYPE_CONVERTER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PUSH_MESSAGING_PUSH_MESSAGING_TYPE_CONVERTER_H_
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PUSH_MESSAGING_PUSH_TYPE_CONVERTER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PUSH_MESSAGING_PUSH_TYPE_CONVERTER_H_
#include "mojo/public/cpp/bindings/type_converter.h"
#include "third_party/blink/public/mojom/push_messaging/push_messaging.mojom-blink.h"
......@@ -11,7 +11,6 @@
namespace blink {
class PushSubscriptionOptions;
class PushSubscription;
} // namespace blink
......@@ -31,4 +30,4 @@ struct TypeConverter<blink::mojom::blink::PushSubscriptionOptionsPtr,
} // namespace mojo
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PUSH_MESSAGING_PUSH_MESSAGING_TYPE_CONVERTER_H_
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PUSH_MESSAGING_PUSH_TYPE_CONVERTER_H_
......@@ -32,6 +32,8 @@ async_test(function(test) {
assert_equals(typeof pushSubscription.endpoint, 'string');
assert_idl_attribute(pushSubscription, 'expirationTime');
// TODO(viviy): check for not null after passing expiration time in
// PushMessagingManager
assert_equals(pushSubscription.expirationTime, null);
try {
......
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