1 // Copyright 2013 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/dom_storage/dom_storage_session.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/logging.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "base/tracked_objects.h"
13 #include "content/browser/dom_storage/dom_storage_context_impl.h"
14 #include "content/browser/dom_storage/dom_storage_task_runner.h"
15
16 namespace content {
17
18 namespace {
19
PostMergeTaskResult(const SessionStorageNamespace::MergeResultCallback & callback,SessionStorageNamespace::MergeResult result)20 void PostMergeTaskResult(
21 const SessionStorageNamespace::MergeResultCallback& callback,
22 SessionStorageNamespace::MergeResult result) {
23 callback.Run(result);
24 }
25
RunMergeTaskAndPostResult(const base::Callback<SessionStorageNamespace::MergeResult (void)> & task,scoped_refptr<base::SingleThreadTaskRunner> result_loop,const SessionStorageNamespace::MergeResultCallback & callback)26 void RunMergeTaskAndPostResult(
27 const base::Callback<SessionStorageNamespace::MergeResult(void)>& task,
28 scoped_refptr<base::SingleThreadTaskRunner> result_loop,
29 const SessionStorageNamespace::MergeResultCallback& callback) {
30 SessionStorageNamespace::MergeResult result = task.Run();
31 result_loop->PostTask(
32 FROM_HERE, base::Bind(&PostMergeTaskResult, callback, result));
33 }
34
35 } // namespace
36
DOMStorageSession(DOMStorageContextImpl * context)37 DOMStorageSession::DOMStorageSession(DOMStorageContextImpl* context)
38 : context_(context),
39 namespace_id_(context->AllocateSessionId()),
40 persistent_namespace_id_(context->AllocatePersistentSessionId()),
41 should_persist_(false) {
42 context->task_runner()->PostTask(
43 FROM_HERE,
44 base::Bind(&DOMStorageContextImpl::CreateSessionNamespace,
45 context_, namespace_id_, persistent_namespace_id_));
46 }
47
DOMStorageSession(DOMStorageContextImpl * context,const std::string & persistent_namespace_id)48 DOMStorageSession::DOMStorageSession(DOMStorageContextImpl* context,
49 const std::string& persistent_namespace_id)
50 : context_(context),
51 namespace_id_(context->AllocateSessionId()),
52 persistent_namespace_id_(persistent_namespace_id),
53 should_persist_(false) {
54 context->task_runner()->PostTask(
55 FROM_HERE,
56 base::Bind(&DOMStorageContextImpl::CreateSessionNamespace,
57 context_, namespace_id_, persistent_namespace_id_));
58 }
59
DOMStorageSession(DOMStorageSession * master_dom_storage_session)60 DOMStorageSession::DOMStorageSession(
61 DOMStorageSession* master_dom_storage_session)
62 : context_(master_dom_storage_session->context_),
63 namespace_id_(master_dom_storage_session->context_->AllocateSessionId()),
64 persistent_namespace_id_(
65 master_dom_storage_session->persistent_namespace_id()),
66 should_persist_(false) {
67 context_->task_runner()->PostTask(
68 FROM_HERE,
69 base::Bind(&DOMStorageContextImpl::CreateAliasSessionNamespace,
70 context_,
71 master_dom_storage_session->namespace_id(),
72 namespace_id_,
73 persistent_namespace_id_));
74 }
75
SetShouldPersist(bool should_persist)76 void DOMStorageSession::SetShouldPersist(bool should_persist) {
77 should_persist_ = should_persist;
78 }
79
should_persist() const80 bool DOMStorageSession::should_persist() const {
81 return should_persist_;
82 }
83
IsFromContext(DOMStorageContextImpl * context)84 bool DOMStorageSession::IsFromContext(DOMStorageContextImpl* context) {
85 return context_.get() == context;
86 }
87
Clone()88 DOMStorageSession* DOMStorageSession::Clone() {
89 return CloneFrom(context_.get(), namespace_id_);
90 }
91
92 // static
CloneFrom(DOMStorageContextImpl * context,int64 namepace_id_to_clone)93 DOMStorageSession* DOMStorageSession::CloneFrom(DOMStorageContextImpl* context,
94 int64 namepace_id_to_clone) {
95 int64 clone_id = context->AllocateSessionId();
96 std::string persistent_clone_id = context->AllocatePersistentSessionId();
97 context->task_runner()->PostTask(
98 FROM_HERE,
99 base::Bind(&DOMStorageContextImpl::CloneSessionNamespace,
100 context, namepace_id_to_clone, clone_id, persistent_clone_id));
101 return new DOMStorageSession(context, clone_id, persistent_clone_id);
102 }
103
DOMStorageSession(DOMStorageContextImpl * context,int64 namespace_id,const std::string & persistent_namespace_id)104 DOMStorageSession::DOMStorageSession(DOMStorageContextImpl* context,
105 int64 namespace_id,
106 const std::string& persistent_namespace_id)
107 : context_(context),
108 namespace_id_(namespace_id),
109 persistent_namespace_id_(persistent_namespace_id),
110 should_persist_(false) {
111 // This ctor is intended for use by the Clone() method.
112 }
113
~DOMStorageSession()114 DOMStorageSession::~DOMStorageSession() {
115 context_->task_runner()->PostTask(
116 FROM_HERE,
117 base::Bind(&DOMStorageContextImpl::DeleteSessionNamespace,
118 context_, namespace_id_, should_persist_));
119 }
120
AddTransactionLogProcessId(int process_id)121 void DOMStorageSession::AddTransactionLogProcessId(int process_id) {
122 context_->task_runner()->PostTask(
123 FROM_HERE,
124 base::Bind(&DOMStorageContextImpl::AddTransactionLogProcessId,
125 context_, namespace_id_, process_id));
126 }
127
RemoveTransactionLogProcessId(int process_id)128 void DOMStorageSession::RemoveTransactionLogProcessId(int process_id) {
129 context_->task_runner()->PostTask(
130 FROM_HERE,
131 base::Bind(&DOMStorageContextImpl::RemoveTransactionLogProcessId,
132 context_, namespace_id_, process_id));
133 }
134
Merge(bool actually_merge,int process_id,DOMStorageSession * other,const SessionStorageNamespace::MergeResultCallback & callback)135 void DOMStorageSession::Merge(
136 bool actually_merge,
137 int process_id,
138 DOMStorageSession* other,
139 const SessionStorageNamespace::MergeResultCallback& callback) {
140 scoped_refptr<base::SingleThreadTaskRunner> current_loop(
141 base::ThreadTaskRunnerHandle::Get());
142 SessionStorageNamespace::MergeResultCallback cb =
143 base::Bind(&DOMStorageSession::ProcessMergeResult,
144 this,
145 actually_merge,
146 callback,
147 other->persistent_namespace_id());
148 context_->task_runner()->PostTask(
149 FROM_HERE,
150 base::Bind(&RunMergeTaskAndPostResult,
151 base::Bind(&DOMStorageContextImpl::MergeSessionStorage,
152 context_, namespace_id_, actually_merge, process_id,
153 other->namespace_id_),
154 current_loop,
155 cb));
156 }
157
ProcessMergeResult(bool actually_merge,const SessionStorageNamespace::MergeResultCallback & callback,const std::string & new_persistent_namespace_id,SessionStorageNamespace::MergeResult result)158 void DOMStorageSession::ProcessMergeResult(
159 bool actually_merge,
160 const SessionStorageNamespace::MergeResultCallback& callback,
161 const std::string& new_persistent_namespace_id,
162 SessionStorageNamespace::MergeResult result) {
163 if (actually_merge &&
164 (result == SessionStorageNamespace::MERGE_RESULT_MERGEABLE ||
165 result == SessionStorageNamespace::MERGE_RESULT_NO_TRANSACTIONS)) {
166 persistent_namespace_id_ = new_persistent_namespace_id;
167 }
168 callback.Run(result);
169 }
170
171 } // namespace content
172