use of com.android.ide.common.rendering.api.SessionParams in project android_frameworks_base by DirtyUnicorns.
the class RenderSessionImpl method render.
/**
* Renders the scene.
* <p>
* {@link #acquire(long)} must have been called before this.
*
* @param freshRender whether the render is a new one and should erase the existing bitmap (in
* the case where bitmaps are reused). This is typically needed when not playing
* animations.)
*
* @throws IllegalStateException if the current context is different than the one owned by
* the scene, or if {@link #acquire(long)} was not called.
*
* @see SessionParams#getRenderingMode()
* @see RenderSession#render(long)
*/
public Result render(boolean freshRender) {
checkLock();
SessionParams params = getParams();
try {
if (mViewRoot == null) {
return ERROR_NOT_INFLATED.createResult();
}
measure(params);
HardwareConfig hardwareConfig = params.getHardwareConfig();
Result renderResult = SUCCESS.createResult();
if (params.isLayoutOnly()) {
// delete the canvas and image to reset them on the next full rendering
mImage = null;
mCanvas = null;
} else {
// draw the views
// create the BufferedImage into which the layout will be rendered.
boolean newImage = false;
// When disableBitmapCaching is true, we do not reuse mImage and
// we create a new one in every render.
// This is useful when mImage is just a wrapper of Graphics2D so
// it doesn't get cached.
boolean disableBitmapCaching = Boolean.TRUE.equals(params.getFlag(RenderParamsFlags.FLAG_KEY_DISABLE_BITMAP_CACHING));
if (mNewRenderSize || mCanvas == null || disableBitmapCaching) {
mNewRenderSize = false;
if (params.getImageFactory() != null) {
mImage = params.getImageFactory().getImage(mMeasuredScreenWidth, mMeasuredScreenHeight);
} else {
mImage = new BufferedImage(mMeasuredScreenWidth, mMeasuredScreenHeight, BufferedImage.TYPE_INT_ARGB);
newImage = true;
}
if (params.isBgColorOverridden()) {
// since we override the content, it's the same as if it was a new image.
newImage = true;
Graphics2D gc = mImage.createGraphics();
gc.setColor(new Color(params.getOverrideBgColor(), true));
gc.setComposite(AlphaComposite.Src);
gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
gc.dispose();
}
// create an Android bitmap around the BufferedImage
Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage, true, /*isMutable*/
hardwareConfig.getDensity());
if (mCanvas == null) {
// create a Canvas around the Android bitmap
mCanvas = new Canvas(bitmap);
} else {
mCanvas.setBitmap(bitmap);
}
mCanvas.setDensity(hardwareConfig.getDensity().getDpiValue());
}
if (freshRender && !newImage) {
Graphics2D gc = mImage.createGraphics();
gc.setComposite(AlphaComposite.Src);
gc.setColor(new Color(0x00000000, true));
gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
// done
gc.dispose();
}
if (mElapsedFrameTimeNanos >= 0) {
long initialTime = System_Delegate.nanoTime();
if (!mFirstFrameExecuted) {
// We need to run an initial draw call to initialize the animations
render(getContext(), mViewRoot, NOP_CANVAS, mMeasuredScreenWidth, mMeasuredScreenHeight);
// The first frame will initialize the animations
Choreographer_Delegate.doFrame(initialTime);
mFirstFrameExecuted = true;
}
// Second frame will move the animations
Choreographer_Delegate.doFrame(initialTime + mElapsedFrameTimeNanos);
}
renderResult = render(getContext(), mViewRoot, mCanvas, mMeasuredScreenWidth, mMeasuredScreenHeight);
}
mSystemViewInfoList = visitAllChildren(mViewRoot, 0, params.getExtendedViewInfoMode(), false);
// success!
return renderResult;
} catch (Throwable e) {
// get the real cause of the exception.
Throwable t = e;
while (t.getCause() != null) {
t = t.getCause();
}
return ERROR_UNKNOWN.createResult(t.getMessage(), t);
}
}
use of com.android.ide.common.rendering.api.SessionParams in project android_frameworks_base by DirtyUnicorns.
the class Main method testScrolling.
/** Test activity.xml */
@Test
public void testScrolling() throws ClassNotFoundException {
// Create the layout pull parser.
LayoutPullParser parser = createLayoutPullParser("scrolled.xml");
// Create LayoutLibCallback.
LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
layoutLibCallback.initResources();
SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5, layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false, RenderingMode.V_SCROLL, 22);
params.setForceNoDecor();
params.setExtendedViewInfoMode(true);
RenderResult result = renderAndVerify(params, "scrolled.png");
assertNotNull(result);
assertTrue(result.getResult().isSuccess());
ViewInfo rootLayout = result.getRootViews().get(0);
// Check the first box in the main LinearLayout
assertEquals(-90, rootLayout.getChildren().get(0).getTop());
assertEquals(-30, rootLayout.getChildren().get(0).getLeft());
assertEquals(90, rootLayout.getChildren().get(0).getBottom());
assertEquals(150, rootLayout.getChildren().get(0).getRight());
// Check the first box within the nested LinearLayout
assertEquals(-450, rootLayout.getChildren().get(5).getChildren().get(0).getTop());
assertEquals(90, rootLayout.getChildren().get(5).getChildren().get(0).getLeft());
assertEquals(-270, rootLayout.getChildren().get(5).getChildren().get(0).getBottom());
assertEquals(690, rootLayout.getChildren().get(5).getChildren().get(0).getRight());
}
use of com.android.ide.common.rendering.api.SessionParams in project android_frameworks_base by DirtyUnicorns.
the class Main method testVectorDrawable.
/**
* Test a vector drawable that uses trimStart and trimEnd. It also tests all the primitives
* for vector drawables (lines, moves and cubic and quadratic curves).
*/
@Test
public void testVectorDrawable() throws ClassNotFoundException {
// Create the layout pull parser.
LayoutPullParser parser = createLayoutPullParser("vector_drawable.xml");
// Create LayoutLibCallback.
LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
layoutLibCallback.initResources();
SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5, layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false, RenderingMode.V_SCROLL, 22);
renderAndVerify(params, "vector_drawable.png", TimeUnit.SECONDS.toNanos(2));
}
use of com.android.ide.common.rendering.api.SessionParams in project android_frameworks_base by AOSPA.
the class RenderSessionImpl method postInflateProcess.
/**
* Post process on a view hierarchy that was just inflated.
* <p/>
* At the moment this only supports TabHost: If {@link TabHost} is detected, look for the
* {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically
* based on the content of the {@link FrameLayout}.
* @param view the root view to process.
* @param layoutlibCallback callback to the project.
* @param skip the view and it's children are not processed.
*/
// For the use of Pair
@SuppressWarnings("deprecation")
private void postInflateProcess(View view, LayoutlibCallback layoutlibCallback, View skip) throws PostInflateException {
if (view == skip) {
return;
}
if (view instanceof TabHost) {
setupTabHost((TabHost) view, layoutlibCallback);
} else if (view instanceof QuickContactBadge) {
QuickContactBadge badge = (QuickContactBadge) view;
badge.setImageToDefault();
} else if (view instanceof AdapterView<?>) {
// get the view ID.
int id = view.getId();
BridgeContext context = getContext();
// get a ResourceReference from the integer ID.
ResourceReference listRef = context.resolveId(id);
if (listRef != null) {
SessionParams params = getParams();
AdapterBinding binding = params.getAdapterBindings().get(listRef);
// if there was no adapter binding, trying to get it from the call back.
if (binding == null) {
binding = layoutlibCallback.getAdapterBinding(listRef, context.getViewKey(view), view);
}
if (binding != null) {
if (view instanceof AbsListView) {
if ((binding.getFooterCount() > 0 || binding.getHeaderCount() > 0) && view instanceof ListView) {
ListView list = (ListView) view;
boolean skipCallbackParser = false;
int count = binding.getHeaderCount();
for (int i = 0; i < count; i++) {
Pair<View, Boolean> pair = context.inflateView(binding.getHeaderAt(i), list, false, skipCallbackParser);
if (pair.getFirst() != null) {
list.addHeaderView(pair.getFirst());
}
skipCallbackParser |= pair.getSecond();
}
count = binding.getFooterCount();
for (int i = 0; i < count; i++) {
Pair<View, Boolean> pair = context.inflateView(binding.getFooterAt(i), list, false, skipCallbackParser);
if (pair.getFirst() != null) {
list.addFooterView(pair.getFirst());
}
skipCallbackParser |= pair.getSecond();
}
}
if (view instanceof ExpandableListView) {
((ExpandableListView) view).setAdapter(new FakeExpandableAdapter(listRef, binding, layoutlibCallback));
} else {
((AbsListView) view).setAdapter(new FakeAdapter(listRef, binding, layoutlibCallback));
}
} else if (view instanceof AbsSpinner) {
((AbsSpinner) view).setAdapter(new FakeAdapter(listRef, binding, layoutlibCallback));
}
}
}
} else if (view instanceof ViewGroup) {
mInflater.postInflateProcess(view);
ViewGroup group = (ViewGroup) view;
final int count = group.getChildCount();
for (int c = 0; c < count; c++) {
View child = group.getChildAt(c);
postInflateProcess(child, layoutlibCallback, skip);
}
}
}
use of com.android.ide.common.rendering.api.SessionParams in project android_frameworks_base by AOSPA.
the class RenderSessionImpl method render.
/**
* Renders the scene.
* <p>
* {@link #acquire(long)} must have been called before this.
*
* @param freshRender whether the render is a new one and should erase the existing bitmap (in
* the case where bitmaps are reused). This is typically needed when not playing
* animations.)
*
* @throws IllegalStateException if the current context is different than the one owned by
* the scene, or if {@link #acquire(long)} was not called.
*
* @see SessionParams#getRenderingMode()
* @see RenderSession#render(long)
*/
public Result render(boolean freshRender) {
checkLock();
SessionParams params = getParams();
try {
if (mViewRoot == null) {
return ERROR_NOT_INFLATED.createResult();
}
measure(params);
HardwareConfig hardwareConfig = params.getHardwareConfig();
Result renderResult = SUCCESS.createResult();
if (params.isLayoutOnly()) {
// delete the canvas and image to reset them on the next full rendering
mImage = null;
mCanvas = null;
} else {
// draw the views
// create the BufferedImage into which the layout will be rendered.
boolean newImage = false;
// When disableBitmapCaching is true, we do not reuse mImage and
// we create a new one in every render.
// This is useful when mImage is just a wrapper of Graphics2D so
// it doesn't get cached.
boolean disableBitmapCaching = Boolean.TRUE.equals(params.getFlag(RenderParamsFlags.FLAG_KEY_DISABLE_BITMAP_CACHING));
if (mNewRenderSize || mCanvas == null || disableBitmapCaching) {
mNewRenderSize = false;
if (params.getImageFactory() != null) {
mImage = params.getImageFactory().getImage(mMeasuredScreenWidth, mMeasuredScreenHeight);
} else {
mImage = new BufferedImage(mMeasuredScreenWidth, mMeasuredScreenHeight, BufferedImage.TYPE_INT_ARGB);
newImage = true;
}
if (params.isBgColorOverridden()) {
// since we override the content, it's the same as if it was a new image.
newImage = true;
Graphics2D gc = mImage.createGraphics();
gc.setColor(new Color(params.getOverrideBgColor(), true));
gc.setComposite(AlphaComposite.Src);
gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
gc.dispose();
}
// create an Android bitmap around the BufferedImage
Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage, true, /*isMutable*/
hardwareConfig.getDensity());
if (mCanvas == null) {
// create a Canvas around the Android bitmap
mCanvas = new Canvas(bitmap);
} else {
mCanvas.setBitmap(bitmap);
}
mCanvas.setDensity(hardwareConfig.getDensity().getDpiValue());
}
if (freshRender && !newImage) {
Graphics2D gc = mImage.createGraphics();
gc.setComposite(AlphaComposite.Src);
gc.setColor(new Color(0x00000000, true));
gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
// done
gc.dispose();
}
if (mElapsedFrameTimeNanos >= 0) {
long initialTime = System_Delegate.nanoTime();
if (!mFirstFrameExecuted) {
// We need to run an initial draw call to initialize the animations
render(getContext(), mViewRoot, NOP_CANVAS, mMeasuredScreenWidth, mMeasuredScreenHeight);
// The first frame will initialize the animations
Choreographer_Delegate.doFrame(initialTime);
mFirstFrameExecuted = true;
}
// Second frame will move the animations
Choreographer_Delegate.doFrame(initialTime + mElapsedFrameTimeNanos);
}
renderResult = render(getContext(), mViewRoot, mCanvas, mMeasuredScreenWidth, mMeasuredScreenHeight);
}
mSystemViewInfoList = visitAllChildren(mViewRoot, 0, params.getExtendedViewInfoMode(), false);
// success!
return renderResult;
} catch (Throwable e) {
// get the real cause of the exception.
Throwable t = e;
while (t.getCause() != null) {
t = t.getCause();
}
return ERROR_UNKNOWN.createResult(t.getMessage(), t);
}
}
Aggregations