summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp6
-rw-r--r--WebKit/android/WebCoreSupport/ChromeClientAndroid.h2
-rwxr-xr-xWebKit/android/WebCoreSupport/GeolocationPermissions.cpp108
-rw-r--r--[-rwxr-xr-x]WebKit/android/WebCoreSupport/GeolocationPermissions.h11
4 files changed, 93 insertions, 34 deletions
diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
index 9102395..e9e77e9 100644
--- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
+++ b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
@@ -479,6 +479,12 @@ void ChromeClientAndroid::requestGeolocationPermissionForFrame(Frame* frame, Geo
m_geolocationPermissions->queryPermissionState(frame);
}
+void ChromeClientAndroid::cancelGeolocationPermissionRequestForFrame(Frame* frame)
+{
+ if (m_geolocationPermissions)
+ m_geolocationPermissions->cancelPermissionStateQuery(frame);
+}
+
void ChromeClientAndroid::provideGeolocationPermissions(const String &origin, bool allow, bool remember)
{
ASSERT(m_geolocationPermissions);
diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.h b/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
index 15473ca..2c061b2 100644
--- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
+++ b/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
@@ -143,7 +143,7 @@ namespace android {
// Methods used to request and provide Geolocation permissions.
virtual void requestGeolocationPermissionForFrame(Frame*, Geolocation*);
- virtual void cancelGeolocationPermissionRequestForFrame(Frame*) { }
+ virtual void cancelGeolocationPermissionRequestForFrame(Frame*);
// Android-specific
void provideGeolocationPermissions(const String &origin, bool allow, bool remember);
void storeGeolocationPermissions();
diff --git a/WebKit/android/WebCoreSupport/GeolocationPermissions.cpp b/WebKit/android/WebCoreSupport/GeolocationPermissions.cpp
index aeee017..b630f66 100755
--- a/WebKit/android/WebCoreSupport/GeolocationPermissions.cpp
+++ b/WebKit/android/WebCoreSupport/GeolocationPermissions.cpp
@@ -100,21 +100,56 @@ void GeolocationPermissions::queryPermissionState(Frame* frame)
}
// If there's no pending request, prompt the user.
- if (m_originInProgress.isEmpty()) {
- m_originInProgress = originString;
-
+ if (nextOriginInQueue().isEmpty()) {
// Although multiple tabs may request permissions for the same origin
// simultaneously, the routing in WebViewCore/CallbackProxy ensures that
// the result of the request will make it back to this object, so
// there's no need for a globally unique ID for the request.
- m_webViewCore->geolocationPermissionsShowPrompt(m_originInProgress);
- return;
+ m_webViewCore->geolocationPermissionsShowPrompt(originString);
}
- // If the request in progress is not for this origin, queue this request.
- if ((m_originInProgress != originString)
- && (m_queuedOrigins.find(originString) == WTF::notFound))
+ // Add this request to the queue so we can track which frames requested it.
+ if (m_queuedOrigins.find(originString) == WTF::notFound) {
m_queuedOrigins.append(originString);
+ FrameSet frameSet;
+ frameSet.add(frame);
+ m_queuedOriginsToFramesMap.add(originString, frameSet);
+ } else {
+ ASSERT(m_queuedOriginsToFramesMap.contains(originString));
+ m_queuedOriginsToFramesMap.find(originString)->second.add(frame);
+ }
+}
+
+void GeolocationPermissions::cancelPermissionStateQuery(WebCore::Frame* frame)
+{
+ // We cancel any queued request for the given frame. There can be at most
+ // one of these, since each frame maps to a single origin. We only cancel
+ // the request if this frame is the only one reqesting permission for this
+ // origin.
+ //
+ // We can use the origin string to avoid searching the map.
+ String originString = frame->document()->securityOrigin()->toString();
+ size_t index = m_queuedOrigins.find(originString);
+ if (index == WTF::notFound)
+ return;
+
+ ASSERT(m_queuedOriginsToFramesMap.contains(originString));
+ OriginToFramesMap::iterator iter = m_queuedOriginsToFramesMap.find(originString);
+ ASSERT(iter->second.contains(frame));
+ iter->second.remove(frame);
+ if (!iter->second.isEmpty())
+ return;
+
+ m_queuedOrigins.remove(index);
+ m_queuedOriginsToFramesMap.remove(iter);
+
+ // If this is the origin currently being shown, cancel the prompt
+ // and show the next in the queue, if present.
+ if (index == 0) {
+ m_webViewCore->geolocationPermissionsHidePrompt();
+ if (!nextOriginInQueue().isEmpty())
+ m_webViewCore->geolocationPermissionsShowPrompt(nextOriginInQueue());
+ }
}
void GeolocationPermissions::makeAsynchronousCallbackToGeolocation(String origin, bool allow)
@@ -133,38 +168,38 @@ void GeolocationPermissions::providePermissionState(String origin, bool allow, b
// while a permission result is in the process of being marshalled back to
// the WebCore thread from the browser. In this case, we simply ignore the
// call.
- if (origin != m_originInProgress)
+ if (origin != nextOriginInQueue())
return;
- maybeCallbackFrames(m_originInProgress, allow);
+ maybeCallbackFrames(origin, allow);
recordPermissionState(origin, allow, remember);
// If the permissions are set to be remembered, cancel any queued requests
// for this domain in other tabs.
if (remember)
- cancelPendingRequestsInOtherTabs(m_originInProgress);
+ cancelPendingRequestsInOtherTabs(origin);
- // Clear the origin in progress to signal that this request is done.
- m_originInProgress = "";
+ // Clear the origin from the queue.
+ ASSERT(!m_queuedOrigins.isEmpty());
+ m_queuedOrigins.remove(0);
+ ASSERT(m_queuedOriginsToFramesMap.contains(origin));
+ m_queuedOriginsToFramesMap.remove(origin);
// If there are other requests queued, start the next one.
- if (!m_queuedOrigins.isEmpty()) {
- m_originInProgress = m_queuedOrigins.first();
- m_queuedOrigins.remove(0);
- m_webViewCore->geolocationPermissionsShowPrompt(m_originInProgress);
- }
+ if (!nextOriginInQueue().isEmpty())
+ m_webViewCore->geolocationPermissionsShowPrompt(nextOriginInQueue());
}
void GeolocationPermissions::recordPermissionState(String origin, bool allow, bool remember)
{
if (remember) {
- s_permanentPermissions.set(m_originInProgress, allow);
+ s_permanentPermissions.set(origin, allow);
s_permanentPermissionsModified = true;
} else {
// It's possible that another tab recorded a permanent permission for
// this origin while our request was in progress, but we record it
// anyway.
- m_temporaryPermissions.set(m_originInProgress, allow);
+ m_temporaryPermissions.set(origin, allow);
}
}
@@ -179,19 +214,22 @@ void GeolocationPermissions::cancelPendingRequestsInOtherTabs(String origin)
void GeolocationPermissions::cancelPendingRequests(String origin)
{
size_t index = m_queuedOrigins.find(origin);
- if (index != WTF::notFound) {
- // Get the permission from the permanent list.
- PermissionsMap::const_iterator iter = s_permanentPermissions.find(origin);
-#ifndef NDEBUG
- PermissionsMap::const_iterator end = s_permanentPermissions.end();
- ASSERT(iter != end);
-#endif
- bool allow = iter->second;
- maybeCallbackFrames(origin, allow);
+ // Don't cancel the request if it's currently being shown, in which case
+ // it's at index 0.
+ if (index == WTF::notFound || !index)
+ return;
- m_queuedOrigins.remove(index);
- }
+ // Get the permission from the permanent list.
+ ASSERT(s_permanentPermissions.contains(origin));
+ PermissionsMap::const_iterator iter = s_permanentPermissions.find(origin);
+ bool allow = iter->second;
+
+ maybeCallbackFrames(origin, allow);
+
+ m_queuedOrigins.remove(index);
+ ASSERT(m_queuedOriginsToFramesMap.contains(origin));
+ m_queuedOriginsToFramesMap.remove(origin);
}
void GeolocationPermissions::timerFired(Timer<GeolocationPermissions>* timer)
@@ -203,8 +241,8 @@ void GeolocationPermissions::timerFired(Timer<GeolocationPermissions>* timer)
void GeolocationPermissions::resetTemporaryPermissionStates()
{
ASSERT(s_permanentPermissionsLoaded);
- m_originInProgress = "";
m_queuedOrigins.clear();
+ m_queuedOriginsToFramesMap.clear();
m_temporaryPermissions.clear();
// If any permission results are being marshalled back to this thread, this
// will render them inefective.
@@ -213,6 +251,12 @@ void GeolocationPermissions::resetTemporaryPermissionStates()
m_webViewCore->geolocationPermissionsHidePrompt();
}
+const WebCore::String& GeolocationPermissions::nextOriginInQueue()
+{
+ static const String emptyString = "";
+ return m_queuedOrigins.isEmpty() ? emptyString : m_queuedOrigins[0];
+}
+
void GeolocationPermissions::maybeCallbackFrames(String origin, bool allow)
{
// We can't track which frame issued the request, as frames can be deleted
diff --git a/WebKit/android/WebCoreSupport/GeolocationPermissions.h b/WebKit/android/WebCoreSupport/GeolocationPermissions.h
index 33434b9..e59c11b 100755..100644
--- a/WebKit/android/WebCoreSupport/GeolocationPermissions.h
+++ b/WebKit/android/WebCoreSupport/GeolocationPermissions.h
@@ -74,6 +74,7 @@ namespace android {
// the Geolocation objects in all frames in this WebView that are from
// the same origin as the requesting frame.
void queryPermissionState(WebCore::Frame* frame);
+ void cancelPermissionStateQuery(WebCore::Frame*);
// Provides this object with a permission state set by the user. The
// permission is specified by 'allow' and applied to 'origin'. If
@@ -135,11 +136,19 @@ namespace android {
static void maybeLoadPermanentPermissions();
+ const WebCore::String& nextOriginInQueue();
+
WebViewCore* m_webViewCore;
WebCore::Frame* m_mainFrame;
- WebCore::String m_originInProgress;
+ // A vector of the origins queued to make a permission request.
+ // The first in the vector is the origin currently making the request.
typedef Vector<WebCore::String> OriginVector;
OriginVector m_queuedOrigins;
+ // A map from a queued origin to the set of frames that have requested
+ // permission for that origin.
+ typedef HashSet<WebCore::Frame*> FrameSet;
+ typedef HashMap<WebCore::String, FrameSet> OriginToFramesMap;
+ OriginToFramesMap m_queuedOriginsToFramesMap;
typedef WTF::HashMap<WebCore::String, bool> PermissionsMap;
PermissionsMap m_temporaryPermissions;