summaryrefslogtreecommitdiffstats
path: root/WebCore
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-04-11 20:08:03 +0100
committerBen Murdoch <benm@google.com>2011-04-11 20:35:41 +0100
commit622d72beb96a024bb18591feb39d4b21d0a34bd7 (patch)
tree9a8e5353390326dc19931af1079ebe466f97987f /WebCore
parent68c221808cf7a4776ba8feae02611d3c78e9f857 (diff)
downloadexternal_webkit-622d72beb96a024bb18591feb39d4b21d0a34bd7.zip
external_webkit-622d72beb96a024bb18591feb39d4b21d0a34bd7.tar.gz
external_webkit-622d72beb96a024bb18591feb39d4b21d0a34bd7.tar.bz2
Clear DOM storage when clearing other cached data. Do not merge.
Empty out DOM local and session storage in addition to HTML5 database and app cache when we get a request from java to delete cached data. Cherry pick of I5b6ee075d2a8fb44ee373ad4462a33623c9c2460 Bug: 4267038 Change-Id: Id2dece1963d443c3758710e9c3e871054991ae32
Diffstat (limited to 'WebCore')
-rw-r--r--WebCore/page/DOMWindow.cpp13
-rw-r--r--WebCore/page/DOMWindow.h3
-rw-r--r--WebCore/page/PageGroup.cpp90
-rw-r--r--WebCore/page/PageGroup.h8
-rw-r--r--WebCore/storage/StorageAreaImpl.cpp4
-rw-r--r--WebCore/storage/StorageEventDispatcher.cpp4
-rw-r--r--WebCore/storage/StorageNamespace.h4
-rw-r--r--WebCore/storage/StorageNamespaceImpl.cpp23
-rw-r--r--WebCore/storage/StorageNamespaceImpl.h8
9 files changed, 156 insertions, 1 deletions
diff --git a/WebCore/page/DOMWindow.cpp b/WebCore/page/DOMWindow.cpp
index 2f0f84f..a004059 100644
--- a/WebCore/page/DOMWindow.cpp
+++ b/WebCore/page/DOMWindow.cpp
@@ -1406,4 +1406,17 @@ EventTargetData* DOMWindow::ensureEventTargetData()
return &m_eventTargetData;
}
+#if ENABLE(DOM_STORAGE) && defined(ANDROID)
+void DOMWindow::clearDOMStorage()
+{
+ if (m_sessionStorage)
+ m_sessionStorage->disconnectFrame();
+ m_sessionStorage = 0;
+
+ if (m_localStorage)
+ m_localStorage->disconnectFrame();
+ m_localStorage = 0;
+}
+#endif
+
} // namespace WebCore
diff --git a/WebCore/page/DOMWindow.h b/WebCore/page/DOMWindow.h
index dc1e68c..ee7af7f 100644
--- a/WebCore/page/DOMWindow.h
+++ b/WebCore/page/DOMWindow.h
@@ -205,6 +205,9 @@ namespace WebCore {
// HTML 5 key/value storage
Storage* sessionStorage() const;
Storage* localStorage() const;
+#ifdef ANDROID
+ void clearDOMStorage();
+#endif
#endif
Console* console() const;
diff --git a/WebCore/page/PageGroup.cpp b/WebCore/page/PageGroup.cpp
index f376d52..b4758c5 100644
--- a/WebCore/page/PageGroup.cpp
+++ b/WebCore/page/PageGroup.cpp
@@ -41,6 +41,11 @@
#include "ChromiumBridge.h"
#endif
+#ifdef ANDROID
+#include "DOMWindow.h"
+#include "FileSystem.h"
+#endif
+
namespace WebCore {
static unsigned getUniqueIdentifier()
@@ -109,6 +114,91 @@ void PageGroup::closeLocalStorage()
#endif
}
+#if ENABLE(DOM_STORAGE) && defined(ANDROID)
+void PageGroup::clearDomStorage()
+{
+ if (!pageGroups)
+ return;
+
+
+ PageGroupMap::iterator end = pageGroups->end();
+
+ for (PageGroupMap::iterator it = pageGroups->begin(); it != end; ++it) {
+ String basePath = "";
+
+ // This is being called as a result of the user explicitly
+ // asking to clear all stored data (e.g. through a settings
+ // dialog. We need a page in the page group to fire a
+ // StorageEvent. There isn't really a correct page to use
+ // as the source (as the clear request hasn't come from a
+ // particular page). One thing we should ensure though is that
+ // we don't try to clear a private browsing mode page as that has no concept
+ // of DOM storage..
+
+ HashSet<Page*> pages = it->second->pages();
+ HashSet<Page*>::iterator pagesEnd = pages.end();
+ Page* page = 0;
+ for(HashSet<Page*>::iterator pit = pages.begin(); pit != pagesEnd; ++pit) {
+ Page* p = *pit;
+
+ // Grab the storage location from an arbitrary page. This is set
+ // to the same value on all private browsing and "normal" pages,
+ // so we can get it from anything.
+ if (basePath.isEmpty())
+ basePath = p->settings()->localStorageDatabasePath();
+
+ // DOM storage is disabled in private browsing pages, so nothing to do if
+ // this is such a page.
+ if (p->settings()->privateBrowsingEnabled())
+ continue;
+
+ // Clear session storage.
+ StorageNamespace* sessionStorage = p->sessionStorage(false);
+ if (sessionStorage)
+ sessionStorage->clear(p);
+
+ // Save this page so we can clear local storage.
+ page = p;
+ }
+
+ // If page is still null at this point, then the only pages that are
+ // open are private browsing pages. Hence no pages are currently using local
+ // storage, so we don't need a page pointer to send any events and the
+ // clear function will handle a 0 input.
+ it->second->localStorage()->clear(page);
+ it->second->localStorage()->close();
+
+ // Closing the storage areas will stop the background thread and so
+ // we need to remove the local storage ref here so that next time
+ // we come to a site that uses it the thread will get started again.
+ it->second->removeLocalStorage();
+
+ // At this point, active local and session storage have been cleared and the
+ // StorageAreas for this PageGroup closed. The final sync will have taken
+ // place. All that is left is to purge the database files.
+ if (!basePath.isEmpty()) {
+ Vector<String> files = listDirectory(basePath, "*.localstorage");
+ Vector<String>::iterator filesEnd = files.end();
+ for (Vector<String>::iterator it = files.begin(); it != filesEnd; ++it)
+ deleteFile(*it);
+ }
+ }
+}
+
+void PageGroup::removeLocalStorage()
+{
+ HashSet<Page*> pages = this->pages();
+ HashSet<Page*>::iterator pagesEnd = pages.end();
+ for(HashSet<Page*>::iterator pit = pages.begin(); pit != pagesEnd; ++pit) {
+ Page* p = *pit;
+ for (Frame* frame = p->mainFrame(); frame; frame = frame->tree()->traverseNext())
+ frame->document()->domWindow()->clearDOMStorage();
+ }
+
+ m_localStorage = 0;
+}
+#endif
+
void PageGroup::addPage(Page* page)
{
ASSERT(page);
diff --git a/WebCore/page/PageGroup.h b/WebCore/page/PageGroup.h
index 446f0c7..cd2d9e3 100644
--- a/WebCore/page/PageGroup.h
+++ b/WebCore/page/PageGroup.h
@@ -48,6 +48,10 @@ namespace WebCore {
static PageGroup* pageGroup(const String& groupName);
static void closeLocalStorage();
+#if ENABLE(DOM_STORAGE) && defined(ANDROID)
+ static void clearDomStorage();
+#endif
+
const HashSet<Page*>& pages() const { return m_pages; }
void addPage(Page*);
@@ -90,6 +94,10 @@ namespace WebCore {
private:
void addVisitedLink(LinkHash stringHash);
+#if ENABLE(DOM_STORAGE) && defined(ANDROID)
+ void removeLocalStorage();
+#endif
+
String m_name;
HashSet<Page*> m_pages;
diff --git a/WebCore/storage/StorageAreaImpl.cpp b/WebCore/storage/StorageAreaImpl.cpp
index aa04781..d5d75e7 100644
--- a/WebCore/storage/StorageAreaImpl.cpp
+++ b/WebCore/storage/StorageAreaImpl.cpp
@@ -93,6 +93,10 @@ StorageAreaImpl::StorageAreaImpl(StorageAreaImpl* area)
static bool privateBrowsingEnabled(Frame* frame)
{
+#if PLATFORM(ANDROID)
+ if (!frame)
+ return false;
+#endif
#if PLATFORM(CHROMIUM)
// The frame pointer can be NULL in Chromium since this call is made in a different
// process from where the Frame object exists. Luckily, private browseing is
diff --git a/WebCore/storage/StorageEventDispatcher.cpp b/WebCore/storage/StorageEventDispatcher.cpp
index dc0295b..aa91924 100644
--- a/WebCore/storage/StorageEventDispatcher.cpp
+++ b/WebCore/storage/StorageEventDispatcher.cpp
@@ -40,6 +40,10 @@ namespace WebCore {
void StorageEventDispatcher::dispatch(const String& key, const String& oldValue, const String& newValue, StorageType storageType, SecurityOrigin* securityOrigin, Frame* sourceFrame)
{
+#ifdef ANDROID
+ if (!sourceFrame)
+ return;
+#endif
Page* page = sourceFrame->page();
if (!page)
return;
diff --git a/WebCore/storage/StorageNamespace.h b/WebCore/storage/StorageNamespace.h
index e84e5a6..e911c94 100644
--- a/WebCore/storage/StorageNamespace.h
+++ b/WebCore/storage/StorageNamespace.h
@@ -50,6 +50,10 @@ public:
virtual PassRefPtr<StorageNamespace> copy() = 0;
virtual void close() = 0;
virtual void unlock() = 0;
+
+#ifdef ANDROID
+ virtual void clear(Page*) = 0;
+#endif
};
} // namespace WebCore
diff --git a/WebCore/storage/StorageNamespaceImpl.cpp b/WebCore/storage/StorageNamespaceImpl.cpp
index 19ff6b4..47b2958 100644
--- a/WebCore/storage/StorageNamespaceImpl.cpp
+++ b/WebCore/storage/StorageNamespaceImpl.cpp
@@ -35,6 +35,10 @@
#include "StorageSyncManager.h"
#include <wtf/StdLibExtras.h>
+#ifdef ANDROID
+#include "Page.h"
+#endif
+
namespace WebCore {
typedef HashMap<String, StorageNamespace*> LocalStorageNamespaceMap;
@@ -137,6 +141,25 @@ void StorageNamespaceImpl::close()
m_isShutdown = true;
}
+#ifdef ANDROID
+void StorageNamespaceImpl::clear(Page* page)
+{
+ ASSERT(isMainThread());
+ if (m_isShutdown)
+ return;
+
+ // Clear all the keys for each of the storage areas.
+ StorageAreaMap::iterator end = m_storageAreaMap.end();
+ for (StorageAreaMap::iterator it = m_storageAreaMap.begin(); it != end; ++it) {
+ // if there is no page provided, then the user tried to clear storage
+ // with only pages in private browsing mode open. So we do not need to
+ // provide a Frame* here (as the frame is only used to dispatch storage events
+ // and private browsing pages won't be using them).
+ it->second->clear(page ? page->mainFrame() : 0);
+ }
+}
+#endif
+
void StorageNamespaceImpl::unlock()
{
// Because there's a single event loop per-process, this is a no-op.
diff --git a/WebCore/storage/StorageNamespaceImpl.h b/WebCore/storage/StorageNamespaceImpl.h
index b81b55a..8199eab 100644
--- a/WebCore/storage/StorageNamespaceImpl.h
+++ b/WebCore/storage/StorageNamespaceImpl.h
@@ -37,7 +37,9 @@
#include <wtf/RefPtr.h>
namespace WebCore {
-
+#ifdef ANDROID
+ class Page;
+#endif
class StorageAreaImpl;
class StorageNamespaceImpl : public StorageNamespace {
@@ -51,6 +53,10 @@ namespace WebCore {
virtual void close();
virtual void unlock();
+#ifdef ANDROID
+ virtual void clear(Page*);
+#endif
+
private:
StorageNamespaceImpl(StorageType, const String& path, unsigned quota);