Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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
  • Loading branch information...
commit 622d72beb96a024bb18591feb39d4b21d0a34bd7 1 parent 68c2218
Ben Murdoch authored
View
13 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
View
3  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;
View
90 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);
View
8 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;
View
4 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
View
4 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;
View
4 WebCore/storage/StorageNamespace.h
@@ -50,6 +50,10 @@ class StorageNamespace : public RefCounted<StorageNamespace> {
virtual PassRefPtr<StorageNamespace> copy() = 0;
virtual void close() = 0;
virtual void unlock() = 0;
+
+#ifdef ANDROID
+ virtual void clear(Page*) = 0;
+#endif
};
} // namespace WebCore
View
23 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.
View
8 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);
View
6 WebKit/android/jni/WebStorage.cpp
@@ -29,6 +29,7 @@
#include "JavaSharedClient.h"
#include "KURL.h"
+#include "PageGroup.h"
#include "WebCoreJni.h"
#include <JNIHelp.h>
@@ -130,6 +131,11 @@ static void DeleteAllData(JNIEnv* env, jobject obj)
{
WebCore::DatabaseTracker::tracker().deleteAllDatabases();
WebCore::cacheStorage().empty();
+ // FIXME: this is a workaround for eliminating any DOM Storage data (both
+ // session and local storage) as there is no functionality inside WebKit at the
+ // moment to do it. That functionality is a WIP in https://bugs.webkit.org/show_bug.cgi?id=51878
+ // and when that patch lands and we merge it, we should move towards that approach instead.
+ WebCore::PageGroup::clearDomStorage();
}
static void SetAppCacheMaximumSize(JNIEnv* env, jobject obj, unsigned long long size)
Please sign in to comment.
Something went wrong with that request. Please try again.