Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 1 | // Copyright 2019 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "content/browser/content_index/content_index_database.h" |
| 6 | |
Rayan Kanso | 5e2ff0e | 2019-09-04 10:33:10 | [diff] [blame^] | 7 | #include <set> |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 8 | #include <string> |
| 9 | |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 10 | #include "base/barrier_closure.h" |
Rayan Kanso | e147def | 2019-07-22 09:56:35 | [diff] [blame] | 11 | #include "base/optional.h" |
Rayan Kanso | 5e2ff0e | 2019-09-04 10:33:10 | [diff] [blame^] | 12 | #include "base/stl_util.h" |
Rayan Kanso | 24f7d41 | 2019-07-11 10:09:30 | [diff] [blame] | 13 | #include "base/task/post_task.h" |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 14 | #include "base/time/time.h" |
Rayan Kanso | 837b795 | 2019-07-01 10:31:29 | [diff] [blame] | 15 | #include "content/browser/background_fetch/storage/image_helpers.h" |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 16 | #include "content/browser/content_index/content_index.pb.h" |
Rayan Kanso | 9f3944a | 2019-07-30 12:18:07 | [diff] [blame] | 17 | #include "content/browser/content_index/content_index_metrics.h" |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 18 | #include "content/public/browser/browser_context.h" |
Rayan Kanso | 24f7d41 | 2019-07-11 10:09:30 | [diff] [blame] | 19 | #include "content/public/browser/browser_task_traits.h" |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 20 | #include "content/public/browser/browser_thread.h" |
Rayan Kanso | 37c0870 | 2019-07-12 17:07:41 | [diff] [blame] | 21 | #include "url/gurl.h" |
Rayan Kanso | d33e277 | 2019-06-27 16:52:41 | [diff] [blame] | 22 | #include "url/origin.h" |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 23 | |
Rayan Kanso | 837b795 | 2019-07-01 10:31:29 | [diff] [blame] | 24 | // TODO(crbug.com/973844): Move image utility functions to common library. |
| 25 | using content::background_fetch::DeserializeIcon; |
| 26 | using content::background_fetch::SerializeIcon; |
| 27 | |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 28 | namespace content { |
| 29 | |
| 30 | namespace { |
| 31 | |
| 32 | constexpr char kEntryPrefix[] = "content_index:entry_"; |
Rayan Kanso | 837b795 | 2019-07-01 10:31:29 | [diff] [blame] | 33 | constexpr char kIconPrefix[] = "content_index:icon_"; |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 34 | |
| 35 | std::string EntryKey(const std::string& id) { |
| 36 | return kEntryPrefix + id; |
| 37 | } |
| 38 | |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 39 | std::string IconsKey(const std::string& id) { |
Rayan Kanso | 837b795 | 2019-07-01 10:31:29 | [diff] [blame] | 40 | return kIconPrefix + id; |
| 41 | } |
| 42 | |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 43 | std::string CreateSerializedContentEntry( |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 44 | const blink::mojom::ContentDescription& description, |
Rayan Kanso | 37c0870 | 2019-07-12 17:07:41 | [diff] [blame] | 45 | const GURL& launch_url, |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 46 | base::Time entry_time) { |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 47 | // Convert description. |
| 48 | proto::ContentDescription description_proto; |
Rayan Kanso | 475b85b | 2019-06-28 01:56:44 | [diff] [blame] | 49 | description_proto.set_id(description.id); |
| 50 | description_proto.set_title(description.title); |
| 51 | description_proto.set_description(description.description); |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 52 | description_proto.set_category(static_cast<int>(description.category)); |
Rayan Kanso | 35c07cf | 2019-08-20 18:46:03 | [diff] [blame] | 53 | |
| 54 | for (const auto& icon : description.icons) { |
| 55 | auto* icon_proto = description_proto.add_icons(); |
| 56 | icon_proto->set_src(icon->src); |
| 57 | if (icon->sizes) |
| 58 | icon_proto->set_sizes(*icon->sizes); |
| 59 | if (icon->type) |
| 60 | icon_proto->set_type(*icon->type); |
| 61 | } |
| 62 | |
Rayan Kanso | 475b85b | 2019-06-28 01:56:44 | [diff] [blame] | 63 | description_proto.set_launch_url(description.launch_url); |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 64 | |
| 65 | // Create entry. |
| 66 | proto::ContentEntry entry; |
| 67 | *entry.mutable_description() = std::move(description_proto); |
Rayan Kanso | 37c0870 | 2019-07-12 17:07:41 | [diff] [blame] | 68 | entry.set_launch_url(launch_url.spec()); |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 69 | entry.set_timestamp(entry_time.ToDeltaSinceWindowsEpoch().InMicroseconds()); |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 70 | |
| 71 | return entry.SerializeAsString(); |
| 72 | } |
| 73 | |
| 74 | blink::mojom::ContentDescriptionPtr DescriptionFromProto( |
| 75 | const proto::ContentDescription& description) { |
| 76 | // Validate. |
| 77 | if (description.category() < |
| 78 | static_cast<int>(blink::mojom::ContentCategory::kMinValue) || |
| 79 | description.category() > |
| 80 | static_cast<int>(blink::mojom::ContentCategory::kMaxValue)) { |
| 81 | return nullptr; |
| 82 | } |
| 83 | |
| 84 | // Convert. |
| 85 | auto result = blink::mojom::ContentDescription::New(); |
| 86 | result->id = description.id(); |
| 87 | result->title = description.title(); |
| 88 | result->description = description.description(); |
| 89 | result->category = |
| 90 | static_cast<blink::mojom::ContentCategory>(description.category()); |
Rayan Kanso | 35c07cf | 2019-08-20 18:46:03 | [diff] [blame] | 91 | for (const auto& icon : description.icons()) { |
| 92 | auto mojo_icon = blink::mojom::ContentIconDefinition::New(); |
| 93 | mojo_icon->src = icon.src(); |
| 94 | if (icon.has_sizes()) |
| 95 | mojo_icon->sizes = icon.sizes(); |
| 96 | if (icon.has_type()) |
| 97 | mojo_icon->type = icon.type(); |
| 98 | result->icons.push_back(std::move(mojo_icon)); |
| 99 | } |
| 100 | |
Rayan Kanso | 475b85b | 2019-06-28 01:56:44 | [diff] [blame] | 101 | result->launch_url = description.launch_url(); |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 102 | return result; |
| 103 | } |
| 104 | |
Rayan Kanso | e147def | 2019-07-22 09:56:35 | [diff] [blame] | 105 | base::Optional<ContentIndexEntry> EntryFromSerializedProto( |
| 106 | int64_t service_worker_registration_id, |
| 107 | const std::string& serialized_proto) { |
| 108 | proto::ContentEntry entry_proto; |
| 109 | if (!entry_proto.ParseFromString(serialized_proto)) |
| 110 | return base::nullopt; |
| 111 | |
| 112 | GURL launch_url(entry_proto.launch_url()); |
| 113 | if (!launch_url.is_valid()) |
| 114 | return base::nullopt; |
| 115 | |
| 116 | auto description = DescriptionFromProto(entry_proto.description()); |
| 117 | base::Time registration_time = base::Time::FromDeltaSinceWindowsEpoch( |
| 118 | base::TimeDelta::FromMicroseconds(entry_proto.timestamp())); |
| 119 | |
| 120 | return ContentIndexEntry(service_worker_registration_id, |
| 121 | std::move(description), std::move(launch_url), |
| 122 | registration_time); |
| 123 | } |
| 124 | |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 125 | } // namespace |
| 126 | |
| 127 | ContentIndexDatabase::ContentIndexDatabase( |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 128 | BrowserContext* browser_context, |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 129 | scoped_refptr<ServiceWorkerContextWrapper> service_worker_context) |
Rayan Kanso | ba07580 | 2019-06-28 16:33:48 | [diff] [blame] | 130 | : provider_(browser_context->GetContentIndexProvider()), |
Jeremy Roman | 7c5cfabd | 2019-08-12 15:45:27 | [diff] [blame] | 131 | service_worker_context_(std::move(service_worker_context)) {} |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 132 | |
| 133 | ContentIndexDatabase::~ContentIndexDatabase() = default; |
| 134 | |
| 135 | void ContentIndexDatabase::AddEntry( |
| 136 | int64_t service_worker_registration_id, |
Rayan Kanso | d33e277 | 2019-06-27 16:52:41 | [diff] [blame] | 137 | const url::Origin& origin, |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 138 | blink::mojom::ContentDescriptionPtr description, |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 139 | const std::vector<SkBitmap>& icons, |
Rayan Kanso | 37c0870 | 2019-07-12 17:07:41 | [diff] [blame] | 140 | const GURL& launch_url, |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 141 | blink::mojom::ContentIndexService::AddCallback callback) { |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 142 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 143 | |
| 144 | auto wrapped_callback = base::BindOnce( |
| 145 | [](blink::mojom::ContentIndexService::AddCallback callback, |
| 146 | blink::mojom::ContentIndexError error) { |
| 147 | base::PostTask(FROM_HERE, {BrowserThread::UI}, |
| 148 | base::BindOnce(std::move(callback), error)); |
| 149 | }, |
| 150 | std::move(callback)); |
| 151 | |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 152 | RunOrPostTaskOnThread( |
| 153 | FROM_HERE, ServiceWorkerContext::GetCoreThreadId(), |
| 154 | base::BindOnce(&ContentIndexDatabase::AddEntryOnCoreThread, |
| 155 | weak_ptr_factory_core_.GetWeakPtr(), |
| 156 | service_worker_registration_id, origin, |
| 157 | std::move(description), icons, launch_url, |
| 158 | std::move(wrapped_callback))); |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 159 | } |
| 160 | |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 161 | void ContentIndexDatabase::AddEntryOnCoreThread( |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 162 | int64_t service_worker_registration_id, |
| 163 | const url::Origin& origin, |
| 164 | blink::mojom::ContentDescriptionPtr description, |
| 165 | const std::vector<SkBitmap>& icons, |
| 166 | const GURL& launch_url, |
| 167 | blink::mojom::ContentIndexService::AddCallback callback) { |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 168 | DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 169 | |
Rayan Kanso | 394af70 | 2019-07-25 12:50:37 | [diff] [blame] | 170 | if (blocked_origins_.count(origin)) { |
| 171 | // TODO(crbug.com/973844): Does this need a more specific error? |
| 172 | std::move(callback).Run(blink::mojom::ContentIndexError::STORAGE_ERROR); |
Rayan Kanso | 9f3944a | 2019-07-30 12:18:07 | [diff] [blame] | 173 | content_index::RecordRegistrationBlocked(description->category); |
Rayan Kanso | 394af70 | 2019-07-25 12:50:37 | [diff] [blame] | 174 | return; |
| 175 | } |
| 176 | |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 177 | auto serialized_icons = std::make_unique<proto::SerializedIcons>(); |
| 178 | proto::SerializedIcons* serialized_icons_ptr = serialized_icons.get(); |
| 179 | |
| 180 | auto barrier_closure = base::BarrierClosure( |
| 181 | icons.size(), |
| 182 | base::BindOnce(&ContentIndexDatabase::DidSerializeIcons, |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 183 | weak_ptr_factory_core_.GetWeakPtr(), |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 184 | service_worker_registration_id, origin, |
| 185 | std::move(description), launch_url, |
| 186 | std::move(serialized_icons), std::move(callback))); |
| 187 | |
| 188 | for (const auto& icon : icons) { |
| 189 | SerializeIcon(icon, |
| 190 | base::BindOnce( |
| 191 | [](base::OnceClosure done_closure, |
| 192 | proto::SerializedIcons* icons, std::string icon) { |
| 193 | icons->add_icons()->set_icon(std::move(icon)); |
| 194 | std::move(done_closure).Run(); |
| 195 | }, |
| 196 | barrier_closure, serialized_icons_ptr)); |
| 197 | } |
Rayan Kanso | 837b795 | 2019-07-01 10:31:29 | [diff] [blame] | 198 | } |
| 199 | |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 200 | void ContentIndexDatabase::DidSerializeIcons( |
Rayan Kanso | 837b795 | 2019-07-01 10:31:29 | [diff] [blame] | 201 | int64_t service_worker_registration_id, |
| 202 | const url::Origin& origin, |
| 203 | blink::mojom::ContentDescriptionPtr description, |
Rayan Kanso | 37c0870 | 2019-07-12 17:07:41 | [diff] [blame] | 204 | const GURL& launch_url, |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 205 | std::unique_ptr<proto::SerializedIcons> serialized_icons, |
| 206 | blink::mojom::ContentIndexService::AddCallback callback) { |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 207 | base::Time entry_time = base::Time::Now(); |
Rayan Kanso | 837b795 | 2019-07-01 10:31:29 | [diff] [blame] | 208 | std::string entry_key = EntryKey(description->id); |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 209 | std::string icon_key = IconsKey(description->id); |
Rayan Kanso | 837b795 | 2019-07-01 10:31:29 | [diff] [blame] | 210 | std::string entry_value = |
Rayan Kanso | 37c0870 | 2019-07-12 17:07:41 | [diff] [blame] | 211 | CreateSerializedContentEntry(*description, launch_url, entry_time); |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 212 | std::string icons_value = serialized_icons->SerializeAsString(); |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 213 | |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 214 | // Entry to pass over to the provider. |
| 215 | ContentIndexEntry entry(service_worker_registration_id, |
Rayan Kanso | 37c0870 | 2019-07-12 17:07:41 | [diff] [blame] | 216 | std::move(description), launch_url, entry_time); |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 217 | |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 218 | service_worker_context_->StoreRegistrationUserData( |
Rayan Kanso | d33e277 | 2019-06-27 16:52:41 | [diff] [blame] | 219 | service_worker_registration_id, origin.GetURL(), |
Rayan Kanso | 837b795 | 2019-07-01 10:31:29 | [diff] [blame] | 220 | {{std::move(entry_key), std::move(entry_value)}, |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 221 | {std::move(icon_key), std::move(icons_value)}}, |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 222 | base::BindOnce(&ContentIndexDatabase::DidAddEntry, |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 223 | weak_ptr_factory_core_.GetWeakPtr(), std::move(callback), |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 224 | std::move(entry))); |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 225 | } |
| 226 | |
| 227 | void ContentIndexDatabase::DidAddEntry( |
| 228 | blink::mojom::ContentIndexService::AddCallback callback, |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 229 | ContentIndexEntry entry, |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 230 | blink::ServiceWorkerStatusCode status) { |
Rayan Kanso | 9f3944a | 2019-07-30 12:18:07 | [diff] [blame] | 231 | content_index::RecordDatabaseOperationStatus("Add", status); |
| 232 | |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 233 | if (status != blink::ServiceWorkerStatusCode::kOk) { |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 234 | std::move(callback).Run(blink::mojom::ContentIndexError::STORAGE_ERROR); |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 235 | return; |
| 236 | } |
| 237 | |
| 238 | std::move(callback).Run(blink::mojom::ContentIndexError::NONE); |
| 239 | |
Rayan Kanso | 24f7d41 | 2019-07-11 10:09:30 | [diff] [blame] | 240 | std::vector<ContentIndexEntry> entries; |
| 241 | entries.push_back(std::move(entry)); |
Sami Kyostila | 8e4d5a9 | 2019-08-02 12:45:05 | [diff] [blame] | 242 | base::PostTask( |
Rayan Kanso | 24f7d41 | 2019-07-11 10:09:30 | [diff] [blame] | 243 | FROM_HERE, {BrowserThread::UI}, |
| 244 | base::BindOnce(&ContentIndexDatabase::NotifyProviderContentAdded, |
| 245 | weak_ptr_factory_ui_.GetWeakPtr(), std::move(entries))); |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 246 | } |
| 247 | |
| 248 | void ContentIndexDatabase::DeleteEntry( |
| 249 | int64_t service_worker_registration_id, |
Rayan Kanso | a42c3caf | 2019-07-19 17:21:20 | [diff] [blame] | 250 | const url::Origin& origin, |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 251 | const std::string& entry_id, |
| 252 | blink::mojom::ContentIndexService::DeleteCallback callback) { |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 253 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 254 | |
| 255 | auto wrapped_callback = base::BindOnce( |
| 256 | [](blink::mojom::ContentIndexService::DeleteCallback callback, |
| 257 | blink::mojom::ContentIndexError error) { |
| 258 | base::PostTask(FROM_HERE, {BrowserThread::UI}, |
| 259 | base::BindOnce(std::move(callback), error)); |
| 260 | }, |
| 261 | std::move(callback)); |
| 262 | |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 263 | RunOrPostTaskOnThread( |
| 264 | FROM_HERE, ServiceWorkerContext::GetCoreThreadId(), |
| 265 | base::BindOnce(&ContentIndexDatabase::DeleteEntryOnCoreThread, |
| 266 | weak_ptr_factory_core_.GetWeakPtr(), |
| 267 | service_worker_registration_id, origin, entry_id, |
| 268 | std::move(wrapped_callback))); |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 269 | } |
| 270 | |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 271 | void ContentIndexDatabase::DeleteEntryOnCoreThread( |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 272 | int64_t service_worker_registration_id, |
| 273 | const url::Origin& origin, |
| 274 | const std::string& entry_id, |
| 275 | blink::mojom::ContentIndexService::DeleteCallback callback) { |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 276 | DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 277 | |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 278 | service_worker_context_->ClearRegistrationUserData( |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 279 | service_worker_registration_id, {EntryKey(entry_id), IconsKey(entry_id)}, |
Rayan Kanso | 24f7d41 | 2019-07-11 10:09:30 | [diff] [blame] | 280 | base::BindOnce(&ContentIndexDatabase::DidDeleteEntry, |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 281 | weak_ptr_factory_core_.GetWeakPtr(), |
Rayan Kanso | a42c3caf | 2019-07-19 17:21:20 | [diff] [blame] | 282 | service_worker_registration_id, origin, entry_id, |
Rayan Kanso | 24f7d41 | 2019-07-11 10:09:30 | [diff] [blame] | 283 | std::move(callback))); |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 284 | } |
| 285 | |
| 286 | void ContentIndexDatabase::DidDeleteEntry( |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 287 | int64_t service_worker_registration_id, |
Rayan Kanso | a42c3caf | 2019-07-19 17:21:20 | [diff] [blame] | 288 | const url::Origin& origin, |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 289 | const std::string& entry_id, |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 290 | blink::mojom::ContentIndexService::DeleteCallback callback, |
| 291 | blink::ServiceWorkerStatusCode status) { |
Rayan Kanso | 9f3944a | 2019-07-30 12:18:07 | [diff] [blame] | 292 | content_index::RecordDatabaseOperationStatus("Delete", status); |
| 293 | |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 294 | if (status != blink::ServiceWorkerStatusCode::kOk) { |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 295 | std::move(callback).Run(blink::mojom::ContentIndexError::STORAGE_ERROR); |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 296 | return; |
| 297 | } |
| 298 | |
| 299 | std::move(callback).Run(blink::mojom::ContentIndexError::NONE); |
Rayan Kanso | 24f7d41 | 2019-07-11 10:09:30 | [diff] [blame] | 300 | |
Sami Kyostila | 8e4d5a9 | 2019-08-02 12:45:05 | [diff] [blame] | 301 | base::PostTask( |
Rayan Kanso | 24f7d41 | 2019-07-11 10:09:30 | [diff] [blame] | 302 | FROM_HERE, {BrowserThread::UI}, |
| 303 | base::BindOnce(&ContentIndexDatabase::NotifyProviderContentDeleted, |
| 304 | weak_ptr_factory_ui_.GetWeakPtr(), |
Rayan Kanso | a42c3caf | 2019-07-19 17:21:20 | [diff] [blame] | 305 | service_worker_registration_id, origin, entry_id)); |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 306 | } |
| 307 | |
| 308 | void ContentIndexDatabase::GetDescriptions( |
| 309 | int64_t service_worker_registration_id, |
| 310 | blink::mojom::ContentIndexService::GetDescriptionsCallback callback) { |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 311 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 312 | |
| 313 | auto wrapped_callback = base::BindOnce( |
| 314 | [](blink::mojom::ContentIndexService::GetDescriptionsCallback callback, |
| 315 | blink::mojom::ContentIndexError error, |
| 316 | std::vector<blink::mojom::ContentDescriptionPtr> descriptions) { |
| 317 | base::PostTask(FROM_HERE, {BrowserThread::UI}, |
| 318 | base::BindOnce(std::move(callback), error, |
| 319 | std::move(descriptions))); |
| 320 | }, |
| 321 | std::move(callback)); |
| 322 | |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 323 | RunOrPostTaskOnThread( |
| 324 | FROM_HERE, ServiceWorkerContext::GetCoreThreadId(), |
| 325 | base::BindOnce(&ContentIndexDatabase::GetDescriptionsOnCoreThread, |
| 326 | weak_ptr_factory_core_.GetWeakPtr(), |
| 327 | service_worker_registration_id, |
| 328 | std::move(wrapped_callback))); |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 329 | } |
| 330 | |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 331 | void ContentIndexDatabase::GetDescriptionsOnCoreThread( |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 332 | int64_t service_worker_registration_id, |
| 333 | blink::mojom::ContentIndexService::GetDescriptionsCallback callback) { |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 334 | DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 335 | |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 336 | service_worker_context_->GetRegistrationUserDataByKeyPrefix( |
| 337 | service_worker_registration_id, kEntryPrefix, |
| 338 | base::BindOnce(&ContentIndexDatabase::DidGetDescriptions, |
Rayan Kanso | 5e2ff0e | 2019-09-04 10:33:10 | [diff] [blame^] | 339 | weak_ptr_factory_core_.GetWeakPtr(), |
| 340 | service_worker_registration_id, std::move(callback))); |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 341 | } |
| 342 | |
| 343 | void ContentIndexDatabase::DidGetDescriptions( |
Rayan Kanso | 5e2ff0e | 2019-09-04 10:33:10 | [diff] [blame^] | 344 | int64_t service_worker_registration_id, |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 345 | blink::mojom::ContentIndexService::GetDescriptionsCallback callback, |
| 346 | const std::vector<std::string>& data, |
| 347 | blink::ServiceWorkerStatusCode status) { |
Rayan Kanso | 9f3944a | 2019-07-30 12:18:07 | [diff] [blame] | 348 | content_index::RecordDatabaseOperationStatus("GetDescriptions", status); |
| 349 | |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 350 | if (status == blink::ServiceWorkerStatusCode::kErrorNotFound) { |
| 351 | std::move(callback).Run(blink::mojom::ContentIndexError::NONE, |
| 352 | /* descriptions= */ {}); |
| 353 | return; |
| 354 | } else if (status != blink::ServiceWorkerStatusCode::kOk) { |
| 355 | std::move(callback).Run(blink::mojom::ContentIndexError::STORAGE_ERROR, |
| 356 | /* descriptions= */ {}); |
| 357 | return; |
| 358 | } |
| 359 | |
| 360 | std::vector<blink::mojom::ContentDescriptionPtr> descriptions; |
| 361 | descriptions.reserve(data.size()); |
| 362 | |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 363 | for (const auto& serialized_entry : data) { |
| 364 | proto::ContentEntry entry; |
| 365 | if (!entry.ParseFromString(serialized_entry)) { |
Rayan Kanso | 5e2ff0e | 2019-09-04 10:33:10 | [diff] [blame^] | 366 | ClearServiceWorkerDataOnCorruption(service_worker_registration_id); |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 367 | std::move(callback).Run(blink::mojom::ContentIndexError::STORAGE_ERROR, |
| 368 | /* descriptions= */ {}); |
| 369 | return; |
| 370 | } |
| 371 | |
| 372 | auto description = DescriptionFromProto(entry.description()); |
| 373 | if (!description) { |
Rayan Kanso | 5e2ff0e | 2019-09-04 10:33:10 | [diff] [blame^] | 374 | // Clear entry data. |
| 375 | service_worker_context_->ClearRegistrationUserData( |
| 376 | service_worker_registration_id, |
| 377 | {EntryKey(entry.description().id()), |
| 378 | IconsKey(entry.description().id())}, |
| 379 | base::BindOnce(&content_index::RecordDatabaseOperationStatus, |
| 380 | "ClearCorruptedData")); |
| 381 | continue; |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 382 | } |
| 383 | |
| 384 | descriptions.push_back(std::move(description)); |
| 385 | } |
| 386 | |
| 387 | std::move(callback).Run(blink::mojom::ContentIndexError::NONE, |
| 388 | std::move(descriptions)); |
| 389 | } |
| 390 | |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 391 | void ContentIndexDatabase::GetIcons( |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 392 | int64_t service_worker_registration_id, |
| 393 | const std::string& description_id, |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 394 | ContentIndexContext::GetIconsCallback callback) { |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 395 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 396 | |
| 397 | auto wrapped_callback = base::BindOnce( |
| 398 | [](ContentIndexContext::GetIconsCallback callback, |
| 399 | std::vector<SkBitmap> icons) { |
| 400 | base::PostTask(FROM_HERE, {BrowserThread::UI}, |
| 401 | base::BindOnce(std::move(callback), std::move(icons))); |
| 402 | }, |
| 403 | std::move(callback)); |
| 404 | |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 405 | RunOrPostTaskOnThread( |
| 406 | FROM_HERE, ServiceWorkerContext::GetCoreThreadId(), |
| 407 | base::BindOnce(&ContentIndexDatabase::GetIconsOnCoreThread, |
| 408 | weak_ptr_factory_core_.GetWeakPtr(), |
| 409 | service_worker_registration_id, description_id, |
| 410 | std::move(wrapped_callback))); |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 411 | } |
| 412 | |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 413 | void ContentIndexDatabase::GetIconsOnCoreThread( |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 414 | int64_t service_worker_registration_id, |
| 415 | const std::string& description_id, |
| 416 | ContentIndexContext::GetIconsCallback callback) { |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 417 | DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); |
Rayan Kanso | 24f7d41 | 2019-07-11 10:09:30 | [diff] [blame] | 418 | |
Rayan Kanso | 837b795 | 2019-07-01 10:31:29 | [diff] [blame] | 419 | service_worker_context_->GetRegistrationUserData( |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 420 | service_worker_registration_id, {IconsKey(description_id)}, |
| 421 | base::BindOnce(&ContentIndexDatabase::DidGetSerializedIcons, |
Rayan Kanso | 5e2ff0e | 2019-09-04 10:33:10 | [diff] [blame^] | 422 | weak_ptr_factory_core_.GetWeakPtr(), |
| 423 | service_worker_registration_id, std::move(callback))); |
Rayan Kanso | 837b795 | 2019-07-01 10:31:29 | [diff] [blame] | 424 | } |
| 425 | |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 426 | void ContentIndexDatabase::DidGetSerializedIcons( |
Rayan Kanso | 5e2ff0e | 2019-09-04 10:33:10 | [diff] [blame^] | 427 | int64_t service_worker_registration_id, |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 428 | ContentIndexContext::GetIconsCallback callback, |
Rayan Kanso | 837b795 | 2019-07-01 10:31:29 | [diff] [blame] | 429 | const std::vector<std::string>& data, |
| 430 | blink::ServiceWorkerStatusCode status) { |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 431 | DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 432 | |
Rayan Kanso | 9f3944a | 2019-07-30 12:18:07 | [diff] [blame] | 433 | content_index::RecordDatabaseOperationStatus("GetIcon", status); |
| 434 | |
Rayan Kanso | 837b795 | 2019-07-01 10:31:29 | [diff] [blame] | 435 | if (status != blink::ServiceWorkerStatusCode::kOk || data.empty()) { |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 436 | std::move(callback).Run({}); |
Rayan Kanso | 837b795 | 2019-07-01 10:31:29 | [diff] [blame] | 437 | return; |
| 438 | } |
| 439 | |
| 440 | DCHECK_EQ(data.size(), 1u); |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 441 | proto::SerializedIcons serialized_icons; |
| 442 | if (!serialized_icons.ParseFromString(data.front())) { |
Rayan Kanso | 5e2ff0e | 2019-09-04 10:33:10 | [diff] [blame^] | 443 | ClearServiceWorkerDataOnCorruption(service_worker_registration_id); |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 444 | std::move(callback).Run({}); |
| 445 | return; |
| 446 | } |
Rayan Kanso | 837b795 | 2019-07-01 10:31:29 | [diff] [blame] | 447 | |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 448 | if (serialized_icons.icons_size() == 0u) { |
| 449 | // There are no icons. |
| 450 | std::move(callback).Run({}); |
| 451 | return; |
| 452 | } |
| 453 | |
| 454 | auto icons = std::make_unique<std::vector<SkBitmap>>(); |
| 455 | std::vector<SkBitmap>* icons_ptr = icons.get(); |
| 456 | |
| 457 | auto barrier_closure = base::BarrierClosure( |
| 458 | serialized_icons.icons_size(), |
| 459 | base::BindOnce(&ContentIndexDatabase::DidDeserializeIcons, |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 460 | weak_ptr_factory_core_.GetWeakPtr(), std::move(callback), |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 461 | std::move(icons))); |
| 462 | |
| 463 | for (auto& serialized_icon : *serialized_icons.mutable_icons()) { |
| 464 | DeserializeIcon(base::WrapUnique(serialized_icon.release_icon()), |
| 465 | base::BindOnce( |
| 466 | [](base::OnceClosure done_closure, |
| 467 | std::vector<SkBitmap>* icons, SkBitmap icon) { |
| 468 | icons->push_back(std::move(icon)); |
| 469 | std::move(done_closure).Run(); |
| 470 | }, |
| 471 | barrier_closure, icons_ptr)); |
| 472 | } |
| 473 | } |
| 474 | |
| 475 | void ContentIndexDatabase::DidDeserializeIcons( |
| 476 | ContentIndexContext::GetIconsCallback callback, |
| 477 | std::unique_ptr<std::vector<SkBitmap>> icons) { |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 478 | DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); |
Rayan Kanso | b0f54fe | 2019-08-05 18:59:14 | [diff] [blame] | 479 | |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 480 | RunOrPostTaskOnThread(FROM_HERE, BrowserThread::UI, |
| 481 | base::BindOnce(std::move(callback), std::move(*icons))); |
Rayan Kanso | 03a847b | 2019-06-27 21:00:09 | [diff] [blame] | 482 | } |
| 483 | |
Rayan Kanso | e147def | 2019-07-22 09:56:35 | [diff] [blame] | 484 | void ContentIndexDatabase::GetAllEntries( |
| 485 | ContentIndexContext::GetAllEntriesCallback callback) { |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 486 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 487 | |
| 488 | auto wrapped_callback = base::BindOnce( |
| 489 | [](ContentIndexContext::GetAllEntriesCallback callback, |
| 490 | blink::mojom::ContentIndexError error, |
| 491 | std::vector<ContentIndexEntry> entries) { |
| 492 | base::PostTask( |
| 493 | FROM_HERE, {BrowserThread::UI}, |
| 494 | base::BindOnce(std::move(callback), error, std::move(entries))); |
| 495 | }, |
| 496 | std::move(callback)); |
| 497 | |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 498 | RunOrPostTaskOnThread( |
| 499 | FROM_HERE, ServiceWorkerContext::GetCoreThreadId(), |
| 500 | base::BindOnce(&ContentIndexDatabase::GetAllEntriesOnCoreThread, |
| 501 | weak_ptr_factory_core_.GetWeakPtr(), |
| 502 | std::move(wrapped_callback))); |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 503 | } |
| 504 | |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 505 | void ContentIndexDatabase::GetAllEntriesOnCoreThread( |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 506 | ContentIndexContext::GetAllEntriesCallback callback) { |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 507 | DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); |
Rayan Kanso | e147def | 2019-07-22 09:56:35 | [diff] [blame] | 508 | |
| 509 | service_worker_context_->GetUserDataForAllRegistrationsByKeyPrefix( |
| 510 | kEntryPrefix, |
| 511 | base::BindOnce(&ContentIndexDatabase::DidGetEntries, |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 512 | weak_ptr_factory_core_.GetWeakPtr(), std::move(callback))); |
Rayan Kanso | e147def | 2019-07-22 09:56:35 | [diff] [blame] | 513 | } |
| 514 | |
| 515 | void ContentIndexDatabase::DidGetEntries( |
| 516 | ContentIndexContext::GetAllEntriesCallback callback, |
| 517 | const std::vector<std::pair<int64_t, std::string>>& user_data, |
| 518 | blink::ServiceWorkerStatusCode status) { |
Rayan Kanso | 9f3944a | 2019-07-30 12:18:07 | [diff] [blame] | 519 | content_index::RecordDatabaseOperationStatus("GetAllEntries", status); |
| 520 | |
Rayan Kanso | e147def | 2019-07-22 09:56:35 | [diff] [blame] | 521 | if (status != blink::ServiceWorkerStatusCode::kOk) { |
Rayan Kanso | e147def | 2019-07-22 09:56:35 | [diff] [blame] | 522 | std::move(callback).Run(blink::mojom::ContentIndexError::STORAGE_ERROR, |
| 523 | /* entries= */ {}); |
| 524 | return; |
| 525 | } |
| 526 | |
| 527 | if (user_data.empty()) { |
| 528 | std::move(callback).Run(blink::mojom::ContentIndexError::NONE, |
| 529 | /* entries= */ {}); |
| 530 | return; |
| 531 | } |
| 532 | |
| 533 | std::vector<ContentIndexEntry> entries; |
| 534 | entries.reserve(user_data.size()); |
Rayan Kanso | 5e2ff0e | 2019-09-04 10:33:10 | [diff] [blame^] | 535 | std::set<int64_t> corrupted_sw_ids; |
Rayan Kanso | e147def | 2019-07-22 09:56:35 | [diff] [blame] | 536 | |
| 537 | for (const auto& ud : user_data) { |
| 538 | auto entry = EntryFromSerializedProto(ud.first, ud.second); |
| 539 | if (!entry) { |
Rayan Kanso | 5e2ff0e | 2019-09-04 10:33:10 | [diff] [blame^] | 540 | corrupted_sw_ids.insert(ud.first); |
| 541 | continue; |
Rayan Kanso | e147def | 2019-07-22 09:56:35 | [diff] [blame] | 542 | } |
| 543 | |
| 544 | entries.emplace_back(std::move(*entry)); |
| 545 | } |
| 546 | |
Rayan Kanso | 5e2ff0e | 2019-09-04 10:33:10 | [diff] [blame^] | 547 | if (!corrupted_sw_ids.empty()) { |
| 548 | // Remove soon-to-be-deleted entries. |
| 549 | base::EraseIf(entries, [&corrupted_sw_ids](const auto& entry) { |
| 550 | return corrupted_sw_ids.count(entry.service_worker_registration_id); |
| 551 | }); |
| 552 | |
| 553 | for (int64_t service_worker_registration_id : corrupted_sw_ids) |
| 554 | ClearServiceWorkerDataOnCorruption(service_worker_registration_id); |
| 555 | } |
| 556 | |
Rayan Kanso | e147def | 2019-07-22 09:56:35 | [diff] [blame] | 557 | std::move(callback).Run(blink::mojom::ContentIndexError::NONE, |
| 558 | std::move(entries)); |
| 559 | } |
| 560 | |
| 561 | void ContentIndexDatabase::GetEntry( |
| 562 | int64_t service_worker_registration_id, |
| 563 | const std::string& description_id, |
| 564 | ContentIndexContext::GetEntryCallback callback) { |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 565 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 566 | |
| 567 | auto wrapped_callback = base::BindOnce( |
| 568 | [](ContentIndexContext::GetEntryCallback callback, |
| 569 | base::Optional<ContentIndexEntry> entry) { |
| 570 | base::PostTask(FROM_HERE, {BrowserThread::UI}, |
| 571 | base::BindOnce(std::move(callback), std::move(entry))); |
| 572 | }, |
| 573 | std::move(callback)); |
| 574 | |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 575 | RunOrPostTaskOnThread( |
| 576 | FROM_HERE, ServiceWorkerContext::GetCoreThreadId(), |
| 577 | base::BindOnce(&ContentIndexDatabase::GetEntryOnCoreThread, |
| 578 | weak_ptr_factory_core_.GetWeakPtr(), |
| 579 | service_worker_registration_id, description_id, |
| 580 | std::move(wrapped_callback))); |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 581 | } |
| 582 | |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 583 | void ContentIndexDatabase::GetEntryOnCoreThread( |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 584 | int64_t service_worker_registration_id, |
| 585 | const std::string& description_id, |
| 586 | ContentIndexContext::GetEntryCallback callback) { |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 587 | DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 588 | |
Rayan Kanso | e147def | 2019-07-22 09:56:35 | [diff] [blame] | 589 | service_worker_context_->GetRegistrationUserData( |
| 590 | service_worker_registration_id, {EntryKey(description_id)}, |
| 591 | base::BindOnce(&ContentIndexDatabase::DidGetEntry, |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 592 | weak_ptr_factory_core_.GetWeakPtr(), |
Rayan Kanso | e147def | 2019-07-22 09:56:35 | [diff] [blame] | 593 | service_worker_registration_id, std::move(callback))); |
| 594 | } |
| 595 | |
| 596 | void ContentIndexDatabase::DidGetEntry( |
| 597 | int64_t service_worker_registration_id, |
| 598 | ContentIndexContext::GetEntryCallback callback, |
| 599 | const std::vector<std::string>& data, |
| 600 | blink::ServiceWorkerStatusCode status) { |
Rayan Kanso | 9f3944a | 2019-07-30 12:18:07 | [diff] [blame] | 601 | content_index::RecordDatabaseOperationStatus("GetEntry", status); |
| 602 | |
Rayan Kanso | e147def | 2019-07-22 09:56:35 | [diff] [blame] | 603 | if (status != blink::ServiceWorkerStatusCode::kOk) { |
Rayan Kanso | e147def | 2019-07-22 09:56:35 | [diff] [blame] | 604 | std::move(callback).Run(base::nullopt); |
| 605 | return; |
| 606 | } |
| 607 | |
| 608 | DCHECK_EQ(data.size(), 1u); |
| 609 | std::move(callback).Run( |
| 610 | EntryFromSerializedProto(service_worker_registration_id, data.front())); |
| 611 | } |
| 612 | |
Rayan Kanso | 5e2ff0e | 2019-09-04 10:33:10 | [diff] [blame^] | 613 | void ContentIndexDatabase::ClearServiceWorkerDataOnCorruption( |
| 614 | int64_t service_worker_registration_id) { |
| 615 | DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); |
| 616 | |
| 617 | service_worker_context_->ClearRegistrationUserDataByKeyPrefixes( |
| 618 | service_worker_registration_id, {kEntryPrefix, kIconPrefix}, |
| 619 | base::BindOnce(&content_index::RecordDatabaseOperationStatus, |
| 620 | "ClearCorruptedData")); |
| 621 | } |
| 622 | |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 623 | void ContentIndexDatabase::DeleteItem(int64_t service_worker_registration_id, |
| 624 | const url::Origin& origin, |
| 625 | const std::string& description_id) { |
| 626 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 627 | |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 628 | RunOrPostTaskOnThread( |
| 629 | FROM_HERE, ServiceWorkerContext::GetCoreThreadId(), |
| 630 | base::BindOnce(&ContentIndexDatabase::DeleteEntryOnCoreThread, |
| 631 | weak_ptr_factory_core_.GetWeakPtr(), |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 632 | service_worker_registration_id, origin, description_id, |
| 633 | base::BindOnce(&ContentIndexDatabase::DidDeleteItem, |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 634 | weak_ptr_factory_core_.GetWeakPtr(), |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 635 | service_worker_registration_id, origin, |
| 636 | description_id))); |
| 637 | } |
| 638 | |
| 639 | void ContentIndexDatabase::DidDeleteItem( |
| 640 | int64_t service_worker_registration_id, |
| 641 | const url::Origin& origin, |
| 642 | const std::string& description_id, |
| 643 | blink::mojom::ContentIndexError error) { |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 644 | DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 645 | |
| 646 | if (error != blink::mojom::ContentIndexError::NONE) |
| 647 | return; |
| 648 | |
| 649 | service_worker_context_->FindReadyRegistrationForId( |
| 650 | service_worker_registration_id, origin.GetURL(), |
| 651 | base::BindOnce(&ContentIndexDatabase::StartActiveWorkerForDispatch, |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 652 | weak_ptr_factory_core_.GetWeakPtr(), description_id)); |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 653 | } |
| 654 | |
| 655 | void ContentIndexDatabase::StartActiveWorkerForDispatch( |
| 656 | const std::string& description_id, |
| 657 | blink::ServiceWorkerStatusCode service_worker_status, |
| 658 | scoped_refptr<ServiceWorkerRegistration> registration) { |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 659 | DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 660 | |
| 661 | content_index::RecordDisptachStatus("Find", service_worker_status); |
| 662 | |
| 663 | if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) |
| 664 | return; |
| 665 | |
| 666 | ServiceWorkerVersion* service_worker_version = registration->active_version(); |
| 667 | DCHECK(service_worker_version); |
| 668 | |
| 669 | service_worker_version->RunAfterStartWorker( |
| 670 | ServiceWorkerMetrics::EventType::CONTENT_DELETE, |
| 671 | base::BindOnce(&ContentIndexDatabase::DeliverMessageToWorker, |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 672 | weak_ptr_factory_core_.GetWeakPtr(), |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 673 | base::WrapRefCounted(service_worker_version), |
| 674 | std::move(registration), description_id)); |
| 675 | } |
| 676 | |
| 677 | void ContentIndexDatabase::DeliverMessageToWorker( |
| 678 | scoped_refptr<ServiceWorkerVersion> service_worker, |
| 679 | scoped_refptr<ServiceWorkerRegistration> registration, |
| 680 | const std::string& description_id, |
| 681 | blink::ServiceWorkerStatusCode service_worker_status) { |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 682 | DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 683 | |
| 684 | content_index::RecordDisptachStatus("Start", service_worker_status); |
| 685 | |
| 686 | if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) |
| 687 | return; |
| 688 | |
| 689 | // Don't allow DB operations while the `contentdelete` event is firing. |
| 690 | // This is to prevent re-registering the deleted content within the event. |
| 691 | BlockOrigin(service_worker->script_origin()); |
| 692 | |
| 693 | int request_id = service_worker->StartRequest( |
| 694 | ServiceWorkerMetrics::EventType::CONTENT_DELETE, |
| 695 | base::BindOnce(&ContentIndexDatabase::DidDispatchEvent, |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 696 | weak_ptr_factory_core_.GetWeakPtr(), |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 697 | service_worker->script_origin())); |
| 698 | |
| 699 | service_worker->endpoint()->DispatchContentDeleteEvent( |
| 700 | description_id, service_worker->CreateSimpleEventCallback(request_id)); |
| 701 | } |
| 702 | |
| 703 | void ContentIndexDatabase::DidDispatchEvent( |
| 704 | const url::Origin& origin, |
| 705 | blink::ServiceWorkerStatusCode service_worker_status) { |
Matt Falkenhagen | 105efb82 | 2019-08-29 20:49:17 | [diff] [blame] | 706 | DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); |
Rayan Kanso | 7806f69 | 2019-08-21 12:30:44 | [diff] [blame] | 707 | |
| 708 | content_index::RecordDisptachStatus("Dispatch", service_worker_status); |
| 709 | UnblockOrigin(origin); |
| 710 | } |
| 711 | |
Rayan Kanso | 394af70 | 2019-07-25 12:50:37 | [diff] [blame] | 712 | void ContentIndexDatabase::BlockOrigin(const url::Origin& origin) { |
| 713 | blocked_origins_[origin]++; |
| 714 | } |
| 715 | |
| 716 | void ContentIndexDatabase::UnblockOrigin(const url::Origin& origin) { |
| 717 | DCHECK(blocked_origins_.count(origin)); |
| 718 | auto it = blocked_origins_.find(origin); |
| 719 | if (it->second == 1) |
| 720 | blocked_origins_.erase(it); |
| 721 | else |
| 722 | it->second--; |
| 723 | } |
| 724 | |
Rayan Kanso | ba07580 | 2019-06-28 16:33:48 | [diff] [blame] | 725 | void ContentIndexDatabase::Shutdown() { |
Rayan Kanso | 24f7d41 | 2019-07-11 10:09:30 | [diff] [blame] | 726 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Rayan Kanso | ba07580 | 2019-06-28 16:33:48 | [diff] [blame] | 727 | |
| 728 | provider_ = nullptr; |
| 729 | } |
| 730 | |
Rayan Kanso | 24f7d41 | 2019-07-11 10:09:30 | [diff] [blame] | 731 | void ContentIndexDatabase::NotifyProviderContentAdded( |
| 732 | std::vector<ContentIndexEntry> entries) { |
| 733 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 734 | |
| 735 | if (!provider_) |
| 736 | return; |
| 737 | |
Rayan Kanso | a42c3caf | 2019-07-19 17:21:20 | [diff] [blame] | 738 | for (auto& entry : entries) |
| 739 | provider_->OnContentAdded(std::move(entry)); |
Rayan Kanso | 24f7d41 | 2019-07-11 10:09:30 | [diff] [blame] | 740 | } |
| 741 | |
| 742 | void ContentIndexDatabase::NotifyProviderContentDeleted( |
| 743 | int64_t service_worker_registration_id, |
Rayan Kanso | a42c3caf | 2019-07-19 17:21:20 | [diff] [blame] | 744 | const url::Origin& origin, |
Rayan Kanso | 24f7d41 | 2019-07-11 10:09:30 | [diff] [blame] | 745 | const std::string& entry_id) { |
| 746 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 747 | |
| 748 | if (!provider_) |
| 749 | return; |
| 750 | |
Rayan Kanso | a42c3caf | 2019-07-19 17:21:20 | [diff] [blame] | 751 | provider_->OnContentDeleted(service_worker_registration_id, origin, entry_id); |
Rayan Kanso | 24f7d41 | 2019-07-11 10:09:30 | [diff] [blame] | 752 | } |
| 753 | |
Rayan Kanso | 296eb3d | 2019-06-26 11:32:04 | [diff] [blame] | 754 | } // namespace content |