Chromium Code Reviews| Index: components/payments/content/payment_manifest_section_table.cc |
| diff --git a/components/payments/content/payment_manifest_section_table.cc b/components/payments/content/payment_manifest_section_table.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..7e0869eae9bf3dcbebc3e6379ba6ae6d57c37f0c |
| --- /dev/null |
| +++ b/components/payments/content/payment_manifest_section_table.cc |
| @@ -0,0 +1,193 @@ |
| +// Copyright 2017 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 "components/payments/content/payment_manifest_section_table.h" |
| + |
| +#include <stdint.h> |
| + |
| +#include <memory> |
| + |
| +#include "base/logging.h" |
| +#include "content/public/browser/browser_thread.h" |
| +#include "sql/statement.h" |
| + |
| +using content::BrowserThread; |
|
please use gerrit instead
2017/04/06 16:47:19
This pollutes the global namespace of header files
gogerald1
2017/04/07 17:51:07
Acknowledged. Not applicable anymore.
|
| + |
| +namespace payments { |
| +namespace { |
| + |
|
please use gerrit instead
2017/04/06 16:47:19
using ::content::BrowserThread;
gogerald1
2017/04/07 17:51:07
Acknowledged. Not applicable anymore.
|
| +// Note that the finger print is calculated with SHA-256. |
| +const size_t kFingerPrintLength = 32; |
| + |
| +WebDatabaseTable::TypeKey GetKey() { |
| + // We just need a unique constant. Use the address of a static that |
| + // COMDAT folding won't touch in an optimizing linker. |
| + static int table_key = 0; |
| + return reinterpret_cast<void*>(&table_key); |
| +} |
| + |
| +// Converts 2-dimensional vector |finger_prints| to 1-dimesional vector. |
| +std::unique_ptr<std::vector<uint8_t>> SerializeFingerPrints( |
| + const std::vector<std::vector<uint8_t>>& finger_prints) { |
| + auto serialized_finger_prints = base::MakeUnique<std::vector<uint8_t>>(); |
| + |
| + for (const auto& finger_print : finger_prints) { |
| + DCHECK_EQ(finger_print.size(), kFingerPrintLength); |
| + serialized_finger_prints->insert(serialized_finger_prints->end(), |
| + finger_print.begin(), finger_print.end()); |
| + } |
| + |
| + return serialized_finger_prints; |
| +} |
| + |
| +// Converts 1-dimensional vector created by SerializeFingerPrints back to |
| +// 2-dimensional vector. Each vector of the second dimensional vector has exact |
| +// kFingerPrintLength number of elements. |
| +bool DeserializeFingerPrints( |
| + const std::vector<uint8_t>& finger_prints, |
| + std::vector<std::vector<uint8_t>>& deserialized_finger_prints) { |
| + if (finger_prints.size() % kFingerPrintLength != 0) |
| + return false; |
| + |
| + for (size_t i = 0; i < finger_prints.size(); i += kFingerPrintLength) { |
| + deserialized_finger_prints.emplace_back( |
| + finger_prints.begin() + i, |
| + finger_prints.begin() + i + kFingerPrintLength); |
| + } |
| + return true; |
| +} |
| + |
| +} // namespace |
| + |
| +PaymentManifestSectionTable::PaymentManifestSectionTable() {} |
| + |
| +PaymentManifestSectionTable::~PaymentManifestSectionTable() {} |
| + |
| +PaymentManifestSectionTable* PaymentManifestSectionTable::FromWebDatabase( |
| + WebDatabase* db) { |
| + return static_cast<PaymentManifestSectionTable*>(db->GetTable(GetKey())); |
| +} |
| + |
| +WebDatabaseTable::TypeKey PaymentManifestSectionTable::GetTypeKey() const { |
| + return GetKey(); |
| +} |
| + |
| +bool PaymentManifestSectionTable::CreateTablesIfNecessary() { |
| + if (!db_->DoesTableExist("payment_manifest_section")) { |
| + if (!db_->Execute("CREATE TABLE payment_manifest_section ( " |
| + "method_name VARCHAR, " |
| + "package_name VARCHAR, " |
| + "version INTEGER NOT NULL DEFAULT 0, " |
| + "finger_prints BLOB) ")) { |
| + NOTREACHED(); |
| + return false; |
| + } |
| + } |
| + |
| + return true; |
| +} |
| + |
| +bool PaymentManifestSectionTable::IsSyncable() { |
| + return false; |
| +} |
| + |
| +bool PaymentManifestSectionTable::MigrateToVersion( |
| + int version, |
| + bool* update_compatible_version) { |
| + return true; |
| +} |
| + |
| +bool PaymentManifestSectionTable::AddPaymentManifestSections( |
| + const std::string& method_name, |
| + const std::vector<mojom::PaymentManifestSectionPtr>& manifest) { |
| + if (BrowserThread::IsMessageLoopValid(BrowserThread::DB)) |
| + DCHECK_CURRENTLY_ON(BrowserThread::DB); |
|
please use gerrit instead
2017/04/06 16:47:19
DCHECK is pre-processed out of the code in release
gogerald1
2017/04/06 18:31:55
Yes, the reason of using IsMessageLoopValid is for
please use gerrit instead
2017/04/06 18:50:52
ok.
gogerald1
2017/04/07 17:51:07
Acknowledged. Not applicable anymore.
|
| + |
| + if (!db_->BeginTransaction()) |
| + return false; |
| + |
| + sql::Statement s1(db_->GetUniqueStatement( |
| + "DELETE FROM payment_manifest_section WHERE method_name=?")); |
| + s1.BindString(0, method_name); |
| + |
| + if (!s1.Run()) { |
| + db_->RollbackTransaction(); |
| + return false; |
| + } |
| + |
| + sql::Statement s2(db_->GetUniqueStatement( |
| + "INSERT INTO payment_manifest_section " |
| + "(method_name, package_name, version, finger_prints) " |
| + "VALUES (?, ?, ?, ?)")); |
| + for (size_t i = 0; i < manifest.size(); i++) { |
| + int index = 0; |
| + s2.BindString(index++, method_name); |
| + s2.BindString(index++, manifest[i]->package_name); |
| + s2.BindInt64(index++, manifest[i]->version); |
| + |
| + std::unique_ptr<std::vector<uint8_t>> serialized_finger_prints = |
| + SerializeFingerPrints(manifest[i]->sha256_cert_fingerprints); |
| + s2.BindBlob(index, serialized_finger_prints->data(), |
| + serialized_finger_prints->size()); |
| + |
| + if (!s2.Run()) { |
| + db_->RollbackTransaction(); |
| + return false; |
| + } |
| + s2.Reset(true); |
| + } |
| + |
| + if (!db_->CommitTransaction()) { |
| + db_->RollbackTransaction(); |
| + return false; |
| + } |
| + |
| + return true; |
| +} |
| + |
| +std::vector<mojom::PaymentManifestSectionPtr> |
| +PaymentManifestSectionTable::GetPaymentManifestSections( |
| + const std::string& method_name) { |
| + if (BrowserThread::IsMessageLoopValid(BrowserThread::DB)) |
|
please use gerrit instead
2017/04/06 16:47:19
Ditto.
gogerald1
2017/04/07 17:51:07
Acknowledged. Not applicable anymore.
|
| + DCHECK_CURRENTLY_ON(BrowserThread::DB); |
| + |
| + std::vector<mojom::PaymentManifestSectionPtr> manifest; |
| + sql::Statement s( |
| + db_->GetUniqueStatement("SELECT package_name, version, finger_prints " |
| + "FROM payment_manifest_section " |
| + "WHERE method_name=?")); |
| + s.BindString(0, method_name); |
| + |
| + if (!s.is_valid()) |
| + return manifest; |
| + |
| + while (s.Step()) { |
| + mojom::PaymentManifestSectionPtr section = |
| + mojom::PaymentManifestSection::New(); |
| + |
| + int index = 0; |
| + section->package_name = s.ColumnString(index++); |
| + section->version = s.ColumnInt64(index++); |
| + |
| + std::vector<uint8_t> finger_prints; |
| + if (!s.ColumnBlobAsVector(index, &finger_prints)) { |
| + NOTREACHED(); |
|
please use gerrit instead
2017/04/06 16:47:19
Remove NOTREACHED(). This is easily reachable thro
gogerald1
2017/04/07 17:51:07
Done.
|
| + manifest.clear(); |
| + return manifest; |
| + } |
| + |
| + if (!DeserializeFingerPrints(finger_prints, |
| + section->sha256_cert_fingerprints)) { |
| + NOTREACHED(); |
|
please use gerrit instead
2017/04/06 16:47:19
Ditto.
gogerald1
2017/04/07 17:51:07
Done.
|
| + manifest.clear(); |
| + return manifest; |
| + } |
| + |
| + manifest.push_back(std::move(section)); |
| + } |
| + |
| + return manifest; |
| +} |
| + |
| +} // payments |