blob: 93665fdef7b931a0bd1680654004d70594c258ef [file] [log] [blame]
// Copyright 2015 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 "content/browser/notifications/notification_id_generator.h"
#include <sstream>
#include "base/base64.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/sha1.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "content/public/browser/browser_context.h"
#include "url/gurl.h"
namespace content {
namespace {
const char kPersistentNotificationPrefix[] = "p:";
const char kNonPersistentNotificationPrefix[] = "n:";
const char kSeparator = '#';
// Computes a hash based on the path in which the |browser_context| is stored.
// Since we only store the hash, SHA-1 is used to make the probability of
// collisions negligible.
std::string ComputeBrowserContextHash(BrowserContext* browser_context) {
const base::FilePath path = browser_context->GetPath();
#if defined(OS_WIN)
std::string path_hash = base::SHA1HashString(base::WideToUTF8(path.value()));
#else
std::string path_hash = base::SHA1HashString(path.value());
#endif
return base::HexEncode(path_hash.c_str(), path_hash.length());
}
} // namespace
NotificationIdGenerator::NotificationIdGenerator(
BrowserContext* browser_context)
: browser_context_(browser_context) {}
NotificationIdGenerator::~NotificationIdGenerator() {}
// static
bool NotificationIdGenerator::IsPersistentNotification(
const base::StringPiece& notification_id) {
return notification_id.starts_with(kPersistentNotificationPrefix);
}
// static
bool NotificationIdGenerator::IsNonPersistentNotification(
const base::StringPiece& notification_id) {
return notification_id.starts_with(kNonPersistentNotificationPrefix);
}
std::string NotificationIdGenerator::GenerateForPersistentNotification(
const GURL& origin,
const std::string& tag,
int64_t persistent_notification_id) const {
DCHECK(origin.is_valid());
DCHECK_EQ(origin, origin.GetOrigin());
std::stringstream stream;
stream << kPersistentNotificationPrefix;
stream << ComputeBrowserContextHash(browser_context_);
stream << base::IntToString(browser_context_->IsOffTheRecord());
stream << origin;
stream << base::IntToString(!tag.empty());
if (tag.size())
stream << tag;
else
stream << base::Int64ToString(persistent_notification_id);
return stream.str();
}
std::string NotificationIdGenerator::GenerateForNonPersistentNotification(
const GURL& origin,
const std::string& tag,
int non_persistent_notification_id,
int render_process_id) const {
DCHECK(origin.is_valid());
DCHECK_EQ(origin, origin.GetOrigin());
std::stringstream stream;
stream << kNonPersistentNotificationPrefix;
stream << ComputeBrowserContextHash(browser_context_);
stream << base::IntToString(browser_context_->IsOffTheRecord());
stream << origin;
stream << base::IntToString(!tag.empty());
if (tag.empty()) {
stream << base::IntToString(render_process_id);
stream << kSeparator;
stream << base::IntToString(non_persistent_notification_id);
} else {
stream << tag;
}
return stream.str();
}
} // namespace content