diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h index 9c352ad9a..0460bbd35 100644 --- a/include/surfaceflinger/Surface.h +++ b/include/surfaceflinger/Surface.h @@ -122,7 +122,10 @@ public: uint32_t reserved[2]; }; + explicit Surface(const sp& st); + static status_t writeToParcel(const sp& control, Parcel* parcel); + static sp readFromParcel(const Parcel& data); static bool isValid(const sp& surface) { return (surface != 0) && surface->isValid(); @@ -147,14 +150,14 @@ private: Surface& operator = (Surface& rhs); Surface(const Surface& rhs); - Surface(const sp& control); + explicit Surface(const sp& control); Surface(const Parcel& data, const sp& ref); ~Surface(); /* * private stuff... */ - void init(); + void init(const sp& surfaceTexture); static void cleanCachedSurfacesLocked(); diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index c4f9e53d5..ccf98e500 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -184,6 +184,7 @@ status_t SurfaceControl::writeSurfaceToParcel( identity = control->mIdentity; } parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); + parcel->writeStrongBinder(NULL); // NULL ISurfaceTexture in this case. parcel->writeInt32(identity); return NO_ERROR; } @@ -192,7 +193,8 @@ sp SurfaceControl::getSurface() const { Mutex::Autolock _l(mLock); if (mSurfaceData == 0) { - mSurfaceData = new Surface(const_cast(this)); + sp surface_control(const_cast(this)); + mSurfaceData = new Surface(surface_control); } return mSurfaceData; } @@ -208,31 +210,58 @@ Surface::Surface(const sp& surface) mSurface(surface->mSurface), mIdentity(surface->mIdentity) { - init(); + sp st; + if (mSurface != NULL) { + st = mSurface->getSurfaceTexture(); + } + init(st); } Surface::Surface(const Parcel& parcel, const sp& ref) : SurfaceTextureClient() { - mSurface = interface_cast(ref); + mSurface = interface_cast(ref); + sp st_binder(parcel.readStrongBinder()); + sp st; + if (st_binder != NULL) { + st = interface_cast(st_binder); + } else if (mSurface != NULL) { + st = mSurface->getSurfaceTexture(); + } + mIdentity = parcel.readInt32(); - init(); + init(st); +} + +Surface::Surface(const sp& st) + : SurfaceTextureClient(), + mSurface(NULL), + mIdentity(0) +{ + init(st); } status_t Surface::writeToParcel( const sp& surface, Parcel* parcel) { sp sur; + sp st; uint32_t identity = 0; if (Surface::isValid(surface)) { sur = surface->mSurface; + st = surface->getISurfaceTexture(); identity = surface->mIdentity; - } else if (surface != 0 && surface->mSurface != 0) { - LOGW("Parceling invalid surface with non-NULL ISurface as NULL: " - "mSurface = %p, mIdentity = %d", - surface->mSurface.get(), surface->mIdentity); + } else if (surface != 0 && + (surface->mSurface != NULL || + surface->getISurfaceTexture() != NULL)) { + LOGE("Parceling invalid surface with non-NULL ISurface/ISurfaceTexture as NULL: " + "mSurface = %p, surfaceTexture = %p, mIdentity = %d, ", + surface->mSurface.get(), surface->getISurfaceTexture().get(), + surface->mIdentity); } - parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); + + parcel->writeStrongBinder(sur != NULL ? sur->asBinder() : NULL); + parcel->writeStrongBinder(st != NULL ? st->asBinder() : NULL); parcel->writeInt32(identity); return NO_ERROR; @@ -249,8 +278,8 @@ sp Surface::readFromParcel(const Parcel& data) { surface = new Surface(data, binder); sCachedSurfaces.add(binder, surface); } - if (surface->mSurface == 0) { - surface = 0; + if (surface->mSurface == NULL && surface->getISurfaceTexture() == NULL) { + surface = 0; } cleanCachedSurfacesLocked(); return surface; @@ -267,10 +296,9 @@ void Surface::cleanCachedSurfacesLocked() { } } -void Surface::init() +void Surface::init(const sp& surfaceTexture) { - if (mSurface != NULL) { - sp surfaceTexture(mSurface->getSurfaceTexture()); + if (mSurface != NULL || surfaceTexture != NULL) { LOGE_IF(surfaceTexture==0, "got a NULL ISurfaceTexture from ISurface"); if (surfaceTexture != NULL) { setISurfaceTexture(surfaceTexture);