summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/webkit/PluginActivity.java40
-rw-r--r--core/java/android/webkit/PluginManager.java129
-rw-r--r--core/java/android/webkit/PluginUtil.java61
-rw-r--r--core/java/android/webkit/WebViewCore.java55
-rw-r--r--core/java/android/webkit/plugin/NativePlugin.java37
-rw-r--r--core/java/android/webkit/plugin/SurfaceDrawingModel.java37
-rw-r--r--core/java/android/webkit/plugin/WebkitPlugin.java36
7 files changed, 287 insertions, 108 deletions
diff --git a/core/java/android/webkit/PluginActivity.java b/core/java/android/webkit/PluginActivity.java
index cda7b59dfc06..22d6ccb7eba2 100644
--- a/core/java/android/webkit/PluginActivity.java
+++ b/core/java/android/webkit/PluginActivity.java
@@ -19,6 +19,8 @@ import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
+import android.webkit.plugin.SurfaceDrawingModel;
+import android.webkit.plugin.WebkitPlugin;
/**
* This activity is invoked when a plugin elects to go into full screen mode.
@@ -28,8 +30,6 @@ public class PluginActivity extends Activity {
/* package */ static final String INTENT_EXTRA_PACKAGE_NAME =
"android.webkit.plugin.PACKAGE_NAME";
- /* package */ static final String INTENT_EXTRA_CLASS_NAME =
- "android.webkit.plugin.CLASS_NAME";
/* package */ static final String INTENT_EXTRA_NPP_INSTANCE =
"android.webkit.plugin.NPP_INSTANCE";
@@ -42,25 +42,31 @@ public class PluginActivity extends Activity {
if (intent == null) {
// No intent means no class to lookup.
finish();
+ return;
}
- final String packageName =
- intent.getStringExtra(INTENT_EXTRA_PACKAGE_NAME);
- final String className = intent.getStringExtra(INTENT_EXTRA_CLASS_NAME);
+ final String pkgName = intent.getStringExtra(INTENT_EXTRA_PACKAGE_NAME);
final int npp = intent.getIntExtra(INTENT_EXTRA_NPP_INSTANCE, -1);
- // Retrieve the PluginStub implemented in packageName.className
- PluginStub stub =
- PluginUtil.getPluginStub(this, packageName, className);
- if (stub != null) {
- View pluginView = stub.getFullScreenView(npp, this);
- if (pluginView != null) {
- setContentView(pluginView);
- } else {
- // No custom full-sreen view returned by the plugin, odd but
- // just in case, finish the activity.
- finish();
- }
+ // XXX retrieve the existing object instead of creating a new one
+ WebkitPlugin plugin = PluginManager.getInstance(null).getPluginInstance(pkgName, npp);
+
+ if (plugin == null) {
+ //TODO log error
+ finish();
+ return;
+ }
+ SurfaceDrawingModel fullScreenSurface = plugin.getFullScreenSurface();
+ if(fullScreenSurface == null) {
+ //TODO log error
+ finish();
+ return;
+ }
+ View pluginView = fullScreenSurface.getSurface();
+ if (pluginView != null) {
+ setContentView(pluginView);
} else {
+ // No custom full-sreen view returned by the plugin, odd but
+ // just in case, finish the activity.
finish();
}
}
diff --git a/core/java/android/webkit/PluginManager.java b/core/java/android/webkit/PluginManager.java
index 4588f46e5771..88429c50442f 100644
--- a/core/java/android/webkit/PluginManager.java
+++ b/core/java/android/webkit/PluginManager.java
@@ -31,6 +31,8 @@ import android.content.pm.Signature;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.SystemProperties;
import android.util.Log;
+import android.webkit.plugin.NativePlugin;
+import android.webkit.plugin.WebkitPlugin;
/**
* Class for managing the relationship between the {@link WebView} and installed
@@ -41,6 +43,12 @@ import android.util.Log;
*/
public class PluginManager {
+ private class PluginInfo {
+ public PackageInfo packageInfo;
+ public boolean isNative;
+ public Class<? extends WebkitPlugin> pluginClass;
+ }
+
/**
* Service Action: A plugin wishes to be loaded in the WebView must provide
* {@link android.content.IntentFilter IntentFilter} that accepts this
@@ -60,11 +68,14 @@ public class PluginManager {
private static final String LOGTAG = "webkit";
+ private static final String PLUGIN_TYPE = "type";
+ private static final String TYPE_NATIVE = "native";
+
private static PluginManager mInstance = null;
private final Context mContext;
- private ArrayList<PackageInfo> mPackageInfoCache;
+ private ArrayList<PluginInfo> mPluginInfoCache;
// Only plugin matches one of the signatures in the list can be loaded
// inside the WebView process
@@ -76,7 +87,7 @@ public class PluginManager {
private PluginManager(Context context) {
mContext = context;
- mPackageInfoCache = new ArrayList<PackageInfo>();
+ mPluginInfoCache = new ArrayList<PluginInfo>();
}
public static synchronized PluginManager getInstance(Context context) {
@@ -108,35 +119,44 @@ public class PluginManager {
ArrayList<String> directories = new ArrayList<String>();
PackageManager pm = mContext.getPackageManager();
List<ResolveInfo> plugins = pm.queryIntentServices(new Intent(
- PLUGIN_ACTION), PackageManager.GET_SERVICES);
+ PLUGIN_ACTION), PackageManager.GET_SERVICES
+ | PackageManager.GET_META_DATA);
- synchronized(mPackageInfoCache) {
+ synchronized(mPluginInfoCache) {
// clear the list of existing packageInfo objects
- mPackageInfoCache.clear();
+ mPluginInfoCache.clear();
for (ResolveInfo info : plugins) {
+
+ // retrieve the plugin's service information
ServiceInfo serviceInfo = info.serviceInfo;
if (serviceInfo == null) {
Log.w(LOGTAG, "Ignore bad plugin");
continue;
}
+
+ // retrieve information from the plugin's manifest
PackageInfo pkgInfo;
try {
pkgInfo = pm.getPackageInfo(serviceInfo.packageName,
PackageManager.GET_PERMISSIONS
| PackageManager.GET_SIGNATURES);
} catch (NameNotFoundException e) {
- Log.w(LOGTAG, "Cant find plugin: " + serviceInfo.packageName);
+ Log.w(LOGTAG, "Can't find plugin: " + serviceInfo.packageName);
continue;
}
if (pkgInfo == null) {
continue;
}
+
+ // check if their is a conflict in the lib directory names
String directory = pkgInfo.applicationInfo.dataDir + "/lib";
if (directories.contains(directory)) {
continue;
}
+
+ // check if the plugin has the required permissions
String permissions[] = pkgInfo.requestedPermissions;
if (permissions == null) {
continue;
@@ -151,6 +171,8 @@ public class PluginManager {
if (!permissionOk) {
continue;
}
+
+ // check to ensure the plugin is properly signed
Signature signatures[] = pkgInfo.signatures;
if (signatures == null) {
continue;
@@ -169,7 +191,51 @@ public class PluginManager {
continue;
}
}
- mPackageInfoCache.add(pkgInfo);
+
+ PluginInfo pluginInfo = new PluginInfo();
+ pluginInfo.packageInfo = pkgInfo;
+
+ // determine the type of plugin from the manifest
+ if (serviceInfo.metaData == null) {
+ Log.e(LOGTAG, "The plugin '" + serviceInfo.name + "' has no type defined");
+ continue;
+ }
+
+ String pluginType = serviceInfo.metaData.getString(PLUGIN_TYPE);
+ if (TYPE_NATIVE.equals(pluginType)) {
+ pluginInfo.isNative = true;
+ } else {
+ Log.e(LOGTAG, "Unrecognized plugin type: " + pluginType);
+ continue;
+ }
+
+ try {
+ Class<?> cls = getPluginClass(serviceInfo.packageName, serviceInfo.name);
+
+ boolean classFound = false;
+ for(Class<?> implemented : cls.getInterfaces()) {
+ if (pluginInfo.isNative && implemented.equals(NativePlugin.class)) {
+ pluginInfo.pluginClass = cls.asSubclass(WebkitPlugin.class);
+ classFound = true;
+ break;
+ }
+ }
+
+ if (!classFound) {
+ Log.e(LOGTAG, "The plugin's class'" + serviceInfo.name + "' does not extend the appropriate interface.");
+ continue;
+ }
+
+ } catch (NameNotFoundException e) {
+ Log.e(LOGTAG, "Can't find plugin: " + serviceInfo.packageName);
+ continue;
+ } catch (ClassNotFoundException e) {
+ Log.e(LOGTAG, "Can't find plugin's class: " + serviceInfo.name);
+ continue;
+ }
+
+ // if all checks have passed then make the plugin available
+ mPluginInfoCache.add(pluginInfo);
directories.add(directory);
}
}
@@ -177,6 +243,7 @@ public class PluginManager {
return directories.toArray(new String[directories.size()]);
}
+ /* package */
String getPluginsAPKName(String pluginLib) {
// basic error checking on input params
@@ -185,8 +252,9 @@ public class PluginManager {
}
// must be synchronized to ensure the consistency of the cache
- synchronized(mPackageInfoCache) {
- for (PackageInfo pkgInfo : mPackageInfoCache) {
+ synchronized(mPluginInfoCache) {
+ for (PluginInfo pluginInfo : mPluginInfoCache) {
+ PackageInfo pkgInfo = pluginInfo.packageInfo;
if (pluginLib.startsWith(pkgInfo.applicationInfo.dataDir)) {
return pkgInfo.packageName;
}
@@ -200,4 +268,47 @@ public class PluginManager {
String getPluginSharedDataDirectory() {
return mContext.getDir("plugins", 0).getPath();
}
+
+ /* package */
+ WebkitPlugin getPluginInstance(String pkgName, int npp) {
+
+ // must be synchronized to ensure the consistency of the cache
+ synchronized(mPluginInfoCache) {
+
+ // lookup plugin based on pkgName and instantiate if possible.
+ for (PluginInfo pluginInfo : mPluginInfoCache) {
+
+ if (pluginInfo.packageInfo.packageName.equals(pkgName)) {
+
+ try {
+ WebkitPlugin webkitPlugin = pluginInfo.pluginClass.newInstance();
+
+ if (pluginInfo.isNative) {
+ NativePlugin nativePlugin = (NativePlugin) webkitPlugin;
+ nativePlugin.initializePlugin(npp, mContext);
+ }
+
+ return webkitPlugin;
+ } catch (Exception e) {
+ // Any number of things could have happened. Log the exception and
+ // return null. Careful not to use Log.e(LOGTAG, "String", e)
+ // because that reports the exception to the checkin service.
+ Log.e(LOGTAG, Log.getStackTraceString(e));
+ }
+ break;
+ }
+ }
+ }
+ return null;
+ }
+
+ /* package */
+ Class<?> getPluginClass(String packageName, String className)
+ throws NameNotFoundException, ClassNotFoundException {
+ Context pluginContext = mContext.createPackageContext(packageName,
+ Context.CONTEXT_INCLUDE_CODE |
+ Context.CONTEXT_IGNORE_SECURITY);
+ ClassLoader pluginCL = pluginContext.getClassLoader();
+ return pluginCL.loadClass(className);
+ }
}
diff --git a/core/java/android/webkit/PluginUtil.java b/core/java/android/webkit/PluginUtil.java
deleted file mode 100644
index 33ccf9d205fc..000000000000
--- a/core/java/android/webkit/PluginUtil.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.webkit;
-
-import android.content.Context;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.util.Log;
-
-class PluginUtil {
-
- private static final String LOGTAG = "PluginUtil";
-
- /**
- *
- * @param packageName the name of the apk where the class can be found
- * @param className the fully qualified name of a subclass of PluginStub
- */
- /* package */
- static PluginStub getPluginStub(Context context, String packageName,
- String className) {
- try {
- Class<?> stubClass = getPluginClass(context, packageName, className);
- Object stubObject = stubClass.newInstance();
-
- if (stubObject instanceof PluginStub) {
- return (PluginStub) stubObject;
- } else {
- Log.e(LOGTAG, "The plugin class is not of type PluginStub");
- }
- } catch (Exception e) {
- // Any number of things could have happened. Log the exception and
- // return null. Careful not to use Log.e(LOGTAG, "String", e)
- // because that reports the exception to the checkin service.
- Log.e(LOGTAG, Log.getStackTraceString(e));
- }
- return null;
- }
-
- /* package */
- static Class<?> getPluginClass(Context context, String packageName,
- String className) throws NameNotFoundException, ClassNotFoundException {
- Context pluginContext = context.createPackageContext(packageName,
- Context.CONTEXT_INCLUDE_CODE |
- Context.CONTEXT_IGNORE_SECURITY);
- ClassLoader pluginCL = pluginContext.getClassLoader();
- return pluginCL.loadClass(className);
- }
-}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 769f0b1a6d3f..be36fe0fb97c 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -41,6 +41,8 @@ import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
+import android.webkit.plugin.SurfaceDrawingModel;
+import android.webkit.plugin.WebkitPlugin;
import java.util.ArrayList;
import java.util.Collection;
@@ -2175,15 +2177,16 @@ final class WebViewCore {
return null;
}
- String pkgName = PluginManager.getInstance(null).getPluginsAPKName(libName);
+ PluginManager pluginManager = PluginManager.getInstance(null);
+
+ String pkgName = pluginManager.getPluginsAPKName(libName);
if (pkgName == null) {
Log.w(LOGTAG, "Unable to resolve " + libName + " to a plugin APK");
return null;
}
- Class<?> pluginClass = null;
try {
- pluginClass = PluginUtil.getPluginClass(mWebView.getContext(), pkgName, clsName);
+ return pluginManager.getPluginClass(pkgName, clsName);
} catch (NameNotFoundException e) {
Log.e(LOGTAG, "Unable to find plugin classloader for the apk (" + pkgName + ")");
} catch (ClassNotFoundException e) {
@@ -2191,12 +2194,29 @@ final class WebViewCore {
") in the apk (" + pkgName + ")");
}
- return pluginClass;
+ return null;
+ }
+
+ private WebkitPlugin createPluginJavaInstance(String libName, int npp) {
+
+ if (mWebView == null) {
+ return null;
+ }
+
+ PluginManager pluginManager = PluginManager.getInstance(null);
+
+ String pkgName = pluginManager.getPluginsAPKName(libName);
+ if (pkgName == null) {
+ Log.w(LOGTAG, "Unable to resolve " + libName + " to a plugin APK");
+ return null;
+ }
+
+ return pluginManager.getPluginInstance(pkgName, npp);
}
-
+
// called by JNI. PluginWidget function to launch an activity and overlays
// the activity with the View provided by the plugin class.
- private void startFullScreenPluginActivity(String libName, String clsName, int npp) {
+ private void startFullScreenPluginActivity(String libName, int npp) {
if (mWebView == null) {
return;
}
@@ -2209,40 +2229,33 @@ final class WebViewCore {
Intent intent = new Intent("android.intent.webkit.PLUGIN");
intent.putExtra(PluginActivity.INTENT_EXTRA_PACKAGE_NAME, pkgName);
- intent.putExtra(PluginActivity.INTENT_EXTRA_CLASS_NAME, clsName);
intent.putExtra(PluginActivity.INTENT_EXTRA_NPP_INSTANCE, npp);
mWebView.getContext().startActivity(intent);
}
// called by JNI. PluginWidget functions for creating an embedded View for
// the surface drawing model.
- private ViewManager.ChildView createSurface(String libName, String clsName,
- int npp, int x, int y, int width, int height) {
+ private ViewManager.ChildView createSurface(WebkitPlugin webkitPlugin,
+ int x, int y, int width, int height) {
+
if (mWebView == null) {
return null;
}
- String pkgName = PluginManager.getInstance(null).getPluginsAPKName(libName);
- if (pkgName == null) {
- Log.w(LOGTAG, "Unable to resolve " + libName + " to a plugin APK");
+ SurfaceDrawingModel embeddedSurface = webkitPlugin.getEmbeddedSurface();
+ if(embeddedSurface == null) {
+ Log.e(LOGTAG, "Attempted to create an embedded surface with a null drawing model");
return null;
}
- PluginStub stub =PluginUtil.getPluginStub(mWebView.getContext(),pkgName, clsName);
- if (stub == null) {
- Log.e(LOGTAG, "Unable to find plugin class (" + clsName +
- ") in the apk (" + pkgName + ")");
- return null;
- }
-
- View pluginView = stub.getEmbeddedView(npp, mWebView.getContext());
+ View pluginView = embeddedSurface.getSurface();
ViewManager.ChildView view = mWebView.mViewManager.createView();
view.mView = pluginView;
view.attachView(x, y, width, height);
return view;
}
-
+
private void updateSurface(ViewManager.ChildView childView, int x, int y,
int width, int height) {
childView.attachView(x, y, width, height);
diff --git a/core/java/android/webkit/plugin/NativePlugin.java b/core/java/android/webkit/plugin/NativePlugin.java
new file mode 100644
index 000000000000..5019c35e74ef
--- /dev/null
+++ b/core/java/android/webkit/plugin/NativePlugin.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2009, 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.
+ */
+package android.webkit.plugin;
+
+import android.content.Context;
+
+/**
+ *
+ * @hide pending API solidification
+ */
+public interface NativePlugin extends WebkitPlugin {
+
+ void initializePlugin(int npp, Context context);
+
+}
diff --git a/core/java/android/webkit/plugin/SurfaceDrawingModel.java b/core/java/android/webkit/plugin/SurfaceDrawingModel.java
new file mode 100644
index 000000000000..93ba46667f27
--- /dev/null
+++ b/core/java/android/webkit/plugin/SurfaceDrawingModel.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2009, 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.
+ */
+package android.webkit.plugin;
+
+import android.view.View;
+
+/**
+ *
+ * @hide pending API solidification
+ */
+public interface SurfaceDrawingModel {
+
+ public View getSurface();
+
+}
diff --git a/core/java/android/webkit/plugin/WebkitPlugin.java b/core/java/android/webkit/plugin/WebkitPlugin.java
new file mode 100644
index 000000000000..3d13c1cbe086
--- /dev/null
+++ b/core/java/android/webkit/plugin/WebkitPlugin.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009, 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.
+ */
+package android.webkit.plugin;
+
+/**
+ *
+ * @hide pending API solidification
+ */
+public interface WebkitPlugin {
+
+ SurfaceDrawingModel getEmbeddedSurface();
+ SurfaceDrawingModel getFullScreenSurface();
+
+}