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 "DumpLayer.h" 34 #include "FixedPositioning.h" 35 #include "ImagesManager.h" 36 #include "IFrameContentLayerAndroid.h" 37 #include "IFrameLayerAndroid.h" 38 #include "Layer.h" 39 #include "LayerAndroid.h" 40 #include "LayerContent.h" 41 #include "PictureLayerContent.h" 42 #include "ScrollableLayerAndroid.h" 43 #include "SkFlattenable.h" 44 #include "SkPicture.h" 45 #include "TilesManager.h" 46 47 #include <JNIUtility.h> 48 #include <JNIHelp.h> 49 #include <jni.h> 50 51 namespace android { 52 53 enum LayerTypes { 54 LTNone = 0, 55 LTLayerAndroid = 1, 56 LTScrollableLayerAndroid = 2, 57 LTFixedLayerAndroid = 3 58 }; 59 60 #define ID "mID" 61 #define LEFT "layout:mLeft" 62 #define TOP "layout:mTop" 63 #define WIDTH "layout:getWidth()" 64 #define HEIGHT "layout:getHeight()" 65 66 class HierarchyLayerDumper : public LayerDumper { 67 public: 68 HierarchyLayerDumper(SkWStream* stream, int level) 69 : LayerDumper(level) 70 , m_stream(stream) 71 {} 72 73 virtual void beginLayer(const char* className, const LayerAndroid* layerPtr) { 74 LayerDumper::beginLayer(className, layerPtr); 75 for (int i = 0; i < m_indentLevel; i++) { 76 m_stream->writeText(" "); 77 } 78 m_stream->writeText(className); 79 m_stream->writeText("@"); 80 m_stream->writeHexAsText(layerPtr->uniqueId()); 81 m_stream->writeText(" "); 82 83 writeHexVal(ID, (int) layerPtr); 84 writeIntVal(LEFT, layerPtr->getPosition().fX); 85 writeIntVal(TOP, layerPtr->getPosition().fY); 86 writeIntVal(WIDTH, layerPtr->getWidth()); 87 writeIntVal(HEIGHT, layerPtr->getHeight()); 88 } 89 90 virtual void beginChildren(int childCount) { 91 m_stream->writeText("\n"); 92 LayerDumper::beginChildren(childCount); 93 } 94 95 protected: 96 virtual void writeEntry(const char* label, const char* value) { 97 m_stream->writeText(label); 98 m_stream->writeText("="); 99 int len = strlen(value); 100 m_stream->writeDecAsText(len); 101 m_stream->writeText(","); 102 m_stream->writeText(value); 103 m_stream->writeText(" "); 104 } 105 106 private: 107 SkWStream* m_stream; 108 }; 109 110 static void nativeDumpLayerHierarchy(JNIEnv* env, jobject, jint jbaseLayer, jint level, 111 jobject jstream, jbyteArray jstorage) 112 { 113 SkWStream *stream = CreateJavaOutputStreamAdaptor(env, jstream, jstorage); 114 BaseLayerAndroid* baseLayer = reinterpret_cast<BaseLayerAndroid*>(jbaseLayer); 115 SkSafeRef(baseLayer); 116 HierarchyLayerDumper dumper(stream, level); 117 baseLayer->dumpLayers(&dumper); 118 SkSafeUnref(baseLayer); 119 delete stream; 120 } 121 122 static bool nativeSerializeViewState(JNIEnv* env, jobject, jint jbaseLayer, 123 jobject jstream, jbyteArray jstorage) 124 { 125 BaseLayerAndroid* baseLayer = (BaseLayerAndroid*) jbaseLayer; 126 if (!baseLayer) 127 return false; 128 129 SkWStream *stream = CreateJavaOutputStreamAdaptor(env, jstream, jstorage); 130 #if USE(ACCELERATED_COMPOSITING) 131 stream->write32(baseLayer->getBackgroundColor().rgb()); 132 #else 133 stream->write32(0); 134 #endif 135 if (!stream) 136 return false; 137 if (baseLayer->content()) 138 baseLayer->content()->serialize(stream); 139 else 140 return false; 141 int childCount = baseLayer->countChildren(); 142 ALOGV("BaseLayer has %d child(ren)", childCount); 143 stream->write32(childCount); 144 for (int i = 0; i < childCount; i++) { 145 LayerAndroid* layer = static_cast<LayerAndroid*>(baseLayer->getChild(i)); 146 serializeLayer(layer, stream); 147 } 148 delete stream; 149 return true; 150 } 151 152 static BaseLayerAndroid* nativeDeserializeViewState(JNIEnv* env, jobject, jint version, 153 jobject jstream, jbyteArray jstorage) 154 { 155 SkStream* stream = CreateJavaInputStreamAdaptor(env, jstream, jstorage); 156 if (!stream) 157 return 0; 158 Color color = stream->readU32(); 159 SkPicture* picture = new SkPicture(stream); 160 PictureLayerContent* content = new PictureLayerContent(picture); 161 162 BaseLayerAndroid* layer = new BaseLayerAndroid(content); 163 layer->setBackgroundColor(color); 164 165 SkRegion dirtyRegion; 166 dirtyRegion.setRect(0, 0, content->width(), content->height()); 167 layer->markAsDirty(dirtyRegion); 168 169 SkSafeUnref(content); 170 SkSafeUnref(picture); 171 int childCount = stream->readS32(); 172 for (int i = 0; i < childCount; i++) { 173 LayerAndroid* childLayer = deserializeLayer(version, stream); 174 if (childLayer) 175 layer->addChild(childLayer); 176 } 177 delete stream; 178 return layer; 179 } 180 181 // Serialization helpers 182 183 void writeMatrix(SkWStream *stream, const SkMatrix& matrix) 184 { 185 for (int i = 0; i < 9; i++) 186 stream->writeScalar(matrix[i]); 187 } 188 189 SkMatrix readMatrix(SkStream *stream) 190 { 191 SkMatrix matrix; 192 for (int i = 0; i < 9; i++) 193 matrix.set(i, stream->readScalar()); 194 return matrix; 195 } 196 197 void writeSkLength(SkWStream *stream, SkLength length) 198 { 199 stream->write32(length.type); 200 stream->writeScalar(length.value); 201 } 202 203 SkLength readSkLength(SkStream *stream) 204 { 205 SkLength len; 206 len.type = (SkLength::SkLengthType) stream->readU32(); 207 len.value = stream->readScalar(); 208 return len; 209 } 210 211 void writeSkRect(SkWStream *stream, SkRect rect) 212 { 213 stream->writeScalar(rect.fLeft); 214 stream->writeScalar(rect.fTop); 215 stream->writeScalar(rect.fRight); 216 stream->writeScalar(rect.fBottom); 217 } 218 219 SkRect readSkRect(SkStream *stream) 220 { 221 SkRect rect; 222 rect.fLeft = stream->readScalar(); 223 rect.fTop = stream->readScalar(); 224 rect.fRight = stream->readScalar(); 225 rect.fBottom = stream->readScalar(); 226 return rect; 227 } 228 229 void writeTransformationMatrix(SkWStream *stream, TransformationMatrix& matrix) 230 { 231 double value; 232 int dsize = sizeof(double); 233 value = matrix.m11(); 234 stream->write(&value, dsize); 235 value = matrix.m12(); 236 stream->write(&value, dsize); 237 value = matrix.m13(); 238 stream->write(&value, dsize); 239 value = matrix.m14(); 240 stream->write(&value, dsize); 241 value = matrix.m21(); 242 stream->write(&value, dsize); 243 value = matrix.m22(); 244 stream->write(&value, dsize); 245 value = matrix.m23(); 246 stream->write(&value, dsize); 247 value = matrix.m24(); 248 stream->write(&value, dsize); 249 value = matrix.m31(); 250 stream->write(&value, dsize); 251 value = matrix.m32(); 252 stream->write(&value, dsize); 253 value = matrix.m33(); 254 stream->write(&value, dsize); 255 value = matrix.m34(); 256 stream->write(&value, dsize); 257 value = matrix.m41(); 258 stream->write(&value, dsize); 259 value = matrix.m42(); 260 stream->write(&value, dsize); 261 value = matrix.m43(); 262 stream->write(&value, dsize); 263 value = matrix.m44(); 264 stream->write(&value, dsize); 265 } 266 267 void readTransformationMatrix(SkStream *stream, TransformationMatrix& matrix) 268 { 269 double value; 270 int dsize = sizeof(double); 271 stream->read(&value, dsize); 272 matrix.setM11(value); 273 stream->read(&value, dsize); 274 matrix.setM12(value); 275 stream->read(&value, dsize); 276 matrix.setM13(value); 277 stream->read(&value, dsize); 278 matrix.setM14(value); 279 stream->read(&value, dsize); 280 matrix.setM21(value); 281 stream->read(&value, dsize); 282 matrix.setM22(value); 283 stream->read(&value, dsize); 284 matrix.setM23(value); 285 stream->read(&value, dsize); 286 matrix.setM24(value); 287 stream->read(&value, dsize); 288 matrix.setM31(value); 289 stream->read(&value, dsize); 290 matrix.setM32(value); 291 stream->read(&value, dsize); 292 matrix.setM33(value); 293 stream->read(&value, dsize); 294 matrix.setM34(value); 295 stream->read(&value, dsize); 296 matrix.setM41(value); 297 stream->read(&value, dsize); 298 matrix.setM42(value); 299 stream->read(&value, dsize); 300 matrix.setM43(value); 301 stream->read(&value, dsize); 302 matrix.setM44(value); 303 } 304 305 void serializeLayer(LayerAndroid* layer, SkWStream* stream) 306 { 307 if (!layer) { 308 ALOGV("NULL layer!"); 309 stream->write8(LTNone); 310 return; 311 } 312 if (layer->isMedia() || layer->isVideo()) { 313 ALOGV("Layer isn't supported for serialization: isMedia: %s, isVideo: %s", 314 layer->isMedia() ? "true" : "false", 315 layer->isVideo() ? "true" : "false"); 316 stream->write8(LTNone); 317 return; 318 } 319 LayerTypes type = LTLayerAndroid; 320 if (layer->contentIsScrollable()) 321 type = LTScrollableLayerAndroid; 322 stream->write8(type); 323 324 // Start with Layer fields 325 stream->writeBool(layer->shouldInheritFromRootTransform()); 326 stream->writeScalar(layer->getOpacity()); 327 stream->writeScalar(layer->getSize().width()); 328 stream->writeScalar(layer->getSize().height()); 329 stream->writeScalar(layer->getPosition().x()); 330 stream->writeScalar(layer->getPosition().y()); 331 stream->writeScalar(layer->getAnchorPoint().x()); 332 stream->writeScalar(layer->getAnchorPoint().y()); 333 writeMatrix(stream, layer->getMatrix()); 334 writeMatrix(stream, layer->getChildrenMatrix()); 335 336 // Next up, LayerAndroid fields 337 stream->writeBool(layer->m_haveClip); 338 stream->writeBool(layer->isPositionFixed()); 339 stream->writeBool(layer->m_backgroundColorSet); 340 stream->writeBool(layer->isIFrame()); 341 342 // With the current LayerAndroid hierarchy, LayerAndroid doesn't have 343 // those fields anymore. Let's keep the current serialization format for 344 // now and output blank fields... not great, but probably better than 345 // dealing with multiple versions. 346 if (layer->fixedPosition()) { 347 FixedPositioning* fixedPosition = layer->fixedPosition(); 348 writeSkLength(stream, fixedPosition->m_fixedLeft); 349 writeSkLength(stream, fixedPosition->m_fixedTop); 350 writeSkLength(stream, fixedPosition->m_fixedRight); 351 writeSkLength(stream, fixedPosition->m_fixedBottom); 352 writeSkLength(stream, fixedPosition->m_fixedMarginLeft); 353 writeSkLength(stream, fixedPosition->m_fixedMarginTop); 354 writeSkLength(stream, fixedPosition->m_fixedMarginRight); 355 writeSkLength(stream, fixedPosition->m_fixedMarginBottom); 356 writeSkRect(stream, fixedPosition->m_fixedRect); 357 stream->write32(fixedPosition->m_renderLayerPos.x()); 358 stream->write32(fixedPosition->m_renderLayerPos.y()); 359 } else { 360 SkLength length; 361 SkRect rect; 362 writeSkLength(stream, length); // fixedLeft 363 writeSkLength(stream, length); // fixedTop 364 writeSkLength(stream, length); // fixedRight 365 writeSkLength(stream, length); // fixedBottom 366 writeSkLength(stream, length); // fixedMarginLeft 367 writeSkLength(stream, length); // fixedMarginTop 368 writeSkLength(stream, length); // fixedMarginRight 369 writeSkLength(stream, length); // fixedMarginBottom 370 writeSkRect(stream, rect); // fixedRect 371 stream->write32(0); // renderLayerPos.x() 372 stream->write32(0); // renderLayerPos.y() 373 } 374 375 stream->writeBool(layer->m_backfaceVisibility); 376 stream->writeBool(layer->m_visible); 377 stream->write32(layer->m_backgroundColor); 378 stream->writeBool(layer->m_preserves3D); 379 stream->writeScalar(layer->m_anchorPointZ); 380 stream->writeScalar(layer->m_drawOpacity); 381 bool hasContentsImage = layer->m_imageCRC != 0; 382 stream->writeBool(hasContentsImage); 383 if (hasContentsImage) { 384 SkFlattenableWriteBuffer buffer(1024); 385 buffer.setFlags(SkFlattenableWriteBuffer::kCrossProcess_Flag); 386 ImageTexture* imagetexture = 387 ImagesManager::instance()->retainImage(layer->m_imageCRC); 388 if (imagetexture && imagetexture->bitmap()) 389 imagetexture->bitmap()->flatten(buffer); 390 ImagesManager::instance()->releaseImage(layer->m_imageCRC); 391 stream->write32(buffer.size()); 392 buffer.writeToStream(stream); 393 } 394 bool hasRecordingPicture = layer->m_content != 0 && !layer->m_content->isEmpty(); 395 stream->writeBool(hasRecordingPicture); 396 if (hasRecordingPicture) 397 layer->m_content->serialize(stream); 398 // TODO: support m_animations (maybe?) 399 stream->write32(0); // placeholder for m_animations.size(); 400 writeTransformationMatrix(stream, layer->m_transform); 401 writeTransformationMatrix(stream, layer->m_childrenTransform); 402 if (type == LTScrollableLayerAndroid) { 403 ScrollableLayerAndroid* scrollableLayer = 404 static_cast<ScrollableLayerAndroid*>(layer); 405 stream->writeScalar(scrollableLayer->m_scrollLimits.fLeft); 406 stream->writeScalar(scrollableLayer->m_scrollLimits.fTop); 407 stream->writeScalar(scrollableLayer->m_scrollLimits.width()); 408 stream->writeScalar(scrollableLayer->m_scrollLimits.height()); 409 } 410 int childCount = layer->countChildren(); 411 stream->write32(childCount); 412 for (int i = 0; i < childCount; i++) 413 serializeLayer(layer->getChild(i), stream); 414 } 415 416 LayerAndroid* deserializeLayer(int version, SkStream* stream) 417 { 418 int type = stream->readU8(); 419 if (type == LTNone) 420 return 0; 421 // Cast is to disambiguate between ctors. 422 LayerAndroid *layer; 423 if (type == LTLayerAndroid) 424 layer = new LayerAndroid((RenderLayer*) 0); 425 else if (type == LTScrollableLayerAndroid) 426 layer = new ScrollableLayerAndroid((RenderLayer*) 0); 427 else { 428 ALOGV("Unexpected layer type: %d, aborting!", type); 429 return 0; 430 } 431 432 // Layer fields 433 layer->setShouldInheritFromRootTransform(stream->readBool()); 434 layer->setOpacity(stream->readScalar()); 435 layer->setSize(stream->readScalar(), stream->readScalar()); 436 layer->setPosition(stream->readScalar(), stream->readScalar()); 437 layer->setAnchorPoint(stream->readScalar(), stream->readScalar()); 438 layer->setMatrix(readMatrix(stream)); 439 layer->setChildrenMatrix(readMatrix(stream)); 440 441 // LayerAndroid fields 442 layer->m_haveClip = stream->readBool(); 443 444 // Keep the legacy serialization/deserialization format... 445 bool isFixed = stream->readBool(); 446 447 layer->m_backgroundColorSet = stream->readBool(); 448 449 bool isIframe = stream->readBool(); 450 // If we are a scrollable layer android, we are an iframe content 451 if (isIframe && type == LTScrollableLayerAndroid) { 452 IFrameContentLayerAndroid* iframeContent = new IFrameContentLayerAndroid(*layer); 453 layer->unref(); 454 layer = iframeContent; 455 } else if (isIframe) { // otherwise we are just the iframe (we use it to compute offset) 456 IFrameLayerAndroid* iframe = new IFrameLayerAndroid(*layer); 457 layer->unref(); 458 layer = iframe; 459 } 460 461 if (isFixed) { 462 FixedPositioning* fixedPosition = new FixedPositioning(layer); 463 464 fixedPosition->m_fixedLeft = readSkLength(stream); 465 fixedPosition->m_fixedTop = readSkLength(stream); 466 fixedPosition->m_fixedRight = readSkLength(stream); 467 fixedPosition->m_fixedBottom = readSkLength(stream); 468 fixedPosition->m_fixedMarginLeft = readSkLength(stream); 469 fixedPosition->m_fixedMarginTop = readSkLength(stream); 470 fixedPosition->m_fixedMarginRight = readSkLength(stream); 471 fixedPosition->m_fixedMarginBottom = readSkLength(stream); 472 fixedPosition->m_fixedRect = readSkRect(stream); 473 fixedPosition->m_renderLayerPos.setX(stream->readS32()); 474 fixedPosition->m_renderLayerPos.setY(stream->readS32()); 475 476 layer->setFixedPosition(fixedPosition); 477 } else { 478 // Not a fixed element, bypass the values in the stream 479 readSkLength(stream); // fixedLeft 480 readSkLength(stream); // fixedTop 481 readSkLength(stream); // fixedRight 482 readSkLength(stream); // fixedBottom 483 readSkLength(stream); // fixedMarginLeft 484 readSkLength(stream); // fixedMarginTop 485 readSkLength(stream); // fixedMarginRight 486 readSkLength(stream); // fixedMarginBottom 487 readSkRect(stream); // fixedRect 488 stream->readS32(); // renderLayerPos.x() 489 stream->readS32(); // renderLayerPos.y() 490 } 491 492 layer->m_backfaceVisibility = stream->readBool(); 493 layer->m_visible = stream->readBool(); 494 layer->m_backgroundColor = stream->readU32(); 495 layer->m_preserves3D = stream->readBool(); 496 layer->m_anchorPointZ = stream->readScalar(); 497 layer->m_drawOpacity = stream->readScalar(); 498 bool hasContentsImage = stream->readBool(); 499 if (hasContentsImage) { 500 int size = stream->readU32(); 501 SkAutoMalloc storage(size); 502 stream->read(storage.get(), size); 503 SkFlattenableReadBuffer buffer(storage.get(), size); 504 SkBitmap contentsImage; 505 contentsImage.unflatten(buffer); 506 SkBitmapRef* imageRef = new SkBitmapRef(contentsImage); 507 layer->setContentsImage(imageRef); 508 delete imageRef; 509 } 510 bool hasRecordingPicture = stream->readBool(); 511 if (hasRecordingPicture) { 512 SkPicture* picture = new SkPicture(stream); 513 PictureLayerContent* content = new PictureLayerContent(picture); 514 layer->setContent(content); 515 SkSafeUnref(content); 516 SkSafeUnref(picture); 517 } 518 int animationCount = stream->readU32(); // TODO: Support (maybe?) 519 readTransformationMatrix(stream, layer->m_transform); 520 readTransformationMatrix(stream, layer->m_childrenTransform); 521 if (type == LTScrollableLayerAndroid) { 522 ScrollableLayerAndroid* scrollableLayer = 523 static_cast<ScrollableLayerAndroid*>(layer); 524 scrollableLayer->m_scrollLimits.set( 525 stream->readScalar(), 526 stream->readScalar(), 527 stream->readScalar(), 528 stream->readScalar()); 529 } 530 int childCount = stream->readU32(); 531 for (int i = 0; i < childCount; i++) { 532 LayerAndroid *childLayer = deserializeLayer(version, stream); 533 if (childLayer) 534 layer->addChild(childLayer); 535 } 536 ALOGV("Created layer with id %d", layer->uniqueId()); 537 return layer; 538 } 539 540 /* 541 * JNI registration 542 */ 543 static JNINativeMethod gSerializerMethods[] = { 544 { "nativeDumpLayerHierarchy", "(IILjava/io/OutputStream;[B)V", 545 (void*) nativeDumpLayerHierarchy }, 546 { "nativeSerializeViewState", "(ILjava/io/OutputStream;[B)Z", 547 (void*) nativeSerializeViewState }, 548 { "nativeDeserializeViewState", "(ILjava/io/InputStream;[B)I", 549 (void*) nativeDeserializeViewState }, 550 }; 551 552 int registerViewStateSerializer(JNIEnv* env) 553 { 554 return jniRegisterNativeMethods(env, "android/webkit/ViewStateSerializer", 555 gSerializerMethods, NELEM(gSerializerMethods)); 556 } 557 558 } 559