/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.litho.displaylist;
import java.lang.reflect.Method;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.view.DisplayListCanvas;
import android.view.RenderNode;
import android.view.View;
import static com.facebook.litho.displaylist.Utils.safeInvoke;
/**
* Implementation of {@link PlatformDisplayList} for Android Marshmallow.
*/
public class DisplayListMarshmallow implements PlatformDisplayList {
private static Class sRenderNodeClass;
private static Method sStartMethod;
protected static boolean sInitialized = false;
protected static boolean sInitializationFailed = false;
protected final RenderNode mDisplayList;
protected static void ensureInitialized() throws Exception {
if (sInitialized || sInitializationFailed) {
return;
}
// Unfortunately we still need to use reflection here since in Marshmallow Google changed
// the return of this method from HardwareCanvas to DisplayListCanvas.
sRenderNodeClass = Class.forName("android.view.RenderNode");
sStartMethod = sRenderNodeClass.getDeclaredMethod("start", int.class, int.class);
sInitialized = true;
}
static PlatformDisplayList createDisplayList(String debugName) {
try {
ensureInitialized();
if (sInitialized) {
RenderNode renderNode = RenderNode.create(debugName, null);
return new DisplayListMarshmallow(renderNode);
}
} catch (Throwable e) {
sInitializationFailed = true;
}
return null;
}
DisplayListMarshmallow(RenderNode displayList) {
mDisplayList = displayList;
}
@Override
public Canvas start(int width, int height) throws DisplayListException {
return (Canvas) safeInvoke(sStartMethod, mDisplayList, width, height);
}
@Override
public void end(Canvas canvas) {
Object displayListCanvas = canvas;
mDisplayList.end((DisplayListCanvas) displayListCanvas);
}
@Override
public void clear() {
mDisplayList.destroyDisplayListData();
}
@Override
public void print(Canvas canvas) {
mDisplayList.output();
}
@Override
public void draw(Canvas canvas) throws DisplayListException {
Object displayListCanvas = canvas;
if (!(displayListCanvas instanceof DisplayListCanvas)) {
throw new DisplayListException(new ClassCastException());
}
((DisplayListCanvas) displayListCanvas).drawRenderNode(mDisplayList);
}
@Override
public void setBounds(int left, int top, int right, int bottom) {
mDisplayList.setLeftTopRightBottom(left, top, right, bottom);
mDisplayList.setClipToBounds(false);
}
@Override
public boolean isValid() {
return mDisplayList.isValid();
}
}