Back out dcc28a7cfa31, 13342c7d1fc3, f005ff7b0e2a (bug 692198, bug 692196, bug 692200) because of test failures
authorMatt Brubeck <mbrubeck@mozilla.com>
Thu, 13 Oct 2011 12:17:06 -0700
changeset 78712 2f53f26d9e1b90687890a3b5010854536a444f84
parent 78711 40f077f9c4a2529d9fccb9f35e7fdc7fa101482d
child 78713 2d9076dbcd1510fd732978ad61d666f8899db238
push id21326
push userbmo@edmorley.co.uk
push dateFri, 14 Oct 2011 10:00:06 +0000
treeherdermozilla-central@ca73f057dab7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs692198, 692196, 692200
milestone10.0a1
backs outdcc28a7cfa318ff0dde12e0c0bd7cd5cd9e8341a
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Back out dcc28a7cfa31, 13342c7d1fc3, f005ff7b0e2a (bug 692198, bug 692196, bug 692200) because of test failures
content/base/src/nsObjectLoadingContent.cpp
dom/plugins/base/PluginPRLibrary.cpp
dom/plugins/base/PluginPRLibrary.h
dom/plugins/base/android/ANPSurface.cpp
dom/plugins/base/nsNPAPIPluginInstance.cpp
dom/plugins/base/nsNPAPIPluginInstance.h
dom/plugins/base/nsPluginHost.cpp
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/plugins/base/nsPluginInstanceOwner.h
embedding/android/GeckoAppShell.java
embedding/android/Makefile.in
embedding/android/SurfaceInfo.java
embedding/android/SurfaceLockInfo.java
mobile/app/mobile.js
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -707,30 +707,16 @@ nsObjectLoadingContent::OnStartRequest(n
         // Do nothing in this case: This is probably due to a display:none
         // frame. If we ever get a frame, HasNewFrame will do the right thing.
         // Abort the load though, we have no use for the data.
         mInstantiating = PR_FALSE;
         return NS_BINDING_ABORTED;
       }
 
       {
-        PluginSupportState pluginState = GetPluginSupportState(thisContent,
-                                                               mContentType);
-        // Do nothing, but fire the plugin not found event if needed
-        if (pluginState != ePluginOtherState) {
-          Fallback(PR_FALSE);
-
-          mFallbackReason = pluginState;
-          FirePluginError(thisContent, pluginState);
-          return NS_BINDING_ABORTED;
-        }
-      }
-
-
-      {
         nsIFrame *nsiframe = do_QueryFrame(frame);
 
         nsWeakFrame weakFrame(nsiframe);
 
         rv = frame->Instantiate(chan, getter_AddRefs(mFinalListener));
 
         mInstantiating = PR_FALSE;
 
@@ -1938,22 +1924,16 @@ nsObjectLoadingContent::Instantiate(nsIO
 
   return rv;
 }
 
 /* static */ PluginSupportState
 nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent,
                                               const nsCString& aContentType)
 {
-#ifdef ANDROID
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
-    return ePluginClickToPlay;
-  }
-#endif
-
   if (!aContent->IsHTML()) {
     return ePluginOtherState;
   }
 
   if (aContent->Tag() == nsGkAtoms::embed ||
       aContent->Tag() == nsGkAtoms::applet) {
     return GetPluginDisabledState(aContentType);
   }
@@ -1978,19 +1958,18 @@ nsObjectLoadingContent::GetPluginSupport
   return hasAlternateContent ? ePluginOtherState :
     GetPluginDisabledState(aContentType);
 }
 
 /* static */ PluginSupportState
 nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType)
 {
 #ifdef ANDROID
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
-    return ePluginClickToPlay;
-  }
+      if (XRE_GetProcessType() == GeckoProcessType_Content)
+        return ePluginClickToPlay;
 #endif
   nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
   nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
   if (!pluginHost) {
     return ePluginUnsupported;
   }
 
   nsresult rv = pluginHost->IsPluginEnabledForType(aContentType.get());
--- a/dom/plugins/base/PluginPRLibrary.cpp
+++ b/dom/plugins/base/PluginPRLibrary.cpp
@@ -50,32 +50,25 @@ static int gNotOptimized;
 #else
 #define CALLING_CONVENTION_HACK
 #endif
 
 #ifdef ANDROID
 #include "AndroidBridge.h"
 #include "android_npapi.h"
 #include <android/log.h>
-#include "nsXULAppAPI.h"
-#include "nsIXULRuntime.h"
 #define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoJavaEnv", ## args)
 #endif
 
 namespace mozilla {
 #ifdef ANDROID
 nsresult
 PluginPRLibrary::NP_Initialize(NPNetscapeFuncs* bFuncs,
 			       NPPluginFuncs* pFuncs, NPError* error)
 {
-  // We need the JNI environment, which is only in the
-  // chrome process (since it is started by Android)
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
-    return NS_ERROR_FAILURE;
-  }
   if (mNP_Initialize) {
     *error = mNP_Initialize(bFuncs, pFuncs, GetJNIForThread());
   } else {
     NP_InitializeFunc pfNP_Initialize = (NP_InitializeFunc)
       PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
     if (!pfNP_Initialize)
       return NS_ERROR_FAILURE;
     *error = pfNP_Initialize(bFuncs, pFuncs, GetJNIForThread());
--- a/dom/plugins/base/PluginPRLibrary.h
+++ b/dom/plugins/base/PluginPRLibrary.h
@@ -37,17 +37,16 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef PluginPRLibrary_h
 #define PluginPRLibrary_h 1
 
 #include "mozilla/PluginLibrary.h"
 #include "nsNPAPIPlugin.h"
 #include "npfunctions.h"
-#include "nsIXULRuntime.h"
 
 namespace mozilla {
 
 class PluginPRLibrary : public PluginLibrary
 {
 public:
     PluginPRLibrary(const char* aFilePath, PRLibrary* aLibrary) :
 #if defined(XP_UNIX) && !defined(XP_MACOSX)
--- a/dom/plugins/base/android/ANPSurface.cpp
+++ b/dom/plugins/base/android/ANPSurface.cpp
@@ -37,138 +37,147 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "assert.h"
 #include "ANPBase.h"
 #include <android/log.h>
 #include "AndroidBridge.h"
 #include "gfxImageSurface.h"
 #include "gfxContext.h"
-#include "nsNPAPIPluginInstance.h"
 
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
 #define ASSIGN(obj, name)   (obj)->name = anp_surface_##name
 
 
 // used to cache JNI method and field IDs for Surface Objects
 static struct ANPSurfaceInterfaceJavaGlue {
   bool        initialized;
   jclass geckoAppShellClass;
-  jclass surfaceInfoCls;
-  jmethodID getSurfaceInfo;
+  jclass lockInfoCls;
+  jmethodID lockSurfaceANP;
+  jmethodID jUnlockSurfaceANP;
+  jfieldID jDirtyTop;
+  jfieldID jDirtyLeft;
+  jfieldID jDirtyBottom;
+  jfieldID jDirtyRight;
   jfieldID jFormat;
   jfieldID jWidth ;
   jfieldID jHeight;
+  jfieldID jBuffer;
 } gSurfaceJavaGlue;
 
 #define getClassGlobalRef(env, cname)                                    \
      (jClass = jclass(env->NewGlobalRef(env->FindClass(cname))))
 
 static void init(JNIEnv* env) {
   if (gSurfaceJavaGlue.initialized)
     return;
   
   gSurfaceJavaGlue.geckoAppShellClass = mozilla::AndroidBridge::GetGeckoAppShellClass();
   
   jmethodID getClass = env->GetStaticMethodID(gSurfaceJavaGlue.geckoAppShellClass, 
-                                              "getSurfaceInfoClass",
+                                              "getSurfaceLockInfoClass",
                                               "()Ljava/lang/Class;");
 
-  gSurfaceJavaGlue.surfaceInfoCls = (jclass) env->NewGlobalRef(env->CallStaticObjectMethod(gSurfaceJavaGlue.geckoAppShellClass, getClass));
+  gSurfaceJavaGlue.lockInfoCls = (jclass) env->NewGlobalRef(env->CallStaticObjectMethod(gSurfaceJavaGlue.geckoAppShellClass, getClass));
+
+  gSurfaceJavaGlue.jDirtyTop = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "dirtyTop", "I");
+  gSurfaceJavaGlue.jDirtyLeft = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "dirtyLeft", "I");
+  gSurfaceJavaGlue.jDirtyBottom = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "dirtyBottom", "I");
+  gSurfaceJavaGlue.jDirtyRight = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "dirtyRight", "I");
 
-  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.jFormat = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "format", "I");
+  gSurfaceJavaGlue.jWidth = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "width", "I");
+  gSurfaceJavaGlue.jHeight = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "height", "I");
 
-  gSurfaceJavaGlue.getSurfaceInfo = env->GetStaticMethodID(gSurfaceJavaGlue.geckoAppShellClass, "getSurfaceInfo", "(Landroid/view/SurfaceView;)Lorg/mozilla/gecko/SurfaceInfo;");
+  gSurfaceJavaGlue.jBuffer = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "buffer", "Ljava/nio/Buffer;");
+  gSurfaceJavaGlue.lockSurfaceANP = env->GetStaticMethodID(gSurfaceJavaGlue.geckoAppShellClass, "lockSurfaceANP", "(Landroid/view/SurfaceView;IIII)Lorg/mozilla/gecko/SurfaceLockInfo;");
+  gSurfaceJavaGlue.jUnlockSurfaceANP = env->GetStaticMethodID(gSurfaceJavaGlue.geckoAppShellClass, "unlockSurfaceANP", "(Landroid/view/SurfaceView;)V");
   gSurfaceJavaGlue.initialized = true;
 }
 
 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__);
     return false;
   }
 
   init(env);
 
+  jvalue args[5];
+  args[0].l = surfaceView;
+  if (dirtyRect) {
+    args[1].i = dirtyRect->top;
+    args[2].i = dirtyRect->left;
+    args[3].i = dirtyRect->bottom;
+    args[4].i = dirtyRect->right;
+    LOG("dirty rect: %d, %d, %d, %d", dirtyRect->top, dirtyRect->left, dirtyRect->bottom, dirtyRect->right);
+  } else {
+    args[1].i = args[2].i = args[3].i = args[4].i = 0;
+  }
+  
   jobject info = env->CallStaticObjectMethod(gSurfaceJavaGlue.geckoAppShellClass,
-                                             gSurfaceJavaGlue.getSurfaceInfo, surfaceView);
+                                             gSurfaceJavaGlue.lockSurfaceANP, 
+                                             surfaceView, args[1].i, args[2].i, args[3].i, args[4].i);
 
   LOG("info: %p", info);
   if (!info)
     return false;
 
+  // the surface may have expanded the dirty region so we must to pass that
+  // information back to the plugin.
+  if (dirtyRect) {
+    dirtyRect->left   = env->GetIntField(info, gSurfaceJavaGlue.jDirtyLeft);
+    dirtyRect->right  = env->GetIntField(info, gSurfaceJavaGlue.jDirtyRight);
+    dirtyRect->top    = env->GetIntField(info, gSurfaceJavaGlue.jDirtyTop);
+    dirtyRect->bottom = env->GetIntField(info, gSurfaceJavaGlue.jDirtyBottom);
+    LOG("dirty rect: %d, %d, %d, %d", dirtyRect->top, dirtyRect->left, dirtyRect->bottom, dirtyRect->right);
+  }
+
   bitmap->width  = env->GetIntField(info, gSurfaceJavaGlue.jWidth);
   bitmap->height = env->GetIntField(info, gSurfaceJavaGlue.jHeight);
 
-  if (bitmap->width <= 0 || bitmap->height <= 0)
-    return false;
-
   int format = env->GetIntField(info, gSurfaceJavaGlue.jFormat);
-  gfxImageFormat targetFormat;
 
   // format is PixelFormat
   if (format & 0x00000001) {
-    // We actually can't handle this right now because gfxImageSurface
-    // doesn't support RGBA32.
-    LOG("Unable to handle 32bit pixel format");
-    return false;
-  } else if (format & 0x00000004) {
+    bitmap->format = kRGBA_8888_ANPBitmapFormat;
+    bitmap->rowBytes = bitmap->width * 4;
+  }
+  else if (format & 0x00000004) {
     bitmap->format = kRGB_565_ANPBitmapFormat;
     bitmap->rowBytes = bitmap->width * 2;
-    targetFormat = gfxASurface::ImageFormatRGB16_565;
-  } else {
+  }
+  else {
     LOG("format from glue is unknown %d\n", format);
     return false;
   }
 
-  nsNPAPIPluginInstance* pinst = nsNPAPIPluginInstance::FindByJavaSurface((void*)surfaceView);
-  if (!pinst) {
-    LOG("Failed to get plugin instance");
-    return false;
-  }
-
-  NPRect lockRect;
-  if (dirtyRect) {
-    lockRect.top = dirtyRect->top;
-    lockRect.left = dirtyRect->left;
-    lockRect.right = dirtyRect->right;
-    lockRect.bottom = dirtyRect->bottom;
-  } else {
-    // No dirty rect, use the whole bitmap
-    lockRect.top = lockRect.left = 0;
-    lockRect.right = bitmap->width;
-    lockRect.bottom = bitmap->height;
-  }
+  jobject buf = env->GetObjectField(info, gSurfaceJavaGlue.jBuffer);
+  bitmap->baseAddr = env->GetDirectBufferAddress(buf);
   
-  gfxImageSurface* target = pinst->LockTargetSurface(bitmap->width, bitmap->height, targetFormat, &lockRect);
-  bitmap->baseAddr = target->Data();
-
+  LOG("format: %d, width: %d, height: %d",  bitmap->format,  bitmap->width,  bitmap->height);
   env->DeleteLocalRef(info);
-
-  return true;
+  env->DeleteLocalRef(buf);
+  return ( bitmap->width > 0 && bitmap->height > 0 );
 }
 
 static void anp_unlock(JNIEnv* env, jobject surfaceView) {
   LOG("%s", __PRETTY_FUNCTION__);
 
   if (!surfaceView) {
     LOG("null surface, exiting %s", __PRETTY_FUNCTION__);
     return;
   }
 
-  nsNPAPIPluginInstance* pinst = nsNPAPIPluginInstance::FindByJavaSurface((void*)surfaceView);
-  if (!pinst) {
-    LOG("Could not find plugin instance!");
-    return;
-  }
-  
-  pinst->UnlockTargetSurface(true /* invalidate the locked area */);
+  init(env);
+  env->CallStaticVoidMethod(gSurfaceJavaGlue.geckoAppShellClass, gSurfaceJavaGlue.jUnlockSurfaceANP, surfaceView);
+  LOG("returning from %s", __PRETTY_FUNCTION__);
+
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 #define ASSIGN(obj, name)   (obj)->name = anp_##name
 
 void InitSurfaceInterface(ANPSurfaceInterfaceV0 *i) {
 
--- 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 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 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 ANDROID
     mSurface(nsnull),
-    mTargetSurface(nsnull),
     mDrawingModel(0),
 #endif
     mRunning(NOT_STARTED),
     mWindowless(false),
     mWindowlessLocal(false),
     mTransparent(false),
     mUsesDOMForCursor(false),
     mInPluginInitCall(false),
@@ -122,47 +117,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 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 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;
 }
@@ -358,22 +333,17 @@ nsNPAPIPluginInstance::InitializePlugin(
     // crafted specially to be directly behind the arrays from GetAttributes()
     // with a null entry as a separator. This is for 4.x backwards compatibility!
     // see bug 111008 for details
     if (tagtype != nsPluginTagType_Embed) {
       PRUint16 pcount = 0;
       const char* const* pnames = nsnull;
       const char* const* pvalues = nsnull;    
       if (NS_SUCCEEDED(GetParameters(pcount, pnames, pvalues))) {
-        // Android expects an empty string as the separator instead of null
-#ifdef ANDROID
-        NS_ASSERTION(PL_strcmp(values[count], "") == 0, "attribute/parameter array not setup correctly for Android NPAPI plugins");
-#else
         NS_ASSERTION(!values[count], "attribute/parameter array not setup correctly for NPAPI plugins");
-#endif
         if (pcount)
           count += ++pcount; // if it's all setup correctly, then all we need is to
                              // change the count (attrs + PARAM/blank + params)
       }
     }
   }
 
   PRInt32       mode;
@@ -795,71 +765,19 @@ void* nsNPAPIPluginInstance::GetJavaSurf
   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()
-{
-  mTargetSurfaceLock->Lock();
-  return mTargetSurface;
-}
-
-gfxImageSurface*
-nsNPAPIPluginInstance::LockTargetSurface(PRUint32 aWidth, PRUint32 aHeight, gfxImageFormat aFormat,
-                                         NPRect* aRect)
-{
-  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;
-
-  return mTargetSurface;
-}
-
-void
-nsNPAPIPluginInstance::InvalidateTargetRect()
-{
-    InvalidateRect(&mTargetLockRect);
-}
-
-void
-nsNPAPIPluginInstance::UnlockTargetSurface(bool aInvalidate)
-{
-  mTargetSurfaceLock->Unlock();
-
-  if (aInvalidate) {
-    NS_DispatchToMainThread(NS_NewRunnableMethod(this, &nsNPAPIPluginInstance::InvalidateTargetRect));
-  }
-}
-
-nsNPAPIPluginInstance*
-nsNPAPIPluginInstance::FindByJavaSurface(void* aJavaSurface)
-{
-  return sSurfaceMap[aJavaSurface];
-}
-
 #endif
 
 nsresult nsNPAPIPluginInstance::GetDrawingModel(PRInt32* aModel)
 {
 #if defined(XP_MACOSX) || defined(ANDROID)
   *aModel = (PRInt32)mDrawingModel;
   return NS_OK;
 #else
--- a/dom/plugins/base/nsNPAPIPluginInstance.h
+++ b/dom/plugins/base/nsNPAPIPluginInstance.h
@@ -45,26 +45,19 @@
 #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"
-
 #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;
 
@@ -150,23 +143,16 @@ public:
 #ifdef XP_MACOSX
   void SetDrawingModel(NPDrawingModel aModel);
   void SetEventModel(NPEventModel aModel);
 #endif
 
 #ifdef 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);
 #endif
 
   nsresult NewStreamListener(const char* aURL, void* notifyData,
                              nsIPluginStreamListener** listener);
 
   nsNPAPIPluginInstance(nsNPAPIPlugin* plugin);
   virtual ~nsNPAPIPluginInstance();
 
@@ -273,18 +259,13 @@ private:
 
   // non-null during a HandleEvent call
   void* mCurrentPluginEvent;
 
   nsCOMPtr<nsIURI> mURI;
 
   bool mUsePluginLayersPref;
 #ifdef ANDROID
-  void InvalidateTargetRect();
-  
   void* mSurface;
-  gfxImageSurface *mTargetSurface;
-  mozilla::Mutex* mTargetSurfaceLock;
-  NPRect mTargetLockRect;
 #endif
 };
 
 #endif // nsNPAPIPluginInstance_h_
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -2247,16 +2247,21 @@ nsresult nsPluginHost::ScanPluginsDirect
       if (!aCreatePluginList && *aPluginsChanged)
         break;
     }
     return NS_OK;
 }
 
 nsresult nsPluginHost::LoadPlugins()
 {
+#ifdef ANDROID
+  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    return NS_OK;
+  }
+#endif
   // do not do anything if it is already done
   // use ReloadPlugins() to enforce loading
   if (mPluginsLoaded)
     return NS_OK;
 
   if (mPluginsDisabled)
     return NS_OK;
 
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -1228,51 +1228,36 @@ nsresult nsPluginInstanceOwner::EnsureCa
     start = 0;
     end = numRealAttrs;
     increment = 1;
   }
 
   // Set to the next slot to fill in name and value cache arrays.
   PRUint32 nextAttrParamIndex = 0;
 
-  // Whether or not we force the wmode below while traversing
-  // the name/value pairs.
-  bool wmodeSet = false;
+  // Potentially add WMODE attribute.
+  if (!wmodeType.IsEmpty()) {
+    mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING("wmode"));
+    mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(NS_ConvertUTF8toUTF16(wmodeType));
+    nextAttrParamIndex++;
+  }
 
   // Add attribute name/value pairs.
   for (PRInt32 index = start; index != end; index += increment) {
     const nsAttrName* attrName = mContent->GetAttrNameAt(index);
     nsIAtom* atom = attrName->LocalName();
     nsAutoString value;
     mContent->GetAttr(attrName->NamespaceID(), atom, value);
     nsAutoString name;
     atom->ToString(name);
 
     FixUpURLS(name, value);
 
     mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(name);
-    if (!wmodeType.IsEmpty() && 
-        0 == PL_strcasecmp(mCachedAttrParamNames[nextAttrParamIndex], "wmode")) {
-      mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(NS_ConvertUTF8toUTF16(wmodeType));
-
-      if (!wmodeSet) {
-        // We allocated space to add a wmode attr, but we don't need it now.
-        mNumCachedAttrs--;
-        wmodeSet = true;
-      }
-    } else {
-      mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(value);
-    }
-    nextAttrParamIndex++;
-  }
-
-  // Potentially add WMODE attribute.
-  if (!wmodeType.IsEmpty() && !wmodeSet) {
-    mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING("wmode"));
-    mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(NS_ConvertUTF8toUTF16(wmodeType));
+    mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(value);
     nextAttrParamIndex++;
   }
 
   // Potentially add SRC attribute.
   if (!data.IsEmpty()) {
     mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING("SRC"));
     mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(data);
     nextAttrParamIndex++;
@@ -1666,37 +1651,16 @@ void nsPluginInstanceOwner::ScrollPositi
       }
       pluginWidget->EndDrawPlugin();
     }
   }
 #endif
 }
 
 #ifdef ANDROID
-void nsPluginInstanceOwner::AddPluginView(const gfxRect& aRect)
-{
-  void* javaSurface = mInstance->GetJavaSurface();
-
-  if (!javaSurface)
-    return;
-
-  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);
-}
-
 void nsPluginInstanceOwner::RemovePluginView()
 {
   if (mInstance && mObjectFrame) {
     void* surface = mInstance->GetJavaSurface();
     if (surface) {
       JNIEnv* env = GetJNIForThread();
       if (env) {
         jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
@@ -2828,41 +2792,93 @@ void nsPluginInstanceOwner::Paint(const 
   pluginEvent.wParam = (uint32)aHPS;
   pluginEvent.lParam = (uint32)&rectl;
   mInstance->HandleEvent(&pluginEvent, nsnull);
 }
 #endif
 
 #ifdef ANDROID
 
+class AndroidPaintEventRunnable : public nsRunnable
+{
+public:
+  AndroidPaintEventRunnable(void* aSurface, nsNPAPIPluginInstance* inst, const gfxRect& aFrameRect)
+    : mSurface(aSurface), mInstance(inst), mFrameRect(aFrameRect) {
+  }
+
+  ~AndroidPaintEventRunnable() {
+  }
+
+  NS_IMETHOD Run()
+  {
+    LOG("%p - AndroidPaintEventRunnable::Run\n", this);
+
+    if (!mInstance || !mSurface)
+      return NS_OK;
+
+    // This needs to happen on the gecko main thread.
+    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,
+                              mSurface,
+                              mFrameRect.x,
+                              mFrameRect.y,
+                              mFrameRect.width,
+                              mFrameRect.height);
+    return NS_OK;
+  }
+private:
+  void* mSurface;
+  nsCOMPtr<nsNPAPIPluginInstance> mInstance;
+  gfxRect mFrameRect;
+};
+
+
 void nsPluginInstanceOwner::Paint(gfxContext* aContext,
                                   const gfxRect& aFrameRect,
                                   const gfxRect& aDirtyRect)
 {
   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;
+
+    {
+      ANPEvent event;
+      event.inSize = sizeof(ANPEvent);
+      event.eventType = kLifecycle_ANPEventType;
+      event.data.lifecycle.action = kOnScreen_ANPLifecycleAction;
+      mInstance->HandleEvent(&event, nsnull);
     }
 
-    aContext->SetOperator(gfxContext::OPERATOR_SOURCE);
-    aContext->SetSource(pluginSurface, gfxPoint(aFrameRect.x, aFrameRect.y));
-    aContext->Clip(aDirtyRect);
-    aContext->Paint();
-
-    mInstance->UnlockTargetSurface(false);
+    /*
+    gfxMatrix currentMatrix = aContext->CurrentMatrix();
+    gfxSize scale = currentMatrix.ScaleFactors(true);
+    printf_stderr("!!!!!!!! scale!!:  %f x %f\n", scale.width, scale.height);
+    */
+
+    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,
+                              mInstance->GetJavaSurface(),
+                              aFrameRect.x,
+                              aFrameRect.y,
+                              aFrameRect.width,
+                              aFrameRect.height);
     return;
   }
 
   if (model != kBitmap_ANPDrawingModel)
     return;
 
 #ifdef ANP_BITMAP_DRAWING_MODEL
   static nsRefPtr<gfxImageSurface> pluginSurface;
--- a/dom/plugins/base/nsPluginInstanceOwner.h
+++ b/dom/plugins/base/nsPluginInstanceOwner.h
@@ -304,17 +304,16 @@ 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);
   void RemovePluginView();
 #endif 
  
   nsPluginNativeWindow       *mPluginWindow;
   nsRefPtr<nsNPAPIPluginInstance> mInstance;
   nsObjectFrame              *mObjectFrame; // owns nsPluginInstanceOwner
   nsCOMPtr<nsIContent>        mContent;
   nsCString                   mDocumentBase;
--- a/embedding/android/GeckoAppShell.java
+++ b/embedding/android/GeckoAppShell.java
@@ -1350,17 +1350,20 @@ public class GeckoAppShell
         getMainHandler().post(new Runnable() { 
                 public void run() {
                     AbsoluteLayout.LayoutParams lp = new AbsoluteLayout.LayoutParams((int)w,
                                                                                      (int)h,
                                                                                      (int)x,
                                                                                      (int)y);
 
                     if (GeckoApp.mainLayout.indexOfChild(view) == -1) {
-                        view.setWillNotDraw(true);
+                        view.setWillNotDraw(false);
+                        if(view instanceof SurfaceView)
+                            ((SurfaceView)view).setZOrderOnTop(true);
+
                         GeckoApp.mainLayout.addView(view, lp);
                     }
                     else
                     {
                         try {
                             GeckoApp.mainLayout.updateViewLayout(view, lp);
                         } catch (IllegalArgumentException e) {
                             Log.i("updateViewLayout - IllegalArgumentException", "e:" + e);
@@ -1404,54 +1407,113 @@ public class GeckoAppShell
             Log.i("GeckoAppShell", "class not found", cnfe);
         } catch (android.content.pm.PackageManager.NameNotFoundException nnfe) {
             Log.i("GeckoAppShell", "package not found", nnfe);
         }
         Log.e("GeckoAppShell", "couldn't find class");
         return null;
     }
 
-    public static SurfaceInfo getSurfaceInfo(SurfaceView sview)
+    static HashMap<SurfaceView, SurfaceLockInfo> sSufaceMap = new HashMap<SurfaceView, SurfaceLockInfo>();
+
+    public static void lockSurfaceANP()
     {
-        Log.i("GeckoAppShell", "getSurfaceInfo " + sview);
+         Log.i("GeckoAppShell", "other lockSurfaceANP");
+    }
+
+    public static org.mozilla.gecko.SurfaceLockInfo lockSurfaceANP(android.view.SurfaceView sview, int top, int left, int bottom, int right)
+    {
+        Log.i("GeckoAppShell", "real lockSurfaceANP " + sview + ", " + top + ",  " + left + ", " + bottom + ", " + right);
         if (sview == null)
             return null;
 
         int format = -1;
         try {
             Field privateFormatField = SurfaceView.class.getDeclaredField("mFormat");
             privateFormatField.setAccessible(true);
             format = privateFormatField.getInt(sview);
         } catch (Exception e) {
             Log.i("GeckoAppShell", "mFormat is not a field of sview: ", e);
         }
 
         int n = 0;
-        if (format == PixelFormat.RGB_565) {
+        if (format == PixelFormat.RGB_565)
             n = 2;
-        } else if (format == PixelFormat.RGBA_8888) {
+        else if (format == PixelFormat.RGBA_8888)
             n = 4;
-        } else {
-            Log.i("GeckoAppShell", "Unknown pixel format: " + format);
+
+        if (n == 0)
             return null;
+
+        SurfaceLockInfo info = sSufaceMap.get(sview);
+        if (info == null) {
+            info = new SurfaceLockInfo();
+            sSufaceMap.put(sview, info);
         }
 
-        SurfaceInfo info = new SurfaceInfo();
+        Rect r = new Rect(left, top, right, bottom);
+
+        info.canvas = sview.getHolder().lockCanvas(r);
+        int bufSizeRequired = info.canvas.getWidth() * info.canvas.getHeight() * n;
+        Log.i("GeckoAppShell", "lockSurfaceANP - bufSizeRequired: " + n + " " + info.canvas.getHeight() + " " + info.canvas.getWidth());
+
+        if (info.width != info.canvas.getWidth() || info.height != info.canvas.getHeight() || info.buffer == null || info.buffer.capacity() < bufSizeRequired) {
+            info.width = info.canvas.getWidth();
+            info.height = info.canvas.getHeight();
 
-        Rect r = sview.getHolder().getSurfaceFrame();
-        info.width = r.right;
-        info.height = r.bottom;
+            // XXX Bitmaps instead of ByteBuffer
+            info.buffer = ByteBuffer.allocateDirect(bufSizeRequired);  //leak
+            Log.i("GeckoAppShell", "!!!!!!!!!!!  lockSurfaceANP - Allocating buffer! " + bufSizeRequired);
+
+        }
+
+        info.canvas.drawColor(Color.WHITE, PorterDuff.Mode.CLEAR);
+
         info.format = format;
+        info.dirtyTop = top;
+        info.dirtyBottom = bottom;
+        info.dirtyLeft = left;
+        info.dirtyRight = right;
 
         return info;
     }
 
-    public static Class getSurfaceInfoClass() {
-        Log.i("GeckoAppShell", "class name: " + SurfaceInfo.class.getName());
-        return SurfaceInfo.class;
+    public static void unlockSurfaceANP(SurfaceView sview) {
+        SurfaceLockInfo info = sSufaceMap.get(sview);
+
+        int n = 0;
+        Bitmap.Config config;
+        if (info.format == PixelFormat.RGB_565) {
+            n = 2;
+            config = Bitmap.Config.RGB_565;
+        } else {
+            n = 4;
+            config = Bitmap.Config.ARGB_8888;
+        }
+
+        Log.i("GeckoAppShell", "unlockSurfaceANP: " + (info.width * info.height * n));
+
+        Bitmap bm = Bitmap.createBitmap(info.width, info.height, config);
+        bm.copyPixelsFromBuffer(info.buffer);
+        info.canvas.drawBitmap(bm, 0, 0, null);
+        sview.getHolder().unlockCanvasAndPost(info.canvas);
+    }
+
+    public static Class getSurfaceLockInfoClass() {
+        Log.i("GeckoAppShell", "class name: " + SurfaceLockInfo.class.getName());
+        return SurfaceLockInfo.class;
+    }
+
+    public static Method getSurfaceLockMethod() {
+        Method[] m = GeckoAppShell.class.getMethods();
+        for (int i = 0; i < m.length; i++) {
+            if (m[i].getName().equals("lockSurfaceANP"))
+                return m[i];
+        }
+        return null;
     }
 
     static native void executeNextRunnable();
 
     static class GeckoRunnableCallback implements Runnable {
         public void run() {
             Log.i("GeckoShell", "run GeckoRunnableCallback");
             GeckoAppShell.executeNextRunnable();
--- a/embedding/android/Makefile.in
+++ b/embedding/android/Makefile.in
@@ -48,17 +48,17 @@ DIRS = locales
 JAVAFILES = \
   GeckoApp.java \
   GeckoAppShell.java \
   GeckoConnectivityReceiver.java \
   GeckoEvent.java \
   GeckoSurfaceView.java \
   GeckoInputConnection.java \
   AlertNotification.java \
-  SurfaceInfo.java \
+  SurfaceLockInfo.java \
   $(NULL)
 
 PROCESSEDJAVAFILES = \
   App.java \
   Restarter.java \
   NotificationHandler.java \
   LauncherShortcuts.java \
   $(NULL)
deleted file mode 100644
--- a/embedding/android/SurfaceInfo.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.mozilla.gecko;
-
-public class SurfaceInfo {
-    public int format;
-    public int width;
-    public int height;
-}
new file mode 100644
--- /dev/null
+++ b/embedding/android/SurfaceLockInfo.java
@@ -0,0 +1,18 @@
+package org.mozilla.gecko;
+
+import android.graphics.Canvas;
+import java.nio.Buffer;
+
+public class SurfaceLockInfo {
+    public int dirtyTop;
+    public int dirtyLeft;
+    public int dirtyRight;
+    public int dirtyBottom;
+
+    public int bpr;
+    public int format;
+    public int width;
+    public int height;
+    public Buffer buffer;
+    public Canvas canvas;
+}
--- a/mobile/app/mobile.js
+++ b/mobile/app/mobile.js
@@ -370,17 +370,19 @@ pref("privacy.item.history", true);
 pref("privacy.item.formdata", true);
 pref("privacy.item.downloads", true);
 pref("privacy.item.passwords", true);
 pref("privacy.item.sessions", true);
 pref("privacy.item.geolocation", true);
 pref("privacy.item.siteSettings", true);
 pref("privacy.item.syncAccount", true);
 
+#ifdef MOZ_PLATFORM_MAEMO
 pref("plugins.force.wmode", "opaque");
+#endif
 
 // URL to the Learn More link XXX this is the firefox one.  Bug 495578 fixes this.
 pref("browser.geolocation.warning.infoURL", "http://www.mozilla.com/%LOCALE%/firefox/geolocation/");
 
 // enable geo
 pref("geo.enabled", true);
 
 // content sink control -- controls responsiveness during page load