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 16namespace content { 17 18namespace { 19 20void PostMergeTaskResult( 21 const SessionStorageNamespace::MergeResultCallback& callback, 22 SessionStorageNamespace::MergeResult result) { 23 callback.Run(result); 24} 25 26void 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 37DOMStorageSession::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 48DOMStorageSession::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 60DOMStorageSession::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 76void DOMStorageSession::SetShouldPersist(bool should_persist) { 77 should_persist_ = should_persist; 78} 79 80bool DOMStorageSession::should_persist() const { 81 return should_persist_; 82} 83 84bool DOMStorageSession::IsFromContext(DOMStorageContextImpl* context) { 85 return context_.get() == context; 86} 87 88DOMStorageSession* DOMStorageSession::Clone() { 89 return CloneFrom(context_.get(), namespace_id_); 90} 91 92// static 93DOMStorageSession* 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 104DOMStorageSession::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 114DOMStorageSession::~DOMStorageSession() { 115 context_->task_runner()->PostTask( 116 FROM_HERE, 117 base::Bind(&DOMStorageContextImpl::DeleteSessionNamespace, 118 context_, namespace_id_, should_persist_)); 119} 120 121void 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 128void 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 135void 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 158void 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