[M108 Migration] Support unlimitedstorage privilege for Indexed DB 80/287180/8
authorv-saha <v.saha@samsung.com>
Tue, 24 Jan 2023 06:49:37 +0000 (12:19 +0530)
committerDae-Hyun Ko <dhyuna.ko@samsung.com>
Tue, 31 Jan 2023 00:44:19 +0000 (00:44 +0000)
The unlimitedstorage privilege can be granted when temporary quota is
exceeded during indexedDB transaction. The minimum preserve space for
system is changed to 10% of the total disk space from 1GB.
The unlimitedstorage quota is the amount of available disk space
excluding 10% of the total disk space. the maximum quota is less than
or equal to 2GB.

Reference:
https://review.tizen.org/gerrit/277648

Change-Id: Ib2a05423c1d2b3ed7cb8db44caad8705941d99b9
Signed-off-by: v-saha <v.saha@samsung.com>
20 files changed:
content/browser/background_fetch/background_fetch_test_data_manager.cc
content/browser/indexed_db/transaction_impl.cc
storage/browser/quota/quota_client_type.h
storage/browser/quota/quota_manager_impl.cc
storage/browser/quota/quota_manager_impl.h
storage/browser/quota/quota_manager_proxy.cc
storage/browser/quota/quota_manager_proxy.h
storage/browser/quota/special_storage_policy.h
storage/browser/test/mock_quota_manager_proxy.cc
storage/browser/test/mock_quota_manager_proxy.h
tizen_src/ewk/efl_integration/BUILD.gn
tizen_src/ewk/efl_integration/browser/special_storage_policy_efl.cc [new file with mode: 0644]
tizen_src/ewk/efl_integration/browser/special_storage_policy_efl.h [new file with mode: 0644]
tizen_src/ewk/efl_integration/browser_context_efl.cc
tizen_src/ewk/efl_integration/browser_context_efl.h
tizen_src/ewk/efl_integration/eweb_view.cc
tizen_src/ewk/efl_integration/eweb_view.h
tizen_src/ewk/efl_integration/public/ewk_view.cc
tizen_src/ewk/ubrowser/window.cc
tizen_src/ewk/ubrowser/window.h

index 46107c2..ed03054 100644 (file)
@@ -41,7 +41,9 @@ class MockBGFQuotaManagerProxy : public storage::MockQuotaManagerProxy {
       const blink::StorageKey& storage_key,
       blink::mojom::StorageType type,
       scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
-      UsageAndQuotaCallback callback) override {
+      UsageAndQuotaCallback callback,
+      storage::QuotaClientType id,
+      int64_t transaction_size) override {
     DCHECK(callback_task_runner);
 
     // While this DCHECK is true, the PostTask() below isn't strictly necessary.
index 510e70c..feb5ee3 100644 (file)
@@ -246,7 +246,8 @@ void TransactionImpl::Commit(int64_t num_errors_handled) {
       bucket_locator_.storage_key, blink::mojom::StorageType::kTemporary,
       indexed_db_context_->IDBTaskRunner(),
       base::BindOnce(&TransactionImpl::OnGotUsageAndQuotaForCommit,
-                     weak_factory_.GetWeakPtr()));
+                     weak_factory_.GetWeakPtr()),
+      storage::QuotaClientType::kIndexedDatabase, transaction_->size());
 }
 
 void TransactionImpl::OnGotUsageAndQuotaForCommit(
index ccd83b1..fe3149a 100644 (file)
@@ -15,6 +15,7 @@ namespace storage {
 // Values are not expected to be persisted or logged. Enum members may be added,
 // removed, and reordered without warning.
 enum class QuotaClientType {
+  kUnknown = 0,
   kFileSystem = 1,
   kDatabase = 2,
   kIndexedDatabase = 3,
index 28e4554..af881c2 100644 (file)
@@ -214,8 +214,14 @@ class QuotaManagerImpl::UsageAndQuotaInfoGatherer : public QuotaTask {
       manager()->GetStorageCapacity(
           base::BindOnce(&UsageAndQuotaInfoGatherer::OnGotCapacity,
                          weak_factory_.GetWeakPtr(), barrier));
+#if BUILDFLAG(IS_TIZEN)
+      // max quota size is 2 GB on Tizen
+      SetDesiredStorageKeyQuota(barrier, blink::mojom::QuotaStatusCode::kOk,
+                          2 * 1024 * kMBytes);
+#else
       SetDesiredStorageKeyQuota(barrier, blink::mojom::QuotaStatusCode::kOk,
                                 kNoLimit);
+#endif
     } else if (type_ == StorageType::kSyncable) {
       SetDesiredStorageKeyQuota(barrier, blink::mojom::QuotaStatusCode::kOk,
                                 kSyncableStorageDefaultHostQuota);
@@ -1339,12 +1345,16 @@ void QuotaManagerImpl::GetUsageAndQuota(const StorageKey& storage_key,
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(callback);
 
+#if !BUILDFLAG(IS_TIZEN)
+  // it needs maximum quota for unlimitedstorage policy. the max quota will be
+  // calculated in GetUsageAndQuotaForWebApps().
   if (IsStorageUnlimited(storage_key, type)) {
     // TODO(michaeln): This seems like a non-obvious odd behavior, probably for
     // apps/extensions, but it would be good to eliminate this special case.
     std::move(callback).Run(blink::mojom::QuotaStatusCode::kOk, 0, kNoLimit);
     return;
   }
+#endif
 
   GetUsageAndQuotaWithBreakdown(
       storage_key, type,
@@ -3077,4 +3087,45 @@ QuotaAvailability QuotaManagerImpl::GetVolumeInfo(const base::FilePath& path) {
                            base::SysInfo::AmountOfFreeDiskSpace(path));
 }
 
+#if BUILDFLAG(IS_TIZEN)
+void QuotaManagerImpl::GetTizenUnlimitedStoragePrivilege(
+    const GURL& origin,
+    QuotaClientType id,
+    int64_t transaction_size,
+    UsageAndQuotaCallback callback,
+    blink::mojom::QuotaStatusCode status,
+    int64_t usage,
+    int64_t quota) {
+  if (id == storage::QuotaClientType::kIndexedDatabase &&
+      status == blink::mojom::QuotaStatusCode::kOk &&
+      transaction_size + usage > quota) {
+    if (special_storage_policy_.get()) {
+      special_storage_policy_->RequestUnlimitedStoragePolicy(
+          origin, quota,
+          base::BindOnce(
+              &QuotaManagerImpl::DidGetTizenUnlimitedStoragePrivilege,
+              weak_factory_.GetWeakPtr(), origin, std::move(callback), status,
+              usage, quota));
+      // callback will be invoked after checking unlimitedstorage privilege.
+      return;
+    }
+  }
+  std::move(callback).Run(status, usage, quota);
+}
+
+void QuotaManagerImpl::DidGetTizenUnlimitedStoragePrivilege(
+    const GURL& origin,
+    UsageAndQuotaCallback callback,
+    blink::mojom::QuotaStatusCode status,
+    int64_t usage,
+    int64_t quota,
+    bool policy_changed) {
+  if (policy_changed)
+    GetUsageAndQuota(StorageKey(url::Origin::Create(origin)),
+                     StorageType::kTemporary, std::move(callback));
+  else
+    std::move(callback).Run(status, usage, quota);
+}
+#endif
+
 }  // namespace storage
index b6dfe1f..e214300 100644 (file)
@@ -434,6 +434,24 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl
   // DevTools clients/QuotaOverrideHandle with an active override.
   void WithdrawOverridesForHandle(int handle_id);
 
+#if BUILDFLAG(IS_TIZEN)
+  void GetTizenUnlimitedStoragePrivilege(const GURL& origin,
+                                         QuotaClientType id,
+                                         int64_t transaction_size,
+                                         UsageAndQuotaCallback callback,
+                                         blink::mojom::QuotaStatusCode status,
+                                         int64_t usage,
+                                         int64_t quota);
+
+  void DidGetTizenUnlimitedStoragePrivilege(
+      const GURL& origin,
+      UsageAndQuotaCallback callback,
+      blink::mojom::QuotaStatusCode status,
+      int64_t usage,
+      int64_t quota,
+      bool policy_changed);
+#endif
+
   // Cap size for per-host persistent quota determined by the histogram.
   // Cap size for per-host persistent quota determined by the histogram.
   // This is a bit lax value because the histogram says nothing about per-host
index a447f5b..6bf3767 100644 (file)
@@ -32,6 +32,7 @@
 #include "storage/browser/quota/storage_directory_util.h"
 #include "third_party/blink/public/common/storage_key/storage_key.h"
 #include "third_party/blink/public/mojom/quota/quota_types.mojom.h"
+#include "url/gurl.h"
 
 using ::blink::StorageKey;
 
@@ -528,7 +529,9 @@ void QuotaManagerProxy::GetUsageAndQuota(
     const StorageKey& storage_key,
     blink::mojom::StorageType type,
     scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
-    UsageAndQuotaCallback callback) {
+    UsageAndQuotaCallback callback,
+    QuotaClientType id,
+    int64_t transaction_size) {
   DCHECK(callback_task_runner);
   DCHECK(callback);
 
@@ -537,7 +540,7 @@ void QuotaManagerProxy::GetUsageAndQuota(
         FROM_HERE,
         base::BindOnce(&QuotaManagerProxy::GetUsageAndQuota, this, storage_key,
                        type, std::move(callback_task_runner),
-                       std::move(callback)));
+                       std::move(callback), id, transaction_size));
     return;
   }
 
@@ -550,7 +553,17 @@ void QuotaManagerProxy::GetUsageAndQuota(
     return;
   }
 
-  quota_manager_impl_->GetUsageAndQuota(storage_key, type, std::move(respond));
+  UsageAndQuotaCallback wrapped_callback =
+#if BUILDFLAG(IS_TIZEN)
+      (type == blink::mojom::StorageType::kTemporary)
+          ? base::BindOnce(&QuotaManagerImpl::GetTizenUnlimitedStoragePrivilege,
+                           quota_manager_impl_, storage_key.origin().GetURL(),
+                           id, transaction_size, std::move(callback))
+          :
+#endif
+          std::move(callback);
+
+  quota_manager_impl_->GetUsageAndQuota(storage_key, type, std::move(wrapped_callback));
 }
 
 void QuotaManagerProxy::GetBucketUsageAndQuota(
index 6f626c7..59e3790 100644 (file)
@@ -228,7 +228,9 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerProxy
       const blink::StorageKey& storage_key,
       blink::mojom::StorageType type,
       scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
-      UsageAndQuotaCallback callback);
+      UsageAndQuotaCallback callback,
+      QuotaClientType id = QuotaClientType::kUnknown,
+      int64_t transaction_size = 0);
 
   void GetBucketUsageAndQuota(
       const BucketInfo& bucket,
index 30b3826..16d0079 100644 (file)
@@ -5,6 +5,7 @@
 #ifndef STORAGE_BROWSER_QUOTA_SPECIAL_STORAGE_POLICY_H_
 #define STORAGE_BROWSER_QUOTA_SPECIAL_STORAGE_POLICY_H_
 
+#include "base/callback.h"
 #include "base/component_export.h"
 #include "base/memory/ref_counted.h"
 #include "base/observer_list.h"
@@ -28,6 +29,8 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SpecialStoragePolicy
     : public base::RefCountedThreadSafe<SpecialStoragePolicy> {
  public:
   REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
+  using QuotaExceededReplyCallback =
+      base::OnceCallback<void(bool policy_changed)>;
 
   using StoragePolicy = int;
   enum ChangeFlags {
@@ -79,6 +82,15 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SpecialStoragePolicy
   // Returns true if some origins are only allowed session-only storage.
   virtual bool HasSessionOnlyOrigins() = 0;
 
+#if BUILDFLAG(IS_TIZEN)
+  virtual void RequestUnlimitedStoragePolicy(
+      const GURL& origin,
+      int64_t quota,
+      QuotaExceededReplyCallback callback) {
+    return;
+  }
+#endif
+
   // Adds/removes an observer, the policy does not take
   // ownership of the observer. Should only be called on the IO thread.
   void AddObserver(Observer* observer);
index 0809ff1..49b5132 100644 (file)
@@ -89,7 +89,9 @@ void MockQuotaManagerProxy::GetUsageAndQuota(
     const blink::StorageKey& storage_key,
     blink::mojom::StorageType type,
     scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
-    QuotaManager::UsageAndQuotaCallback callback) {
+    QuotaManager::UsageAndQuotaCallback callback,
+    QuotaClientType id,
+    int64_t transaction_size) {
   if (mock_quota_manager_) {
     mock_quota_manager_->GetUsageAndQuota(storage_key, type,
                                           std::move(callback));
index aad73e7..46d6b7b 100644 (file)
@@ -74,7 +74,9 @@ class MockQuotaManagerProxy : public QuotaManagerProxy {
       const blink::StorageKey& storage_key,
       blink::mojom::StorageType type,
       scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
-      UsageAndQuotaCallback callback) override;
+      UsageAndQuotaCallback callback,
+      QuotaClientType id = QuotaClientType::kUnknown,
+      int64_t transaction_size = 0) override;
 
   void GetUsageAndQuota(
       const storage::BucketLocator& bucket_locator,
index d5e87fb..3c4b39e 100755 (executable)
@@ -209,6 +209,8 @@ shared_library("chromium-ewk") {
     "browser/sound_effect.cc",
     "browser/sound_effect.h",
     "browser/sound_effect_tizen.cc",
+    "browser/special_storage_policy_efl.cc",
+    "browser/special_storage_policy_efl.h",
     "browser/ssl_host_state_delegate_efl.cc",
     "browser/ssl_host_state_delegate_efl.h",
     "browser/tizen_extensible_host.cc",
diff --git a/tizen_src/ewk/efl_integration/browser/special_storage_policy_efl.cc b/tizen_src/ewk/efl_integration/browser/special_storage_policy_efl.cc
new file mode 100644 (file)
index 0000000..9e1e926
--- /dev/null
@@ -0,0 +1,82 @@
+// Copyright (c) 2018 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "special_storage_policy_efl.h"
+
+#include "base/containers/contains.h"
+#include "base/stl_util.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "url/origin.h"
+
+using content::BrowserThread;
+
+SpecialStoragePolicyEfl::SpecialStoragePolicyEfl() {}
+
+SpecialStoragePolicyEfl::~SpecialStoragePolicyEfl() {
+  quota_exceeded_callback_.Reset();
+}
+
+bool SpecialStoragePolicyEfl::IsStorageUnlimited(const GURL& origin) {
+  base::AutoLock locker(lock_);
+  if (!base::Contains(unlimited_, origin))
+    return false;
+  return unlimited_.find(origin)->second;
+}
+
+#if BUILDFLAG(IS_TIZEN)
+void SpecialStoragePolicyEfl::RequestUnlimitedStoragePolicy(
+    const GURL& origin,
+    int64_t quota,
+    QuotaExceededReplyCallback callback) {
+  {
+    base::AutoLock locker(lock_);
+    if (base::Contains(unlimited_, origin) ||
+        quota_exceeded_callback_.is_null()) {
+      LOG(INFO) << __func__ << " unlimited.";
+      std::move(callback).Run(false /* policy_changed */);
+      return;
+    }
+  }
+  LOG(INFO) << __func__ << " quota exceeded callback run.";
+  std::move(quota_exceeded_callback_).Run(origin, quota);
+  quota_exceeded_reply_callback_ = std::move(callback);
+}
+#endif
+
+void SpecialStoragePolicyEfl::SetQuotaExceededCallback(
+    QuotaExceededCallback callback) {
+  quota_exceeded_callback_ = std::move(callback);
+}
+
+void SpecialStoragePolicyEfl::SetUnlimitedStoragePolicy(const GURL& origin,
+                                                        bool allow) {
+  if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
+    content::GetIOThreadTaskRunner({})->PostTask(
+        FROM_HERE,
+        base::BindOnce(&SpecialStoragePolicyEfl::SetUnlimitedStoragePolicy,
+                       base::Unretained(this), origin, allow));
+    return;
+  }
+
+  bool policy_changed = IsStorageUnlimited(origin) != allow;
+  LOG(INFO) << __func__ << "() allow:" << allow
+            << ", changed:" << policy_changed;
+  {
+    base::AutoLock locker(lock_);
+    unlimited_[origin] = allow;
+  }
+  if (policy_changed) {
+    if (allow)
+      NotifyGranted(url::Origin::Create(origin),
+                    SpecialStoragePolicy::STORAGE_UNLIMITED);
+    else
+      NotifyRevoked(url::Origin::Create(origin),
+                    SpecialStoragePolicy::STORAGE_UNLIMITED);
+  }
+  if (!quota_exceeded_reply_callback_.is_null()) {
+    LOG(INFO) << __func__ << " quota exceeded reply callback run.";
+    std::move(quota_exceeded_reply_callback_).Run(policy_changed);
+  }
+}
diff --git a/tizen_src/ewk/efl_integration/browser/special_storage_policy_efl.h b/tizen_src/ewk/efl_integration/browser/special_storage_policy_efl.h
new file mode 100644 (file)
index 0000000..81c530f
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright (c) 2018 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SPECIAL_STORAGE_POLICY_EFL_H_
+#define SPECIAL_STORAGE_POLICY_EFL_H_
+
+#include <map>
+
+#include "base/callback.h"
+#include "base/synchronization/lock.h"
+#include "storage/browser/quota/special_storage_policy.h"
+#include "url/gurl.h"
+
+class SpecialStoragePolicyEfl : public storage::SpecialStoragePolicy {
+ public:
+  using QuotaExceededCallback =
+      base::OnceCallback<void(const GURL& origin, int64_t quota)>;
+  SpecialStoragePolicyEfl();
+
+  // storage::SpecialStoragePolicy implementation.
+  bool IsStorageProtected(const GURL& origin) override { return false; }
+  bool IsStorageUnlimited(const GURL& origin) override;
+  bool IsStorageSessionOnly(const GURL& origin) override { return false; }
+  bool HasIsolatedStorage(const GURL& origin) override { return false; }
+  bool HasSessionOnlyOrigins() override { return false; }
+  bool IsStorageDurable(const GURL& origin) override { return false; }
+
+// for quota exceeded callback
+#if BUILDFLAG(IS_TIZEN)
+  void RequestUnlimitedStoragePolicy(
+      const GURL& origin,
+      int64_t quota,
+      QuotaExceededReplyCallback callback) override;
+#endif
+  void SetQuotaExceededCallback(QuotaExceededCallback callback);
+  void SetUnlimitedStoragePolicy(const GURL& origin, bool allow);
+
+ protected:
+  ~SpecialStoragePolicyEfl() override;
+
+  SpecialStoragePolicyEfl(const SpecialStoragePolicyEfl&) = delete;
+  SpecialStoragePolicyEfl& operator=(const SpecialStoragePolicyEfl&) = delete;
+
+ private:
+  base::Lock lock_;
+  std::map<GURL, bool> unlimited_;
+  QuotaExceededCallback quota_exceeded_callback_;
+  QuotaExceededReplyCallback quota_exceeded_reply_callback_;
+};
+
+#endif  // SPECIAL_STORAGE_POLICY_EFL_H_
index 42348cf..2c50667 100644 (file)
@@ -321,4 +321,10 @@ BrowsingDataRemoverDelegate*
 BrowserContextEfl::GetBrowsingDataRemoverDelegate() {
   return nullptr;
 }
+
+SpecialStoragePolicyEfl* BrowserContextEfl::GetSpecialStoragePolicyEfl() {
+  if (!special_storage_policy_efl_.get())
+    special_storage_policy_efl_ = new SpecialStoragePolicyEfl();
+  return special_storage_policy_efl_.get();
+}
 }
index bef9a1e..47668bc 100644 (file)
@@ -10,6 +10,7 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/synchronization/lock.h"
 #include "browser/geolocation/geolocation_permission_context_efl.h"
+#include "browser/special_storage_policy_efl.h"
 #include "browser/ssl_host_state_delegate_efl.h"
 #include "components/visitedlink/browser/visitedlink_delegate.h"
 #include "content/public/browser/browser_context.h"
@@ -101,8 +102,9 @@ class BrowserContextEfl : public BrowserContext,
   }
   BrowserPluginGuestManager* GetGuestManager() override { return 0; }
   storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override {
-    return 0;
+    return GetSpecialStoragePolicyEfl();
   }
+  SpecialStoragePolicyEfl* GetSpecialStoragePolicyEfl();
   PushMessagingService* GetPushMessagingService() override { return 0; }
   base::FilePath GetPath() override;
   base::FilePath GetCachePath() const;
@@ -151,6 +153,7 @@ class BrowserContextEfl : public BrowserContext,
   std::unique_ptr<SSLHostStateDelegateEfl> ssl_host_state_delegate_;
   std::unique_ptr<BackgroundSyncController> background_sync_controller_;
   std::unique_ptr<PermissionControllerDelegate> permission_controller_delegate_;
+  scoped_refptr<SpecialStoragePolicyEfl> special_storage_policy_efl_;
 };
 }
 
index e28f0fe..9dbc816 100644 (file)
@@ -2540,3 +2540,51 @@ void EWebView::DidRespondRequestManifest(
     void* user_data) {
   callback(evas_object_, manifest, user_data);
 }
+
+void EWebView::SetExceededIndexedDatabaseQuotaCallback(
+    Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback,
+    void* user_data) {
+  exceeded_indexed_db_quota_callback_.Set(callback, user_data);
+  content::BrowserContextEfl* browser_context =
+      static_cast<content::BrowserContextEfl*>(
+          web_contents_->GetBrowserContext());
+  if (browser_context) {
+    browser_context->GetSpecialStoragePolicyEfl()->SetQuotaExceededCallback(
+        base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
+                       base::Unretained(this)));
+  }
+}
+
+void EWebView::InvokeExceededIndexedDatabaseQuotaCallback(
+    const GURL& origin,
+    int64_t current_quota) {
+  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+    base::ThreadPool::PostTask(
+        FROM_HERE, {BrowserThread::UI},
+        base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
+                       base::Unretained(this), origin, current_quota));
+    return;
+  }
+  LOG(INFO) << __func__ << "()" << origin << ", " << current_quota;
+  CHECK(!exceeded_indexed_db_quota_origin_.get());
+  exceeded_indexed_db_quota_origin_.reset(new Ewk_Security_Origin(origin));
+  exceeded_indexed_db_quota_callback_.Run(
+      evas_object_, exceeded_indexed_db_quota_origin_.get(), current_quota);
+}
+
+void EWebView::ExceededIndexedDatabaseQuotaReply(bool allow) {
+  if (!exceeded_indexed_db_quota_origin_.get()) {
+    LOG(WARNING) << __func__ << "() : callback is not invoked!";
+    return;
+  }
+  LOG(INFO) << __func__ << "()" << exceeded_indexed_db_quota_origin_->GetURL()
+            << ", " << allow;
+  content::BrowserContextEfl* browser_context =
+      static_cast<content::BrowserContextEfl*>(
+          web_contents_->GetBrowserContext());
+  if (browser_context) {
+    browser_context->GetSpecialStoragePolicyEfl()->SetUnlimitedStoragePolicy(
+        exceeded_indexed_db_quota_origin_->GetURL(), allow);
+  }
+  exceeded_indexed_db_quota_origin_.reset();
+}
index 3fd06db..53a930f 100755 (executable)
@@ -114,6 +114,30 @@ class WebViewCallback {
   void* user_data_;
 };
 
+template <typename CallbackPtr, typename... CallbackParameter>
+class WebViewExceededQuotaCallback {
+ public:
+  WebViewExceededQuotaCallback() { Set(nullptr, nullptr); }
+
+  void Set(CallbackPtr cb, void* data) {
+    callback_ = cb;
+    user_data_ = data;
+  }
+
+  bool IsCallbackSet() const { return callback_; }
+
+  /* LCOV_EXCL_START */
+  void Run(Evas_Object* webview, CallbackParameter... param) {
+    if (IsCallbackSet())
+      callback_(webview, param..., user_data_);
+  }
+  /* LCOV_EXCL_STOP */
+
+ private:
+  CallbackPtr callback_;
+  void* user_data_;
+};
+
 class WebApplicationIconUrlGetCallback {
  public:
   WebApplicationIconUrlGetCallback(Ewk_Web_App_Icon_URL_Get_Callback func,
@@ -485,6 +509,13 @@ class EWebView {
     return gin_native_bridge_dispatcher_host_.get();
   }
 
+  void SetExceededIndexedDatabaseQuotaCallback(
+      Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback,
+      void* user_data);
+  void InvokeExceededIndexedDatabaseQuotaCallback(const GURL& origin,
+                                                  int64_t current_quota);
+  void ExceededIndexedDatabaseQuotaReply(bool allow);
+
   /// ---- Event handling
   bool HandleShow();
   bool HandleHide();
@@ -636,6 +667,13 @@ class EWebView {
   std::unique_ptr<content::GinNativeBridgeDispatcherHost>
       gin_native_bridge_dispatcher_host_;
 
+  WebViewExceededQuotaCallback<
+      Ewk_View_Exceeded_Indexed_Database_Quota_Callback,
+      Ewk_Security_Origin*,
+      long long>
+      exceeded_indexed_db_quota_callback_;
+  std::unique_ptr<Ewk_Security_Origin> exceeded_indexed_db_quota_origin_;
+
 #if BUILDFLAG(IS_TIZEN)
   blink::mojom::FileChooserParams::Mode filechooser_mode_;
 #endif
index 0e7b349..3ebd7f3 100644 (file)
@@ -813,20 +813,22 @@ void ewk_view_application_cache_permission_reply(Evas_Object* ewkView, Eina_Bool
   LOG_EWK_API_MOCKUP("Not Supported by chromium");
 }
 
-void ewk_view_exceeded_indexed_database_quota_callback_set(Evas_Object* ewkView, Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback, void* userData)
+void ewk_view_exceeded_indexed_database_quota_callback_set(Evas_Object* view, Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback, void* user_data)
 {
   // Chromium does not support quota for Indexed DB only.
   // IndexedDB uses temporary storage that is shared
   // between other features.
-  LOG_EWK_API_MOCKUP("Not Supported by chromium");
+  EWK_VIEW_IMPL_GET_OR_RETURN(view, impl);
+  impl->SetExceededIndexedDatabaseQuotaCallback(callback, user_data);
 }
 
-void ewk_view_exceeded_indexed_database_quota_reply(Evas_Object* ewkView, Eina_Bool allow)
+void ewk_view_exceeded_indexed_database_quota_reply(Evas_Object* view, Eina_Bool allow)
 {
   // Chromium does not support quota for Indexed DB only.
   // IndexedDB uses temporary storage that is shared
   // between other features.
-  LOG_EWK_API_MOCKUP("Not Supported by chromium");
+  EWK_VIEW_IMPL_GET_OR_RETURN(view, impl);
+  impl->ExceededIndexedDatabaseQuotaReply(allow);
 }
 
 Eina_Bool ewk_view_text_find(Evas_Object *view, const char *text, Ewk_Find_Options options, unsigned int max_match_count)
index f34e706..393a104 100644 (file)
@@ -195,6 +195,8 @@ Window::Window(Browser& browser, int width, int height, bool incognito)
       web_view_, &Window::OnQuotaPermissionRequest, this);
   ewk_view_did_change_theme_color_callback_set(
       web_view_, &Window::OnThemeColorChanged, this);
+  ewk_view_exceeded_indexed_database_quota_callback_set(
+      web_view_, Window::OnQuotaExceededIndexedDB, this);
 
   ewk_settings_form_profile_data_enabled_set(GetEwkSettings(), true);
   ewk_settings_form_candidate_data_enabled_set(GetEwkSettings(), true);
@@ -844,6 +846,15 @@ void Window::OnScreenshotCaptured(Evas_Object* image, void* user_data) {
     log_info("Screenshot image could not be saved");
 }
 
+void Window::OnQuotaExceededIndexedDB(Evas_Object*,
+                                      Ewk_Security_Origin* origin,
+                                      long long currentQuota,
+                                      void* data) {
+  log_trace("%s", __PRETTY_FUNCTION__);
+  Window* thiz = static_cast<Window*>(data);
+  ewk_view_exceeded_indexed_database_quota_reply(thiz->web_view_, true);
+}
+
 void Window::Exit() const {
   browser_.Exit();
 }
index 9289c70..61c9987 100644 (file)
@@ -9,6 +9,7 @@
 #include <Ecore_Evas.h>
 #include <ewk_settings_internal.h>
 #include <ewk_quota_permission_request_internal.h>
+#include <ewk_view_internal.h>
 
 #include "build/build_config.h"
 
@@ -67,6 +68,10 @@ class Window {
   static void OnOrientationChanged(void*, Evas_Object*, void*);
   static void OnNewWindowPolicyDecide(void*, Evas_Object*, void*);
   static void OnBackForwardListChanged(void*, Evas_Object*, void*);
+  static void OnQuotaExceededIndexedDB(Evas_Object*,
+                                       Ewk_Security_Origin* origin,
+                                       long long currentQuota,
+                                       void* data);
   static void OnQuotaPermissionRequest(Evas_Object*, const Ewk_Quota_Permission_Request*, void*);
   static void OnScreenshotCaptured(Evas_Object*, void*);
   static void OnUserMediaPermissionRequest(void* data, Evas_Object*, void* event_info);