I would like to develop a plugin for the default android browser which would specify the category of sites in the google search result. The android browser dont explicitly s
I recently tried to make an android plugin and found many questions on SO but not many detailed answers, so I'd thought I'd share my research here even though the question is quite old now. I'm not sure if a plugin is really what you want to do here since you could probably use google's JSON/ATOM Custom Search API and parse that, but nonetheless I give details on how to get plugins working on Android. I hope it is useful for others.
If you look here: PluginManager.java you will see the following lines:
// Only plugin matches one of the signatures in the list can be loaded
// inside the WebView process
private static final String SIGNATURE_1 = "308204c5..."
The signature used here is the one for the Adobe Flash plugin (support for which has now been dropped by Adobe.)
and further down here you will see:
if (SystemProperties.getBoolean("ro.secure", false)) {
boolean signatureMatch = false;
for (Signature signature : signatures) {
for (int i = 0; i < SIGNATURES.length; i++) {
if (SIGNATURES[i].equals(signature)) {
signatureMatch = true;
break;
}
}
}
if (!signatureMatch) {
return false;
}
}
This means that if ro.secure=0
then it won't check the signatures - it would only allow the flash plugin otherwise.
ro.secure
is a build property that you can set if you have root privaleges for your device or you have a dev build (type adb shell getprop ro.secure
to find out what you have). You can research how to change this if necessary. I was using a Qualcomm Snapdragon MDP8960 which is development board which had ro.secure=0 already. To get your plugin signature included in android you'll have to talk to someone in charge - not sure how feasible this is at present.
Now to write a plugin - you can find an example called SampleBrowserPlugin in the android sourcetree (make sure you have a 64 bit linux machine if you want to build it - type make SampleBrowserPlugin
from the source tree root. You might need to set up the build configuration first using lunch
and you can find instructions on the android source tree site)
I actually grabbed the source I needed from android source on github and made an NDK build of the source as I am more familiar with how to do this than modifying the android build scripts. It will also be a lot faster than downloading the whole android tree - you can see what to download by looking at what is included in Android.mk (see below).
Basically, I pulled the shared object libraries that I needed from the device to make sure my plugin would be compatible. They were in /system/lib
on my device: (e.g. type adb pull /system/libnativehelper.so
etc from the directory where you want them stored)
get the following:
libnativehelper.so
libandroid.so
libutils.so
libcutils.so
libEGL.so
libGLESv2.so
libskia.so
Put them where SO_LIB_PATH
points to in Android.mk
(see below and change Path as necessary).
Then after installing the NDK sdk you should be able to use the following build script - don't need a 64 bit machine - (you can install winbash, use cygwin, or a linux virtual machine e.g. Oracle VM VirtualBox:
(Place these files in C:/Path/BrowserPlugin/jni/
and make sure the ndk-build
command is on your path)
(if you're on linux remove the .cmd
from ndk-build.cmd
)
build.sh:
#!/bin/bash
echo -e "Mode\t\t: Debug"
OPTIM=debug
### ---------------- Generic Build Command ----------------
# run NDK build
ndk-build.cmd \
-d \
-B \
NDK_DEBUG=1 \
NDK_PROJECT_PATH=C:/Path/BrowserPlugin/jni \
NDK_APPLICATION_MK=C:/Path/BrowserPlugin/jni/Application.mk \
NDK_MODULE_PATH=C:/Path/BrowserPlugin/jni \
NDK_APP_OUT=C:/Path/BrowserPlugin/jni/Out/ \
APP_BUILD_SCRIPT=C:/Path/BrowserPlugin/jni/Android.mk \
APP_OPTIM=$OPTIM
cp C:/Path/BrowserPlugin/jni/Out/local/armeabi/libsampleplugin.so C:/Path/BrowserPlugin/libs/armeabi/.
echo "copied libsampleplugin.so into PROJECT_ROOT/libs dir"
Android.mk:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
main.cpp \
PluginObject.cpp \
RenderingThread.cpp \
animation/AnimationPlugin.cpp \
animation/AnimationThread.cpp \
audio/AudioPlugin.cpp \
background/BackgroundPlugin.cpp \
form/FormPlugin.cpp \
navigation/NavigationPlugin.cpp \
paint/PaintPlugin.cpp \
video/VideoPlugin.cpp \
jni-bridge.cpp \
WEBCORE_PATH := C:/Path/AndroidBrowserPlugin/webkit/Source/WebCore
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \
$(LOCAL_PATH) \
$(LOCAL_PATH)/animation \
$(LOCAL_PATH)/audio \
$(LOCAL_PATH)/background \
$(LOCAL_PATH)/form \
$(LOCAL_PATH)/navigation \
$(LOCAL_PATH)/paint \
$(LOCAL_PATH)/video \
$(WEBCORE_PATH)/bridge \
$(WEBCORE_PATH)/plugins \
C:/Path/AndroidBrowserPlugin/webkit/Source/WebKit/android/JavaVM \
C:/Path/AndroidBrowserPlugin/webkit/Source/WebKit/android/plugins \
C:/Path/AndroidBrowserPlugin/platform_external_skia/include/core \
C:/Path/AndroidBrowserPlugin/frameworks_native/include \
C:/Path/AndroidBrowserPlugin/frameworks_native/libs \
C:/Path/AndroidBrowserPlugin/frameworks_native/opengl/libs \
C:/Path/AndroidBrowserPlugin/platform_system_core/include \
C:/Path/AndroidBrowserPlugin/frameworks_native/opengl/include \
C:/Users/user/android-ndk-r8c/platforms/android-14/arch-arm/usr/include \
C:/Path/AndroidBrowserPlugin/BrowserPlugin/jni/libs/armeabi \
C:/Path/AndroidBrowserPlugin/platform_bionic \
C:/Path/AndroidBrowserPlugin/platform_bionic/libc/private \
C:/Path/AndroidBrowserPlugin/platform_hardware_libhardware/include
SO_LIB_PATH := C:/Path/AndroidBrowserPlugin/libs_qualcomm_MDP8960
LOCAL_LDLIBS := \
-L$(SO_LIB_PATH)/ -lnativehelper -landroid -lutils -lcutils -lEGL -lGLESv2 -lskia
LOCAL_CFLAGS += -fvisibility=hidden
LOCAL_CFLAGS += -DHAVE_PTHREADS -DANDROID
LOCAL_MODULE:= libsampleplugin
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
Application.mk:
# =============================================================================
#
# Main build file defining the project modules and their global variables.
#
# =============================================================================
# Don't remove this - mandatory
APP_PROJECT_PATH := $(call my-dir)
# The only STL implementation currently working with exceptions
APP_STL := gnustl_static
# Don't optimize for better debugging
APP_OPTIM := debug
You may also need some header files (e.g. JNIHelp.h
) which you can place e.g. in the root where you are doing the ndk build BrowserPlugin/jni/
.
Hopefully bash build.sh
should build your libsampleplugin.so
which the build script copies into the app directory. You can then e.g. import the project into eclipse and build the app. Install it on the device, then e.g. use WAMP server to host the following file:
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Test Plugin</title>
</head>
<body>
<object type="application/x-testbrowserplugin" height=50 width=250 id="testPlugin">
<param name="DrawingModel" value="Bitmap" />
<param name="PluginType" value="Form" />
</object>
</body>
</html>
run ipconfig
from your host machine to get the IP address e.g. 192.168.x.x
Then point your device browser to e.g. http://192.168.x.x/
and voila you should see a form plugin.
I couldn't get the animation plugins to work properly, and the form plugin didn't work fully, but at least the plugin was recognised and loaded ok.
Now, you can write a webkit NPAPI plugin to do what you like either using the sample plugin browser as a guide, or other internet resources.
This is actually quite interesting topic which was discussed recently during blackhat 2014 (FakeID) but in a bit different context. They've found security bug in signature validation.
In your case there are two helpful links : 1) http://androidxref.com/4.3_r2.1/xref/frameworks/base/tests/BrowserTestPlugin/ This is the newest sample of writing webkit plugins. Try to build it - it will require to have webkit external statically linked otherwise you will get ‘ fatal error: android_npapi.h: No such file or directory’ 2) http://androidxref.com/2.2.3/xref/development/samples/BrowserPlugin/ This is older sample but it has wider description of "how to build" browser plugin
Use combination of both link to start your plugin development
However this doesn't solve signature check problem. Even if the plugin is recognised it won't be allowed to run. I'm not sure what is the process with google to do browser plugin development