Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright 2011, The Android Open Source Project
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *  * Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  *  * Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #define LOG_TAG "ViewStateSerializer"
     27 #define LOG_NDEBUG 1
     28 
     29 #include "config.h"
     30 
     31 #include "BaseLayerAndroid.h"
     32 #include "CreateJavaOutputStreamAdaptor.h"
     33 #include "FixedPositioning.h"
     34 #include "ImagesManager.h"
     35 #include "IFrameContentLayerAndroid.h"
     36 #include "IFrameLayerAndroid.h"
     37 #include "Layer.h"
     38 #include "LayerAndroid.h"
     39 #include "LayerContent.h"
     40 #include "PictureLayerContent.h"
     41 #include "ScrollableLayerAndroid.h"
     42 #include "SkFlattenable.h"
     43 #include "SkPicture.h"
     44 #include "TilesManager.h"
     45 
     46 #include <JNIUtility.h>
     47 #include <JNIHelp.h>
     48 #include <jni.h>
     49 
     50 namespace android {
     51 
     52 enum LayerTypes {
     53     LTNone = 0,
     54     LTLayerAndroid = 1,
     55     LTScrollableLayerAndroid = 2,
     56     LTFixedLayerAndroid = 3
     57 };
     58 
     59 static bool nativeSerializeViewState(JNIEnv* env, jobject, jint jbaseLayer,
     60                                      jobject jstream, jbyteArray jstorage)
     61 {
     62     BaseLayerAndroid* baseLayer = (BaseLayerAndroid*) jbaseLayer;
     63     if (!baseLayer)
     64         return false;
     65 
     66     SkWStream *stream = CreateJavaOutputStreamAdaptor(env, jstream, jstorage);
     67 #if USE(ACCELERATED_COMPOSITING)
     68     stream->write32(baseLayer->getBackgroundColor().rgb());
     69 #else
     70     stream->write32(0);
     71 #endif
     72     if (!stream)
     73         return false;
     74     if (baseLayer->content())
     75         baseLayer->content()->serialize(stream);
     76     else
     77         return false;
     78     int childCount = baseLayer->countChildren();
     79     ALOGV("BaseLayer has %d child(ren)", childCount);
     80     stream->write32(childCount);
     81     for (int i = 0; i < childCount; i++) {
     82         LayerAndroid* layer = static_cast<LayerAndroid*>(baseLayer->getChild(i));
     83         serializeLayer(layer, stream);
     84     }
     85     delete stream;
     86     return true;
     87 }
     88 
     89 static BaseLayerAndroid* nativeDeserializeViewState(JNIEnv* env, jobject, jint version,
     90                                                     jobject jstream, jbyteArray jstorage)
     91 {
     92     SkStream* stream = CreateJavaInputStreamAdaptor(env, jstream, jstorage);
     93     if (!stream)
     94         return 0;
     95     Color color = stream->readU32();
     96     SkPicture* picture = new SkPicture(stream);
     97     PictureLayerContent* content = new PictureLayerContent(picture);
     98 
     99     BaseLayerAndroid* layer = new BaseLayerAndroid(content);
    100     layer->setBackgroundColor(color);
    101 
    102     SkRegion dirtyRegion;
    103     dirtyRegion.setRect(0, 0, content->width(), content->height());
    104     layer->markAsDirty(dirtyRegion);
    105 
    106     SkSafeUnref(content);
    107     SkSafeUnref(picture);
    108     int childCount = stream->readS32();
    109     for (int i = 0; i < childCount; i++) {
    110         LayerAndroid* childLayer = deserializeLayer(version, stream);
    111         if (childLayer)
    112             layer->addChild(childLayer);
    113     }
    114     delete stream;
    115     return layer;
    116 }
    117 
    118 // Serialization helpers
    119 
    120 void writeMatrix(SkWStream *stream, const SkMatrix& matrix)
    121 {
    122     for (int i = 0; i < 9; i++)
    123         stream->writeScalar(matrix[i]);
    124 }
    125 
    126 SkMatrix readMatrix(SkStream *stream)
    127 {
    128     SkMatrix matrix;
    129     for (int i = 0; i < 9; i++)
    130         matrix.set(i, stream->readScalar());
    131     return matrix;
    132 }
    133 
    134 void writeSkLength(SkWStream *stream, SkLength length)
    135 {
    136     stream->write32(length.type);
    137     stream->writeScalar(length.value);
    138 }
    139 
    140 SkLength readSkLength(SkStream *stream)
    141 {
    142     SkLength len;
    143     len.type = (SkLength::SkLengthType) stream->readU32();
    144     len.value = stream->readScalar();
    145     return len;
    146 }
    147 
    148 void writeSkRect(SkWStream *stream, SkRect rect)
    149 {
    150     stream->writeScalar(rect.fLeft);
    151     stream->writeScalar(rect.fTop);
    152     stream->writeScalar(rect.fRight);
    153     stream->writeScalar(rect.fBottom);
    154 }
    155 
    156 SkRect readSkRect(SkStream *stream)
    157 {
    158     SkRect rect;
    159     rect.fLeft = stream->readScalar();
    160     rect.fTop = stream->readScalar();
    161     rect.fRight = stream->readScalar();
    162     rect.fBottom = stream->readScalar();
    163     return rect;
    164 }
    165 
    166 void writeTransformationMatrix(SkWStream *stream, TransformationMatrix& matrix)
    167 {
    168     double value;
    169     int dsize = sizeof(double);
    170     value = matrix.m11();
    171     stream->write(&value, dsize);
    172     value = matrix.m12();
    173     stream->write(&value, dsize);
    174     value = matrix.m13();
    175     stream->write(&value, dsize);
    176     value = matrix.m14();
    177     stream->write(&value, dsize);
    178     value = matrix.m21();
    179     stream->write(&value, dsize);
    180     value = matrix.m22();
    181     stream->write(&value, dsize);
    182     value = matrix.m23();
    183     stream->write(&value, dsize);
    184     value = matrix.m24();
    185     stream->write(&value, dsize);
    186     value = matrix.m31();
    187     stream->write(&value, dsize);
    188     value = matrix.m32();
    189     stream->write(&value, dsize);
    190     value = matrix.m33();
    191     stream->write(&value, dsize);
    192     value = matrix.m34();
    193     stream->write(&value, dsize);
    194     value = matrix.m41();
    195     stream->write(&value, dsize);
    196     value = matrix.m42();
    197     stream->write(&value, dsize);
    198     value = matrix.m43();
    199     stream->write(&value, dsize);
    200     value = matrix.m44();
    201     stream->write(&value, dsize);
    202 }
    203 
    204 void readTransformationMatrix(SkStream *stream, TransformationMatrix& matrix)
    205 {
    206     double value;
    207     int dsize = sizeof(double);
    208     stream->read(&value, dsize);
    209     matrix.setM11(value);
    210     stream->read(&value, dsize);
    211     matrix.setM12(value);
    212     stream->read(&value, dsize);
    213     matrix.setM13(value);
    214     stream->read(&value, dsize);
    215     matrix.setM14(value);
    216     stream->read(&value, dsize);
    217     matrix.setM21(value);
    218     stream->read(&value, dsize);
    219     matrix.setM22(value);
    220     stream->read(&value, dsize);
    221     matrix.setM23(value);
    222     stream->read(&value, dsize);
    223     matrix.setM24(value);
    224     stream->read(&value, dsize);
    225     matrix.setM31(value);
    226     stream->read(&value, dsize);
    227     matrix.setM32(value);
    228     stream->read(&value, dsize);
    229     matrix.setM33(value);
    230     stream->read(&value, dsize);
    231     matrix.setM34(value);
    232     stream->read(&value, dsize);
    233     matrix.setM41(value);
    234     stream->read(&value, dsize);
    235     matrix.setM42(value);
    236     stream->read(&value, dsize);
    237     matrix.setM43(value);
    238     stream->read(&value, dsize);
    239     matrix.setM44(value);
    240 }
    241 
    242 void serializeLayer(LayerAndroid* layer, SkWStream* stream)
    243 {
    244     if (!layer) {
    245         ALOGV("NULL layer!");
    246         stream->write8(LTNone);
    247         return;
    248     }
    249     if (layer->isMedia() || layer->isVideo()) {
    250         ALOGV("Layer isn't supported for serialization: isMedia: %s, isVideo: %s",
    251              layer->isMedia() ? "true" : "false",
    252              layer->isVideo() ? "true" : "false");
    253         stream->write8(LTNone);
    254         return;
    255     }
    256     LayerTypes type = LTLayerAndroid;
    257     if (layer->contentIsScrollable())
    258         type = LTScrollableLayerAndroid;
    259     stream->write8(type);
    260 
    261     // Start with Layer fields
    262     stream->writeBool(layer->shouldInheritFromRootTransform());
    263     stream->writeScalar(layer->getOpacity());
    264     stream->writeScalar(layer->getSize().width());
    265     stream->writeScalar(layer->getSize().height());
    266     stream->writeScalar(layer->getPosition().x());
    267     stream->writeScalar(layer->getPosition().y());
    268     stream->writeScalar(layer->getAnchorPoint().x());
    269     stream->writeScalar(layer->getAnchorPoint().y());
    270     writeMatrix(stream, layer->getMatrix());
    271     writeMatrix(stream, layer->getChildrenMatrix());
    272 
    273     // Next up, LayerAndroid fields
    274     stream->writeBool(layer->m_haveClip);
    275     stream->writeBool(layer->isPositionFixed());
    276     stream->writeBool(layer->m_backgroundColorSet);
    277     stream->writeBool(layer->isIFrame());
    278 
    279     // With the current LayerAndroid hierarchy, LayerAndroid doesn't have
    280     // those fields anymore. Let's keep the current serialization format for
    281     // now and output blank fields... not great, but probably better than
    282     // dealing with multiple versions.
    283     if (layer->fixedPosition()) {
    284         FixedPositioning* fixedPosition = layer->fixedPosition();
    285         writeSkLength(stream, fixedPosition->m_fixedLeft);
    286         writeSkLength(stream, fixedPosition->m_fixedTop);
    287         writeSkLength(stream, fixedPosition->m_fixedRight);
    288         writeSkLength(stream, fixedPosition->m_fixedBottom);
    289         writeSkLength(stream, fixedPosition->m_fixedMarginLeft);
    290         writeSkLength(stream, fixedPosition->m_fixedMarginTop);
    291         writeSkLength(stream, fixedPosition->m_fixedMarginRight);
    292         writeSkLength(stream, fixedPosition->m_fixedMarginBottom);
    293         writeSkRect(stream, fixedPosition->m_fixedRect);
    294         stream->write32(fixedPosition->m_renderLayerPos.x());
    295         stream->write32(fixedPosition->m_renderLayerPos.y());
    296     } else {
    297         SkLength length;
    298         SkRect rect;
    299         writeSkLength(stream, length); // fixedLeft
    300         writeSkLength(stream, length); // fixedTop
    301         writeSkLength(stream, length); // fixedRight
    302         writeSkLength(stream, length); // fixedBottom
    303         writeSkLength(stream, length); // fixedMarginLeft
    304         writeSkLength(stream, length); // fixedMarginTop
    305         writeSkLength(stream, length); // fixedMarginRight
    306         writeSkLength(stream, length); // fixedMarginBottom
    307         writeSkRect(stream, rect);     // fixedRect
    308         stream->write32(0);            // renderLayerPos.x()
    309         stream->write32(0);            // renderLayerPos.y()
    310     }
    311 
    312     stream->writeBool(layer->m_backfaceVisibility);
    313     stream->writeBool(layer->m_visible);
    314     stream->write32(layer->m_backgroundColor);
    315     stream->writeBool(layer->m_preserves3D);
    316     stream->writeScalar(layer->m_anchorPointZ);
    317     stream->writeScalar(layer->m_drawOpacity);
    318     bool hasContentsImage = layer->m_imageCRC != 0;
    319     stream->writeBool(hasContentsImage);
    320     if (hasContentsImage) {
    321         SkFlattenableWriteBuffer buffer(1024);
    322         buffer.setFlags(SkFlattenableWriteBuffer::kCrossProcess_Flag);
    323         ImageTexture* imagetexture =
    324                 ImagesManager::instance()->retainImage(layer->m_imageCRC);
    325         if (imagetexture && imagetexture->bitmap())
    326             imagetexture->bitmap()->flatten(buffer);
    327         ImagesManager::instance()->releaseImage(layer->m_imageCRC);
    328         stream->write32(buffer.size());
    329         buffer.writeToStream(stream);
    330     }
    331     bool hasRecordingPicture = layer->m_content != 0 && !layer->m_content->isEmpty();
    332     stream->writeBool(hasRecordingPicture);
    333     if (hasRecordingPicture)
    334         layer->m_content->serialize(stream);
    335     // TODO: support m_animations (maybe?)
    336     stream->write32(0); // placeholder for m_animations.size();
    337     writeTransformationMatrix(stream, layer->m_transform);
    338     writeTransformationMatrix(stream, layer->m_childrenTransform);
    339     if (type == LTScrollableLayerAndroid) {
    340         ScrollableLayerAndroid* scrollableLayer =
    341                 static_cast<ScrollableLayerAndroid*>(layer);
    342         stream->writeScalar(scrollableLayer->m_scrollLimits.fLeft);
    343         stream->writeScalar(scrollableLayer->m_scrollLimits.fTop);
    344         stream->writeScalar(scrollableLayer->m_scrollLimits.width());
    345         stream->writeScalar(scrollableLayer->m_scrollLimits.height());
    346     }
    347     int childCount = layer->countChildren();
    348     stream->write32(childCount);
    349     for (int i = 0; i < childCount; i++)
    350         serializeLayer(layer->getChild(i), stream);
    351 }
    352 
    353 LayerAndroid* deserializeLayer(int version, SkStream* stream)
    354 {
    355     int type = stream->readU8();
    356     if (type == LTNone)
    357         return 0;
    358     // Cast is to disambiguate between ctors.
    359     LayerAndroid *layer;
    360     if (type == LTLayerAndroid)
    361         layer = new LayerAndroid((RenderLayer*) 0);
    362     else if (type == LTScrollableLayerAndroid)
    363         layer = new ScrollableLayerAndroid((RenderLayer*) 0);
    364     else {
    365         ALOGV("Unexpected layer type: %d, aborting!", type);
    366         return 0;
    367     }
    368 
    369     // Layer fields
    370     layer->setShouldInheritFromRootTransform(stream->readBool());
    371     layer->setOpacity(stream->readScalar());
    372     layer->setSize(stream->readScalar(), stream->readScalar());
    373     layer->setPosition(stream->readScalar(), stream->readScalar());
    374     layer->setAnchorPoint(stream->readScalar(), stream->readScalar());
    375     layer->setMatrix(readMatrix(stream));
    376     layer->setChildrenMatrix(readMatrix(stream));
    377 
    378     // LayerAndroid fields
    379     layer->m_haveClip = stream->readBool();
    380 
    381     // Keep the legacy serialization/deserialization format...
    382     bool isFixed = stream->readBool();
    383 
    384     layer->m_backgroundColorSet = stream->readBool();
    385 
    386     bool isIframe = stream->readBool();
    387     // If we are a scrollable layer android, we are an iframe content
    388     if (isIframe && type == LTScrollableLayerAndroid) {
    389          IFrameContentLayerAndroid* iframeContent = new IFrameContentLayerAndroid(*layer);
    390          layer->unref();
    391          layer = iframeContent;
    392     } else if (isIframe) { // otherwise we are just the iframe (we use it to compute offset)
    393          IFrameLayerAndroid* iframe = new IFrameLayerAndroid(*layer);
    394          layer->unref();
    395          layer = iframe;
    396     }
    397 
    398     if (isFixed) {
    399         FixedPositioning* fixedPosition = new FixedPositioning(layer);
    400 
    401         fixedPosition->m_fixedLeft = readSkLength(stream);
    402         fixedPosition->m_fixedTop = readSkLength(stream);
    403         fixedPosition->m_fixedRight = readSkLength(stream);
    404         fixedPosition->m_fixedBottom = readSkLength(stream);
    405         fixedPosition->m_fixedMarginLeft = readSkLength(stream);
    406         fixedPosition->m_fixedMarginTop = readSkLength(stream);
    407         fixedPosition->m_fixedMarginRight = readSkLength(stream);
    408         fixedPosition->m_fixedMarginBottom = readSkLength(stream);
    409         fixedPosition->m_fixedRect = readSkRect(stream);
    410         fixedPosition->m_renderLayerPos.setX(stream->readS32());
    411         fixedPosition->m_renderLayerPos.setY(stream->readS32());
    412 
    413         layer->setFixedPosition(fixedPosition);
    414     } else {
    415         // Not a fixed element, bypass the values in the stream
    416         readSkLength(stream); // fixedLeft
    417         readSkLength(stream); // fixedTop
    418         readSkLength(stream); // fixedRight
    419         readSkLength(stream); // fixedBottom
    420         readSkLength(stream); // fixedMarginLeft
    421         readSkLength(stream); // fixedMarginTop
    422         readSkLength(stream); // fixedMarginRight
    423         readSkLength(stream); // fixedMarginBottom
    424         readSkRect(stream);   // fixedRect
    425         stream->readS32();    // renderLayerPos.x()
    426         stream->readS32();    // renderLayerPos.y()
    427     }
    428 
    429     layer->m_backfaceVisibility = stream->readBool();
    430     layer->m_visible = stream->readBool();
    431     layer->m_backgroundColor = stream->readU32();
    432     layer->m_preserves3D = stream->readBool();
    433     layer->m_anchorPointZ = stream->readScalar();
    434     layer->m_drawOpacity = stream->readScalar();
    435     bool hasContentsImage = stream->readBool();
    436     if (hasContentsImage) {
    437         int size = stream->readU32();
    438         SkAutoMalloc storage(size);
    439         stream->read(storage.get(), size);
    440         SkFlattenableReadBuffer buffer(storage.get(), size);
    441         SkBitmap contentsImage;
    442         contentsImage.unflatten(buffer);
    443         SkBitmapRef* imageRef = new SkBitmapRef(contentsImage);
    444         layer->setContentsImage(imageRef);
    445         delete imageRef;
    446     }
    447     bool hasRecordingPicture = stream->readBool();
    448     if (hasRecordingPicture) {
    449         SkPicture* picture = new SkPicture(stream);
    450         PictureLayerContent* content = new PictureLayerContent(picture);
    451         layer->setContent(content);
    452         SkSafeUnref(content);
    453         SkSafeUnref(picture);
    454     }
    455     int animationCount = stream->readU32(); // TODO: Support (maybe?)
    456     readTransformationMatrix(stream, layer->m_transform);
    457     readTransformationMatrix(stream, layer->m_childrenTransform);
    458     if (type == LTScrollableLayerAndroid) {
    459         ScrollableLayerAndroid* scrollableLayer =
    460                 static_cast<ScrollableLayerAndroid*>(layer);
    461         scrollableLayer->m_scrollLimits.set(
    462                 stream->readScalar(),
    463                 stream->readScalar(),
    464                 stream->readScalar(),
    465                 stream->readScalar());
    466     }
    467     int childCount = stream->readU32();
    468     for (int i = 0; i < childCount; i++) {
    469         LayerAndroid *childLayer = deserializeLayer(version, stream);
    470         if (childLayer)
    471             layer->addChild(childLayer);
    472     }
    473     ALOGV("Created layer with id %d", layer->uniqueId());
    474     return layer;
    475 }
    476 
    477 /*
    478  * JNI registration
    479  */
    480 static JNINativeMethod gSerializerMethods[] = {
    481     { "nativeSerializeViewState", "(ILjava/io/OutputStream;[B)Z",
    482         (void*) nativeSerializeViewState },
    483     { "nativeDeserializeViewState", "(ILjava/io/InputStream;[B)I",
    484         (void*) nativeDeserializeViewState },
    485 };
    486 
    487 int registerViewStateSerializer(JNIEnv* env)
    488 {
    489     return jniRegisterNativeMethods(env, "android/webkit/ViewStateSerializer",
    490                                     gSerializerMethods, NELEM(gSerializerMethods));
    491 }
    492 
    493 }
    494