summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WebCore/Android.mk1
-rw-r--r--WebCore/bindings/js/JSNavigatorCustom.cpp3
-rw-r--r--WebCore/bindings/v8/custom/V8NavigatorCustom.cpp4
-rw-r--r--WebCore/page/Navigator.cpp23
-rw-r--r--WebCore/page/Navigator.h10
-rw-r--r--WebCore/page/Page.cpp18
-rw-r--r--WebCore/platform/android/PackageNotifier.cpp97
-rw-r--r--WebCore/platform/android/PackageNotifier.h69
-rw-r--r--WebKit/android/jni/JavaBridge.cpp53
9 files changed, 270 insertions, 8 deletions
diff --git a/WebCore/Android.mk b/WebCore/Android.mk
index de67b20..f153c9c 100644
--- a/WebCore/Android.mk
+++ b/WebCore/Android.mk
@@ -410,6 +410,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/android/PlatformTouchPointAndroid.cpp \
platform/android/PopupMenuAndroid.cpp \
platform/android/RenderThemeAndroid.cpp \
+ platform/android/PackageNotifier.cpp \
platform/android/ScreenAndroid.cpp \
platform/android/ScrollViewAndroid.cpp \
platform/android/SearchPopupMenuAndroid.cpp \
diff --git a/WebCore/bindings/js/JSNavigatorCustom.cpp b/WebCore/bindings/js/JSNavigatorCustom.cpp
index b30db5a..af0c9ae 100644
--- a/WebCore/bindings/js/JSNavigatorCustom.cpp
+++ b/WebCore/bindings/js/JSNavigatorCustom.cpp
@@ -69,7 +69,8 @@ JSC::JSValue WebCore::JSNavigator::isApplicationInstalled(JSC::ExecState* exec,
RefPtr<ApplicationInstalledCallback> callback(JSCustomApplicationInstalledCallback::create(
object, static_cast<JSDOMGlobalObject*>(exec->dynamicGlobalObject())));
- m_impl->isApplicationInstalled(appName, callback.release());
+ if (!m_impl->isApplicationInstalled(appName, callback.release()))
+ setDOMException(exec, INVALID_STATE_ERR);
return jsUndefined();
}
diff --git a/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp b/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp
index c3c406e..b6ae42d 100644
--- a/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp
@@ -84,7 +84,9 @@ v8::Handle<v8::Value> V8Navigator::isApplicationInstalledCallback(const v8::Argu
ASSERT(callback);
Navigator* navigator = V8Navigator::toNative(args.Holder());
- navigator->isApplicationInstalled(toWebCoreString(args[0]), callback.release());
+ if (!navigator->isApplicationInstalled(toWebCoreString(args[0]), callback.release()))
+ return throwError(INVALID_STATE_ERR);
+
return v8::Undefined();
}
diff --git a/WebCore/page/Navigator.cpp b/WebCore/page/Navigator.cpp
index 3c0424f..bb07911 100644
--- a/WebCore/page/Navigator.cpp
+++ b/WebCore/page/Navigator.cpp
@@ -45,6 +45,7 @@
#if PLATFORM(ANDROID)
#include "ApplicationInstalledCallback.h"
#include "Connection.h"
+#include "PackageNotifier.h"
#endif
namespace WebCore {
@@ -171,10 +172,26 @@ Connection* Navigator::connection() const
#endif
#if PLATFORM(ANDROID) && ENABLE(APPLICATION_INSTALLED)
-void Navigator::isApplicationInstalled(const String& name, PassRefPtr<ApplicationInstalledCallback> callback)
+
+bool Navigator::isApplicationInstalled(const String& name, PassRefPtr<ApplicationInstalledCallback> callback)
+{
+ if (m_applicationInstalledCallback)
+ return false;
+
+ m_applicationInstalledCallback = callback;
+ m_applicationNameQuery = name;
+
+ packageNotifier().requestPackageResult();
+
+ return true;
+}
+
+void Navigator::onPackageResult()
{
- //TODO(implement);
- callback->handleEvent(false);
+ if (m_applicationInstalledCallback) {
+ m_applicationInstalledCallback->handleEvent(packageNotifier().isPackageInstalled(m_applicationNameQuery));
+ m_applicationInstalledCallback = 0;
+ }
}
#endif
diff --git a/WebCore/page/Navigator.h b/WebCore/page/Navigator.h
index 83ed83f..c6acfd5 100644
--- a/WebCore/page/Navigator.h
+++ b/WebCore/page/Navigator.h
@@ -21,6 +21,7 @@
#define Navigator_h
#include "NavigatorBase.h"
+#include "PlatformString.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
@@ -32,7 +33,6 @@ namespace WebCore {
class MimeTypeArray;
class PluginData;
class PluginArray;
- class String;
#if PLATFORM(ANDROID)
class ApplicationInstalledCallback;
class Connection;
@@ -67,7 +67,8 @@ namespace WebCore {
#endif
#if PLATFORM(ANDROID) && ENABLE(APPLICATION_INSTALLED)
- void isApplicationInstalled(const String& name, PassRefPtr<ApplicationInstalledCallback> callback);
+ bool isApplicationInstalled(const String& name, PassRefPtr<ApplicationInstalledCallback> callback);
+ void onPackageResult();
#endif
#if ENABLE(DOM_STORAGE)
@@ -87,6 +88,11 @@ namespace WebCore {
#if PLATFORM(ANDROID)
mutable RefPtr<Connection> m_connection;
#endif
+
+#if PLATFORM(ANDROID) && ENABLE(APPLICATION_INSTALLED)
+ RefPtr<ApplicationInstalledCallback> m_applicationInstalledCallback;
+ String m_applicationNameQuery;
+#endif
};
}
diff --git a/WebCore/page/Page.cpp b/WebCore/page/Page.cpp
index 1704bfb..b685e59 100644
--- a/WebCore/page/Page.cpp
+++ b/WebCore/page/Page.cpp
@@ -81,6 +81,10 @@
#include "GeolocationController.h"
#endif
+#if PLATFORM(ANDROID) && ENABLE(APPLICATION_INSTALLED)
+#include "PackageNotifier.h"
+#endif
+
namespace WebCore {
static HashSet<Page*>* allPages;
@@ -105,6 +109,17 @@ static void networkStateChanged()
frames[i]->document()->dispatchWindowEvent(Event::create(eventName, false, false));
}
+#if PLATFORM(ANDROID) && ENABLE(APPLICATION_INSTALLED)
+static void onPackageResultAvailable()
+{
+ HashSet<Page*>::iterator end = allPages->end();
+ for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it) {
+ for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext())
+ frame->domWindow()->navigator()->onPackageResult();
+ }
+}
+#endif
+
Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, EditorClient* editorClient, DragClient* dragClient, InspectorClient* inspectorClient, PluginHalterClient* pluginHalterClient, GeolocationControllerClient* geolocationControllerClient)
: m_chrome(new Chrome(this, chromeClient))
, m_dragCaretController(new SelectionController(0, true))
@@ -163,6 +178,9 @@ Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, Edi
allPages = new HashSet<Page*>;
networkStateNotifier().setNetworkStateChangedFunction(networkStateChanged);
+#if PLATFORM(ANDROID) && ENABLE(APPLICATION_INSTALLED)
+ packageNotifier().setOnResultAvailable(onPackageResultAvailable);
+#endif
}
ASSERT(!allPages->contains(this));
diff --git a/WebCore/platform/android/PackageNotifier.cpp b/WebCore/platform/android/PackageNotifier.cpp
new file mode 100644
index 0000000..e057cdf
--- /dev/null
+++ b/WebCore/platform/android/PackageNotifier.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PackageNotifier.h"
+
+#if ENABLE(APPLICATION_INSTALLED)
+
+#include <wtf/Assertions.h>
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+PackageNotifier::PackageNotifier()
+ : m_onResultAvailable(0), m_isInitialized(false), m_timer(this, &PackageNotifier::timerFired) { }
+
+void PackageNotifier::setOnResultAvailable(Callback callback)
+{
+ m_onResultAvailable = callback;
+}
+
+void PackageNotifier::addPackageNames(const HashSet<String>& packageNames)
+{
+ if (!m_isInitialized)
+ m_isInitialized = true;
+
+ typedef HashSet<String>::const_iterator NamesIterator;
+ for (NamesIterator iter = packageNames.begin(); iter != packageNames.end(); ++iter)
+ m_packageNames.add(*iter);
+
+ if (m_onResultAvailable)
+ m_onResultAvailable();
+}
+
+void PackageNotifier::addPackageName(const String& packageName)
+{
+ ASSERT(m_isInitialized);
+ m_packageNames.add(packageName);
+}
+
+void PackageNotifier::removePackageName(const String& packageName)
+{
+ ASSERT(m_isInitialized);
+ m_packageNames.remove(packageName);
+}
+
+void PackageNotifier::requestPackageResult()
+{
+ if (!m_isInitialized || m_timer.isActive())
+ return;
+
+ m_timer.startOneShot(0);
+}
+
+void PackageNotifier::timerFired(Timer<PackageNotifier>*)
+{
+ m_timer.stop();
+ if (m_onResultAvailable)
+ m_onResultAvailable();
+}
+
+bool PackageNotifier::isPackageInstalled(const String& packageName)
+{
+ return m_packageNames.contains(packageName);
+}
+
+PackageNotifier& packageNotifier()
+{
+ AtomicallyInitializedStatic(PackageNotifier*, packageNotifier = new PackageNotifier);
+ return *packageNotifier;
+}
+
+}
+
+#endif // ENABLE(APPLICATION_INSTALLED)
diff --git a/WebCore/platform/android/PackageNotifier.h b/WebCore/platform/android/PackageNotifier.h
new file mode 100644
index 0000000..ad44bc7
--- /dev/null
+++ b/WebCore/platform/android/PackageNotifier.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PackageNotifier_h
+#define PackageNotifier_h
+
+#if ENABLE(APPLICATION_INSTALLED)
+
+#include "PlatformString.h"
+#include "StringHash.h"
+#include "Timer.h"
+#include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class PackageNotifier : public Noncopyable {
+public:
+ PackageNotifier();
+
+ typedef void (*Callback)();
+ void setOnResultAvailable(Callback);
+
+ void addPackageNames(const HashSet<String>& packageNames);
+ void addPackageName(const String& packageName);
+ void removePackageName(const String& packageName);
+
+ void requestPackageResult();
+ bool isPackageInstalled(const String& packageName);
+
+private:
+ void timerFired(Timer<PackageNotifier>*);
+
+ Callback m_onResultAvailable;
+
+ HashSet<String> m_packageNames;
+ bool m_isInitialized;
+ Timer<PackageNotifier> m_timer;
+};
+
+PackageNotifier& packageNotifier();
+
+}
+
+#endif
+
+#endif // PackageNotifier_h \ No newline at end of file
diff --git a/WebKit/android/jni/JavaBridge.cpp b/WebKit/android/jni/JavaBridge.cpp
index feca297..0e65e1c 100644
--- a/WebKit/android/jni/JavaBridge.cpp
+++ b/WebKit/android/jni/JavaBridge.cpp
@@ -35,6 +35,7 @@
#include "KeyGeneratorClient.h"
#include "KURL.h"
#include "NetworkStateNotifier.h"
+#include "PackageNotifier.h"
#include "Page.h"
#include "PluginClient.h"
#include "PluginDatabase.h"
@@ -102,6 +103,10 @@ public:
static void SetDeferringTimers(JNIEnv* env, jobject obj, jboolean defer);
static void ServiceFuncPtrQueue(JNIEnv*);
static void UpdatePluginDirectories(JNIEnv* env, jobject obj, jobjectArray array, jboolean reload);
+ static void AddPackageNames(JNIEnv* env, jobject obj, jobject packageNames);
+ static void AddPackageName(JNIEnv* env, jobject obj, jstring packageName);
+ static void RemovePackageName(JNIEnv* env, jobject obj, jstring packageName);
+
private:
jweak mJavaObject;
@@ -392,6 +397,46 @@ void JavaBridge::UpdatePluginDirectories(JNIEnv* env, jobject obj,
WebCore::Page::refreshPlugins(reload);
}
+void JavaBridge::AddPackageNames(JNIEnv* env, jobject obj, jobject packageNames)
+{
+ if (!packageNames)
+ return;
+
+ // dalvikvm will raise exception if any of these fail
+ jclass setClass = env->FindClass("java/util/Set");
+ jmethodID iterator = env->GetMethodID(setClass, "iterator",
+ "()Ljava/util/Iterator;");
+ jobject iter = env->CallObjectMethod(packageNames, iterator);
+
+ jclass iteratorClass = env->FindClass("java/util/Iterator");
+ jmethodID hasNext = env->GetMethodID(iteratorClass, "hasNext", "()Z");
+ jmethodID next = env->GetMethodID(iteratorClass, "next", "()Ljava/lang/Object;");
+
+ HashSet<WebCore::String> namesSet;
+ while (env->CallBooleanMethod(iter, hasNext)) {
+ jstring name = static_cast<jstring>(env->CallObjectMethod(iter, next));
+ namesSet.add(to_string(env, name));
+ env->DeleteLocalRef(name);
+ }
+
+ packageNotifier().addPackageNames(namesSet);
+
+ env->DeleteLocalRef(iteratorClass);
+ env->DeleteLocalRef(iter);
+ env->DeleteLocalRef(setClass);
+}
+
+void JavaBridge::AddPackageName(JNIEnv* env, jobject obj, jstring packageName)
+{
+ packageNotifier().addPackageName(to_string(env, packageName));
+}
+
+void JavaBridge::RemovePackageName(JNIEnv* env, jobject obj, jstring packageName)
+{
+ packageNotifier().removePackageName(to_string(env, packageName));
+}
+
+
// ----------------------------------------------------------------------------
/*
@@ -414,7 +459,13 @@ static JNINativeMethod gWebCoreJavaBridgeMethods[] = {
{ "nativeServiceFuncPtrQueue", "()V",
(void*) JavaBridge::ServiceFuncPtrQueue },
{ "nativeUpdatePluginDirectories", "([Ljava/lang/String;Z)V",
- (void*) JavaBridge::UpdatePluginDirectories }
+ (void*) JavaBridge::UpdatePluginDirectories },
+ { "addPackageNames", "(Ljava/util/Set;)V",
+ (void*) JavaBridge::AddPackageNames },
+ { "addPackageName", "(Ljava/lang/String;)V",
+ (void*) JavaBridge::AddPackageName },
+ { "removePackageName", "(Ljava/lang/String;)V",
+ (void*) JavaBridge::RemovePackageName }
};
int register_javabridge(JNIEnv* env)