Rolled up Android plugin fixes including bugs 692988, 694366, 702330, 702334, 702338, 702341, 702614, 702627, 702964
authorJames Willcox <jwillcox@mozilla.com>
Mon, 21 Nov 2011 02:55:50 -0500
changeset 81580 87da67ee3e59c01da745c148d147cd0bd688fc01
parent 81579 5ce8d4e02e8137936d90021eee03490eb6946b6e
child 81581 1900e3edd32da17ec4b1af6ce3726a8eed4d8eea
child 81947 239e7d505041f16f5a727d388d4c4b8997f00163
push idunknown
push userunknown
push dateunknown
bugs692988, 694366, 702330, 702334, 702338, 702341, 702614, 702627, 702964
milestone11.0a1
Rolled up Android plugin fixes including bugs 692988, 694366, 702330, 702334, 702338, 702341, 702614, 702627, 702964 Bug 692988 - anp_system_getApplicationDataDirectory() is just plain wrong Bug 694366 - Allow Flash to use transparent wmode Bug 702330 - Revert to drawing Flash plugin with a SurfaceView Bug 702334 - Fix deadlocks caused by Flash Bug 702338 - Enable plugins Bug 702341 - Flash plugins don't respond to panning/zooming changes Bug 702614 - Flash should use Skia to implement ANPCanvas and similar interfaces Bug 702627 - Flash: queue invalidation after async surface request Bug 702964 - Support subregion lock on plugin surfaces
Makefile.in
dom/plugins/base/Makefile.in
dom/plugins/base/android/ANPBase.h
dom/plugins/base/android/ANPCanvas.cpp
dom/plugins/base/android/ANPPaint.cpp
dom/plugins/base/android/ANPPath.cpp
dom/plugins/base/android/ANPSurface.cpp
dom/plugins/base/android/ANPSystem.cpp
dom/plugins/base/android/ANPTypeface.cpp
dom/plugins/base/android/Makefile.in
dom/plugins/base/nsNPAPIPluginInstance.cpp
dom/plugins/base/nsNPAPIPluginInstance.h
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/plugins/base/nsPluginInstanceOwner.h
other-licenses/skia-npapi/ANPCanvas.cpp
other-licenses/skia-npapi/ANPPaint.cpp
other-licenses/skia-npapi/ANPPath.cpp
other-licenses/skia-npapi/ANPTypeface.cpp
other-licenses/skia-npapi/Makefile.in
other-licenses/skia-npapi/SkANP.cpp
other-licenses/skia-npapi/SkANP.h
toolkit/library/Makefile.in
--- a/Makefile.in
+++ b/Makefile.in
@@ -61,17 +61,17 @@ TIERS += base
 tier_base_dirs = \
 	config \
 	build \
 	probes \
 	$(NULL)
 
 ifndef LIBXUL_SDK
 ifeq (android,$(MOZ_WIDGET_TOOLKIT))
-tier_base_dirs += other-licenses/android
+tier_base_dirs += other-licenses/android other-licenses/skia-npapi
 endif
 
 tier_base_dirs += memory
 endif
 
 ifdef COMPILE_ENVIRONMENT
 include $(topsrcdir)/$(MOZ_BUILD_APP)/build.mk
 endif
--- a/dom/plugins/base/Makefile.in
+++ b/dom/plugins/base/Makefile.in
@@ -128,17 +128,20 @@ else
 	CPPSRCS += nsPluginNativeWindow.cpp
 endif
 endif
 endif
 endif
 endif
 
 LOCAL_INCLUDES += \
+  -DSK_BUILD_FOR_ANDROID_NDK \
   -I$(topsrcdir)/xpcom/base/ \
+  -I$(topsrcdir)/gfx/skia/include/core \
+  -I$(topsrcdir)/gfx/skia/include/config \
   $(MOZ_CAIRO_CFLAGS) \
   $(NULL)
 
 include $(topsrcdir)/dom/dom-config.mk
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
--- a/dom/plugins/base/android/ANPBase.h
+++ b/dom/plugins/base/android/ANPBase.h
@@ -34,59 +34,34 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "android_npapi.h"
 #include <stdlib.h>
 #include "nsAutoPtr.h"
-#include "gfxFont.h"
 #include "nsISupportsImpl.h"
 
 #define NOT_IMPLEMENTED_FATAL() do {                                    \
     __android_log_print(ANDROID_LOG_ERROR, "GeckoPlugins",              \
                         "%s not implemented %s, %d",                    \
                         __PRETTY_FUNCTION__, __FILE__, __LINE__);       \
     abort();                                                            \
   } while(0)
 
 #define NOT_IMPLEMENTED()                                               \
     __android_log_print(ANDROID_LOG_ERROR, "GeckoPlugins",              \
                         "!!!!!!!!!!!!!!  %s not implemented %s, %d",    \
                         __PRETTY_FUNCTION__, __FILE__, __LINE__);       \
 
-class gfxFont;
-
 void InitAudioTrackInterface(ANPAudioTrackInterfaceV0 *i);
 void InitBitmapInterface(ANPBitmapInterfaceV0 *i);
 void InitCanvasInterface(ANPCanvasInterfaceV0 *i);
 void InitEventInterface(ANPEventInterfaceV0 *i);
 void InitLogInterface(ANPLogInterfaceV0 *i);
 void InitMatrixInterface(ANPMatrixInterfaceV0 *i);
 void InitPaintInterface(ANPPaintInterfaceV0 *i);
 void InitPathInterface(ANPPathInterfaceV0 *i);
 void InitSurfaceInterface(ANPSurfaceInterfaceV0 *i);
 void InitSystemInterface(ANPSystemInterfaceV0 *i);
 void InitTypeFaceInterface(ANPTypefaceInterfaceV0 *i);
 void InitWindowInterface(ANPWindowInterfaceV0 *i);
-
-struct ANPTypeface {
-  gfxFont* mFont;
-  nsAutoRefCnt mRefCnt;
-};
-
-
-typedef struct {
-  ANPMatrixFlag flags;
-  ANPColor color;
-  ANPPaintStyle style;
-  float strokeWidth;
-  float strokeMiter;
-  ANPPaintCap paintCap;
-  ANPPaintJoin paintJoin;
-  ANPTextEncoding textEncoding;
-  ANPPaintAlign paintAlign;
-  float textSize;
-  float textScaleX;
-  float textSkewX;
-  ANPTypeface typeface;
-} ANPPaintPrivate;
--- a/dom/plugins/base/android/ANPCanvas.cpp
+++ b/dom/plugins/base/android/ANPCanvas.cpp
@@ -1,373 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Android NPAPI support code
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Doug Turner <dougt@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "assert.h"
-#include "ANPBase.h"
-#include <android/log.h>
-
-#include "cairo.h"
-#include "gfxPlatform.h"
-#include "gfxASurface.h"
-#include "gfxImageSurface.h"
-#include "gfxUtils.h"
-#include "gfxContext.h"
-
-#define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
-#define ASSIGN(obj, name)   (obj)->name = anp_canvas_##name
-
-
-ANPCanvas*
-anp_canvas_newCanvas(const ANPBitmap* bitmap)
-{
-  PRUint32 stride;
-  gfxASurface::gfxImageFormat  format;
-
-  if (bitmap->format == kRGBA_8888_ANPBitmapFormat) {
-    stride = bitmap->width * 4;
-    format = gfxImageSurface::ImageFormatARGB32;
-  }
-  else if (bitmap->format == kRGB_565_ANPBitmapFormat) {
-    stride = bitmap->width * 2;
-    format = gfxImageSurface::ImageFormatRGB16_565;
-  }
-  else {
-    LOG("%s -- Unknown format", __PRETTY_FUNCTION__);
-    return nsnull;
-  }
-
-  gfxImageSurface* pluginSurface = new gfxImageSurface(static_cast<unsigned char*>(bitmap->baseAddr),
-                                                       gfxIntSize(bitmap->width,  bitmap->height), 
-                                                       stride,
-                                                       format);
-  if (pluginSurface->CairoStatus()) {
-    LOG("%s -- %d x %d FAILED to create gfxImageSurface", __PRETTY_FUNCTION__, bitmap->width, bitmap->height);
-    return nsnull;
-  }
-
-  gfxContext *pluginContext = new gfxContext(pluginSurface);
-  NS_ADDREF(pluginContext);
-  return (ANPCanvas*) pluginContext;
-}
-
-void
-anp_canvas_deleteCanvas(ANPCanvas* canvas)
-{
-  if (!canvas)
-    return;
-  gfxContext *ctx = (gfxContext*)canvas;
-  NS_RELEASE( ctx );
-}
-
-void
-anp_canvas_save(ANPCanvas* canvas)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  ctx->Save();
-}
-
-void
-anp_canvas_restore(ANPCanvas* canvas)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  ctx->Restore();
-}
-
-void
-anp_canvas_translate(ANPCanvas* canvas, float tx, float ty)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  ctx->Translate(gfxPoint(tx,ty));
-}
-
-void
-anp_canvas_scale(ANPCanvas* canvas, float sx, float sy)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  ctx->Scale(sx, sy);
-}
-
-void
-anp_canvas_rotate(ANPCanvas* canvas, float degrees)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  ctx->Rotate(degrees);
-}
-
-void
-anp_canvas_skew(ANPCanvas* canvas, float kx, float ky)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  LOG("%s is not impl.", __PRETTY_FUNCTION__);
-}
-
-void
-anp_canvas_concat(ANPCanvas* canvas, const ANPMatrix*)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  LOG("%s is not impl.", __PRETTY_FUNCTION__);
-}
-
-void
-anp_canvas_clipRect(ANPCanvas* canvas, const ANPRectF* r)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  ctx->Clip(gfxRect(r->left,
-                    r->top,
-                    r->right - r->left,
-                    r->bottom - r->top));
-}
-
-void
-anp_canvas_clipPath(ANPCanvas* canvas, const ANPPath*)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  LOG("%s is not impl.", __PRETTY_FUNCTION__);
-}
-
-void
-anp_canvas_getTotalMatrix(ANPCanvas* canvas, ANPMatrix*)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  LOG("%s is not impl.", __PRETTY_FUNCTION__);
-}
-
-bool
-anp_canvas_getLocalClipBounds(ANPCanvas* canvas, ANPRectF* bounds, bool aa)
-{
-  if (!canvas)
-    return false;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  LOG("%s is not impl.", __PRETTY_FUNCTION__);
-  return false;
-}
-
-bool
-anp_canvas_getDeviceClipBounds(ANPCanvas* canvas, ANPRectI* bounds)
-{
-  if (!canvas)
-    return false;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  LOG("%s is not impl.", __PRETTY_FUNCTION__);
-  return false;
-}
-
-void
-anp_canvas_drawColor(ANPCanvas* canvas, ANPColor c)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  ctx->SetDeviceColor(gfxRGBA(c, gfxRGBA::PACKED_ARGB));
-  LOG("returning from %s", __PRETTY_FUNCTION__);
-}
-
-void
-anp_canvas_drawPaint(ANPCanvas* canvas, const ANPPaint* paint)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  LOG("%s", "                    **************   NOT IMPLEMENTED!!!");
-}
-
-void
-anp_canvas_drawLine(ANPCanvas* canvas, float x0, float y0, float x1, float y1,
-                    const ANPPaint* paint)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  ctx->NewPath();
-  ctx->SetColor(((ANPPaintPrivate*)paint)->color);
-  ctx->Line(gfxPoint(x0, y0), gfxPoint(x1, y1));
-  ctx->Fill();
-}
-
-void
-anp_canvas_drawRect(ANPCanvas* canvas, const ANPRectF* r, const ANPPaint* paint)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-
-  ctx->NewPath();
-  ctx->SetColor(((ANPPaintPrivate*)paint)->color);
-  ctx->Rectangle(gfxRect(r->left,
-                         r->top,
-                         r->right - r->left,
-                         r->bottom - r->top));
-  ctx->Fill();
-}
-
-void
-anp_canvas_drawOval(ANPCanvas* canvas, const ANPRectF* r, const ANPPaint* paint)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-   
-  ctx->NewPath();
-  ctx->SetColor(((ANPPaintPrivate*)paint)->color);
-
-  float sizeX = (r->right   - r->left);
-  float sizeY = (r->bottom  - r->top);
-
-  ctx->Ellipse(gfxPoint(r->left + ( sizeX / 2), r->top  + ( sizeY  / 2)),
-               gfxSize(sizeX, sizeY));
-  ctx->Fill();
-}
-
-void
-anp_canvas_drawPath(ANPCanvas* canvas, const ANPPath*, const ANPPaint* paint)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  LOG("%s is not impl.", __PRETTY_FUNCTION__);
-}
-
-void
-anp_canvas_drawText(ANPCanvas* canvas, const void* text, uint32_t byteLength,
-                                float x, float y, const ANPPaint* paint)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  LOG("%s is not impl.", __PRETTY_FUNCTION__);
-}
-
-void
-anp_canvas_drawPosText(ANPCanvas* canvas, const void* text, uint32_t byteLength,
-                       const float xy[], const ANPPaint* paint)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  LOG("%s is not impl.", __PRETTY_FUNCTION__);
-}
-
-void
-anp_canvas_drawBitmap(ANPCanvas* canvas, const ANPBitmap*, float x, float y,
-                      const ANPPaint* paint)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  LOG("%s is not impl.", __PRETTY_FUNCTION__);
-}
-
-void
-anp_canvas_drawBitmapRect(ANPCanvas* canvas, const ANPBitmap*,
-                          const ANPRectI* src, const ANPRectF* dst,
-                          const ANPPaint* paint)
-{
-  if (!canvas)
-    return;
-
-  gfxContext* ctx = (gfxContext*)canvas;
-  LOG("%s is not impl.", __PRETTY_FUNCTION__);
-}
-
-void InitCanvasInterface(ANPCanvasInterfaceV0 *i) {
-  _assert(i->inSize == sizeof(*i));
-  ASSIGN(i, newCanvas);
-  ASSIGN(i, deleteCanvas);
-  ASSIGN(i, save);
-  ASSIGN(i, restore);
-  ASSIGN(i, translate);
-  ASSIGN(i, scale);
-  ASSIGN(i, rotate);
-  ASSIGN(i, skew);
-  ASSIGN(i, concat);
-  ASSIGN(i, clipRect);
-  ASSIGN(i, clipPath);
-  ASSIGN(i, getTotalMatrix);
-  ASSIGN(i, getLocalClipBounds);
-  ASSIGN(i, getDeviceClipBounds);
-  ASSIGN(i, drawColor);
-  ASSIGN(i, drawPaint);
-  ASSIGN(i, drawLine);
-  ASSIGN(i, drawRect);
-  ASSIGN(i, drawOval);
-  ASSIGN(i, drawPath);
-  ASSIGN(i, drawText);
-  ASSIGN(i, drawPosText);
-  ASSIGN(i, drawBitmap);
-  ASSIGN(i, drawBitmapRect);
-}
--- a/dom/plugins/base/android/ANPPaint.cpp
+++ b/dom/plugins/base/android/ANPPaint.cpp
@@ -1,454 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Android NPAPI support code
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Doug Turner <dougt@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include <stdlib.h>
-#include <assert.h>
-#include <android/log.h>
-#include "ANPBase.h"
-
-#define LOG(args...)  
-//__android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
-#define ASSIGN(obj, name)   (obj)->name = anp_paint_##name
-
-ANPPaint*
-anp_paint_newPaint()
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) calloc(1, sizeof(ANPPaintPrivate));
-  return (ANPPaint*) p;
-}
-
-void
-anp_paint_deletePaint(ANPPaint* paint)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  free((void*)p);
-}
-
-
-ANPPaintFlags
-anp_paint_getFlags(const ANPPaint* paint)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return kAntiAlias_ANPPaintFlag;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  return p->flags;
-}
-
-void
-anp_paint_setFlags(ANPPaint* paint, ANPPaintFlags flags)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;  
-  p->flags = flags;
-}
-
-
-ANPColor
-anp_paint_getColor(const ANPPaint* paint)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return ANP_MAKE_COLOR(1, 255, 255, 255);
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  return p->color;
-}
-
-void
-anp_paint_setColor(ANPPaint* paint, ANPColor color)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  p->color = color;
-}
-
-
-ANPPaintStyle
-anp_paint_getStyle(const ANPPaint* paint)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return kFill_ANPPaintStyle;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  return p->style;
-}
-
-void
-anp_paint_setStyle(ANPPaint* paint, ANPPaintStyle style)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  p->style = style;
-}
-
-float
-anp_paint_getStrokeWidth(const ANPPaint* paint)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return 0;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  return p->strokeWidth;
-}
-
-float
-anp_paint_getStrokeMiter(const ANPPaint* paint)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return 0;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  return p->strokeMiter;
-}
-
-ANPPaintCap
-anp_paint_getStrokeCap(const ANPPaint* paint)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return kButt_ANPPaintCap;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  return p->paintCap;
-}
-
-ANPPaintJoin
-anp_paint_getStrokeJoin(const ANPPaint* paint)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return kMiter_ANPPaintJoin;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  return p->paintJoin;
-}
-
-void
-anp_paint_setStrokeWidth(ANPPaint* paint, float width)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  p->strokeWidth = width;
-}
-
-void
-anp_paint_setStrokeMiter(ANPPaint* paint, float miter)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  p->strokeMiter = miter;
-}
-
-void
-anp_paint_setStrokeCap(ANPPaint* paint, ANPPaintCap cap)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  p->paintCap = cap;
-}
-
-void
-anp_paint_setStrokeJoin(ANPPaint* paint, ANPPaintJoin join)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  p->paintJoin = join;
-}
-
-
-ANPTextEncoding
-anp_paint_getTextEncoding(const ANPPaint* paint)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return kUTF8_ANPTextEncoding;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  return p->textEncoding;
-}
-
-ANPPaintAlign
-anp_paint_getTextAlign(const ANPPaint* paint)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return kLeft_ANPPaintAlign;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  return p->paintAlign;
-}
-
-float
-anp_paint_getTextSize(const ANPPaint* paint)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return 0;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  return p->textSize;
-}
-
-float
-anp_paint_getTextScaleX(const ANPPaint* paint)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return 0;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  return p->textScaleX;
-}
-
-float
-anp_paint_getTextSkewX(const ANPPaint* paint)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return 0;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  return p->textSkewX;
-}
-
-void
-anp_paint_setTextEncoding(ANPPaint* paint, ANPTextEncoding encoding)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  p->textEncoding = encoding;
-}
-
-void
-anp_paint_setTextAlign(ANPPaint* paint, ANPPaintAlign align)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  p->paintAlign = align;  
-}
-
-void
-anp_paint_setTextSize(ANPPaint* paint, float size)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  p->textSize = size;
-}
-
-void
-anp_paint_setTextScaleX(ANPPaint* paint, float scale)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  p->textScaleX = scale;
-}
-
-void
-anp_paint_setTextSkewX(ANPPaint* paint, float skew)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  p->textSkewX = skew;
-}
-
-
-/** Return the typeface in paint, or null if there is none. This does not
-    modify the owner count of the returned typeface.
-*/
-ANPTypeface*
-anp_paint_getTypeface(const ANPPaint* paint)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return NULL;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  return &p->typeface;
-}
-
-
-/** Set the paint's typeface. If the paint already had a non-null typeface,
-    its owner count is decremented. If the new typeface is non-null, its
-    owner count is incremented.
-*/
-void
-anp_paint_setTypeface(ANPPaint* paint, ANPTypeface* typeface)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  LOG("%s is not impl.", __PRETTY_FUNCTION__);
-}
-
-/** Return the width of the text. If bounds is not null, return the bounds
-    of the text in that rectangle.
-*/
-float
-anp_paint_measureText(ANPPaint* paint, const void* text, uint32_t byteLength,
-                      ANPRectF* bounds)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return 0;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-
-  LOG("%s is not impl.", __PRETTY_FUNCTION__);
-  return 0;
-}
-
-
-/** Return the number of unichars specifed by the text.
-    If widths is not null, returns the array of advance widths for each
-    unichar.
-    If bounds is not null, returns the array of bounds for each unichar.
-*/
-int
-anp_paint_getTextWidths(ANPPaint* paint, const void* text, uint32_t byteLength,
-                        float widths[], ANPRectF bounds[])
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return 0;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  LOG("%s is not impl.", __PRETTY_FUNCTION__);
-  return 0;
-}
-
-
-/** Return in metrics the spacing values for text, respecting the paint's
-    typeface and pointsize, and return the spacing between lines
-    (descent - ascent + leading). If metrics is NULL, it will be ignored.
-*/
-float
-anp_paint_getFontMetrics(ANPPaint* paint, ANPFontMetrics* metrics)
-{
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!paint)
-    return 0;
-
-  ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
-  LOG("%s is not impl.", __PRETTY_FUNCTION__);
-  return 0;
-}
-
-
-void InitPaintInterface(ANPPaintInterfaceV0 *i) {
-  _assert(i->inSize == sizeof(*i));
-  ASSIGN(i, newPaint);
-  ASSIGN(i, deletePaint);
-  ASSIGN(i, getFlags);
-  ASSIGN(i, setFlags);
-  ASSIGN(i, getColor);
-  ASSIGN(i, setColor);
-  ASSIGN(i, getStyle);
-  ASSIGN(i, setStyle);
-  ASSIGN(i, getStrokeWidth);
-  ASSIGN(i, getStrokeMiter);
-  ASSIGN(i, getStrokeCap);
-  ASSIGN(i, getStrokeJoin);
-  ASSIGN(i, setStrokeWidth);
-  ASSIGN(i, setStrokeMiter);
-  ASSIGN(i, setStrokeCap);
-  ASSIGN(i, setStrokeJoin);
-  ASSIGN(i, getTextEncoding);
-  ASSIGN(i, getTextAlign);
-  ASSIGN(i, getTextSize);
-  ASSIGN(i, getTextScaleX);
-  ASSIGN(i, getTextSkewX);
-  ASSIGN(i, setTextEncoding);
-  ASSIGN(i, setTextAlign);
-  ASSIGN(i, setTextSize);
-  ASSIGN(i, setTextScaleX);
-  ASSIGN(i, setTextSkewX);
-  ASSIGN(i, getTypeface);
-  ASSIGN(i, setTypeface);
-  ASSIGN(i, measureText);
-  ASSIGN(i, getTextWidths);
-  ASSIGN(i, getFontMetrics);
-}
--- a/dom/plugins/base/android/ANPPath.cpp
+++ b/dom/plugins/base/android/ANPPath.cpp
@@ -1,171 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Android NPAPI support code
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Doug Turner <dougt@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "assert.h"
-#include "ANPBase.h"
-#include <android/log.h>
-
-#define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
-#define ASSIGN(obj, name)   (obj)->name = anp_path_##name
-
-
-// maybe this should store a list of actions (lineTo,
-// moveTo), and when canvas_drawPath() we apply all of these
-// actions to the gfxContext.
-
-ANPPath*
-anp_path_newPath()
-{
-  LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
-  return 0;
-}
-
-
-void
-anp_path_deletePath(ANPPath* p)
-{
-  LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
-}
-
-
-void
-anp_path_copy(ANPPath* dst, const ANPPath* src)
-{
-  LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
-}
-
-
-bool
-anp_path_equal(const ANPPath* path0, const ANPPath* path1)
-{
-  LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
-  return false;
-}
-
-
-void
-anp_path_reset(ANPPath* p)
-{
-  LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
-}
-
-
-bool
-anp_path_isEmpty(const ANPPath* p)
-{
-  LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
-  return false;
-}
-
-
-void
-anp_path_getBounds(const ANPPath* p, ANPRectF* bounds)
-{
-  LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
-
-  bounds->left = 0;
-  bounds->top = 0;
-  bounds->right = 1000;
-  bounds->left = 1000;
-}
-
-
-void
-anp_path_moveTo(ANPPath* p, float x, float y)
-{
-  LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
-}
-
-void
-anp_path_lineTo(ANPPath* p, float x, float y)
-{
-  LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
-}
-
-void
-anp_path_quadTo(ANPPath* p, float x0, float y0, float x1, float y1)
-{
-  LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
-}
-
-void
-anp_path_cubicTo(ANPPath* p, float x0, float y0, float x1, float y1,
-                      float x2, float y2)
-{
-  LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
-}
-
-void
-anp_path_close(ANPPath* p)
-{
-  LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
-}
-
-
-void
-anp_path_offset(ANPPath* src, float dx, float dy, ANPPath* dst)
-{
-  LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
-}
-
-
-void
-anp_path_transform(ANPPath* src, const ANPMatrix*, ANPPath* dst)
-{
-  LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
-}
-
-
-
-void InitPathInterface(ANPPathInterfaceV0 *i) {
-  _assert(i->inSize == sizeof(*i));
-  ASSIGN(i, newPath);
-  ASSIGN(i, deletePath);
-  ASSIGN(i, copy);
-  ASSIGN(i, equal);
-  ASSIGN(i, reset);
-  ASSIGN(i, isEmpty);
-  ASSIGN(i, getBounds);
-  ASSIGN(i, moveTo);
-  ASSIGN(i, lineTo);
-  ASSIGN(i, quadTo);
-  ASSIGN(i, cubicTo);
-  ASSIGN(i, close);
-  ASSIGN(i, offset);
-  ASSIGN(i, transform);
-}
--- a/dom/plugins/base/android/ANPSurface.cpp
+++ b/dom/plugins/base/android/ANPSurface.cpp
@@ -31,156 +31,260 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "assert.h"
-#include "ANPBase.h"
+#include <dlfcn.h>
 #include <android/log.h>
-#include "AndroidBridge.h"
-#include "gfxImageSurface.h"
-#include "gfxContext.h"
-#include "nsNPAPIPluginInstance.h"
+#include "ANPBase.h"
 
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
 #define ASSIGN(obj, name)   (obj)->name = anp_surface_##name
 
+#define CLEAR_EXCEPTION(env) if (env->ExceptionOccurred()) env->ExceptionClear();
+
+#define ANDROID_REGION_SIZE 512
+
+enum {
+    PIXEL_FORMAT_RGBA_8888   = 1,
+    PIXEL_FORMAT_RGB_565     = 4,
+};
+
+struct SurfaceInfo {
+    uint32_t    w;
+    uint32_t    h;
+    uint32_t    s;
+    uint32_t    usage;
+    uint32_t    format;
+    unsigned char* bits;
+    uint32_t    reserved[2];
+};
+
+typedef struct ARect {
+    int32_t left;
+    int32_t top;
+    int32_t right;
+    int32_t bottom;
+} ARect;
+
 
 // used to cache JNI method and field IDs for Surface Objects
 static struct ANPSurfaceInterfaceJavaGlue {
-  bool        initialized;
-  jclass geckoAppShellClass;
-  jclass surfaceInfoCls;
-  jmethodID getSurfaceInfo;
-  jfieldID jFormat;
-  jfieldID jWidth ;
-  jfieldID jHeight;
+    bool        initialized;
+    jmethodID   getSurfaceHolder;
+    jmethodID   getSurface;
+    jfieldID    surfacePointer;
 } gSurfaceJavaGlue;
 
-#define getClassGlobalRef(env, cname)                                    \
-     (jClass = jclass(env->NewGlobalRef(env->FindClass(cname))))
+static struct ANPSurfaceFunctions {
+    bool initialized;
+
+    int (* lock)(void*, SurfaceInfo*, void*);
+    int (* unlockAndPost)(void*);
+
+    void* (* regionConstructor)(void*);
+    void (* setRegion)(void*, ARect const&);
+} gSurfaceFunctions;
+
+
+static inline void* getSurface(JNIEnv* env, jobject view) {
+  if (!env || !view) {
+    return NULL;
+  }
+
+  if (!gSurfaceJavaGlue.initialized) {
+
+    jclass surfaceViewClass = env->FindClass("android/view/SurfaceView");
+    gSurfaceJavaGlue.getSurfaceHolder = env->GetMethodID(surfaceViewClass, "getHolder", "()Landroid/view/SurfaceHolder;");
+
+    jclass surfaceHolderClass = env->FindClass("android/view/SurfaceHolder");
+    gSurfaceJavaGlue.getSurface = env->GetMethodID(surfaceHolderClass, "getSurface", "()Landroid/view/Surface;");
+
+    jclass surfaceClass = env->FindClass("android/view/Surface");
+    gSurfaceJavaGlue.surfacePointer = env->GetFieldID(surfaceClass,
+        "mSurfacePointer", "I");
+
+    if (!gSurfaceJavaGlue.surfacePointer) {
+      CLEAR_EXCEPTION(env);
 
-static void init(JNIEnv* env) {
-  if (gSurfaceJavaGlue.initialized)
-    return;
-  
-  gSurfaceJavaGlue.geckoAppShellClass = mozilla::AndroidBridge::GetGeckoAppShellClass();
-  
-  jmethodID getClass = env->GetStaticMethodID(gSurfaceJavaGlue.geckoAppShellClass, 
-                                              "getSurfaceInfoClass",
-                                              "()Ljava/lang/Class;");
+      // It was something else in 2.2.
+      gSurfaceJavaGlue.surfacePointer = env->GetFieldID(surfaceClass,
+          "mSurface", "I");
+
+      if (!gSurfaceJavaGlue.surfacePointer) {
+        CLEAR_EXCEPTION(env);
+
+        // And something else in 2.3+
+        gSurfaceJavaGlue.surfacePointer = env->GetFieldID(surfaceClass,
+            "mNativeSurface", "I");
+        
+        CLEAR_EXCEPTION(env);
+      }
+    }
 
-  gSurfaceJavaGlue.surfaceInfoCls = (jclass) env->NewGlobalRef(env->CallStaticObjectMethod(gSurfaceJavaGlue.geckoAppShellClass, getClass));
+    if (!gSurfaceJavaGlue.surfacePointer) {
+      LOG("Failed to acquire surface pointer");
+      return NULL;
+    }
+
+    env->DeleteLocalRef(surfaceClass);
+    env->DeleteLocalRef(surfaceViewClass);
+    env->DeleteLocalRef(surfaceHolderClass);
 
-  gSurfaceJavaGlue.jFormat = env->GetFieldID(gSurfaceJavaGlue.surfaceInfoCls, "format", "I");
-  gSurfaceJavaGlue.jWidth = env->GetFieldID(gSurfaceJavaGlue.surfaceInfoCls, "width", "I");
-  gSurfaceJavaGlue.jHeight = env->GetFieldID(gSurfaceJavaGlue.surfaceInfoCls, "height", "I");
+    gSurfaceJavaGlue.initialized = (gSurfaceJavaGlue.surfacePointer != NULL);
+  }
 
-  gSurfaceJavaGlue.getSurfaceInfo = env->GetStaticMethodID(gSurfaceJavaGlue.geckoAppShellClass, "getSurfaceInfo", "(Landroid/view/SurfaceView;)Lorg/mozilla/gecko/SurfaceInfo;");
-  gSurfaceJavaGlue.initialized = true;
+  jobject holder = env->CallObjectMethod(view, gSurfaceJavaGlue.getSurfaceHolder);
+  jobject surface = env->CallObjectMethod(holder, gSurfaceJavaGlue.getSurface);
+  jint surfacePointer = env->GetIntField(surface, gSurfaceJavaGlue.surfacePointer);
+
+  env->DeleteLocalRef(holder);
+  env->DeleteLocalRef(surface);
+
+  return (void*)surfacePointer;
 }
 
-static bool anp_lock(JNIEnv* env, jobject surfaceView, ANPBitmap* bitmap, ANPRectI* dirtyRect) {
-  LOG("%s", __PRETTY_FUNCTION__);
-  if (!bitmap || !surfaceView) {
-    LOG("%s, null bitmap or surface, exiting", __PRETTY_FUNCTION__);
+static ANPBitmapFormat convertPixelFormat(int32_t format) {
+  switch (format) {
+    case PIXEL_FORMAT_RGBA_8888:  return kRGBA_8888_ANPBitmapFormat;
+    case PIXEL_FORMAT_RGB_565:    return kRGB_565_ANPBitmapFormat;
+    default:            return kUnknown_ANPBitmapFormat;
+  }
+}
+
+static int bytesPerPixel(int32_t format) {
+  switch (format) {
+    case PIXEL_FORMAT_RGBA_8888: return 4;
+    case PIXEL_FORMAT_RGB_565: return 2;
+    default: return -1;
+  }
+}
+
+static bool init() {
+  if (gSurfaceFunctions.initialized)
+    return true;
+
+  void* handle = dlopen("/system/lib/libsurfaceflinger_client.so", RTLD_LAZY);
+
+  if (!handle) {
+    LOG("Failed to open libsurfaceflinger_client.so");
     return false;
   }
 
-  init(env);
-
-  jobject info = env->CallStaticObjectMethod(gSurfaceJavaGlue.geckoAppShellClass,
-                                             gSurfaceJavaGlue.getSurfaceInfo, surfaceView);
-
-  LOG("info: %p", info);
-  if (!info)
-    return false;
+  gSurfaceFunctions.lock = (int (*)(void*, SurfaceInfo*, void*))dlsym(handle, "_ZN7android7Surface4lockEPNS0_11SurfaceInfoEPNS_6RegionEb");
+  gSurfaceFunctions.unlockAndPost = (int (*)(void*))dlsym(handle, "_ZN7android7Surface13unlockAndPostEv");
 
-  bitmap->width  = env->GetIntField(info, gSurfaceJavaGlue.jWidth);
-  bitmap->height = env->GetIntField(info, gSurfaceJavaGlue.jHeight);
+  handle = dlopen("/system/lib/libui.so", RTLD_LAZY);
+  if (!handle) {
+    LOG("Failed to open libui.so");
+    return false;
+  }
 
-  if (bitmap->width <= 0 || bitmap->height <= 0)
-    return false;
-
-  int format = env->GetIntField(info, gSurfaceJavaGlue.jFormat);
-  gfxImageFormat targetFormat;
+  gSurfaceFunctions.regionConstructor = (void* (*)(void*))dlsym(handle, "_ZN7android6RegionC1Ev");
+  gSurfaceFunctions.setRegion = (void (*)(void*, ARect const&))dlsym(handle, "_ZN7android6Region3setERKNS_4RectE");
 
-  // format is PixelFormat
-  if (format & 0x00000001) {
-    /*
-    bitmap->format = kRGBA_8888_ANPBitmapFormat;
-    bitmap->rowBytes = bitmap->width * 4;
-    targetFormat = gfxASurface::ImageFormatARGB32;
-    */
-    
-    // We actually can't handle this right now because gfxImageSurface
-    // doesn't support RGBA32.
-    LOG("Unable to handle 32bit pixel format");
+  gSurfaceFunctions.initialized = (gSurfaceFunctions.lock && gSurfaceFunctions.unlockAndPost &&
+                                   gSurfaceFunctions.regionConstructor && gSurfaceFunctions.setRegion);
+  LOG("Initialized? %d\n", gSurfaceFunctions.initialized);
+  return gSurfaceFunctions.initialized;
+}
+
+static bool anp_surface_lock(JNIEnv* env, jobject surfaceView, ANPBitmap* bitmap, ANPRectI* dirtyRect) {
+  if (!bitmap || !surfaceView) {
     return false;
-  } else if (format & 0x00000004) {
-    bitmap->format = kRGB_565_ANPBitmapFormat;
-    bitmap->rowBytes = bitmap->width * 2;
-    targetFormat = gfxASurface::ImageFormatRGB16_565;
-  } else {
-    LOG("format from glue is unknown %d\n", format);
+  }
+
+  void* surface = getSurface(env, surfaceView);
+
+  if (!bitmap || !surface) {
+    return false;
+  }
+
+  if (!init()) {
     return false;
   }
 
-  nsNPAPIPluginInstance* pinst = nsNPAPIPluginInstance::FindByJavaSurface((void*)surfaceView);
-  if (!pinst) {
-    LOG("Failed to get plugin instance");
+  void* region = NULL;
+  if (dirtyRect) {
+    region = malloc(ANDROID_REGION_SIZE);
+    gSurfaceFunctions.regionConstructor(region);
+
+    ARect rect;
+    rect.left = dirtyRect->left;
+    rect.top = dirtyRect->top;
+    rect.right = dirtyRect->right;
+    rect.bottom = dirtyRect->bottom;
+
+    gSurfaceFunctions.setRegion(region, rect);
+  }
+
+  SurfaceInfo info;
+  int err = gSurfaceFunctions.lock(surface, &info, region);
+  if (err < 0) {
+    LOG("Failed to lock surface");
     return false;
   }
 
-  NPRect lockRect;
+  // the surface may have expanded the dirty region so we must to pass that
+  // information back to the plugin.
   if (dirtyRect) {
-    lockRect.top = dirtyRect->top;
-    lockRect.left = dirtyRect->left;
-    lockRect.right = dirtyRect->right;
-    lockRect.bottom = dirtyRect->bottom;
+    ARect* dirtyBounds = (ARect*)region; // The bounds are the first member, so this should work!
+
+    dirtyRect->left = dirtyBounds->left;
+    dirtyRect->right = dirtyBounds->right;
+    dirtyRect->top = dirtyBounds->top;
+    dirtyRect->bottom = dirtyBounds->bottom;
+  }
+
+  if (region)
+    free(region);
+
+  int bpr = info.s * bytesPerPixel(info.format);
+
+  bitmap->format = convertPixelFormat(info.format);
+  bitmap->width = info.w;
+  bitmap->height = info.h;
+  bitmap->rowBytes = bpr;
+
+  if (info.w > 0 && info.h > 0) {
+    bitmap->baseAddr = info.bits;
   } else {
-    // No dirty rect, use the whole bitmap
-    lockRect.top = lockRect.left = 0;
-    lockRect.right = bitmap->width;
-    lockRect.bottom = bitmap->height;
+    bitmap->baseAddr = NULL;
+    return false;
   }
-  
-  gfxImageSurface* target = pinst->LockTargetSurface(bitmap->width, bitmap->height, targetFormat, &lockRect);
-  bitmap->baseAddr = target->Data();
-
-  env->DeleteLocalRef(info);
 
   return true;
 }
 
-static void anp_unlock(JNIEnv* env, jobject surfaceView) {
-  LOG("%s", __PRETTY_FUNCTION__);
-
+static void anp_surface_unlock(JNIEnv* env, jobject surfaceView) {
   if (!surfaceView) {
-    LOG("null surface, exiting %s", __PRETTY_FUNCTION__);
     return;
   }
 
-  nsNPAPIPluginInstance* pinst = nsNPAPIPluginInstance::FindByJavaSurface((void*)surfaceView);
-  if (!pinst) {
-    LOG("Could not find plugin instance!");
+  if (!init()) {
     return;
   }
-  
-  pinst->UnlockTargetSurface(true /* invalidate the locked area */);
+
+  void* surface = getSurface(env, surfaceView);
+
+  if (!surface) {
+    return;
+  }
+
+  gSurfaceFunctions.unlockAndPost(surface);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-#define ASSIGN(obj, name)   (obj)->name = anp_##name
-
-void InitSurfaceInterface(ANPSurfaceInterfaceV0 *i) {
-
+void InitSurfaceInterface(ANPSurfaceInterfaceV0* i) {
   ASSIGN(i, lock);
   ASSIGN(i, unlock);
 
   // setup the java glue struct
   gSurfaceJavaGlue.initialized = false;
+
+  // setup the function struct
+  gSurfaceFunctions.initialized = false;
 }
--- a/dom/plugins/base/android/ANPSystem.cpp
+++ b/dom/plugins/base/android/ANPSystem.cpp
@@ -47,18 +47,24 @@
 #include "PluginPRLibrary.h"
 
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
 #define ASSIGN(obj, name)   (obj)->name = anp_system_##name
 
 const char*
 anp_system_getApplicationDataDirectory()
 {
-  LOG("getApplicationDataDirectory return /data/data/org.mozilla.%s", MOZ_APP_NAME);
-  return "/data/data/org.mozilla." MOZ_APP_NAME;
+  static char *dir = NULL;
+
+  if (!dir) {
+    dir = getenv("ANDROID_PLUGIN_DATADIR");
+  }
+
+  LOG("getApplicationDataDirectory return %s", dir);
+  return dir;
 }
 
 jclass anp_system_loadJavaClass(NPP instance, const char* className)
 {
   LOG("%s", __PRETTY_FUNCTION__);
 
   JNIEnv* env = GetJNIForThread();
   jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
--- a/dom/plugins/base/android/ANPTypeface.cpp
+++ b/dom/plugins/base/android/ANPTypeface.cpp
@@ -1,158 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Android NPAPI support code
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Doug Turner <dougt@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "assert.h"
-#include "ANPBase.h"
-#include <android/log.h>
-#include "gfxAndroidPlatform.h"
-
-#define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
-#define ASSIGN(obj, name)   (obj)->name = anp_typeface_##name
-
-ANPTypeface*
-anp_typeface_createFromName(const char name[], ANPTypefaceStyle aStyle)
-{
-  LOG("%s - %s\n", __PRETTY_FUNCTION__, name);
-
-  gfxFontStyle style (aStyle == kItalic_ANPTypefaceStyle ? FONT_STYLE_ITALIC :
-                      FONT_STYLE_NORMAL,
-                      NS_FONT_STRETCH_NORMAL,
-                      aStyle == kBold_ANPTypefaceStyle ? 700 : 400,
-                      16.0,
-                      NS_NewPermanentAtom(NS_LITERAL_STRING("en")),
-                      0.0,
-                      false, false,
-                      NS_LITERAL_STRING(""),
-                      NS_LITERAL_STRING(""));
-  ANPTypeface* tf = new ANPTypeface;
-  gfxAndroidPlatform * p = (gfxAndroidPlatform*)gfxPlatform::GetPlatform();
-  nsRefPtr<gfxFont> font = gfxFT2Font::GetOrMakeFont(NS_ConvertASCIItoUTF16(name), &style);
-  font.forget(&tf->mFont);
-  if (tf->mFont) {
-    ++tf->mRefCnt;
-  }
-  return tf;
-}
-
-ANPTypeface*
-anp_typeface_createFromTypeface(const ANPTypeface* family,
-                                ANPTypefaceStyle)
-{
-  NOT_IMPLEMENTED();
-  return 0;
-}
-
-int32_t
-anp_typeface_getRefCount(const ANPTypeface*)
-{
-  NOT_IMPLEMENTED();
-  return 0;
-}
-
-void
-anp_typeface_ref(ANPTypeface* tf)
-{
-  LOG("%s\n", __PRETTY_FUNCTION__);
-  if (tf->mFont)
-    ++tf->mRefCnt;
-
-}
-
-void
-anp_typeface_unref(ANPTypeface* tf)
-{
-  LOG("%s\n", __PRETTY_FUNCTION__);
-  if (tf->mFont)
-    --tf->mRefCnt;
-  if (tf->mRefCnt.get() == 0) {
-    NS_IF_RELEASE(tf->mFont);
-  }
-}
-
-ANPTypefaceStyle
-anp_typeface_getStyle(const ANPTypeface* ft)
-{
-  LOG("%s\n", __PRETTY_FUNCTION__);
-  return kBold_ANPTypefaceStyle;
-}
-
-int32_t
-anp_typeface_getFontPath(const ANPTypeface*, char path[], int32_t length,
-                         int32_t* index)
-{
-  NOT_IMPLEMENTED();
-  return 0;
-}
-
-static const char* gFontDir;
-#define FONT_DIR_SUFFIX     "/fonts/"
-
-const char*
-anp_typeface_getFontDirectoryPath()
-{
-  LOG("%s\n", __PRETTY_FUNCTION__);
-  if (NULL == gFontDir) {
-    const char* root = getenv("ANDROID_ROOT");
-    size_t len = strlen(root);
-    char* storage = (char*)malloc(len + sizeof(FONT_DIR_SUFFIX));
-    if (NULL == storage) {
-      return NULL;
-    }
-    memcpy(storage, root, len);
-    memcpy(storage + len, FONT_DIR_SUFFIX, sizeof(FONT_DIR_SUFFIX));
-    // save this assignment for last, so that if multiple threads call us
-    // (which should never happen), we never return an incomplete global.
-    // At worst, we would allocate storage for the path twice.
-    gFontDir = storage;
-  }
-
-  return 0;
-}
-
-void InitTypeFaceInterface(ANPTypefaceInterfaceV0 *i) {
-  _assert(i->inSize == sizeof(*i));
-  ASSIGN(i, createFromName);
-  ASSIGN(i, createFromTypeface);
-  ASSIGN(i, getRefCount);
-  ASSIGN(i, ref);
-  ASSIGN(i, unref);
-  ASSIGN(i, getStyle);
-  ASSIGN(i, getFontPath);
-  ASSIGN(i, getFontDirectoryPath);
-}
-
--- a/dom/plugins/base/android/Makefile.in
+++ b/dom/plugins/base/android/Makefile.in
@@ -52,30 +52,27 @@ EXPORT_LIBRARY = 1
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 EXPORTS = \
   android_npapi.h \
   $(NULL)
 
 CPPSRCS += ANPAudio.cpp    \
-           ANPCanvas.cpp   \
            ANPEvent.cpp    \
            ANPMatrix.cpp   \
-           ANPPath.cpp     \
            ANPSystem.cpp   \
            ANPWindow.cpp   \
            ANPBitmap.cpp   \
            ANPLog.cpp      \
-           ANPPaint.cpp    \
            ANPSurface.cpp  \
-           ANPTypeface.cpp \
            $(NULL)
 
 LOCAL_INCLUDES += \
   -I$(topsrcdir)/dom/plugins/base \
+  -I$(topsrcdir)/dom/plugins/base/android/include \
   $(MOZ_CAIRO_CFLAGS) \
   $(NULL)
 
 DEFINES += -DMOZ_APP_NAME='"$(MOZ_APP_NAME)"'
 
 include $(topsrcdir)/config/rules.mk
 
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -60,45 +60,40 @@
 #include "nsSize.h"
 #include "nsNetCID.h"
 #include "nsIContent.h"
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "ANPBase.h"
 #include <android/log.h>
 #include "android_npapi.h"
+#include "mozilla/Mutex.h"
 #include "mozilla/CondVar.h"
 #include "AndroidBridge.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::plugins::parent;
 
-#ifdef MOZ_WIDGET_ANDROID
-#include <map>
-static std::map<void*, nsNPAPIPluginInstance*> sSurfaceMap;
-#endif
-
 static NS_DEFINE_IID(kIOutputStreamIID, NS_IOUTPUTSTREAM_IID);
 static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID);
 
 NS_IMPL_THREADSAFE_ISUPPORTS0(nsNPAPIPluginInstance)
 
 nsNPAPIPluginInstance::nsNPAPIPluginInstance(nsNPAPIPlugin* plugin)
   :
 #ifdef XP_MACOSX
 #ifdef NP_NO_QUICKDRAW
     mDrawingModel(NPDrawingModelCoreGraphics),
 #else
     mDrawingModel(NPDrawingModelQuickDraw),
 #endif
 #endif
 #ifdef MOZ_WIDGET_ANDROID
     mSurface(nsnull),
-    mTargetSurface(nsnull),
     mDrawingModel(0),
 #endif
     mRunning(NOT_STARTED),
     mWindowless(false),
     mWindowlessLocal(false),
     mTransparent(false),
     mCached(false),
     mUsesDOMForCursor(false),
@@ -123,47 +118,27 @@ nsNPAPIPluginInstance::nsNPAPIPluginInst
   nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
   if (prefs) {
     bool useLayersPref;
     nsresult rv = prefs->GetBoolPref("plugins.use_layers", &useLayersPref);
     if (NS_SUCCEEDED(rv))
       mUsePluginLayersPref = useLayersPref;
   }
 
-#ifdef MOZ_WIDGET_ANDROID
-  mTargetSurfaceLock = new Mutex("nsNPAPIPluginInstance::SurfaceLock");
-#endif
-
   PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance ctor: this=%p\n",this));
 }
 
 nsNPAPIPluginInstance::~nsNPAPIPluginInstance()
 {
   PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance dtor: this=%p\n",this));
 
   if (mMIMEType) {
     PR_Free((void *)mMIMEType);
     mMIMEType = nsnull;
   }
-
-#ifdef MOZ_WIDGET_ANDROID
-  if (mSurface) {
-    sSurfaceMap.erase(mSurface);
-  }
-
-  if (mTargetSurface) {
-    delete mTargetSurface;
-    mTargetSurface = nsnull;
-  }
-
-  if (mTargetSurfaceLock) {
-    delete mTargetSurfaceLock;
-    mTargetSurfaceLock = nsnull;
-  }
-#endif
 }
 
 void
 nsNPAPIPluginInstance::Destroy()
 {
   Stop();
   mPlugin = nsnull;
 }
@@ -755,117 +730,60 @@ void nsNPAPIPluginInstance::SetEventMode
 }
 #endif
 
 #if defined(MOZ_WIDGET_ANDROID)
 void nsNPAPIPluginInstance::SetDrawingModel(PRUint32 aModel)
 {
   mDrawingModel = aModel;
 }
-
 class SurfaceGetter : public nsRunnable {
 public:
-  SurfaceGetter(NPPluginFuncs* aPluginFunctions, NPP_t aNPP) : 
-    mHaveSurface(false), mPluginFunctions(aPluginFunctions), mNPP(aNPP) {
-    mLock = new Mutex("SurfaceGetter::Lock");
-    mCondVar = new CondVar(*mLock, "SurfaceGetter::CondVar");
-    
+  SurfaceGetter(nsNPAPIPluginInstance* aInstance, NPPluginFuncs* aPluginFunctions, NPP_t aNPP) : 
+    mInstance(aInstance), mPluginFunctions(aPluginFunctions), mNPP(aNPP) {
   }
   ~SurfaceGetter() {
-    delete mLock;
-    delete mCondVar;
   }
   nsresult Run() {
-    MutexAutoLock lock(*mLock);
-    (*mPluginFunctions->getvalue)(&mNPP, kJavaSurface_ANPGetValue, &mSurface);
-    mHaveSurface = true;
-    mCondVar->Notify();
+    void* surface;
+    (*mPluginFunctions->getvalue)(&mNPP, kJavaSurface_ANPGetValue, &surface);
+    mInstance->SetJavaSurface(surface);
     return NS_OK;
   }
-  void* GetSurface() {
-    MutexAutoLock lock(*mLock);
-    mHaveSurface = false;
-    AndroidBridge::Bridge()->PostToJavaThread(this);
-    while (!mHaveSurface)
-      mCondVar->Wait();
-    return mSurface;
+  void RequestSurface() {
+    mozilla::AndroidBridge::Bridge()->PostToJavaThread(this);
   }
 private:
+  nsNPAPIPluginInstance* mInstance;
   NPP_t mNPP;
-  void* mSurface;
-  Mutex* mLock;
-  CondVar* mCondVar;
-  bool mHaveSurface;
   NPPluginFuncs* mPluginFunctions;
 };
 
 
 void* nsNPAPIPluginInstance::GetJavaSurface()
 {
   if (mDrawingModel != kSurface_ANPDrawingModel)
     return nsnull;
   
-  if (mSurface)
-    return mSurface;
-
-  nsCOMPtr<SurfaceGetter> sg = new SurfaceGetter(mPlugin->PluginFuncs(), mNPP);
-  mSurface = sg->GetSurface();
-  sSurfaceMap[mSurface] = this;
   return mSurface;
 }
 
-gfxImageSurface*
-nsNPAPIPluginInstance::LockTargetSurface()
+void nsNPAPIPluginInstance::SetJavaSurface(void* aSurface)
 {
-  mTargetSurfaceLock->Lock();
-  return mTargetSurface;
+  mSurface = aSurface;
 }
 
-gfxImageSurface*
-nsNPAPIPluginInstance::LockTargetSurface(PRUint32 aWidth, PRUint32 aHeight, gfxImageFormat aFormat,
-                                         NPRect* aRect)
+void nsNPAPIPluginInstance::RequestJavaSurface()
 {
-  mTargetSurfaceLock->Lock();
-  if (!mTargetSurface ||
-      mTargetSurface->Width() != aWidth ||
-      mTargetSurface->Height() != aHeight ||
-      mTargetSurface->Format() != aFormat) {
-
-    if (mTargetSurface) {
-      delete mTargetSurface;
-    }
-
-    mTargetSurface = new gfxImageSurface(gfxIntSize(aWidth, aHeight), aFormat);
-  }
-
-  mTargetLockRect = *aRect;
+  if (mSurfaceGetter.get())
+    return;
 
-  return mTargetSurface;
-}
-
-void
-nsNPAPIPluginInstance::InvalidateTargetRect()
-{
-    InvalidateRect(&mTargetLockRect);
-}
+  mSurfaceGetter = new SurfaceGetter(this, mPlugin->PluginFuncs(), mNPP);
 
-void
-nsNPAPIPluginInstance::UnlockTargetSurface(bool aInvalidate)
-{
-  mTargetSurfaceLock->Unlock();
-
-  if (aInvalidate) {
-    NS_DispatchToMainThread(NS_NewRunnableMethod(this, &nsNPAPIPluginInstance::InvalidateTargetRect));
-  }
-}
-
-nsNPAPIPluginInstance*
-nsNPAPIPluginInstance::FindByJavaSurface(void* aJavaSurface)
-{
-  return sSurfaceMap[aJavaSurface];
+  ((SurfaceGetter*)mSurfaceGetter.get())->RequestSurface();
 }
 
 #endif
 
 nsresult nsNPAPIPluginInstance::GetDrawingModel(PRInt32* aModel)
 {
 #if defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID)
   *aModel = (PRInt32)mDrawingModel;
--- a/dom/plugins/base/nsNPAPIPluginInstance.h
+++ b/dom/plugins/base/nsNPAPIPluginInstance.h
@@ -44,27 +44,23 @@
 #include "nsTArray.h"
 #include "nsPIDOMWindow.h"
 #include "nsITimer.h"
 #include "nsIPluginTagInfo.h"
 #include "nsIURI.h"
 #include "nsIChannel.h"
 #include "nsInterfaceHashtable.h"
 #include "nsHashKeys.h"
-
-#include "gfxASurface.h"
-#include "gfxImageSurface.h"
+#ifdef MOZ_WIDGET_ANDROID
+#include "nsIRunnable.h"
+#endif
 
 #include "mozilla/TimeStamp.h"
 #include "mozilla/PluginLibrary.h"
 
-#ifdef ANDROID
-#include "mozilla/Mutex.h"
-#endif
-
 struct JSObject;
 
 class nsPluginStreamListenerPeer; // browser-initiated stream class
 class nsNPAPIPluginStreamListener; // plugin-initiated stream class
 class nsIPluginInstanceOwner;
 class nsIPluginStreamListener;
 class nsIOutputStream;
 
@@ -151,23 +147,18 @@ public:
 #ifdef XP_MACOSX
   void SetDrawingModel(NPDrawingModel aModel);
   void SetEventModel(NPEventModel aModel);
 #endif
 
 #ifdef MOZ_WIDGET_ANDROID
   void SetDrawingModel(PRUint32 aModel);
   void* GetJavaSurface();
-
-  gfxImageSurface* LockTargetSurface();
-  gfxImageSurface* LockTargetSurface(PRUint32 aWidth, PRUint32 aHeight, gfxASurface::gfxImageFormat aFormat,
-                                     NPRect* aRect);
-  void UnlockTargetSurface(bool aInvalidate);
-
-  static nsNPAPIPluginInstance* FindByJavaSurface(void* aJavaSurface);
+  void SetJavaSurface(void* aSurface);
+  void RequestJavaSurface();
 #endif
 
   nsresult NewStreamListener(const char* aURL, void* notifyData,
                              nsIPluginStreamListener** listener);
 
   nsNPAPIPluginInstance(nsNPAPIPlugin* plugin);
   virtual ~nsNPAPIPluginInstance();
 
@@ -234,16 +225,17 @@ protected:
   NPP_t mNPP;
 
 #ifdef XP_MACOSX
   NPDrawingModel mDrawingModel;
 #endif
 
 #ifdef MOZ_WIDGET_ANDROID
   PRUint32 mDrawingModel;
+  nsCOMPtr<nsIRunnable> mSurfaceGetter;
 #endif
 
   enum {
     NOT_STARTED,
     RUNNING,
     DESTROYING,
     DESTROYED
   } mRunning;
@@ -285,18 +277,13 @@ private:
   // Timestamp for the last time this plugin was stopped.
   // This is only valid when the plugin is actually stopped!
   mozilla::TimeStamp mStopTime;
 
   nsCOMPtr<nsIURI> mURI;
 
   bool mUsePluginLayersPref;
 #ifdef MOZ_WIDGET_ANDROID
-  void InvalidateTargetRect();
-  
   void* mSurface;
-  gfxImageSurface *mTargetSurface;
-  mozilla::Mutex* mTargetSurfaceLock;
-  NPRect mTargetLockRect;
 #endif
 };
 
 #endif // nsNPAPIPluginInstance_h_
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -326,16 +326,21 @@ nsPluginInstanceOwner::nsPluginInstanceO
 #ifndef NP_NO_QUICKDRAW
   mEventModel = NPEventModelCarbon;
 #else
   mEventModel = NPEventModelCocoa;
 #endif
 #endif
 
   mWaitingForPaint = false;
+
+#ifdef MOZ_WIDGET_ANDROID
+  mPluginViewAdded = false;
+  mLastPluginRect = gfxRect(0, 0, 0, 0);
+#endif
 }
 
 nsPluginInstanceOwner::~nsPluginInstanceOwner()
 {
   PRInt32 cnt;
 
   if (mWaitingForPaint) {
     // We don't care when the event is dispatched as long as it's "soon",
@@ -1668,49 +1673,82 @@ void nsPluginInstanceOwner::ScrollPositi
       }
       pluginWidget->EndDrawPlugin();
     }
   }
 #endif
 }
 
 #ifdef MOZ_WIDGET_ANDROID
-void nsPluginInstanceOwner::AddPluginView(const gfxRect& aRect)
+bool nsPluginInstanceOwner::AddPluginView(const gfxRect& aRect)
 {
+  AndroidBridge::AutoLocalJNIFrame frame(1);
+
   void* javaSurface = mInstance->GetJavaSurface();
-
-  if (!javaSurface)
-    return;
+  if (!javaSurface) {
+    mInstance->RequestJavaSurface();
+    return false;
+  }
+
+  if (aRect.IsEqualEdges(mLastPluginRect)) {
+    // Already added and in position, no work to do
+    return true;
+  }
 
   JNIEnv* env = GetJNIForThread();
   jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
   jmethodID method = env->GetStaticMethodID(cls,
                                             "addPluginView",
                                             "(Landroid/view/View;DDDD)V");
+
   env->CallStaticVoidMethod(cls,
                             method,
                             javaSurface,
                             aRect.x,
                             aRect.y,
                             aRect.width,
                             aRect.height);
+
+  if (!mPluginViewAdded) {
+    ANPEvent event;
+    event.inSize = sizeof(ANPEvent);
+    event.eventType = kLifecycle_ANPEventType;
+    event.data.lifecycle.action = kOnScreen_ANPLifecycleAction;
+    mInstance->HandleEvent(&event, nsnull);
+
+    mPluginViewAdded = true;
+  }
+
+  return true;
 }
 
 void nsPluginInstanceOwner::RemovePluginView()
 {
-  if (mInstance && mObjectFrame) {
+  AndroidBridge::AutoLocalJNIFrame frame(1);
+
+  if (mInstance && mObjectFrame && mPluginViewAdded) {
+    mPluginViewAdded = false;
+
     void* surface = mInstance->GetJavaSurface();
     if (surface) {
       JNIEnv* env = GetJNIForThread();
       if (env) {
         jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
         jmethodID method = env->GetStaticMethodID(cls,
                                                   "removePluginView",
                                                   "(Landroid/view/View;)V");
         env->CallStaticVoidMethod(cls, method, surface);
+
+        {
+          ANPEvent event;
+          event.inSize = sizeof(ANPEvent);
+          event.eventType = kLifecycle_ANPEventType;
+          event.data.lifecycle.action = kOffScreen_ANPLifecycleAction;
+          mInstance->HandleEvent(&event, nsnull);
+        }
       }
     }
   }
 }
 #endif
 
 nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent)
 {
@@ -2841,30 +2879,23 @@ void nsPluginInstanceOwner::Paint(gfxCon
 {
   if (!mInstance || !mObjectFrame)
     return;
 
   PRInt32 model;
   mInstance->GetDrawingModel(&model);
 
   if (model == kSurface_ANPDrawingModel) {
-    AddPluginView(aFrameRect);
-
-    gfxImageSurface* pluginSurface = mInstance->LockTargetSurface();
-    if (!pluginSurface) {
-      mInstance->UnlockTargetSurface(false);
-      return;
+    if (!AddPluginView(aFrameRect)) {
+      NPRect rect;
+      rect.left = rect.top = 0;
+      rect.right = aFrameRect.width;
+      rect.bottom = aFrameRect.height;
+      InvalidateRect(&rect);
     }
-
-    aContext->SetOperator(gfxContext::OPERATOR_SOURCE);
-    aContext->SetSource(pluginSurface, gfxPoint(aFrameRect.x, aFrameRect.y));
-    aContext->Clip(aDirtyRect);
-    aContext->Paint();
-
-    mInstance->UnlockTargetSurface(false);
     return;
   }
 
   if (model != kBitmap_ANPDrawingModel)
     return;
 
 #ifdef ANP_BITMAP_DRAWING_MODEL
   static nsRefPtr<gfxImageSurface> pluginSurface;
@@ -3551,36 +3582,20 @@ void nsPluginInstanceOwner::UpdateWindow
   mPluginWindow->y = origin.y;
 
   mPluginWindow->clipRect.left = 0;
   mPluginWindow->clipRect.top = 0;
 
   if (mPluginWindowVisible && mPluginDocumentActiveState) {
     mPluginWindow->clipRect.right = mPluginWindow->width;
     mPluginWindow->clipRect.bottom = mPluginWindow->height;
-#ifdef MOZ_WIDGET_ANDROID
-    if (mInstance) {
-      ANPEvent event;
-      event.inSize = sizeof(ANPEvent);
-      event.eventType = kLifecycle_ANPEventType;
-      event.data.lifecycle.action = kOnScreen_ANPLifecycleAction;
-      mInstance->HandleEvent(&event, nsnull);
-    }
-#endif
   } else {
     mPluginWindow->clipRect.right = 0;
     mPluginWindow->clipRect.bottom = 0;
 #ifdef MOZ_WIDGET_ANDROID
-    if (mInstance) {
-      ANPEvent event;
-      event.inSize = sizeof(ANPEvent);
-      event.eventType = kLifecycle_ANPEventType;
-      event.data.lifecycle.action = kOffScreen_ANPLifecycleAction;
-      mInstance->HandleEvent(&event, nsnull);
-    }
     RemovePluginView();
 #endif
   }
 
   if (!aSetWindow)
     return;
 
   if (mPluginWindow->x               != oldWindow.x               ||
--- a/dom/plugins/base/nsPluginInstanceOwner.h
+++ b/dom/plugins/base/nsPluginInstanceOwner.h
@@ -305,18 +305,20 @@ private:
   {
     nsIntSize size;
     return NS_SUCCEEDED(mInstance->GetImageSize(&size)) &&
     size == nsIntSize(mPluginWindow->width, mPluginWindow->height);
   }
   
   void FixUpURLS(const nsString &name, nsAString &value);
 #ifdef ANDROID
-  void AddPluginView(const gfxRect& aRect);
+  bool AddPluginView(const gfxRect& aRect);
   void RemovePluginView();
+  bool mPluginViewAdded;
+  gfxRect mLastPluginRect;
 #endif 
  
   nsPluginNativeWindow       *mPluginWindow;
   nsRefPtr<nsNPAPIPluginInstance> mInstance;
   nsObjectFrame              *mObjectFrame; // owns nsPluginInstanceOwner
   nsCOMPtr<nsIContent>        mContent;
   nsCString                   mDocumentBase;
   char                       *mTagText;
new file mode 100644
--- /dev/null
+++ b/other-licenses/skia-npapi/ANPCanvas.cpp
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2008, 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.
+ */
+
+// must include config.h first for webkit to fiddle with new/delete
+#include "SkANP.h"
+
+static ANPCanvas* anp_newCanvas(const ANPBitmap* bitmap) {
+    SkBitmap bm;
+    return new ANPCanvas(*SkANP::SetBitmap(&bm, *bitmap));
+}
+
+static void anp_deleteCanvas(ANPCanvas* canvas) {
+    delete canvas;
+}
+
+static void anp_save(ANPCanvas* canvas) {
+    canvas->skcanvas->save();
+}
+
+static void anp_restore(ANPCanvas* canvas) {
+    canvas->skcanvas->restore();
+}
+
+static void anp_translate(ANPCanvas* canvas, float tx, float ty) {
+    canvas->skcanvas->translate(SkFloatToScalar(tx), SkFloatToScalar(ty));
+}
+
+static void anp_scale(ANPCanvas* canvas, float sx, float sy) {
+    canvas->skcanvas->scale(SkFloatToScalar(sx), SkFloatToScalar(sy));
+}
+
+static void anp_rotate(ANPCanvas* canvas, float degrees) {
+    canvas->skcanvas->rotate(SkFloatToScalar(degrees));
+}
+
+static void anp_skew(ANPCanvas* canvas, float kx, float ky) {
+    canvas->skcanvas->skew(SkFloatToScalar(kx), SkFloatToScalar(ky));
+}
+
+static void anp_clipRect(ANPCanvas* canvas, const ANPRectF* rect) {
+    SkRect r;
+    canvas->skcanvas->clipRect(*SkANP::SetRect(&r, *rect));
+}
+
+static void anp_clipPath(ANPCanvas* canvas, const ANPPath* path) {
+    canvas->skcanvas->clipPath(*path);
+}
+static void anp_concat(ANPCanvas* canvas, const ANPMatrix* matrix) {
+    canvas->skcanvas->concat(*matrix);
+}
+
+static void anp_getTotalMatrix(ANPCanvas* canvas, ANPMatrix* matrix) {
+    const SkMatrix& src = canvas->skcanvas->getTotalMatrix();
+    *matrix = *reinterpret_cast<const ANPMatrix*>(&src);
+}
+
+static bool anp_getLocalClipBounds(ANPCanvas* canvas, ANPRectF* r,
+                                   bool antialias) {
+    SkRect bounds;
+    if (canvas->skcanvas->getClipBounds(&bounds,
+                antialias ? SkCanvas::kAA_EdgeType : SkCanvas::kBW_EdgeType)) {
+        SkANP::SetRect(r, bounds);
+        return true;
+    }
+    return false;
+}
+
+static bool anp_getDeviceClipBounds(ANPCanvas* canvas, ANPRectI* r) {
+    const SkRegion& clip = canvas->skcanvas->getTotalClip();
+    if (!clip.isEmpty()) {
+        SkANP::SetRect(r, clip.getBounds());
+        return true;
+    }
+    return false;
+}
+
+static void anp_drawColor(ANPCanvas* canvas, ANPColor color) {
+    canvas->skcanvas->drawColor(color);
+}
+
+static void anp_drawPaint(ANPCanvas* canvas, const ANPPaint* paint) {
+    canvas->skcanvas->drawPaint(*paint);
+}
+
+static void anp_drawLine(ANPCanvas* canvas, float x0, float y0,
+                         float x1, float y1, const ANPPaint* paint) {
+    canvas->skcanvas->drawLine(SkFloatToScalar(x0), SkFloatToScalar(y0),
+                           SkFloatToScalar(x1), SkFloatToScalar(y1), *paint);
+}
+
+static void anp_drawRect(ANPCanvas* canvas, const ANPRectF* rect,
+                         const ANPPaint* paint) {
+    SkRect  r;
+    canvas->skcanvas->drawRect(*SkANP::SetRect(&r, *rect), *paint);
+}
+
+static void anp_drawOval(ANPCanvas* canvas, const ANPRectF* rect,
+                         const ANPPaint* paint) {
+    SkRect  r;
+    canvas->skcanvas->drawOval(*SkANP::SetRect(&r, *rect), *paint);
+}
+
+static void anp_drawPath(ANPCanvas* canvas, const ANPPath* path,
+                         const ANPPaint* paint) {
+    canvas->skcanvas->drawPath(*path, *paint);
+}
+
+static void anp_drawText(ANPCanvas* canvas, const void* text, uint32_t length,
+                         float x, float y, const ANPPaint* paint) {
+    canvas->skcanvas->drawText(text, length,
+                               SkFloatToScalar(x), SkFloatToScalar(y),
+                               *paint);
+}
+
+static void anp_drawPosText(ANPCanvas* canvas, const void* text,
+                uint32_t byteLength, const float xy[], const ANPPaint* paint) {
+    canvas->skcanvas->drawPosText(text, byteLength,
+                                  reinterpret_cast<const SkPoint*>(xy), *paint);
+}
+
+static void anp_drawBitmap(ANPCanvas* canvas, const ANPBitmap* bitmap,
+                           float x, float y, const ANPPaint* paint) {
+    SkBitmap    bm;
+    canvas->skcanvas->drawBitmap(*SkANP::SetBitmap(&bm, *bitmap),
+                                 SkFloatToScalar(x), SkFloatToScalar(y),
+                                 paint);
+}
+
+static void anp_drawBitmapRect(ANPCanvas* canvas, const ANPBitmap* bitmap,
+                              const ANPRectI* src, const ANPRectF* dst,
+                               const ANPPaint* paint) {
+    SkBitmap    bm;
+    SkRect      dstR;
+    SkIRect     srcR, *srcPtr = NULL;
+
+    if (src) {
+        srcPtr = SkANP::SetRect(&srcR, *src);
+    }
+    canvas->skcanvas->drawBitmapRect(*SkANP::SetBitmap(&bm, *bitmap), srcPtr,
+                           *SkANP::SetRect(&dstR, *dst), paint);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define ASSIGN(obj, name)   (obj)->name = anp_##name
+
+void InitCanvasInterface(ANPCanvasInterfaceV0* i) {
+    ASSIGN(i, newCanvas);
+    ASSIGN(i, deleteCanvas);
+    ASSIGN(i, save);
+    ASSIGN(i, restore);
+    ASSIGN(i, translate);
+    ASSIGN(i, scale);
+    ASSIGN(i, rotate);
+    ASSIGN(i, skew);
+    ASSIGN(i, clipRect);
+    ASSIGN(i, clipPath);
+    ASSIGN(i, concat);
+    ASSIGN(i, getTotalMatrix);
+    ASSIGN(i, getLocalClipBounds);
+    ASSIGN(i, getDeviceClipBounds);
+    ASSIGN(i, drawColor);
+    ASSIGN(i, drawPaint);
+    ASSIGN(i, drawLine);
+    ASSIGN(i, drawRect);
+    ASSIGN(i, drawOval);
+    ASSIGN(i, drawPath);
+    ASSIGN(i, drawText);
+    ASSIGN(i, drawPosText);
+    ASSIGN(i, drawBitmap);
+    ASSIGN(i, drawBitmapRect);
+}
new file mode 100644
--- /dev/null
+++ b/other-licenses/skia-npapi/ANPPaint.cpp
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2008, 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.
+ */
+
+// must include config.h first for webkit to fiddle with new/delete
+#include "SkANP.h"
+#include "SkTypeface.h"
+
+static ANPPaint* anp_newPaint() {
+    return new ANPPaint;
+}
+
+static void anp_deletePaint(ANPPaint* paint) {
+    delete paint;
+}
+
+static ANPPaintFlags anp_getFlags(const ANPPaint* paint) {
+    return paint->getFlags();
+}
+
+static void anp_setFlags(ANPPaint* paint, ANPPaintFlags flags) {
+    paint->setFlags(flags);
+}
+
+static ANPColor anp_getColor(const ANPPaint* paint) {
+    return paint->getColor();
+}
+
+static void anp_setColor(ANPPaint* paint, ANPColor color) {
+    paint->setColor(color);
+}
+
+static ANPPaintStyle anp_getStyle(const ANPPaint* paint) {
+    return paint->getStyle();
+}
+
+static void anp_setStyle(ANPPaint* paint, ANPPaintStyle style) {
+    paint->setStyle(static_cast<SkPaint::Style>(style));
+}
+
+static float anp_getStrokeWidth(const ANPPaint* paint) {
+    return SkScalarToFloat(paint->getStrokeWidth());
+}
+
+static float anp_getStrokeMiter(const ANPPaint* paint) {
+    return SkScalarToFloat(paint->getStrokeMiter());
+}
+
+static ANPPaintCap anp_getStrokeCap(const ANPPaint* paint) {
+    return paint->getStrokeCap();
+}
+
+static ANPPaintJoin anp_getStrokeJoin(const ANPPaint* paint) {
+    return paint->getStrokeJoin();
+}
+
+static void anp_setStrokeWidth(ANPPaint* paint, float width) {
+    paint->setStrokeWidth(SkFloatToScalar(width));
+}
+
+static void anp_setStrokeMiter(ANPPaint* paint, float miter) {
+    paint->setStrokeMiter(SkFloatToScalar(miter));
+}
+
+static void anp_setStrokeCap(ANPPaint* paint, ANPPaintCap cap) {
+    paint->setStrokeCap(static_cast<SkPaint::Cap>(cap));
+}
+
+static void anp_setStrokeJoin(ANPPaint* paint, ANPPaintJoin join) {
+    paint->setStrokeJoin(static_cast<SkPaint::Join>(join));
+}
+
+static ANPTextEncoding anp_getTextEncoding(const ANPPaint* paint) {
+    return paint->getTextEncoding();
+}
+
+static ANPPaintAlign anp_getTextAlign(const ANPPaint* paint) {
+    return paint->getTextAlign();
+}
+
+static float anp_getTextSize(const ANPPaint* paint) {
+    return SkScalarToFloat(paint->getTextSize());
+}
+
+static float anp_getTextScaleX(const ANPPaint* paint) {
+    return SkScalarToFloat(paint->getTextScaleX());
+}
+
+static float anp_getTextSkewX(const ANPPaint* paint) {
+    return SkScalarToFloat(paint->getTextSkewX());
+}
+
+static ANPTypeface* anp_getTypeface(const ANPPaint* paint) {
+    return reinterpret_cast<ANPTypeface*>(paint->getTypeface());
+}
+
+static void anp_setTextEncoding(ANPPaint* paint, ANPTextEncoding encoding) {
+    paint->setTextEncoding(static_cast<SkPaint::TextEncoding>(encoding));
+}
+
+static void anp_setTextAlign(ANPPaint* paint, ANPPaintAlign align) {
+    paint->setTextAlign(static_cast<SkPaint::Align>(align));
+}
+
+static void anp_setTextSize(ANPPaint* paint, float textSize) {
+    paint->setTextSize(SkFloatToScalar(textSize));
+}
+
+static void anp_setTextScaleX(ANPPaint* paint, float scaleX) {
+    paint->setTextScaleX(SkFloatToScalar(scaleX));
+}
+
+static void anp_setTextSkewX(ANPPaint* paint, float skewX) {
+    paint->setTextSkewX(SkFloatToScalar(skewX));
+}
+
+static void anp_setTypeface(ANPPaint* paint, ANPTypeface* tf) {
+    paint->setTypeface(tf);
+}
+
+static float anp_measureText(ANPPaint* paint, const void* text,
+                             uint32_t byteLength, ANPRectF* bounds) {
+    SkScalar w = paint->measureText(text, byteLength,
+                                    reinterpret_cast<SkRect*>(bounds));
+    return SkScalarToFloat(w);
+}
+
+/** Return the number of unichars specifed by the text.
+ If widths is not null, returns the array of advance widths for each
+ unichar.
+ If bounds is not null, returns the array of bounds for each unichar.
+ */
+static int anp_getTextWidths(ANPPaint* paint, const void* text,
+                       uint32_t byteLength, float widths[], ANPRectF bounds[]) {
+    return paint->getTextWidths(text, byteLength, widths,
+                                reinterpret_cast<SkRect*>(bounds));
+}
+
+static float anp_getFontMetrics(ANPPaint* paint, ANPFontMetrics* metrics) {
+    SkPaint::FontMetrics fm;
+    SkScalar spacing = paint->getFontMetrics(&fm);
+    if (metrics) {
+        metrics->fTop = SkScalarToFloat(fm.fTop);
+        metrics->fAscent = SkScalarToFloat(fm.fAscent);
+        metrics->fDescent = SkScalarToFloat(fm.fDescent);
+        metrics->fBottom = SkScalarToFloat(fm.fBottom);
+        metrics->fLeading = SkScalarToFloat(fm.fLeading);
+    }
+    return SkScalarToFloat(spacing);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define ASSIGN(obj, name)   (obj)->name = anp_##name
+
+void InitPaintInterface(ANPPaintInterfaceV0* i) {
+    ASSIGN(i, newPaint);
+    ASSIGN(i, deletePaint);
+    ASSIGN(i, getFlags);
+    ASSIGN(i, setFlags);
+    ASSIGN(i, getColor);
+    ASSIGN(i, setColor);
+    ASSIGN(i, getStyle);
+    ASSIGN(i, setStyle);
+    ASSIGN(i, getStrokeWidth);
+    ASSIGN(i, getStrokeMiter);
+    ASSIGN(i, getStrokeCap);
+    ASSIGN(i, getStrokeJoin);
+    ASSIGN(i, setStrokeWidth);
+    ASSIGN(i, setStrokeMiter);
+    ASSIGN(i, setStrokeCap);
+    ASSIGN(i, setStrokeJoin);
+    ASSIGN(i, getTextEncoding);
+    ASSIGN(i, getTextAlign);
+    ASSIGN(i, getTextSize);
+    ASSIGN(i, getTextScaleX);
+    ASSIGN(i, getTextSkewX);
+    ASSIGN(i, getTypeface);
+    ASSIGN(i, setTextEncoding);
+    ASSIGN(i, setTextAlign);
+    ASSIGN(i, setTextSize);
+    ASSIGN(i, setTextScaleX);
+    ASSIGN(i, setTextSkewX);
+    ASSIGN(i, setTypeface);
+    ASSIGN(i, measureText);
+    ASSIGN(i, getTextWidths);
+    ASSIGN(i, getFontMetrics);
+}
new file mode 100644
--- /dev/null
+++ b/other-licenses/skia-npapi/ANPPath.cpp
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+// must include config.h first for webkit to fiddle with new/delete
+#include "SkANP.h"
+
+static ANPPath* anp_newPath() {
+    return new ANPPath;
+}
+
+static void anp_deletePath(ANPPath* path) {
+    delete path;
+}
+
+static void anp_copy(ANPPath* dst, const ANPPath* src) {
+    *dst = *src;
+}
+
+static bool anp_equal(const ANPPath* p0, const ANPPath* p1) {
+    return *p0 == *p1;
+}
+
+static void anp_reset(ANPPath* path) {
+    path->reset();
+}
+
+static bool anp_isEmpty(const ANPPath* path) {
+    return path->isEmpty();
+}
+
+static void anp_getBounds(const ANPPath* path, ANPRectF* bounds) {
+    SkANP::SetRect(bounds, path->getBounds());
+}
+
+static void anp_moveTo(ANPPath* path, float x, float y) {
+    path->moveTo(SkFloatToScalar(x), SkFloatToScalar(y));
+}
+
+static void anp_lineTo(ANPPath* path, float x, float y) {
+    path->lineTo(SkFloatToScalar(x), SkFloatToScalar(y));
+}
+
+static void anp_quadTo(ANPPath* path, float x0, float y0, float x1, float y1) {
+    path->quadTo(SkFloatToScalar(x0), SkFloatToScalar(y0),
+                 SkFloatToScalar(x1), SkFloatToScalar(y1));
+}
+
+static void anp_cubicTo(ANPPath* path, float x0, float y0,
+                        float x1, float y1, float x2, float y2) {
+    path->cubicTo(SkFloatToScalar(x0), SkFloatToScalar(y0),
+                  SkFloatToScalar(x1), SkFloatToScalar(y1),
+                  SkFloatToScalar(x2), SkFloatToScalar(y2));
+}
+
+static void anp_close(ANPPath* path) {
+    path->close();
+}
+
+static void anp_offset(ANPPath* path, float dx, float dy, ANPPath* dst) {
+    path->offset(SkFloatToScalar(dx), SkFloatToScalar(dy), dst);
+}
+
+static void anp_transform(ANPPath* src, const ANPMatrix* matrix,
+                          ANPPath* dst) {
+    src->transform(*matrix, dst);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define ASSIGN(obj, name)   (obj)->name = anp_##name
+
+void InitPathInterface(ANPPathInterfaceV0* i) {
+    ASSIGN(i, newPath);
+    ASSIGN(i, deletePath);
+    ASSIGN(i, copy);
+    ASSIGN(i, equal);
+    ASSIGN(i, reset);
+    ASSIGN(i, isEmpty);
+    ASSIGN(i, getBounds);
+    ASSIGN(i, moveTo);
+    ASSIGN(i, lineTo);
+    ASSIGN(i, quadTo);
+    ASSIGN(i, cubicTo);
+    ASSIGN(i, close);
+    ASSIGN(i, offset);
+    ASSIGN(i, transform);
+}
new file mode 100644
--- /dev/null
+++ b/other-licenses/skia-npapi/ANPTypeface.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2008, 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.
+ */
+
+// must include config.h first for webkit to fiddle with new/delete
+#include "SkANP.h"
+#include "SkFontHost.h"
+
+static ANPTypeface* anp_createFromName(const char name[], ANPTypefaceStyle s) {
+    SkTypeface* tf = SkTypeface::CreateFromName(name,
+                                        static_cast<SkTypeface::Style>(s));
+    return reinterpret_cast<ANPTypeface*>(tf);
+}
+
+static ANPTypeface* anp_createFromTypeface(const ANPTypeface* family,
+                                           ANPTypefaceStyle s) {
+    SkTypeface* tf = SkTypeface::CreateFromTypeface(family,
+                                          static_cast<SkTypeface::Style>(s));
+    return reinterpret_cast<ANPTypeface*>(tf);
+}
+
+static int32_t anp_getRefCount(const ANPTypeface* tf) {
+    return tf ? tf->getRefCnt() : 0;
+}
+
+static void anp_ref(ANPTypeface* tf) {
+    SkSafeRef(tf);
+}
+
+static void anp_unref(ANPTypeface* tf) {
+    SkSafeUnref(tf);
+}
+
+static ANPTypefaceStyle anp_getStyle(const ANPTypeface* tf) {
+    SkTypeface::Style s = tf ? tf->style() : SkTypeface::kNormal;
+    return static_cast<ANPTypefaceStyle>(s);
+}
+
+static int32_t anp_getFontPath(const ANPTypeface* tf, char fileName[],
+                               int32_t length, int32_t* index) {
+    size_t size = SkFontHost::GetFileName(SkTypeface::UniqueID(tf), fileName,
+                                          length, index);
+    return static_cast<int32_t>(size);
+}
+
+static const char* gFontDir;
+#define FONT_DIR_SUFFIX     "/fonts/"
+
+static const char* anp_getFontDirectoryPath() {
+    if (NULL == gFontDir) {
+        const char* root = getenv("ANDROID_ROOT");
+        size_t len = strlen(root);
+        char* storage = (char*)malloc(len + sizeof(FONT_DIR_SUFFIX));
+        if (NULL == storage) {
+            return NULL;
+        }
+        memcpy(storage, root, len);
+        memcpy(storage + len, FONT_DIR_SUFFIX, sizeof(FONT_DIR_SUFFIX));
+        // save this assignment for last, so that if multiple threads call us
+        // (which should never happen), we never return an incomplete global.
+        // At worst, we would allocate storage for the path twice.
+        gFontDir = storage;
+    }
+    return gFontDir;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define ASSIGN(obj, name)   (obj)->name = anp_##name
+
+void InitTypeFaceInterface(ANPTypefaceInterfaceV0* i) {
+    ASSIGN(i, createFromName);
+    ASSIGN(i, createFromTypeface);
+    ASSIGN(i, getRefCount);
+    ASSIGN(i, ref);
+    ASSIGN(i, unref);
+    ASSIGN(i, getStyle);
+    ASSIGN(i, getFontPath);
+    ASSIGN(i, getFontDirectoryPath);
+}
new file mode 100644
--- /dev/null
+++ b/other-licenses/skia-npapi/Makefile.in
@@ -0,0 +1,72 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (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.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Mozilla browser.
+#
+# The Initial Developer of the Original Code is
+#   Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2010
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   James Willcox <jwillcox@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE           = skia_npapi
+LIBRARY_NAME     = skia_npapi
+LIBXUL_LIBRARY   = 1
+EXPORT_LIBRARY   = 1
+
+DEFINES += \
+  -DSK_BUILD_FOR_ANDROID_NDK \
+  $(NULL)
+
+LOCAL_INCLUDES += \
+  -I$(topsrcdir)/dom/plugins/base \
+  -I$(topsrcdir)/dom/plugins/base/android \
+  -I$(topsrcdir)/gfx/skia/include/core \
+  -I$(topsrcdir)/gfx/skia/include/config \
+  $(NULL)
+
+
+CPPSRCS = \
+  SkANP.cpp \
+  ANPCanvas.cpp \
+  ANPPaint.cpp \
+  ANPPath.cpp \
+  ANPTypeface.cpp \
+  $(NULL)
+
+EXPORTS = SkANP.h
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/other-licenses/skia-npapi/SkANP.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2008, 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.
+ */
+
+// must include config.h first for webkit to fiddle with new/delete
+#include "SkANP.h"
+
+SkRect* SkANP::SetRect(SkRect* dst, const ANPRectF& src) {
+    dst->set(SkFloatToScalar(src.left),
+             SkFloatToScalar(src.top),
+             SkFloatToScalar(src.right),
+             SkFloatToScalar(src.bottom));
+    return dst;
+}
+
+SkIRect* SkANP::SetRect(SkIRect* dst, const ANPRectI& src) {
+    dst->set(src.left, src.top, src.right, src.bottom);
+    return dst;
+}
+
+ANPRectI* SkANP::SetRect(ANPRectI* dst, const SkIRect& src) {
+    dst->left = src.fLeft;
+    dst->top = src.fTop;
+    dst->right = src.fRight;
+    dst->bottom = src.fBottom;
+    return dst;
+}
+
+ANPRectF* SkANP::SetRect(ANPRectF* dst, const SkRect& src) {
+    dst->left = SkScalarToFloat(src.fLeft);
+    dst->top = SkScalarToFloat(src.fTop);
+    dst->right = SkScalarToFloat(src.fRight);
+    dst->bottom = SkScalarToFloat(src.fBottom);
+    return dst;
+}
+
+SkBitmap* SkANP::SetBitmap(SkBitmap* dst, const ANPBitmap& src) {
+    SkBitmap::Config config = SkBitmap::kNo_Config;
+    
+    switch (src.format) {
+        case kRGBA_8888_ANPBitmapFormat:
+            config = SkBitmap::kARGB_8888_Config;
+            break;
+        case kRGB_565_ANPBitmapFormat:
+            config = SkBitmap::kRGB_565_Config;
+            break;
+        default:
+            break;
+    }
+    
+    dst->setConfig(config, src.width, src.height, src.rowBytes);
+    dst->setPixels(src.baseAddr);
+    return dst;
+}
+
+bool SkANP::SetBitmap(ANPBitmap* dst, const SkBitmap& src) {
+    if (!(dst->baseAddr = src.getPixels())) {
+        SkDebugf("SkANP::SetBitmap - getPixels() returned null\n");
+        return false;
+    }
+
+    switch (src.config()) {
+        case SkBitmap::kARGB_8888_Config:
+            dst->format = kRGBA_8888_ANPBitmapFormat;
+            break;
+        case SkBitmap::kRGB_565_Config:
+            dst->format = kRGB_565_ANPBitmapFormat;
+            break;
+        default:
+            SkDebugf("SkANP::SetBitmap - unsupported src.config %d\n", src.config());
+            return false;
+    }
+    
+    dst->width    = src.width();
+    dst->height   = src.height();
+    dst->rowBytes = src.rowBytes();
+    return true;
+}
+
+void SkANP::InitEvent(ANPEvent* event, ANPEventType et) {
+    event->inSize = sizeof(ANPEvent);
+    event->eventType = et;
+}
new file mode 100644
--- /dev/null
+++ b/other-licenses/skia-npapi/SkANP.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2008, 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 SkANP_DEFINED
+#define SkANP_DEFINED
+
+#include "android_npapi.h"
+#include "SkCanvas.h"
+#include "SkMatrix.h"
+#include "SkPaint.h"
+#include "SkPath.h"
+#include "SkTypeface.h"
+
+struct ANPMatrix : SkMatrix {
+};
+
+struct ANPPath : SkPath {
+};
+
+struct ANPPaint : SkPaint {
+};
+
+struct ANPTypeface : SkTypeface {
+};
+
+struct ANPCanvas {
+    SkCanvas* skcanvas;
+
+    // draw into the specified bitmap
+    explicit ANPCanvas(const SkBitmap& bm) {
+        skcanvas = new SkCanvas(bm);
+    }
+
+    // redirect all drawing to the specific SkCanvas
+    explicit ANPCanvas(SkCanvas* other) {
+        skcanvas = other;
+        skcanvas->ref();
+    }
+
+    ~ANPCanvas() {
+        skcanvas->unref();
+    }
+};
+
+class SkANP {
+public:
+    static SkRect* SetRect(SkRect* dst, const ANPRectF& src);
+    static SkIRect* SetRect(SkIRect* dst, const ANPRectI& src);
+    static ANPRectI* SetRect(ANPRectI* dst, const SkIRect& src);
+    static ANPRectF* SetRect(ANPRectF* dst, const SkRect& src);
+    static SkBitmap* SetBitmap(SkBitmap* dst, const ANPBitmap& src);
+    static bool SetBitmap(ANPBitmap* dst, const SkBitmap& src);
+    
+    static void InitEvent(ANPEvent* event, ANPEventType et);
+};
+
+#endif
--- a/toolkit/library/Makefile.in
+++ b/toolkit/library/Makefile.in
@@ -299,16 +299,17 @@ endif
 # Platform-specific icon channel stuff - supported mostly-everywhere
 ifneq (,$(filter windows os2 mac cocoa gtk2 qt android,$(MOZ_WIDGET_TOOLKIT)))
 DEFINES += -DICON_DECODER
 COMPONENT_LIBS += imgicon
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),android)
 COMPONENT_LIBS += widget_android
+STATIC_LIBS += skia_npapi
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gonk)
 COMPONENT_LIBS += widget_gonk
 endif
 
 STATIC_LIBS += thebes gl ycbcr