Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2887)

Unified Diff: android_webview/native/aw_quota_manager_bridge_impl.cc

Issue 12253057: Implement WebStorage API methods (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Tests still work in progress :( Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: android_webview/native/aw_quota_manager_bridge_impl.cc
diff --git a/android_webview/native/aw_quota_manager_bridge_impl.cc b/android_webview/native/aw_quota_manager_bridge_impl.cc
new file mode 100644
index 0000000000000000000000000000000000000000..39dd7c734ba0867e5fc47a0e899a87dbe4ce598e
--- /dev/null
+++ b/android_webview/native/aw_quota_manager_bridge_impl.cc
@@ -0,0 +1,338 @@
+// Copyright (c) 2013 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 "android_webview/native/aw_quota_manager_bridge_impl.h"
+
+#include <set>
+
+#include "android_webview/browser/aw_browser_context.h"
+#include "android_webview/browser/aw_content_browser_client.h"
+#include "base/android/jni_array.h"
+#include "base/android/jni_string.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/storage_partition.h"
+#include "content/public/common/content_client.h"
+#include "googleurl/src/gurl.h"
+#include "jni/AwQuotaManagerBridge_jni.h"
+#include "webkit/quota/quota_manager.h"
+#include "webkit/quota/quota_types.h"
+
+using base::android::AttachCurrentThread;
+using content::BrowserThread;
+using content::StoragePartition;
+using quota::QuotaClient;
+using quota::QuotaManager;
+
+namespace android_webview {
+
+namespace {
+
+class GetOriginsTask : public base::RefCountedThreadSafe<GetOriginsTask> {
+ public:
+ GetOriginsTask(
+ const AwQuotaManagerBridgeImpl::GetOriginsCallback& callback,
+ QuotaManager* quota_manager);
+
+ void Run();
+
+ private:
+ friend class base::RefCountedThreadSafe<GetOriginsTask>;
+ ~GetOriginsTask();
+
+ void OnOriginsObtained(const std::set<GURL>& origins,
+ quota::StorageType type);
+
+ void OnUsageAndQuotaObtained(const GURL& origin,
+ quota::QuotaStatusCode status_code,
+ int64 usage,
+ int64 quota);
+
+ void CheckDone();
+ void DoneOnUIThread();
+
+ AwQuotaManagerBridgeImpl::GetOriginsCallback ui_callback_;
+ scoped_refptr<QuotaManager> quota_manager_;
+
+ std::vector<std::string> origin_;
+ std::vector<int64> usage_;
+ std::vector<int64> quota_;
+
+ size_t num_callbacks_to_wait_;
+ size_t num_callbacks_received_;
+
+ DISALLOW_COPY_AND_ASSIGN(GetOriginsTask);
+};
+
+GetOriginsTask::GetOriginsTask(
+ const AwQuotaManagerBridgeImpl::GetOriginsCallback& callback,
+ QuotaManager* quota_manager)
+ : ui_callback_(callback),
+ quota_manager_(quota_manager) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+}
+
+GetOriginsTask::~GetOriginsTask() {}
+
+void GetOriginsTask::Run() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&QuotaManager::GetOriginsModifiedSince,
+ quota_manager_,
+ quota::kStorageTypeTemporary,
+ base::Time() /* Since beginning of time. */,
+ base::Bind(&GetOriginsTask::OnOriginsObtained, this)));
+}
+
+void GetOriginsTask::OnOriginsObtained(
+ const std::set<GURL>& origins, quota::StorageType type) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ num_callbacks_to_wait_ = origins.size();
+ num_callbacks_received_ = 0u;
+
+ for (std::set<GURL>::const_iterator origin = origins.begin();
+ origin != origins.end();
+ ++origin) {
+ quota_manager_->GetUsageAndQuota(
+ *origin,
+ type,
+ base::Bind(&GetOriginsTask::OnUsageAndQuotaObtained, this, *origin));
+ }
+
+ CheckDone();
+}
+
+void GetOriginsTask::OnUsageAndQuotaObtained(const GURL& origin,
+ quota::QuotaStatusCode status_code,
+ int64 usage,
+ int64 quota) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ if (status_code == quota::kQuotaStatusOk) {
+ origin_.push_back(origin.spec());
+ usage_.push_back(usage);
+ quota_.push_back(quota);
+ }
+
+ ++num_callbacks_received_;
+ CheckDone();
+}
+
+void GetOriginsTask::CheckDone() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ if (num_callbacks_received_ == num_callbacks_to_wait_) {
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&GetOriginsTask::DoneOnUIThread, this));
mkosiba (inactive) 2013/02/21 11:38:30 umm... you should be able to do something like thi
boliu 2013/02/21 17:01:57 Oh wow it does work. I thought media::base::BindTo
mkosiba (inactive) 2013/02/22 15:47:08 _if_ you want to be super-an..correct about that y
boliu 2013/02/22 16:58:55 Ha! That involves new-ing 3 empty vectors, and the
+ } else if (num_callbacks_received_ > num_callbacks_to_wait_) {
+ NOTREACHED();
+ }
+}
+
+void GetOriginsTask::DoneOnUIThread() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ ui_callback_.Run(origin_, usage_, quota_);
+}
+
+} // namespace
+
+
+// static
+jint GetDefaultNativeAwQuotaManagerBridge(JNIEnv* env, jclass clazz) {
+ content::ContentBrowserClient* browser_client =
+ content::GetContentClient()->browser();
+ DCHECK(browser_client);
+
+ AwContentBrowserClient* aw_browser_client =
+ AwContentBrowserClient::FromContentBrowserClient(browser_client);
+ AwBrowserContext* browser_context = aw_browser_client->GetAwBrowserContext();
+ DCHECK(browser_context);
+
+ AwQuotaManagerBridgeImpl* bridge = static_cast<AwQuotaManagerBridgeImpl*>(
+ browser_context->GetQuotaManagerBridge());
+ DCHECK(bridge);
+ return reinterpret_cast<jint>(bridge);
+}
+
+AwQuotaManagerBridgeImpl::AwQuotaManagerBridgeImpl(
+ AwBrowserContext* browser_context)
+ : weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ browser_context_(browser_context) {
+}
+
+void AwQuotaManagerBridgeImpl::Init(JNIEnv* env, jobject object) {
+ java_ref_ = JavaObjectWeakGlobalRef(env, object);
+}
+
+QuotaManager* AwQuotaManagerBridgeImpl::GetQuotaManager() const {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ // AndroidWebview does not use per-site storage partitions.
+ // TODO(boliu): Get @ajwong to review this before submit.
+ StoragePartition* storage_partition =
+ content::BrowserContext::GetStoragePartitionForSite(
+ browser_context_, GURL());
+ DCHECK(storage_partition);
+
+ QuotaManager* quota_manager = storage_partition->GetQuotaManager();
+ DCHECK(quota_manager);
+ return quota_manager;
+}
+
+namespace {
+
+void IgnoreStatus(quota::QuotaStatusCode status_code) {}
+
+void DeleteAllOriginData(
+ QuotaManager* quota_manager,
+ const std::set<GURL>& origins,
+ quota::StorageType type) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // TODO(boliu): Maybe not spam the db thread?
+ for (std::set<GURL>::const_iterator origin = origins.begin();
+ origin != origins.end();
+ ++origin) {
+ quota_manager->DeleteOriginData(*origin,
+ type,
+ QuotaClient::kAllClientsMask,
+ base::Bind(&IgnoreStatus));
+ }
+}
+
+} // namespace
+
+void AwQuotaManagerBridgeImpl::DeleteAllData(JNIEnv* env, jobject object) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ scoped_refptr<QuotaManager> quota_manager = GetQuotaManager();
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&QuotaManager::GetOriginsModifiedSince,
+ quota_manager,
+ quota::kStorageTypeTemporary,
+ base::Time() /* Since beginning of time. */,
+ base::Bind(&DeleteAllOriginData, quota_manager)));
+
+ // TODO(boliu): This needs to clear WebStorage (ie localStorage and
+ // sessionStorage).
+}
+
+void AwQuotaManagerBridgeImpl::DeleteOrigin(
+ JNIEnv* env, jobject object, jstring origin) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&QuotaManager::DeleteOriginData,
+ GetQuotaManager(),
+ GURL(base::android::ConvertJavaStringToUTF16(env, origin)),
+ quota::kStorageTypeTemporary,
+ QuotaClient::kAllClientsMask,
+ base::Bind(&IgnoreStatus)));
+}
+
+void AwQuotaManagerBridgeImpl::GetOrigins(
+ JNIEnv* env, jobject object, jint callback_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ const GetOriginsCallback ui_callback = base::Bind(
+ &AwQuotaManagerBridgeImpl::GetOriginsCallbackImpl,
+ weak_factory_.GetWeakPtr(),
+ callback_id);
+
+ (new GetOriginsTask(ui_callback, GetQuotaManager()))->Run();
+}
+
+void AwQuotaManagerBridgeImpl::GetOriginsCallbackImpl(
+ int jcallback_id,
+ const std::vector<std::string>& origin,
+ const std::vector<int64>& usage,
+ const std::vector<int64>& quota) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+ if (obj.is_null())
+ return;
+
+ Java_AwQuotaManagerBridge_onGetOriginsCallback(
+ env,
+ obj.obj(),
+ jcallback_id,
+ base::android::ToJavaArrayOfStrings(env, origin).obj(),
boliu 2013/02/21 18:44:45 Oh wow this is so so wrong...it's a byte[][] on ja
+ base::android::ToJavaLongArray(env, usage.begin(), usage.size()).obj(),
mkosiba (inactive) 2013/02/21 11:38:30 use the version that takes the vector as an arg di
boliu 2013/02/21 17:01:57 Wah?? I was sure I fixed these...must have gotten
+ base::android::ToJavaLongArray(env, quota.begin(), quota.size()).obj());
+}
+
+namespace {
+
+void RunGetUsageAndQuotaCallback(
+ const AwQuotaManagerBridgeImpl::QuotaUsageCallback& ui_callback,
+ int64 usage,
+ int64 quota) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ ui_callback.Run(usage, quota);
+}
+
+void OnUsageAndQuotaObtained(
+ const AwQuotaManagerBridgeImpl::QuotaUsageCallback& ui_callback,
+ quota::QuotaStatusCode status_code,
+ int64 usage,
+ int64 quota) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ if (status_code != quota::kQuotaStatusOk) {
+ // Indicate error. TODO(boliu): Check this does not mean infinite.
+ usage = -1;
+ quota = -1;
+ }
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&RunGetUsageAndQuotaCallback,
mkosiba (inactive) 2013/02/21 11:38:30 same thing here - you should be able to bind the c
boliu 2013/02/21 17:01:57 Fixed here. Bind ftw!!
+ ui_callback,
+ usage,
+ quota));
+}
+
+} // namespace
+
+void AwQuotaManagerBridgeImpl::GetUsageAndQuotaForOrigin(
+ JNIEnv* env, jobject object,
+ jstring origin,
+ jint callback_id,
+ bool is_quota) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ const QuotaUsageCallback ui_callback = base::Bind(
+ &AwQuotaManagerBridgeImpl::QuotaUsageCallbackImpl,
+ weak_factory_.GetWeakPtr(),
+ callback_id,
+ is_quota);
+
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&QuotaManager::GetUsageAndQuota,
+ GetQuotaManager(),
+ GURL(base::android::ConvertJavaStringToUTF16(env, origin)),
+ quota::kStorageTypeTemporary,
+ base::Bind(&OnUsageAndQuotaObtained, ui_callback)));
+}
+
+void AwQuotaManagerBridgeImpl::QuotaUsageCallbackImpl(
+ int jcallback_id, bool is_quota, int64 usage, int64 quota) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+ if (obj.is_null())
+ return;
+
+ Java_AwQuotaManagerBridge_onGetUsageAndQuotaForOriginCallback(
+ env, obj.obj(), jcallback_id, is_quota, usage, quota);
+}
+
+bool RegisterAwQuotaManagerBridge(JNIEnv* env) {
+ return RegisterNativesImpl(env) >= 0;
+}
+
+} // namespace android_webview

Powered by Google App Engine
This is Rietveld 408576698