diff options
159 files changed, 7385 insertions, 4112 deletions
diff --git a/core/java/com/android/internal/widget/remotecompose/core/CompanionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/CompanionOperation.java index deae9a571e12..244bb3d6380b 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/CompanionOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/CompanionOperation.java @@ -17,15 +17,13 @@ package com.android.internal.widget.remotecompose.core; import java.util.List; -/** - * Interface for the companion operations - */ +/** Interface for the companion operations */ public interface CompanionOperation { /** * Read, create and add instance to operations + * * @param buffer data to read to create operation * @param operations command is to be added */ void read(WireBuffer buffer, List<Operation> operations); } - diff --git a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java index 18be4809998c..212df02b1bd3 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java +++ b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java @@ -16,6 +16,7 @@ package com.android.internal.widget.remotecompose.core; import com.android.internal.widget.remotecompose.core.operations.ComponentValue; +import com.android.internal.widget.remotecompose.core.operations.IntegerExpression; import com.android.internal.widget.remotecompose.core.operations.NamedVariable; import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior; import com.android.internal.widget.remotecompose.core.operations.Theme; @@ -25,6 +26,8 @@ import com.android.internal.widget.remotecompose.core.operations.layout.Componen import com.android.internal.widget.remotecompose.core.operations.layout.ComponentEnd; import com.android.internal.widget.remotecompose.core.operations.layout.ComponentStartOperation; import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponent; +import com.android.internal.widget.remotecompose.core.operations.layout.LoopEnd; +import com.android.internal.widget.remotecompose.core.operations.layout.LoopOperation; import com.android.internal.widget.remotecompose.core.operations.layout.RootLayoutComponent; import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ComponentModifiers; import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ModifierOperation; @@ -33,11 +36,12 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.Strin import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Set; /** - * Represents a platform independent RemoteCompose document, - * containing RemoteCompose operations + state + * Represents a platform independent RemoteCompose document, containing RemoteCompose operations + + * state */ public class CoreDocument { @@ -66,6 +70,8 @@ public class CoreDocument { RemoteComposeBuffer mBuffer = new RemoteComposeBuffer(mRemoteComposeState); + private final HashMap<Long, IntegerExpression> mIntegerExpressions = new HashMap<>(); + private int mLastId = 1; // last component id when inflating the file public String getContentDescription() { @@ -133,21 +139,14 @@ public class CoreDocument { /** * Sets the way the player handles the content * - * @param scroll set the horizontal behavior (NONE|SCROLL_HORIZONTAL|SCROLL_VERTICAL) + * @param scroll set the horizontal behavior (NONE|SCROLL_HORIZONTAL|SCROLL_VERTICAL) * @param alignment set the alignment of the content (TOP|CENTER|BOTTOM|START|END) - * @param sizing set the type of sizing for the content (NONE|SIZING_LAYOUT|SIZING_SCALE) - * @param mode set the mode of sizing, either LAYOUT modes or SCALE modes - * the LAYOUT modes are: - * - LAYOUT_MATCH_PARENT - * - LAYOUT_WRAP_CONTENT - * or adding an horizontal mode and a vertical mode: - * - LAYOUT_HORIZONTAL_MATCH_PARENT - * - LAYOUT_HORIZONTAL_WRAP_CONTENT - * - LAYOUT_HORIZONTAL_FIXED - * - LAYOUT_VERTICAL_MATCH_PARENT - * - LAYOUT_VERTICAL_WRAP_CONTENT - * - LAYOUT_VERTICAL_FIXED - * The LAYOUT_*_FIXED modes will use the intrinsic document size + * @param sizing set the type of sizing for the content (NONE|SIZING_LAYOUT|SIZING_SCALE) + * @param mode set the mode of sizing, either LAYOUT modes or SCALE modes the LAYOUT modes are: + * - LAYOUT_MATCH_PARENT - LAYOUT_WRAP_CONTENT or adding an horizontal mode and a vertical + * mode: - LAYOUT_HORIZONTAL_MATCH_PARENT - LAYOUT_HORIZONTAL_WRAP_CONTENT - + * LAYOUT_HORIZONTAL_FIXED - LAYOUT_VERTICAL_MATCH_PARENT - LAYOUT_VERTICAL_WRAP_CONTENT - + * LAYOUT_VERTICAL_FIXED The LAYOUT_*_FIXED modes will use the intrinsic document size */ public void setRootContentBehavior(int scroll, int alignment, int sizing, int mode) { this.mContentScroll = scroll; @@ -160,8 +159,8 @@ public class CoreDocument { * Given dimensions w x h of where to paint the content, returns the corresponding scale factor * according to the contentSizing information * - * @param w horizontal dimension of the rendering area - * @param h vertical dimension of the rendering area + * @param w horizontal dimension of the rendering area + * @param h vertical dimension of the rendering area * @param scaleOutput will contain the computed scale factor */ public void computeScale(float w, float h, float[] scaleOutput) { @@ -169,50 +168,47 @@ public class CoreDocument { float contentScaleY = 1f; if (mContentSizing == RootContentBehavior.SIZING_SCALE) { // we need to add canvas transforms ops here + float scaleX = 1f; + float scaleY = 1f; + float scale = 1f; switch (mContentMode) { - case RootContentBehavior.SCALE_INSIDE: { - float scaleX = w / mWidth; - float scaleY = h / mHeight; - float scale = Math.min(1f, Math.min(scaleX, scaleY)); + case RootContentBehavior.SCALE_INSIDE: + scaleX = w / mWidth; + scaleY = h / mHeight; + scale = Math.min(1f, Math.min(scaleX, scaleY)); contentScaleX = scale; contentScaleY = scale; - } - break; - case RootContentBehavior.SCALE_FIT: { - float scaleX = w / mWidth; - float scaleY = h / mHeight; - float scale = Math.min(scaleX, scaleY); + break; + case RootContentBehavior.SCALE_FIT: + scaleX = w / mWidth; + scaleY = h / mHeight; + scale = Math.min(scaleX, scaleY); contentScaleX = scale; contentScaleY = scale; - } - break; - case RootContentBehavior.SCALE_FILL_WIDTH: { - float scale = w / mWidth; + break; + case RootContentBehavior.SCALE_FILL_WIDTH: + scale = w / mWidth; contentScaleX = scale; contentScaleY = scale; - } - break; - case RootContentBehavior.SCALE_FILL_HEIGHT: { - float scale = h / mHeight; + break; + case RootContentBehavior.SCALE_FILL_HEIGHT: + scale = h / mHeight; contentScaleX = scale; contentScaleY = scale; - } - break; - case RootContentBehavior.SCALE_CROP: { - float scaleX = w / mWidth; - float scaleY = h / mHeight; - float scale = Math.max(scaleX, scaleY); + break; + case RootContentBehavior.SCALE_CROP: + scaleX = w / mWidth; + scaleY = h / mHeight; + scale = Math.max(scaleX, scaleY); contentScaleX = scale; contentScaleY = scale; - } - break; - case RootContentBehavior.SCALE_FILL_BOUNDS: { - float scaleX = w / mWidth; - float scaleY = h / mHeight; + break; + case RootContentBehavior.SCALE_FILL_BOUNDS: + scaleX = w / mWidth; + scaleY = h / mHeight; contentScaleX = scaleX; contentScaleY = scaleY; - } - break; + break; default: // nothing } @@ -225,14 +221,14 @@ public class CoreDocument { * Given dimensions w x h of where to paint the content, returns the corresponding translation * according to the contentAlignment information * - * @param w horizontal dimension of the rendering area - * @param h vertical dimension of the rendering area - * @param contentScaleX the horizontal scale we are going to use for the content - * @param contentScaleY the vertical scale we are going to use for the content + * @param w horizontal dimension of the rendering area + * @param h vertical dimension of the rendering area + * @param contentScaleX the horizontal scale we are going to use for the content + * @param contentScaleY the vertical scale we are going to use for the content * @param translateOutput will contain the computed translation */ - private void computeTranslate(float w, float h, float contentScaleX, float contentScaleY, - float[] translateOutput) { + private void computeTranslate( + float w, float h, float contentScaleX, float contentScaleY, float[] translateOutput) { int horizontalContentAlignment = mContentAlignment & 0xF0; int verticalContentAlignment = mContentAlignment & 0xF; float translateX = 0f; @@ -241,34 +237,28 @@ public class CoreDocument { float contentHeight = mHeight * contentScaleY; switch (horizontalContentAlignment) { - case RootContentBehavior.ALIGNMENT_START: { + case RootContentBehavior.ALIGNMENT_START: // nothing - } - break; - case RootContentBehavior.ALIGNMENT_HORIZONTAL_CENTER: { + break; + case RootContentBehavior.ALIGNMENT_HORIZONTAL_CENTER: translateX = (w - contentWidth) / 2f; - } - break; - case RootContentBehavior.ALIGNMENT_END: { + break; + case RootContentBehavior.ALIGNMENT_END: translateX = w - contentWidth; - } - break; + break; default: // nothing (same as alignment_start) } switch (verticalContentAlignment) { - case RootContentBehavior.ALIGNMENT_TOP: { + case RootContentBehavior.ALIGNMENT_TOP: // nothing - } - break; - case RootContentBehavior.ALIGNMENT_VERTICAL_CENTER: { + break; + case RootContentBehavior.ALIGNMENT_VERTICAL_CENTER: translateY = (h - contentHeight) / 2f; - } - break; - case RootContentBehavior.ALIGNMENT_BOTTOM: { + break; + case RootContentBehavior.ALIGNMENT_BOTTOM: translateY = h - contentHeight; - } - break; + break; default: // nothing (same as alignment_top) } @@ -279,6 +269,7 @@ public class CoreDocument { /** * Returns the list of click areas + * * @return list of click areas in document coordinates */ public Set<ClickAreaRepresentation> getClickAreas() { @@ -287,15 +278,14 @@ public class CoreDocument { /** * Returns the root layout component + * * @return returns the root component if it exists, null otherwise */ public RootLayoutComponent getRootLayoutComponent() { return mRootLayoutComponent; } - /** - * Invalidate the document for layout measures. This will trigger a layout remeasure pass. - */ + /** Invalidate the document for layout measures. This will trigger a layout remeasure pass. */ public void invalidateMeasure() { if (mRootLayoutComponent != null) { mRootLayoutComponent.invalidateMeasure(); @@ -304,6 +294,7 @@ public class CoreDocument { /** * Returns the component with the given id + * * @param id component id * @return the component if it exists, null otherwise */ @@ -332,8 +323,21 @@ public class CoreDocument { } /** - * Callback interface for host actions + * Execute an integer expression with the given id and put its value on the targetId + * + * @param expressionId the id of the integer expression + * @param targetId the id of the value to update with the expression + * @param context the current context */ + public void evaluateIntExpression(long expressionId, int targetId, RemoteContext context) { + IntegerExpression expression = mIntegerExpressions.get(expressionId); + if (expression != null) { + int v = expression.evaluate(context); + context.overrideInteger(targetId, v); + } + } + + /** Callback interface for host actions */ public interface ActionCallback { // TODO: add payload support void onAction(String name); @@ -343,6 +347,7 @@ public class CoreDocument { /** * Warn action listeners for the given named action + * * @param name the action name */ public void runNamedAction(String name) { @@ -360,9 +365,7 @@ public class CoreDocument { mActionListeners.add(callback); } - /** - * Clear existing callbacks for named host actions - */ + /** Clear existing callbacks for named host actions */ public void clearActionCallbacks() { mActionListeners.clear(); } @@ -395,13 +398,14 @@ public class CoreDocument { float mBottom; String mMetadata; - public ClickAreaRepresentation(int id, - String contentDescription, - float left, - float top, - float right, - float bottom, - String metadata) { + public ClickAreaRepresentation( + int id, + String contentDescription, + float left, + float top, + float right, + float bottom, + String metadata) { this.mId = id; this.mContentDescription = contentDescription; this.mLeft = left; @@ -419,8 +423,7 @@ public class CoreDocument { * @return x, y coordinate is within bounds */ public boolean contains(float x, float y) { - return x >= mLeft && x < mRight - && y >= mTop && y < mBottom; + return x >= mLeft && x < mRight && y >= mTop && y < mBottom; } public float getLeft() { @@ -452,12 +455,16 @@ public class CoreDocument { } } - /** - * Load operations from the given buffer - */ + /** Load operations from the given buffer */ public void initFromBuffer(RemoteComposeBuffer buffer) { mOperations = new ArrayList<Operation>(); buffer.inflateFromBuffer(mOperations); + for (Operation op : mOperations) { + if (op instanceof IntegerExpression) { + IntegerExpression expression = (IntegerExpression) op; + mIntegerExpressions.put((long) expression.mId, expression); + } + } mOperations = inflateComponents(mOperations); mBuffer = buffer; for (Operation op : mOperations) { @@ -473,6 +480,7 @@ public class CoreDocument { /** * Inflate a component tree + * * @param operations flat list of operations * @return nested list of operations / components */ @@ -482,6 +490,7 @@ public class CoreDocument { ArrayList<Operation> finalOperationsList = new ArrayList<>(); ArrayList<Operation> ops = finalOperationsList; ClickModifierOperation currentClickModifier = null; + LoopOperation currentLoop = null; mLastId = -1; for (Operation o : operations) { @@ -509,11 +518,22 @@ public class CoreDocument { } else if (o instanceof ClickModifierOperation) { // TODO: refactor to add container <- component... currentClickModifier = (ClickModifierOperation) o; - ops = ((ClickModifierOperation) o).getList(); + ops = currentClickModifier.getList(); } else if (o instanceof ClickModifierEnd) { ops = currentComponent.getList(); ops.add(currentClickModifier); currentClickModifier = null; + } else if (o instanceof LoopOperation) { + currentLoop = (LoopOperation) o; + ops = currentLoop.getList(); + } else if (o instanceof LoopEnd) { + if (currentComponent != null) { + ops = currentComponent.getList(); + ops.add(currentLoop); + } else { + ops = finalOperationsList; + } + currentLoop = null; } else { ops.add(o); } @@ -555,8 +575,8 @@ public class CoreDocument { } /** - * Called when an initialization is needed, allowing the document to eg load - * resources / cache them. + * Called when an initialization is needed, allowing the document to eg load resources / cache + * them. */ public void initializeContext(RemoteContext context) { mRemoteComposeState.reset(); @@ -593,7 +613,7 @@ public class CoreDocument { * * @param majorVersion major version number, increased upon changes breaking the compatibility * @param minorVersion minor version number, increased when adding new features - * @param patch patch level, increased upon bugfixes + * @param patch patch level, increased upon bugfixes */ void setVersion(int majorVersion, int minorVersion, int patch) { mVersion = new Version(majorVersion, minorVersion, patch); @@ -605,22 +625,29 @@ public class CoreDocument { /** * Add a click area to the document, in root coordinates. We are not doing any specific sorting - * through the declared areas on click detections, which means that the first one containing - * the click coordinates will be the one reported; the order of addition of those click areas - * is therefore meaningful. + * through the declared areas on click detections, which means that the first one containing the + * click coordinates will be the one reported; the order of addition of those click areas is + * therefore meaningful. * - * @param id the id of the area, which will be reported on click + * @param id the id of the area, which will be reported on click * @param contentDescription the content description (used for accessibility) - * @param left the left coordinate of the click area (in pixels) - * @param top the top coordinate of the click area (in pixels) - * @param right the right coordinate of the click area (in pixels) - * @param bottom the bottom coordinate of the click area (in pixels) - * @param metadata arbitrary metadata associated with the are, also reported on click + * @param left the left coordinate of the click area (in pixels) + * @param top the top coordinate of the click area (in pixels) + * @param right the right coordinate of the click area (in pixels) + * @param bottom the bottom coordinate of the click area (in pixels) + * @param metadata arbitrary metadata associated with the are, also reported on click */ - public void addClickArea(int id, String contentDescription, - float left, float top, float right, float bottom, String metadata) { - mClickAreas.add(new ClickAreaRepresentation(id, - contentDescription, left, top, right, bottom, metadata)); + public void addClickArea( + int id, + String contentDescription, + float left, + float top, + float right, + float bottom, + String metadata) { + mClickAreas.add( + new ClickAreaRepresentation( + id, contentDescription, left, top, right, bottom, metadata)); } /** @@ -672,9 +699,7 @@ public class CoreDocument { } } - /** - * Warn click listeners when a click area is activated - */ + /** Warn click listeners when a click area is activated */ private void warnClickListeners(ClickAreaRepresentation clickArea) { for (ClickCallbacks listener : mClickListeners) { listener.click(clickArea.mId, clickArea.mMetadata); @@ -743,10 +768,9 @@ public class CoreDocument { * Paint the document * * @param context the provided PaintContext - * @param theme the theme we want to use for this document. + * @param theme the theme we want to use for this document. */ public void paint(RemoteContext context, int theme) { - long time = System.nanoTime(); context.getPaintContext().clearNeedsRepaint(); context.mMode = RemoteContext.ContextMode.UNSET; @@ -760,8 +784,12 @@ public class CoreDocument { if (mContentSizing == RootContentBehavior.SIZING_SCALE) { // we need to add canvas transforms ops here computeScale(context.mWidth, context.mHeight, mScaleOutput); - computeTranslate(context.mWidth, context.mHeight, - mScaleOutput[0], mScaleOutput[1], mTranslateOutput); + computeTranslate( + context.mWidth, + context.mHeight, + mScaleOutput[0], + mScaleOutput[1], + mTranslateOutput); context.mPaintContext.translate(mTranslateOutput[0], mTranslateOutput[1]); context.mPaintContext.scale(mScaleOutput[0], mScaleOutput[1]); } @@ -795,9 +823,10 @@ public class CoreDocument { // or the theme is equal as the one passed in argument to paint. boolean apply = true; if (theme != Theme.UNSPECIFIED) { - apply = op instanceof Theme // always apply a theme setter - || context.getTheme() == theme - || context.getTheme() == Theme.UNSPECIFIED; + apply = + op instanceof Theme // always apply a theme setter + || context.getTheme() == theme + || context.getTheme() == Theme.UNSPECIFIED; } if (apply) { op.apply(context); @@ -808,7 +837,10 @@ public class CoreDocument { mRepaintNext = 1; } context.mMode = RemoteContext.ContextMode.UNSET; - // System.out.println(">> " + ( System.nanoTime() - time)*1E-6f+" ms"); + // System.out.println(">> " + ( System.nanoTime() - time)*1E-6f+" ms"); + if (DEBUG && mRootLayoutComponent != null) { + System.out.println(mRootLayoutComponent.displayHierarchy()); + } } public String[] getStats() { @@ -831,7 +863,6 @@ public class CoreDocument { if (mOperation instanceof Component) { Component com = (Component) mOperation; count += addChildren(com, map, buffer); - } } @@ -893,5 +924,8 @@ public class CoreDocument { } } } -} + public List<Operation> getOperations() { + return mOperations; + } +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/DocumentedCompanion.java b/core/java/com/android/internal/widget/remotecompose/core/DocumentedCompanion.java index 661cf7cf4491..8a792a43f047 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/DocumentedCompanion.java +++ b/core/java/com/android/internal/widget/remotecompose/core/DocumentedCompanion.java @@ -17,6 +17,4 @@ package com.android.internal.widget.remotecompose.core; import com.android.internal.widget.remotecompose.core.documentation.DocumentedCompanionOperation; -public interface DocumentedCompanion extends CompanionOperation , DocumentedCompanionOperation { - -} +public interface DocumentedCompanion extends CompanionOperation, DocumentedCompanionOperation {} diff --git a/core/java/com/android/internal/widget/remotecompose/core/Operation.java b/core/java/com/android/internal/widget/remotecompose/core/Operation.java index 4a8b3d7a76d4..9f565a2915fb 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/Operation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/Operation.java @@ -15,14 +15,10 @@ */ package com.android.internal.widget.remotecompose.core; -/** - * Base interface for RemoteCompose operations - */ +/** Base interface for RemoteCompose operations */ public interface Operation { - /** - * add the operation to the buffer - */ + /** add the operation to the buffer */ void write(WireBuffer buffer); /** @@ -32,8 +28,6 @@ public interface Operation { */ void apply(RemoteContext context); - /** - * Debug utility to display an operation + indentation - */ + /** Debug utility to display an operation + indentation */ String deepToString(String indent); } diff --git a/core/java/com/android/internal/widget/remotecompose/core/Operations.java b/core/java/com/android/internal/widget/remotecompose/core/Operations.java index 4a25b5eff3c9..acebe0761b79 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/Operations.java +++ b/core/java/com/android/internal/widget/remotecompose/core/Operations.java @@ -25,15 +25,18 @@ import com.android.internal.widget.remotecompose.core.operations.ComponentValue; import com.android.internal.widget.remotecompose.core.operations.DataListFloat; import com.android.internal.widget.remotecompose.core.operations.DataListIds; import com.android.internal.widget.remotecompose.core.operations.DataMapIds; +import com.android.internal.widget.remotecompose.core.operations.DataMapLookup; import com.android.internal.widget.remotecompose.core.operations.DrawArc; import com.android.internal.widget.remotecompose.core.operations.DrawBitmap; import com.android.internal.widget.remotecompose.core.operations.DrawBitmapInt; +import com.android.internal.widget.remotecompose.core.operations.DrawBitmapScaled; import com.android.internal.widget.remotecompose.core.operations.DrawCircle; import com.android.internal.widget.remotecompose.core.operations.DrawLine; import com.android.internal.widget.remotecompose.core.operations.DrawOval; import com.android.internal.widget.remotecompose.core.operations.DrawPath; import com.android.internal.widget.remotecompose.core.operations.DrawRect; import com.android.internal.widget.remotecompose.core.operations.DrawRoundRect; +import com.android.internal.widget.remotecompose.core.operations.DrawSector; import com.android.internal.widget.remotecompose.core.operations.DrawText; import com.android.internal.widget.remotecompose.core.operations.DrawTextAnchored; import com.android.internal.widget.remotecompose.core.operations.DrawTextOnPath; @@ -56,6 +59,10 @@ import com.android.internal.widget.remotecompose.core.operations.RootContentDesc import com.android.internal.widget.remotecompose.core.operations.ShaderData; import com.android.internal.widget.remotecompose.core.operations.TextData; import com.android.internal.widget.remotecompose.core.operations.TextFromFloat; +import com.android.internal.widget.remotecompose.core.operations.TextLength; +import com.android.internal.widget.remotecompose.core.operations.TextLookup; +import com.android.internal.widget.remotecompose.core.operations.TextLookupInt; +import com.android.internal.widget.remotecompose.core.operations.TextMeasure; import com.android.internal.widget.remotecompose.core.operations.TextMerge; import com.android.internal.widget.remotecompose.core.operations.Theme; import com.android.internal.widget.remotecompose.core.operations.layout.CanvasContent; @@ -64,12 +71,15 @@ import com.android.internal.widget.remotecompose.core.operations.layout.ClickMod import com.android.internal.widget.remotecompose.core.operations.layout.ComponentEnd; import com.android.internal.widget.remotecompose.core.operations.layout.ComponentStart; import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponentContent; +import com.android.internal.widget.remotecompose.core.operations.layout.LoopEnd; +import com.android.internal.widget.remotecompose.core.operations.layout.LoopOperation; import com.android.internal.widget.remotecompose.core.operations.layout.RootLayoutComponent; import com.android.internal.widget.remotecompose.core.operations.layout.animation.AnimationSpec; import com.android.internal.widget.remotecompose.core.operations.layout.managers.BoxLayout; import com.android.internal.widget.remotecompose.core.operations.layout.managers.CanvasLayout; import com.android.internal.widget.remotecompose.core.operations.layout.managers.ColumnLayout; import com.android.internal.widget.remotecompose.core.operations.layout.managers.RowLayout; +import com.android.internal.widget.remotecompose.core.operations.layout.managers.StateLayout; import com.android.internal.widget.remotecompose.core.operations.layout.managers.TextLayout; import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.BackgroundModifierOperation; import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.BorderModifierOperation; @@ -81,6 +91,7 @@ import com.android.internal.widget.remotecompose.core.operations.layout.modifier import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.PaddingModifierOperation; import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.RoundedClipRectModifierOperation; import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ValueIntegerChangeActionOperation; +import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ValueIntegerExpressionChangeActionOperation; import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ValueStringChangeActionOperation; import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.WidthModifierOperation; import com.android.internal.widget.remotecompose.core.operations.utilities.IntMap; @@ -88,9 +99,7 @@ import com.android.internal.widget.remotecompose.core.types.BooleanConstant; import com.android.internal.widget.remotecompose.core.types.IntegerConstant; import com.android.internal.widget.remotecompose.core.types.LongConstant; -/** - * List of operations supported in a RemoteCompose document - */ +/** List of operations supported in a RemoteCompose document */ public class Operations { //////////////////////////////////////// @@ -112,7 +121,7 @@ public class Operations { public static final int DATA_SHADER = 45; public static final int DATA_TEXT = 102; - /////////////////////////////===================== + ///////////////////////////// ===================== public static final int CLIP_PATH = 38; public static final int CLIP_RECT = 39; public static final int PAINT_VALUES = 40; @@ -121,7 +130,7 @@ public class Operations { public static final int DRAW_CIRCLE = 46; public static final int DRAW_LINE = 47; public static final int DRAW_ROUND_RECT = 51; - public static final int DRAW_ARC = 52; + public static final int DRAW_SECTOR = 52; public static final int DRAW_TEXT_ON_PATH = 53; public static final int DRAW_OVAL = 56; public static final int DATA_PATH = 123; @@ -149,8 +158,15 @@ public class Operations { public static final int ID_LIST = 146; public static final int FLOAT_LIST = 147; public static final int DATA_LONG = 148; + public static final int DRAW_BITMAP_SCALED = 149; + public static final int TEXT_LOOKUP = 151; + public static final int DRAW_ARC = 152; + public static final int TEXT_LOOKUP_INT = 153; + public static final int DATA_MAP_LOOKUP = 154; + public static final int TEXT_MEASURE = 155; + public static final int TEXT_LENGTH = 156; - /////////////////////////////////////////====================== + ///////////////////////////////////////// ====================== //////////////////////////////////////// // Layout commands @@ -163,10 +179,12 @@ public class Operations { public static final int LAYOUT_COLUMN = 204; public static final int LAYOUT_CANVAS = 205; public static final int LAYOUT_CANVAS_CONTENT = 207; - public static final int LAYOUT_TEXT = 208; + public static final int LAYOUT_STATE = 217; + public static final int COMPONENT_START = 2; public static final int COMPONENT_END = 3; + public static final int MODIFIER_WIDTH = 16; public static final int MODIFIER_HEIGHT = 67; public static final int MODIFIER_BACKGROUND = 55; @@ -178,6 +196,8 @@ public class Operations { public static final int MODIFIER_CLICK = 59; public static final int MODIFIER_CLICK_END = 214; + public static final int LOOP_START = 215; + public static final int LOOP_END = 216; public static final int MODIFIER_VISIBILITY = 211; public static final int HOST_ACTION = 209; @@ -185,6 +205,7 @@ public class Operations { public static final int VALUE_INTEGER_CHANGE_ACTION = 212; public static final int VALUE_STRING_CHANGE_ACTION = 213; + public static final int VALUE_INTEGER_EXPRESSION_CHANGE_ACTION = 218; public static final int ANIMATION_SPEC = 14; @@ -194,7 +215,7 @@ public class Operations { static class UniqueIntMap<T> extends IntMap<T> { @Override - public T put(int key, T value) { + public T put(int key, T value) { assert null == get(key) : "Opcode " + key + " already used in Operations !"; return super.put(key, value); } @@ -210,7 +231,7 @@ public class Operations { map.put(ROOT_CONTENT_BEHAVIOR, RootContentBehavior::read); map.put(ROOT_CONTENT_DESCRIPTION, RootContentDescription::read); - map.put(DRAW_ARC, DrawArc::read); + map.put(DRAW_SECTOR, DrawSector::read); map.put(DRAW_BITMAP, DrawBitmap::read); map.put(DRAW_CIRCLE, DrawCircle::read); map.put(DRAW_LINE, DrawLine::read); @@ -247,6 +268,12 @@ public class Operations { map.put(ID_LIST, DataListIds::read); map.put(FLOAT_LIST, DataListFloat::read); map.put(DATA_LONG, LongConstant::read); + map.put(DRAW_BITMAP_SCALED, DrawBitmapScaled::read); + map.put(TEXT_LOOKUP, TextLookup::read); + map.put(TEXT_LOOKUP_INT, TextLookupInt::read); + + map.put(LOOP_START, LoopOperation::read); + map.put(LOOP_END, LoopEnd::read); // Layout @@ -267,6 +294,9 @@ public class Operations { map.put(HOST_ACTION, HostActionOperation::read); map.put(HOST_NAMED_ACTION, HostNamedActionOperation::read); map.put(VALUE_INTEGER_CHANGE_ACTION, ValueIntegerChangeActionOperation::read); + map.put( + VALUE_INTEGER_EXPRESSION_CHANGE_ACTION, + ValueIntegerExpressionChangeActionOperation::read); map.put(VALUE_STRING_CHANGE_ACTION, ValueStringChangeActionOperation::read); map.put(LAYOUT_ROOT, RootLayoutComponent::read); @@ -278,6 +308,12 @@ public class Operations { map.put(LAYOUT_CANVAS_CONTENT, CanvasContent::read); map.put(LAYOUT_TEXT, TextLayout::read); + map.put(LAYOUT_STATE, StateLayout::read); + map.put(COMPONENT_VALUE, ComponentValue::read); + map.put(DRAW_ARC, DrawArc::read); + map.put(DATA_MAP_LOOKUP, DataMapLookup::read); + map.put(TEXT_MEASURE, TextMeasure::read); + map.put(TEXT_LENGTH, TextLength::read); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java b/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java index 4770b122d172..13d6f783a586 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java +++ b/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java @@ -17,15 +17,14 @@ package com.android.internal.widget.remotecompose.core; import com.android.internal.widget.remotecompose.core.operations.paint.PaintBundle; -/** - * Specify an abstract paint context used by RemoteCompose commands to draw - */ +/** Specify an abstract paint context used by RemoteCompose commands to draw */ public abstract class PaintContext { public static final int TEXT_MEASURE_MONOSPACE_WIDTH = 0x01; public static final int TEXT_MEASURE_FONT_HEIGHT = 0x02; protected RemoteContext mContext; private boolean mNeedsRepaint = false; + public RemoteContext getContext() { return mContext; } @@ -46,43 +45,43 @@ public abstract class PaintContext { this.mContext = context; } - /** - * convenience function to call matrixSave() - */ + /** convenience function to call matrixSave() */ public void save() { matrixSave(); } - /** - * convenience function to call matrixRestore() - */ + /** convenience function to call matrixRestore() */ public void restore() { matrixRestore(); } - /** - * convenience function to call matrixSave() - */ + /** convenience function to call matrixSave() */ public void saveLayer(float x, float y, float width, float height) { // TODO matrixSave(); } - public abstract void drawBitmap(int imageId, - int srcLeft, int srcTop, int srcRight, int srcBottom, - int dstLeft, int dstTop, int dstRight, int dstBottom, - int cdId); + public abstract void drawBitmap( + int imageId, + int srcLeft, + int srcTop, + int srcRight, + int srcBottom, + int dstLeft, + int dstTop, + int dstRight, + int dstBottom, + int cdId); public abstract void scale(float scaleX, float scaleY); public abstract void translate(float translateX, float translateY); - public abstract void drawArc(float left, - float top, - float right, - float bottom, - float startAngle, - float sweepAngle); + public abstract void drawArc( + float left, float top, float right, float bottom, float startAngle, float sweepAngle); + + public abstract void drawSector( + float left, float top, float right, float bottom, float startAngle, float sweepAngle); public abstract void drawBitmap(int id, float left, float top, float right, float bottom); @@ -96,43 +95,29 @@ public abstract class PaintContext { public abstract void drawRect(float left, float top, float right, float bottom); - /** - * this caches the paint to a paint stack - */ - public abstract void savePaint(); + /** this caches the paint to a paint stack */ + public abstract void savePaint(); - /** - * This restores the paint form the paint stack - */ - public abstract void restorePaint(); + /** This restores the paint form the paint stack */ + public abstract void restorePaint(); - public abstract void drawRoundRect(float left, - float top, - float right, - float bottom, - float radiusX, - float radiusY); + public abstract void drawRoundRect( + float left, float top, float right, float bottom, float radiusX, float radiusY); public abstract void drawTextOnPath(int textId, int pathId, float hOffset, float vOffset); /** - * Return the dimensions (left, top, right, bottom). - * Relative to a drawTextRun x=0, y=0; + * Return the dimensions (left, top, right, bottom). Relative to a drawTextRun x=0, y=0; * * @param textId * @param start - * @param end if end is -1 it means the whole string - * @param flags how to measure: - * TEXT_MEASURE_MONOSPACE_WIDTH - measure as a monospace font - * TEXT_MEASURE_FULL_HEIGHT - measure bounds of the given string using the - * max ascend and descent of the font (not just of the measured text) + * @param end if end is -1 it means the whole string + * @param flags how to measure: TEXT_MEASURE_MONOSPACE_WIDTH - measure as a monospace font + * TEXT_MEASURE_FULL_HEIGHT - measure bounds of the given string using the max ascend and + * descent of the font (not just of the measured text) * @param bounds the bounds (left, top, right, bottom) */ - public abstract void getTextBounds(int textId, - int start, - int end, - int flags, - float[]bounds); + public abstract void getTextBounds(int textId, int start, int end, int flags, float[] bounds); /** * Draw a text starting ast x,y @@ -146,38 +131,38 @@ public abstract class PaintContext { * @param y * @param rtl */ - public abstract void drawTextRun(int textId, - int start, - int end, - int contextStart, - int contextEnd, - float x, - float y, - boolean rtl); + public abstract void drawTextRun( + int textId, + int start, + int end, + int contextStart, + int contextEnd, + float x, + float y, + boolean rtl); /** * Draw an interpolation between two paths + * * @param path1Id * @param path2Id - * @param tween 0.0 = is path1 1.0 is path2 + * @param tween 0.0 = is path1 1.0 is path2 * @param start * @param stop */ - public abstract void drawTweenPath(int path1Id, - int path2Id, - float tween, - float start, - float stop); + public abstract void drawTweenPath( + int path1Id, int path2Id, float tween, float start, float stop); /** * This applies changes to the current paint + * * @param mPaintData the list of changes */ public abstract void applyPaint(PaintBundle mPaintData); /** - * Scale the rendering by scaleX and saleY (1.0 = no scale). - * Scaling is done about centerX,centerY. + * Scale the rendering by scaleX and saleY (1.0 = no scale). Scaling is done about + * centerX,centerY. * * @param scaleX * @param scaleY @@ -188,6 +173,7 @@ public abstract class PaintContext { /** * Translate the rendering + * * @param translateX * @param translateY */ @@ -195,33 +181,30 @@ public abstract class PaintContext { /** * Skew the rendering + * * @param skewX * @param skewY */ public abstract void matrixSkew(float skewX, float skewY); /** - * Rotate the rendering. - * Note rotates are cumulative. + * Rotate the rendering. Note rotates are cumulative. + * * @param rotate angle to rotate * @param pivotX x-coordinate about which to rotate * @param pivotY y-coordinate about which to rotate */ public abstract void matrixRotate(float rotate, float pivotX, float pivotY); - /** - * Save the current state of the transform - */ + /** Save the current state of the transform */ public abstract void matrixSave(); - /** - * Restore the previously saved state of the transform - */ + /** Restore the previously saved state of the transform */ public abstract void matrixRestore(); /** - * Set the clip to a rectangle. - * Drawing outside the current clip region will have no effect + * Set the clip to a rectangle. Drawing outside the current clip region will have no effect + * * @param left * @param top * @param right @@ -231,13 +214,15 @@ public abstract class PaintContext { /** * Clip based on a path. + * * @param pathId * @param regionOp */ public abstract void clipPath(int pathId, int regionOp); /** - * Clip based ona round rect + * Clip based ona round rect + * * @param width * @param height * @param topStart @@ -245,13 +230,15 @@ public abstract class PaintContext { * @param bottomStart * @param bottomEnd */ - public abstract void roundedClipRect(float width, float height, - float topStart, float topEnd, - float bottomStart, float bottomEnd); - - /** - * Reset the paint - */ + public abstract void roundedClipRect( + float width, + float height, + float topStart, + float topEnd, + float bottomStart, + float bottomEnd); + + /** Reset the paint */ public abstract void reset(); /** @@ -285,4 +272,3 @@ public abstract class PaintContext { mNeedsRepaint = true; } } - diff --git a/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java b/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java index 4a1ccc9d3156..9b7b50f775b0 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java @@ -16,8 +16,8 @@ package com.android.internal.widget.remotecompose.core; /** - * PaintOperation interface, used for operations aimed at painting - * (while any operation _can_ paint, this make it a little more explicit) + * PaintOperation interface, used for operations aimed at painting (while any operation _can_ paint, + * this make it a little more explicit) */ public abstract class PaintOperation implements Operation { @@ -37,4 +37,13 @@ public abstract class PaintOperation implements Operation { } public abstract void paint(PaintContext context); + + /** + * Will return true if the operation is similar enough to the current one, in the context of an + * animated transition. + */ + public boolean suitableForTransition(Operation op) { + // by default expects the op to not be suitable + return false; + } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/Platform.java b/core/java/com/android/internal/widget/remotecompose/core/Platform.java index 903dab49cd06..6725e7e6ac2b 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/Platform.java +++ b/core/java/com/android/internal/widget/remotecompose/core/Platform.java @@ -15,13 +15,36 @@ */ package com.android.internal.widget.remotecompose.core; -/** - * Services that are needed to be provided by the platform during encoding. - */ +/** Services that are needed to be provided by the platform during encoding. */ public interface Platform { byte[] imageToByteArray(Object image); + int getImageWidth(Object image); + int getImageHeight(Object image); - float[] pathToFloatArray(Object image); -} + float[] pathToFloatArray(Object path); + + Platform None = + new Platform() { + @Override + public byte[] imageToByteArray(Object image) { + throw new UnsupportedOperationException(); + } + + @Override + public int getImageWidth(Object image) { + throw new UnsupportedOperationException(); + } + + @Override + public int getImageHeight(Object image) { + throw new UnsupportedOperationException(); + } + + @Override + public float[] pathToFloatArray(Object path) { + throw new UnsupportedOperationException(); + } + }; +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java index 6b1828f0448f..5b5adc28a676 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java +++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java @@ -25,15 +25,18 @@ import com.android.internal.widget.remotecompose.core.operations.ComponentValue; import com.android.internal.widget.remotecompose.core.operations.DataListFloat; import com.android.internal.widget.remotecompose.core.operations.DataListIds; import com.android.internal.widget.remotecompose.core.operations.DataMapIds; +import com.android.internal.widget.remotecompose.core.operations.DataMapLookup; import com.android.internal.widget.remotecompose.core.operations.DrawArc; import com.android.internal.widget.remotecompose.core.operations.DrawBitmap; import com.android.internal.widget.remotecompose.core.operations.DrawBitmapInt; +import com.android.internal.widget.remotecompose.core.operations.DrawBitmapScaled; import com.android.internal.widget.remotecompose.core.operations.DrawCircle; import com.android.internal.widget.remotecompose.core.operations.DrawLine; import com.android.internal.widget.remotecompose.core.operations.DrawOval; import com.android.internal.widget.remotecompose.core.operations.DrawPath; import com.android.internal.widget.remotecompose.core.operations.DrawRect; import com.android.internal.widget.remotecompose.core.operations.DrawRoundRect; +import com.android.internal.widget.remotecompose.core.operations.DrawSector; import com.android.internal.widget.remotecompose.core.operations.DrawText; import com.android.internal.widget.remotecompose.core.operations.DrawTextAnchored; import com.android.internal.widget.remotecompose.core.operations.DrawTextOnPath; @@ -55,6 +58,10 @@ import com.android.internal.widget.remotecompose.core.operations.RootContentBeha import com.android.internal.widget.remotecompose.core.operations.RootContentDescription; import com.android.internal.widget.remotecompose.core.operations.TextData; import com.android.internal.widget.remotecompose.core.operations.TextFromFloat; +import com.android.internal.widget.remotecompose.core.operations.TextLength; +import com.android.internal.widget.remotecompose.core.operations.TextLookup; +import com.android.internal.widget.remotecompose.core.operations.TextLookupInt; +import com.android.internal.widget.remotecompose.core.operations.TextMeasure; import com.android.internal.widget.remotecompose.core.operations.TextMerge; import com.android.internal.widget.remotecompose.core.operations.Theme; import com.android.internal.widget.remotecompose.core.operations.Utils; @@ -62,11 +69,14 @@ import com.android.internal.widget.remotecompose.core.operations.layout.CanvasCo import com.android.internal.widget.remotecompose.core.operations.layout.ComponentEnd; import com.android.internal.widget.remotecompose.core.operations.layout.ComponentStart; import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponentContent; +import com.android.internal.widget.remotecompose.core.operations.layout.LoopEnd; +import com.android.internal.widget.remotecompose.core.operations.layout.LoopOperation; import com.android.internal.widget.remotecompose.core.operations.layout.RootLayoutComponent; import com.android.internal.widget.remotecompose.core.operations.layout.managers.BoxLayout; import com.android.internal.widget.remotecompose.core.operations.layout.managers.CanvasLayout; import com.android.internal.widget.remotecompose.core.operations.layout.managers.ColumnLayout; import com.android.internal.widget.remotecompose.core.operations.layout.managers.RowLayout; +import com.android.internal.widget.remotecompose.core.operations.layout.managers.StateLayout; import com.android.internal.widget.remotecompose.core.operations.layout.managers.TextLayout; import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.BackgroundModifierOperation; import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.BorderModifierOperation; @@ -76,7 +86,9 @@ import com.android.internal.widget.remotecompose.core.operations.layout.modifier import com.android.internal.widget.remotecompose.core.operations.paint.PaintBundle; import com.android.internal.widget.remotecompose.core.operations.utilities.NanMap; import com.android.internal.widget.remotecompose.core.operations.utilities.easing.FloatAnimation; +import com.android.internal.widget.remotecompose.core.types.BooleanConstant; import com.android.internal.widget.remotecompose.core.types.IntegerConstant; +import com.android.internal.widget.remotecompose.core.types.LongConstant; import java.io.File; import java.io.FileInputStream; @@ -86,9 +98,7 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; -/** - * Provides an abstract buffer to encode/decode RemoteCompose operations - */ +/** Provides an abstract buffer to encode/decode RemoteCompose operations */ public class RemoteComposeBuffer { public static final int EASING_CUBIC_STANDARD = FloatAnimation.CUBIC_STANDARD; public static final int EASING_CUBIC_ACCELERATE = FloatAnimation.CUBIC_ACCELERATE; @@ -156,13 +166,13 @@ public class RemoteComposeBuffer { /** * Insert a header * - * @param width the width of the document in pixels - * @param height the height of the document in pixels + * @param width the width of the document in pixels + * @param height the height of the document in pixels * @param contentDescription content description of the document - * @param capabilities bitmask indicating needed capabilities (unused for now) + * @param capabilities bitmask indicating needed capabilities (unused for now) */ - public void header(int width, int height, String contentDescription, - float density, long capabilities) { + public void header( + int width, int height, String contentDescription, float density, long capabilities) { Header.apply(mBuffer, width, height, density, capabilities); int contentDescriptionId = 0; if (contentDescription != null) { @@ -174,8 +184,8 @@ public class RemoteComposeBuffer { /** * Insert a header * - * @param width the width of the document in pixels - * @param height the height of the document in pixels + * @param width the width of the document in pixels + * @param height the height of the document in pixels * @param contentDescription content description of the document */ public void header(int width, int height, String contentDescription) { @@ -185,23 +195,31 @@ public class RemoteComposeBuffer { /** * Insert a bitmap * - * @param image an opaque image that we'll add to the buffer - * @param imageWidth the width of the image + * @param image an opaque image that we'll add to the buffer + * @param imageWidth the width of the image * @param imageHeight the height of the image - * @param srcLeft left coordinate of the source area - * @param srcTop top coordinate of the source area - * @param srcRight right coordinate of the source area - * @param srcBottom bottom coordinate of the source area - * @param dstLeft left coordinate of the destination area - * @param dstTop top coordinate of the destination area - * @param dstRight right coordinate of the destination area - * @param dstBottom bottom coordinate of the destination area - */ - public void drawBitmap(Object image, - int imageWidth, int imageHeight, - int srcLeft, int srcTop, int srcRight, int srcBottom, - int dstLeft, int dstTop, int dstRight, int dstBottom, - String contentDescription) { + * @param srcLeft left coordinate of the source area + * @param srcTop top coordinate of the source area + * @param srcRight right coordinate of the source area + * @param srcBottom bottom coordinate of the source area + * @param dstLeft left coordinate of the destination area + * @param dstTop top coordinate of the destination area + * @param dstRight right coordinate of the destination area + * @param dstBottom bottom coordinate of the destination area + */ + public void drawBitmap( + Object image, + int imageWidth, + int imageHeight, + int srcLeft, + int srcTop, + int srcRight, + int srcBottom, + int dstLeft, + int dstTop, + int dstRight, + int dstBottom, + String contentDescription) { int imageId = mRemoteComposeState.dataGetId(image); if (imageId == -1) { imageId = mRemoteComposeState.cacheData(image); @@ -213,14 +231,39 @@ public class RemoteComposeBuffer { contentDescriptionId = addText(contentDescription); } DrawBitmapInt.apply( - mBuffer, imageId, srcLeft, srcTop, srcRight, srcBottom, - dstLeft, dstTop, dstRight, dstBottom, contentDescriptionId - ); + mBuffer, + imageId, + srcLeft, + srcTop, + srcRight, + srcBottom, + dstLeft, + dstTop, + dstRight, + dstBottom, + contentDescriptionId); } /** - * Adds a text string data to the stream and returns its id - * Will be used to insert string with bitmaps etc. + * look up map and return the id of the object looked up + * + * @param mapId the map to access + * @param strId the string to lookup + * @return id containing the result of the lookup + */ + public int mapLookup(int mapId, int strId) { + int hash = mapId + strId * 33; + int id = mRemoteComposeState.dataGetId(hash); + if (id == -1) { + id = mRemoteComposeState.cacheData(hash); + DataMapLookup.apply(mBuffer, id, mapId, strId); + } + return id; + } + + /** + * Adds a text string data to the stream and returns its id Will be used to insert string with + * bitmaps etc. * * @param text the string to inject in the buffer */ @@ -236,13 +279,13 @@ public class RemoteComposeBuffer { /** * Add a click area to the document * - * @param id the id of the click area, reported in the click listener callback + * @param id the id of the click area, reported in the click listener callback * @param contentDescription the content description of that click area (accessibility) - * @param left left coordinate of the area bounds - * @param top top coordinate of the area bounds - * @param right right coordinate of the area bounds - * @param bottom bottom coordinate of the area bounds - * @param metadata associated metadata, user-provided + * @param left left coordinate of the area bounds + * @param top top coordinate of the area bounds + * @param right right coordinate of the area bounds + * @param bottom bottom coordinate of the area bounds + * @param metadata associated metadata, user-provided */ public void addClickArea( int id, @@ -251,8 +294,7 @@ public class RemoteComposeBuffer { float top, float right, float bottom, - String metadata - ) { + String metadata) { int contentDescriptionId = 0; if (contentDescription != null) { contentDescriptionId = addText(contentDescription); @@ -261,77 +303,204 @@ public class RemoteComposeBuffer { if (metadata != null) { metadataId = addText(metadata); } - ClickArea.apply(mBuffer, id, contentDescriptionId, - left, top, right, bottom, metadataId); + ClickArea.apply(mBuffer, id, contentDescriptionId, left, top, right, bottom, metadataId); } /** * Sets the way the player handles the content * - * @param scroll set the horizontal behavior (NONE|SCROLL_HORIZONTAL|SCROLL_VERTICAL) + * @param scroll set the horizontal behavior (NONE|SCROLL_HORIZONTAL|SCROLL_VERTICAL) * @param alignment set the alignment of the content (TOP|CENTER|BOTTOM|START|END) - * @param sizing set the type of sizing for the content (NONE|SIZING_LAYOUT|SIZING_SCALE) - * @param mode set the mode of sizing, either LAYOUT modes or SCALE modes - * the LAYOUT modes are: - * - LAYOUT_MATCH_PARENT - * - LAYOUT_WRAP_CONTENT - * or adding an horizontal mode and a vertical mode: - * - LAYOUT_HORIZONTAL_MATCH_PARENT - * - LAYOUT_HORIZONTAL_WRAP_CONTENT - * - LAYOUT_HORIZONTAL_FIXED - * - LAYOUT_VERTICAL_MATCH_PARENT - * - LAYOUT_VERTICAL_WRAP_CONTENT - * - LAYOUT_VERTICAL_FIXED - * The LAYOUT_*_FIXED modes will use the intrinsic document size + * @param sizing set the type of sizing for the content (NONE|SIZING_LAYOUT|SIZING_SCALE) + * @param mode set the mode of sizing, either LAYOUT modes or SCALE modes the LAYOUT modes are: + * - LAYOUT_MATCH_PARENT - LAYOUT_WRAP_CONTENT or adding an horizontal mode and a vertical + * mode: - LAYOUT_HORIZONTAL_MATCH_PARENT - LAYOUT_HORIZONTAL_WRAP_CONTENT - + * LAYOUT_HORIZONTAL_FIXED - LAYOUT_VERTICAL_MATCH_PARENT - LAYOUT_VERTICAL_WRAP_CONTENT - + * LAYOUT_VERTICAL_FIXED The LAYOUT_*_FIXED modes will use the intrinsic document size */ public void setRootContentBehavior(int scroll, int alignment, int sizing, int mode) { RootContentBehavior.apply(mBuffer, scroll, alignment, sizing, mode); } /** - * add Drawing the specified arc, which will be scaled to fit inside the specified oval. - * <br> + * add Drawing the specified arc, which will be scaled to fit inside the specified oval. <br> * If the start angle is negative or >= 360, the start angle is treated as start angle modulo - * 360. - * <br> + * 360. <br> * If the sweep angle is >= 360, then the oval is drawn completely. Note that this differs * slightly from SkPath::arcTo, which treats the sweep angle modulo 360. If the sweep angle is - * negative, the sweep angle is treated as sweep angle modulo 360 - * <br> + * negative, the sweep angle is treated as sweep angle modulo 360 <br> * The arc is drawn clockwise. An angle of 0 degrees correspond to the geometric angle of 0 - * degrees (3 o'clock on a watch.) - * <br> + * degrees (3 o'clock on a watch.) <br> * - * @param left left coordinate of oval used to define the shape and size of the arc - * @param top top coordinate of oval used to define the shape and size of the arc - * @param right right coordinate of oval used to define the shape and size of the arc - * @param bottom bottom coordinate of oval used to define the shape and size of the arc + * @param left left coordinate of oval used to define the shape and size of the arc + * @param top top coordinate of oval used to define the shape and size of the arc + * @param right right coordinate of oval used to define the shape and size of the arc + * @param bottom bottom coordinate of oval used to define the shape and size of the arc * @param startAngle Starting angle (in degrees) where the arc begins * @param sweepAngle Sweep angle (in degrees) measured clockwise */ - public void addDrawArc(float left, - float top, - float right, - float bottom, - float startAngle, - float sweepAngle) { + public void addDrawArc( + float left, float top, float right, float bottom, float startAngle, float sweepAngle) { DrawArc.apply(mBuffer, left, top, right, bottom, startAngle, sweepAngle); } /** - * @param image The bitmap to be drawn - * @param left left coordinate of rectangle that the bitmap will be to fit into - * @param top top coordinate of rectangle that the bitmap will be to fit into - * @param right right coordinate of rectangle that the bitmap will be to fit into - * @param bottom bottom coordinate of rectangle that the bitmap will be to fit into + * add Drawing the specified sector, which will be scaled to fit inside the specified oval. <br> + * If the start angle is negative or >= 360, the start angle is treated as start angle modulo + * 360. <br> + * If the sweep angle is >= 360, then the oval is drawn completely. Note that this differs + * slightly from SkPath::arcTo, which treats the sweep angle modulo 360. If the sweep angle is + * negative, the sweep angle is treated as sweep angle modulo 360 <br> + * The arc is drawn clockwise. An angle of 0 degrees correspond to the geometric angle of 0 + * degrees (3 o'clock on a watch.) <br> + * + * @param left left coordinate of oval used to define the shape and size of the arc + * @param top top coordinate of oval used to define the shape and size of the arc + * @param right right coordinate of oval used to define the shape and size of the arc + * @param bottom bottom coordinate of oval used to define the shape and size of the arc + * @param startAngle Starting angle (in degrees) where the arc begins + * @param sweepAngle Sweep angle (in degrees) measured clockwise + */ + public void addDrawSector( + float left, float top, float right, float bottom, float startAngle, float sweepAngle) { + DrawSector.apply(mBuffer, left, top, right, bottom, startAngle, sweepAngle); + } + + /** + * @param image The bitmap to be drawn + * @param left left coordinate of rectangle that the bitmap will be to fit into + * @param top top coordinate of rectangle that the bitmap will be to fit into + * @param right right coordinate of rectangle that the bitmap will be to fit into + * @param bottom bottom coordinate of rectangle that the bitmap will be to fit into + * @param contentDescription content description of the image + */ + public void addDrawBitmap( + Object image, + float left, + float top, + float right, + float bottom, + String contentDescription) { + int imageId = mRemoteComposeState.dataGetId(image); + if (imageId == -1) { + imageId = mRemoteComposeState.cacheData(image); + byte[] data = mPlatform.imageToByteArray(image); + int imageWidth = mPlatform.getImageWidth(image); + int imageHeight = mPlatform.getImageHeight(image); + + BitmapData.apply(mBuffer, imageId, imageWidth, imageHeight, data); + } + int contentDescriptionId = 0; + if (contentDescription != null) { + contentDescriptionId = addText(contentDescription); + } + DrawBitmap.apply(mBuffer, imageId, left, top, right, bottom, contentDescriptionId); + } + + /** + * @param imageId The Id bitmap to be drawn + * @param left left coordinate of rectangle that the bitmap will be to fit into + * @param top top coordinate of rectangle that the bitmap will be to fit into + * @param right right coordinate of rectangle that the bitmap will be to fit into + * @param bottom bottom coordinate of rectangle that the bitmap will be to fit into * @param contentDescription content description of the image */ - public void addDrawBitmap(Object image, - float left, - float top, - float right, - float bottom, - String contentDescription) { + public void addDrawBitmap( + int imageId, + float left, + float top, + float right, + float bottom, + String contentDescription) { + int contentDescriptionId = 0; + if (contentDescription != null) { + contentDescriptionId = addText(contentDescription); + } + DrawBitmap.apply(mBuffer, imageId, left, top, right, bottom, contentDescriptionId); + } + + /** + * @param image The bitmap to be drawn + * @param srcLeft left coordinate in the source bitmap will be to extracted + * @param srcTop top coordinate in the source bitmap will be to extracted + * @param srcRight right coordinate in the source bitmap will be to extracted + * @param srcBottom bottom coordinate in the source bitmap will be to extracted + * @param dstLeft left coordinate of rectangle that the bitmap will be to fit into + * @param dstTop top coordinate of rectangle that the bitmap will be to fit into + * @param dstRight right coordinate of rectangle that the bitmap will be to fit into + * @param dstBottom bottom coordinate of rectangle that the bitmap will be to fit into + * @param scaleType The type of scaling to allow the image to fit. + * @param scaleFactor the scale factor when scale type is FIXED_SCALE (type = 7) + * @param contentDescription associate a string with image for accessibility + */ + public void drawScaledBitmap( + Object image, + float srcLeft, + float srcTop, + float srcRight, + float srcBottom, + float dstLeft, + float dstTop, + float dstRight, + float dstBottom, + int scaleType, + float scaleFactor, + String contentDescription) { + int imageId = mRemoteComposeState.dataGetId(image); + if (imageId == -1) { + imageId = mRemoteComposeState.cacheData(image); + byte[] data = mPlatform.imageToByteArray(image); + int imageWidth = mPlatform.getImageWidth(image); + int imageHeight = mPlatform.getImageHeight(image); + + BitmapData.apply(mBuffer, imageId, imageWidth, imageHeight, data); + } + int contentDescriptionId = 0; + if (contentDescription != null) { + contentDescriptionId = addText(contentDescription); + } + DrawBitmapScaled.apply( + mBuffer, + imageId, + srcLeft, + srcTop, + srcRight, + srcBottom, + dstLeft, + dstTop, + dstRight, + dstBottom, + scaleType, + scaleFactor, + contentDescriptionId); + } + + /** + * Transmit bitmap so the you can use the id form. This is useful if + * + * @param image drawScaledBitmap + * @return id of the image useful with + */ + public int addBitmap(Object image) { + int imageId = mRemoteComposeState.dataGetId(image); + if (imageId == -1) { + imageId = mRemoteComposeState.cacheData(image); + byte[] data = mPlatform.imageToByteArray(image); + int imageWidth = mPlatform.getImageWidth(image); + int imageHeight = mPlatform.getImageHeight(image); + + BitmapData.apply(mBuffer, imageId, imageWidth, imageHeight, data); + } + return imageId; + } + + /** + * Transmit bitmap so the you can use the id form. This is useful if + * + * @param image drawScaledBitmap + * @return id of the image useful with + */ + public int addBitmap(Object image, String name) { int imageId = mRemoteComposeState.dataGetId(image); if (imageId == -1) { imageId = mRemoteComposeState.cacheData(image); @@ -340,14 +509,67 @@ public class RemoteComposeBuffer { int imageHeight = mPlatform.getImageHeight(image); BitmapData.apply(mBuffer, imageId, imageWidth, imageHeight, data); + setBitmapName(imageId, name); } + + return imageId; + } + + /** + * This defines the name of the color given the id. + * + * @param id of the Bitmap + * @param name Name of the color + */ + public void setBitmapName(int id, String name) { + NamedVariable.apply(mBuffer, id, NamedVariable.IMAGE_TYPE, name); + } + + /** + * @param imageId The id of the bitmap to be drawn + * @param srcLeft left coordinate in the source bitmap will be to extracted + * @param srcTop top coordinate in the source bitmap will be to extracted + * @param srcRight right coordinate in the source bitmap will be to extracted + * @param srcBottom bottom coordinate in the source bitmap will be to extracted + * @param dstLeft left coordinate of rectangle that the bitmap will be to fit into + * @param dstTop top coordinate of rectangle that the bitmap will be to fit into + * @param dstRight right coordinate of rectangle that the bitmap will be to fit into + * @param dstBottom bottom coordinate of rectangle that the bitmap will be to fit into + * @param scaleType The type of scaling to allow the image to fit. + * @param scaleFactor the scale factor when scale type is FIXED_SCALE (type = 7) + * @param contentDescription associate a string with image for accessibility + */ + public void drawScaledBitmap( + int imageId, + float srcLeft, + float srcTop, + float srcRight, + float srcBottom, + float dstLeft, + float dstTop, + float dstRight, + float dstBottom, + int scaleType, + float scaleFactor, + String contentDescription) { int contentDescriptionId = 0; if (contentDescription != null) { contentDescriptionId = addText(contentDescription); } - DrawBitmap.apply( - mBuffer, imageId, left, top, right, bottom, contentDescriptionId - ); + DrawBitmapScaled.apply( + mBuffer, + imageId, + srcLeft, + srcTop, + srcRight, + srcBottom, + dstLeft, + dstTop, + dstRight, + dstBottom, + scaleType, + scaleFactor, + contentDescriptionId); } /** @@ -356,7 +578,7 @@ public class RemoteComposeBuffer { * * @param centerX The x-coordinate of the center of the circle to be drawn * @param centerY The y-coordinate of the center of the circle to be drawn - * @param radius The radius of the circle to be drawn + * @param radius The radius of the circle to be drawn */ public void addDrawCircle(float centerX, float centerY, float radius) { DrawCircle.apply(mBuffer, centerX, centerY, radius); @@ -378,9 +600,9 @@ public class RemoteComposeBuffer { /** * Draw the specified oval using the specified paint. * - * @param left left coordinate of oval - * @param top top coordinate of oval - * @param right right coordinate of oval + * @param left left coordinate of oval + * @param top top coordinate of oval + * @param right right coordinate of oval * @param bottom bottom coordinate of oval */ public void addDrawOval(float left, float top, float right, float bottom) { @@ -389,9 +611,9 @@ public class RemoteComposeBuffer { /** * Draw the specified path - * <p> - * Note: path objects are not immutable - * modifying them and calling this will not change the drawing + * + * <p>Note: path objects are not immutable modifying them and calling this will not change the + * drawing * * @param path The path to be drawn */ @@ -415,9 +637,9 @@ public class RemoteComposeBuffer { /** * Draw the specified Rect * - * @param left left coordinate of rectangle to be drawn - * @param top top coordinate of rectangle to be drawn - * @param right right coordinate of rectangle to be drawn + * @param left left coordinate of rectangle to be drawn + * @param top top coordinate of rectangle to be drawn + * @param right right coordinate of rectangle to be drawn * @param bottom bottom coordinate of rectangle to be drawn */ public void addDrawRect(float left, float top, float right, float bottom) { @@ -427,23 +649,23 @@ public class RemoteComposeBuffer { /** * Draw the specified round-rect * - * @param left left coordinate of rectangle to be drawn - * @param top left coordinate of rectangle to be drawn - * @param right left coordinate of rectangle to be drawn - * @param bottom left coordinate of rectangle to be drawn + * @param left left coordinate of rectangle to be drawn + * @param top left coordinate of rectangle to be drawn + * @param right left coordinate of rectangle to be drawn + * @param bottom left coordinate of rectangle to be drawn * @param radiusX The x-radius of the oval used to round the corners * @param radiusY The y-radius of the oval used to round the corners */ - public void addDrawRoundRect(float left, float top, float right, float bottom, - float radiusX, float radiusY) { + public void addDrawRoundRect( + float left, float top, float right, float bottom, float radiusX, float radiusY) { DrawRoundRect.apply(mBuffer, left, top, right, bottom, radiusX, radiusY); } /** * Draw the text, with origin at (x,y) along the specified path. * - * @param text The text to be drawn - * @param path The path the text should follow for its baseline + * @param text The text to be drawn + * @param path The path the text should follow for its baseline * @param hOffset The distance along the path to add to the text's starting position * @param vOffset The distance above(-) or below(+) the path to position the text */ @@ -457,91 +679,79 @@ public class RemoteComposeBuffer { } /** - * Draw the text, with origin at (x,y). The origin is interpreted - * based on the Align setting in the paint. + * Draw the text, with origin at (x,y). The origin is interpreted based on the Align setting in + * the paint. * - * @param text The text to be drawn - * @param start The index of the first character in text to draw - * @param end (end - 1) is the index of the last character in text to draw + * @param text The text to be drawn + * @param start The index of the first character in text to draw + * @param end (end - 1) is the index of the last character in text to draw * @param contextStart * @param contextEnd - * @param x The x-coordinate of the origin of the text being drawn - * @param y The y-coordinate of the baseline of the text being drawn - * @param rtl Draw RTTL - */ - public void addDrawTextRun(String text, - int start, - int end, - int contextStart, - int contextEnd, - float x, - float y, - boolean rtl) { + * @param x The x-coordinate of the origin of the text being drawn + * @param y The y-coordinate of the baseline of the text being drawn + * @param rtl Draw RTTL + */ + public void addDrawTextRun( + String text, + int start, + int end, + int contextStart, + int contextEnd, + float x, + float y, + boolean rtl) { int textId = addText(text); - DrawText.apply( - mBuffer, textId, start, end, - contextStart, contextEnd, x, y, rtl); + DrawText.apply(mBuffer, textId, start, end, contextStart, contextEnd, x, y, rtl); } /** - * Draw the text, with origin at (x,y). The origin is interpreted - * based on the Align setting in the paint. + * Draw the text, with origin at (x,y). The origin is interpreted based on the Align setting in + * the paint. * - * @param textId The text to be drawn - * @param start The index of the first character in text to draw - * @param end (end - 1) is the index of the last character in text to draw + * @param textId The text to be drawn + * @param start The index of the first character in text to draw + * @param end (end - 1) is the index of the last character in text to draw * @param contextStart * @param contextEnd - * @param x The x-coordinate of the origin of the text being drawn - * @param y The y-coordinate of the baseline of the text being drawn - * @param rtl Draw RTTL - */ - public void addDrawTextRun(int textId, - int start, - int end, - int contextStart, - int contextEnd, - float x, - float y, - boolean rtl) { - DrawText.apply( - mBuffer, textId, start, end, - contextStart, contextEnd, x, y, rtl); - } - - /** - * Draw a text on canvas at relative to position (x, y), - * offset panX and panY. - * <br> - * The panning factors (panX, panY) mapped to the - * resulting bounding box of the text, in such a way that a - * panning factor of (0.0, 0.0) would center the text at (x, y) + * @param x The x-coordinate of the origin of the text being drawn + * @param y The y-coordinate of the baseline of the text being drawn + * @param rtl Draw RTTL + */ + public void addDrawTextRun( + int textId, + int start, + int end, + int contextStart, + int contextEnd, + float x, + float y, + boolean rtl) { + DrawText.apply(mBuffer, textId, start, end, contextStart, contextEnd, x, y, rtl); + } + + /** + * Draw a text on canvas at relative to position (x, y), offset panX and panY. <br> + * The panning factors (panX, panY) mapped to the resulting bounding box of the text, in such a + * way that a panning factor of (0.0, 0.0) would center the text at (x, y) + * * <ul> - * <li> Panning of -1.0, -1.0 - the text above & right of x,y.</li> - * <li>Panning of 1.0, 1.0 - the text is below and to the left</li> - * <li>Panning of 1.0, 0.0 - the test is centered & to the right of x,y</li> + * <li>Panning of -1.0, -1.0 - the text above & right of x,y. + * <li>Panning of 1.0, 1.0 - the text is below and to the left + * <li>Panning of 1.0, 0.0 - the test is centered & to the right of x,y * </ul> + * * Setting panY to NaN results in y being the baseline of the text. * - * @param text text to draw - * @param x Coordinate of the Anchor - * @param y Coordinate of the Anchor - * @param panX justifies text -1.0=right, 0.0=center, 1.0=left - * @param panY position text -1.0=above, 0.0=center, 1.0=below, Nan=baseline + * @param text text to draw + * @param x Coordinate of the Anchor + * @param y Coordinate of the Anchor + * @param panX justifies text -1.0=right, 0.0=center, 1.0=left + * @param panY position text -1.0=above, 0.0=center, 1.0=below, Nan=baseline * @param flags 1 = RTL */ - public void drawTextAnchored(String text, - float x, - float y, - float panX, - float panY, - int flags) { + public void drawTextAnchored(String text, float x, float y, float panX, float panY, int flags) { int textId = addText(text); - DrawTextAnchored.apply( - mBuffer, textId, - x, y, - panX, panY, - flags); + DrawTextAnchored.apply(mBuffer, textId, x, y, panX, panY, flags); } /** @@ -556,6 +766,7 @@ public class RemoteComposeBuffer { /** * Merge two text (from id's) output one id + * * @param id1 left id * @param id2 right id * @return new id that merges the two text @@ -576,77 +787,68 @@ public class RemoteComposeBuffer { /** * Create a TextFromFloat command which creates text from a Float. * - * @param value The value to convert + * @param value The value to convert * @param digitsBefore the digits before the decimal point - * @param digitsAfter the digits after the decimal point - * @param flags configure the behaviour using PAD_PRE_* and PAD_AFTER* flags + * @param digitsAfter the digits after the decimal point + * @param flags configure the behaviour using PAD_PRE_* and PAD_AFTER* flags * @return id of the string that can be passed to drawTextAnchored */ - public int createTextFromFloat(float value, short digitsBefore, - short digitsAfter, int flags) { - String placeHolder = Utils.floatToString(value) - + "(" + digitsBefore + "," + digitsAfter + "," + flags + ")"; + public int createTextFromFloat(float value, short digitsBefore, short digitsAfter, int flags) { + String placeHolder = + Utils.floatToString(value) + + "(" + + digitsBefore + + "," + + digitsAfter + + "," + + flags + + ")"; int id = mRemoteComposeState.dataGetId(placeHolder); if (id == -1) { id = mRemoteComposeState.cacheData(placeHolder); // TextData.apply(mBuffer, id, text); } - TextFromFloat.apply(mBuffer, id, value, digitsBefore, - digitsAfter, flags); + TextFromFloat.apply(mBuffer, id, value, digitsBefore, digitsAfter, flags); return id; } /** - * Draw a text on canvas at relative to position (x, y), - * offset panX and panY. - * <br> - * The panning factors (panX, panY) mapped to the - * resulting bounding box of the text, in such a way that a - * panning factor of (0.0, 0.0) would center the text at (x, y) + * Draw a text on canvas at relative to position (x, y), offset panX and panY. <br> + * The panning factors (panX, panY) mapped to the resulting bounding box of the text, in such a + * way that a panning factor of (0.0, 0.0) would center the text at (x, y) + * * <ul> - * <li> Panning of -1.0, -1.0 - the text above & right of x,y.</li> - * <li>Panning of 1.0, 1.0 - the text is below and to the left</li> - * <li>Panning of 1.0, 0.0 - the test is centered & to the right of x,y</li> + * <li>Panning of -1.0, -1.0 - the text above & right of x,y. + * <li>Panning of 1.0, 1.0 - the text is below and to the left + * <li>Panning of 1.0, 0.0 - the test is centered & to the right of x,y * </ul> + * * Setting panY to NaN results in y being the baseline of the text. * * @param textId text to draw - * @param x Coordinate of the Anchor - * @param y Coordinate of the Anchor - * @param panX justifies text -1.0=right, 0.0=center, 1.0=left - * @param panY position text -1.0=above, 0.0=center, 1.0=below, Nan=baseline - * @param flags 1 = RTL + * @param x Coordinate of the Anchor + * @param y Coordinate of the Anchor + * @param panX justifies text -1.0=right, 0.0=center, 1.0=left + * @param panY position text -1.0=above, 0.0=center, 1.0=below, Nan=baseline + * @param flags 1 = RTL */ - public void drawTextAnchored(int textId, - float x, - float y, - float panX, - float panY, - int flags) { + public void drawTextAnchored(int textId, float x, float y, float panX, float panY, int flags) { - DrawTextAnchored.apply( - mBuffer, textId, - x, y, - panX, panY, - flags); + DrawTextAnchored.apply(mBuffer, textId, x, y, panX, panY, flags); } /** * draw an interpolation between two paths that have the same pattern - * <p> - * Warning paths objects are not immutable and this is not taken into consideration + * + * <p>Warning paths objects are not immutable and this is not taken into consideration * * @param path1 The path1 to be drawn between * @param path2 The path2 to be drawn between * @param tween The ratio of path1 and path2 to 0 = all path 1, 1 = all path2 * @param start The start of the subrange of paths to draw 0 = start form start 0.5 is half way - * @param stop The end of the subrange of paths to draw 1 = end at the end 0.5 is end half way + * @param stop The end of the subrange of paths to draw 1 = end at the end 0.5 is end half way */ - public void addDrawTweenPath(Object path1, - Object path2, - float tween, - float start, - float stop) { + public void addDrawTweenPath(Object path1, Object path2, float tween, float start, float stop) { int path1Id = mRemoteComposeState.dataGetId(path1); if (path1Id == -1) { // never been seen before path1Id = addPathData(path1); @@ -663,18 +865,12 @@ public class RemoteComposeBuffer { * * @param path1Id The path1 to be drawn between * @param path2Id The path2 to be drawn between - * @param tween The ratio of path1 and path2 to 0 = all path 1, 1 = all path2 - * @param start The start of the subrange of paths to draw 0 = start form start .5 is 1/2 way - * @param stop The end of the subrange of paths to draw 1 = end at the end .5 is end 1/2 way + * @param tween The ratio of path1 and path2 to 0 = all path 1, 1 = all path2 + * @param start The start of the subrange of paths to draw 0 = start form start .5 is 1/2 way + * @param stop The end of the subrange of paths to draw 1 = end at the end .5 is end 1/2 way */ - public void addDrawTweenPath(int path1Id, - int path2Id, - float tween, - float start, - float stop) { - DrawTweenPath.apply( - mBuffer, path1Id, path2Id, - tween, start, stop); + public void addDrawTweenPath(int path1Id, int path2Id, float tween, float start, float stop) { + DrawTweenPath.apply(mBuffer, path1Id, path2Id, tween, start, stop); } /** @@ -692,11 +888,13 @@ public class RemoteComposeBuffer { /** * Adds a paint Bundle to the doc + * * @param paint */ public void addPaint(PaintBundle paint) { PaintData.apply(mBuffer, paint); } + /////////////////////////////////////////////////////////////////////////////////////////////// public void inflateFromBuffer(ArrayList<Operation> operations) { @@ -741,30 +939,29 @@ public class RemoteComposeBuffer { return "v1.0"; } - public static RemoteComposeBuffer fromFile(String path, - RemoteComposeState remoteComposeState) + public static RemoteComposeBuffer fromFile(String path, RemoteComposeState remoteComposeState) throws IOException { RemoteComposeBuffer buffer = new RemoteComposeBuffer(remoteComposeState); read(new File(path), buffer); return buffer; } - public RemoteComposeBuffer fromFile(File file, - RemoteComposeState remoteComposeState) throws IOException { + public RemoteComposeBuffer fromFile(File file, RemoteComposeState remoteComposeState) + throws IOException { RemoteComposeBuffer buffer = new RemoteComposeBuffer(remoteComposeState); read(file, buffer); return buffer; } - public static RemoteComposeBuffer fromInputStream(InputStream inputStream, - RemoteComposeState remoteComposeState) { + public static RemoteComposeBuffer fromInputStream( + InputStream inputStream, RemoteComposeState remoteComposeState) { RemoteComposeBuffer buffer = new RemoteComposeBuffer(remoteComposeState); read(inputStream, buffer); return buffer; } - RemoteComposeBuffer copyFromOperations(ArrayList<Operation> operations, - RemoteComposeBuffer buffer) { + RemoteComposeBuffer copyFromOperations( + ArrayList<Operation> operations, RemoteComposeBuffer buffer) { for (Operation operation : operations) { operation.write(buffer.mBuffer); @@ -832,9 +1029,9 @@ public class RemoteComposeBuffer { } /** - * This call balances a previous call to save(), and is used to remove all - * modifications to the matrix/clip state since the last save call. - * Do not call restore() more times than save() was called. + * This call balances a previous call to save(), and is used to remove all modifications to the + * matrix/clip state since the last save call. Do not call restore() more times than save() was + * called. */ public void addMatrixRestore() { MatrixRestore.apply(mBuffer); @@ -842,11 +1039,10 @@ public class RemoteComposeBuffer { /** * Add a saves the current matrix and clip onto a private stack. - * <p> - * Subsequent calls to translate,scale,rotate,skew,concat or clipRect, - * clipPath will all operate as usual, but when the balancing call to - * restore() is made, those calls will be forgotten, and the settings that - * existed before the save() will be reinstated. + * + * <p>Subsequent calls to translate,scale,rotate,skew,concat or clipRect, clipPath will all + * operate as usual, but when the balancing call to restore() is made, those calls will be + * forgotten, and the settings that existed before the save() will be reinstated. */ public void addMatrixSave() { MatrixSave.apply(mBuffer); @@ -855,7 +1051,7 @@ public class RemoteComposeBuffer { /** * add a pre-concat the current matrix with the specified rotation. * - * @param angle The amount to rotate, in degrees + * @param angle The amount to rotate, in degrees * @param centerX The x-coord for the pivot point (unchanged by the rotation) * @param centerY The y-coord for the pivot point (unchanged by the rotation) */ @@ -886,8 +1082,8 @@ public class RemoteComposeBuffer { /** * Add a pre-concat of the current matrix with the specified scale. * - * @param scaleX The amount to scale in X - * @param scaleY The amount to scale in Y + * @param scaleX The amount to scale in X + * @param scaleY The amount to scale in Y * @param centerX The x-coord for the pivot point (unchanged by the scale) * @param centerY The y-coord for the pivot point (unchanged by the scale) */ @@ -897,6 +1093,7 @@ public class RemoteComposeBuffer { /** * sets the clip based on clip id + * * @param pathId 0 clears the clip */ public void addClipPath(int pathId) { @@ -905,10 +1102,11 @@ public class RemoteComposeBuffer { /** * Sets the clip based on clip rec - * @param left left coordinate of the clip rectangle - * @param top top coordinate of the clip rectangle - * @param right right coordinate of the clip rectangle - * @param bottom bottom coordinate of the clip rectangle + * + * @param left left coordinate of the clip rectangle + * @param top top coordinate of the clip rectangle + * @param right right coordinate of the clip rectangle + * @param bottom bottom coordinate of the clip rectangle */ public void addClipRect(float left, float top, float right, float bottom) { ClipRect.apply(mBuffer, left, top, right, bottom); @@ -916,6 +1114,7 @@ public class RemoteComposeBuffer { /** * Add a float return a NaN number pointing to that float + * * @param value the value of the float * @return the nan id of float */ @@ -925,9 +1124,9 @@ public class RemoteComposeBuffer { return Utils.asNan(id); } - /** * Add a Integer return an id number pointing to that float. + * * @param value adds an integer and assigns it an id * @return the id of the integer to be used */ @@ -938,7 +1137,32 @@ public class RemoteComposeBuffer { } /** + * Add a long constant return a id. They can be used as parameters to Custom Attributes. + * + * @param value the value of the long + * @return the id of the command representing long + */ + public int addLong(long value) { + int id = mRemoteComposeState.cacheData(value); + LongConstant.apply(mBuffer, id, value); + return id; + } + + /** + * Add a boolean constant return a id. They can be used as parameters to Custom Attributes. + * + * @param value the value of the boolean + * @return the id + */ + public int addBoolean(boolean value) { + int id = mRemoteComposeState.cacheData(value); + BooleanConstant.apply(mBuffer, id, value); + return id; + } + + /** * Add a IntegerId as float ID. + * * @param id id to be converted * @return the id wrapped in a NaN */ @@ -948,6 +1172,7 @@ public class RemoteComposeBuffer { /** * Add a float that is a computation based on variables + * * @param value A RPN style float operation i.e. "4, 3, ADD" outputs 7 * @return NaN id of the result of the calculation */ @@ -958,8 +1183,8 @@ public class RemoteComposeBuffer { } /** - * Add a float that is a computation based on variables. - * see packAnimation + * Add a float that is a computation based on variables. see packAnimation + * * @param value A RPN style float operation i.e. "4, 3, ADD" outputs 7 * @param animation Array of floats that represents animation * @return NaN id of the result of the calculation @@ -970,12 +1195,37 @@ public class RemoteComposeBuffer { return Utils.asNan(id); } + /** + * measure the text and return a measure as a float + * + * @param textId id of the text + * @param mode the mode 0 is the width + * @return + */ + public float textMeasure(int textId, int mode) { + int id = mRemoteComposeState.cacheData(textId + mode * 31); + TextMeasure.apply(mBuffer, id, textId, mode); + return Utils.asNan(id); + } + + /** + * measure the text and return the length of the text as float + * + * @param textId id of the text + * @return id of a float that is the length + */ + public float textLength(int textId) { + // The cache id is computed buy merging the two values together + // to create a relatively unique value + int id = mRemoteComposeState.cacheData(textId + (TextLength.id() << 16)); + TextLength.apply(mBuffer, id, textId); + return Utils.asNan(id); + } /** * add a float array * * @param values - * * @return the id of the array, encoded as a float NaN */ public float addFloatArray(float[] values) { @@ -986,23 +1236,23 @@ public class RemoteComposeBuffer { /** * This creates a list of individual floats - * @param values array of floats to be individually stored * + * @param values array of floats to be individually stored * @return id of the list */ public float addFloatList(float[] values) { - int []listId = new int[values.length]; + int[] listId = new int[values.length]; for (int i = 0; i < listId.length; i++) { listId[i] = mRemoteComposeState.cacheFloat(values[i]); - FloatConstant.apply(mBuffer, listId[i], values[i]); + FloatConstant.apply(mBuffer, listId[i], values[i]); } return addList(listId); } /** * This creates a list of individual floats - * @param listId array id to be stored * + * @param listId array id to be stored * @return id of the list */ public float addList(int[] listId) { @@ -1016,16 +1266,17 @@ public class RemoteComposeBuffer { * * @param keys * @param values - * * @return the id of the map, encoded as a float NaN */ - public float addFloatMap(String[]keys, float[] values) { - int []listId = new int[values.length]; + public float addFloatMap(String[] keys, float[] values) { + int[] listId = new int[values.length]; + byte[] type = new byte[values.length]; for (int i = 0; i < listId.length; i++) { listId[i] = mRemoteComposeState.cacheFloat(values[i]); - FloatConstant.apply(mBuffer, listId[i], values[i]); + FloatConstant.apply(mBuffer, listId[i], values[i]); + type[i] = DataMapIds.TYPE_FLOAT; } - return addMap(keys, listId); + return addMap(keys, type, listId); } /** @@ -1033,17 +1284,49 @@ public class RemoteComposeBuffer { * * @param keys * @param listId - * * @return the id of the map, encoded as a float NaN */ - public float addMap(String []keys, int[] listId) { + public int addMap(String[] keys, byte[] types, int[] listId) { int id = mRemoteComposeState.cacheData(listId, NanMap.TYPE_ARRAY); - DataMapIds.apply(mBuffer, id, keys, listId); - return Utils.asNan(id); + DataMapIds.apply(mBuffer, id, keys, types, listId); + return id; + } + + /** + * This provides access to text in RemoteList + * + * @param dataSet + * @param index index as a float variable + * @return + */ + public int textLookup(float dataSet, float index) { + long hash = + ((long) Float.floatToRawIntBits(dataSet)) + << (32 + Float.floatToRawIntBits(index)); // TODO: is this the correct ()s? + int id = mRemoteComposeState.cacheData(hash); + TextLookup.apply(mBuffer, id, Utils.idFromNan(dataSet), index); + return id; + } + + /** + * This provides access to text in RemoteList + * + * @param dataSet + * @param index index as an int variable + * @return + */ + public int textLookup(float dataSet, int index) { + long hash = + ((long) Float.floatToRawIntBits(dataSet)) + << (32 + Float.floatToRawIntBits(index)); // TODO: is this the correct ()s? + int id = mRemoteComposeState.cacheData(hash); + TextLookupInt.apply(mBuffer, id, Utils.idFromNan(dataSet), index); + return id; } /** * Add and integer expression + * * @param mask defines which elements are operators or variables * @param value array of values to calculate maximum 32 * @return the id as an integer @@ -1051,11 +1334,12 @@ public class RemoteComposeBuffer { public int addIntegerExpression(int mask, int[] value) { int id = mRemoteComposeState.cacheData(value); IntegerExpression.apply(mBuffer, id, mask, value); - return id; + return id; } /** * Add a simple color + * * @param color the RGB color value * @return id that represents that color */ @@ -1067,9 +1351,9 @@ public class RemoteComposeBuffer { return id; } - /** * Add a color that represents the tween between two colors + * * @param color1 the ARGB value of the first color * @param color2 the ARGB value of the second color * @param tween the interpolation bet @@ -1084,8 +1368,8 @@ public class RemoteComposeBuffer { } /** - * Add a color that represents the tween between two colors where color1 - * is the id of a color + * Add a color that represents the tween between two colors where color1 is the id of a color + * * @param color1 id of color * @param color2 rgb color value * @param tween the tween between color1 and color2 (1 = color2) @@ -1100,8 +1384,8 @@ public class RemoteComposeBuffer { } /** - * Add a color that represents the tween between two colors where color2 - * is the id of a color + * Add a color that represents the tween between two colors where color2 is the id of a color + * * @param color1 the ARGB value of the first color * @param color2 id of the second color * @param tween the tween between color1 and color2 (1 = color2) @@ -1116,8 +1400,9 @@ public class RemoteComposeBuffer { } /** - * Add a color that represents the tween between two colors where color1 & - * color2 are the ids of colors + * Add a color that represents the tween between two colors where color1 & color2 are the ids of + * colors + * * @param color1 id of the first color * @param color2 id of the second color * @param tween the tween between color1 and color2 (1 = color2) @@ -1132,8 +1417,9 @@ public class RemoteComposeBuffer { } /** - * Color calculated by Hue saturation and value. - * (as floats they can be variables used to create color transitions) + * Color calculated by Hue saturation and value. (as floats they can be variables used to create + * color transitions) + * * @param hue the Hue * @param sat the saturation * @param value the value @@ -1148,8 +1434,9 @@ public class RemoteComposeBuffer { } /** - * Color calculated by Alpha, Hue saturation and value. - * (as floats they can be variables used to create color transitions) + * Color calculated by Alpha, Hue saturation and value. (as floats they can be variables used to + * create color transitions) + * * @param alpha the Alpha * @param hue the hue * @param sat the saturation @@ -1165,8 +1452,9 @@ public class RemoteComposeBuffer { } /** - * create and animation based on description and return as an array of - * floats. see addAnimatedFloat + * create and animation based on description and return as an array of floats. see + * addAnimatedFloat + * * @param duration the duration of the aimation * @param type the type of animation * @param spec the parameters of the animation if any @@ -1174,23 +1462,20 @@ public class RemoteComposeBuffer { * @param wrap the wraps value so (e.g 360 so angles 355 would animate to 5) * @return */ - public static float[] packAnimation(float duration, - int type, - float[] spec, - float initialValue, - float wrap) { + public static float[] packAnimation( + float duration, int type, float[] spec, float initialValue, float wrap) { return FloatAnimation.packToFloatArray(duration, type, spec, initialValue, wrap); } /** * This defines the name of the color given the id. + * * @param id of the color * @param name Name of the color */ public void setColorName(int id, String name) { - NamedVariable.apply(mBuffer, id, - NamedVariable.COLOR_TYPE, name); + NamedVariable.apply(mBuffer, id, NamedVariable.COLOR_TYPE, name); } /** @@ -1200,16 +1485,14 @@ public class RemoteComposeBuffer { * @param name name of the string */ public void setStringName(int id, String name) { - NamedVariable.apply(mBuffer, id, - NamedVariable.STRING_TYPE, name); + NamedVariable.apply(mBuffer, id, NamedVariable.STRING_TYPE, name); } /** - * Returns a usable component id -- either the one passed in parameter if not -1 - * or a generated one. + * Returns a usable component id -- either the one passed in parameter if not -1 or a generated + * one. * * @param id the current component id (if -1, we'll generate a new one) - * * @return a usable component id */ private int getComponentId(int id) { @@ -1225,63 +1508,64 @@ public class RemoteComposeBuffer { /** * Add a component start tag + * * @param type type of component * @param id component id */ public void addComponentStart(int type, int id) { mLastComponentId = getComponentId(id); - ComponentStart.apply(mBuffer, - type, mLastComponentId, 0f, 0f); + ComponentStart.apply(mBuffer, type, mLastComponentId, 0f, 0f); } /** * Add a component start tag + * * @param type type of component */ public void addComponentStart(int type) { addComponentStart(type, -1); } - /** - * Add a component end tag - */ + /** Add a component end tag */ public void addComponentEnd() { ComponentEnd.apply(mBuffer); } /** * Add a background modifier of provided color + * * @param color the color of the background * @param shape the background shape -- SHAPE_RECTANGLE, SHAPE_CIRCLE */ public void addModifierBackground(int color, int shape) { - float r = ((color >> 16) & 0xff) / 255.0f; - float g = ((color >> 8) & 0xff) / 255.0f; - float b = ((color) & 0xff) / 255.0f; - float a = ((color >> 24) & 0xff) / 255.0f; - BackgroundModifierOperation.apply(mBuffer, 0f, 0f, 0f, 0f, - r, g, b, a, shape); + float r = (color >> 16 & 0xff) / 255.0f; + float g = (color >> 8 & 0xff) / 255.0f; + float b = (color & 0xff) / 255.0f; + float a = (color >> 24 & 0xff) / 255.0f; + BackgroundModifierOperation.apply(mBuffer, 0f, 0f, 0f, 0f, r, g, b, a, shape); } /** * Add a border modifier + * * @param borderWidth the border width * @param borderRoundedCorner the rounded corner radius if the shape is ROUNDED_RECT * @param color the color of the border * @param shape the shape of the border */ - public void addModifierBorder(float borderWidth, float borderRoundedCorner, - int color, int shape) { - float r = ((color >> 16) & 0xff) / 255.0f; - float g = ((color >> 8) & 0xff) / 255.0f; - float b = ((color) & 0xff) / 255.0f; - float a = ((color >> 24) & 0xff) / 255.0f; - BorderModifierOperation.apply(mBuffer, 0f, 0f, 0f, 0f, - borderWidth, borderRoundedCorner, r, g, b, a, shape); + public void addModifierBorder( + float borderWidth, float borderRoundedCorner, int color, int shape) { + float r = (color >> 16 & 0xff) / 255.0f; + float g = (color >> 8 & 0xff) / 255.0f; + float b = (color & 0xff) / 255.0f; + float a = (color >> 24 & 0xff) / 255.0f; + BorderModifierOperation.apply( + mBuffer, 0f, 0f, 0f, 0f, borderWidth, borderRoundedCorner, r, g, b, a, shape); } /** * Add a padding modifier + * * @param left left padding * @param top top padding * @param right right padding @@ -1293,24 +1577,36 @@ public class RemoteComposeBuffer { /** * Sets the clip based on rounded clip rect + * * @param topStart * @param topEnd * @param bottomStart * @param bottomEnd */ - public void addRoundClipRectModifier(float topStart, float topEnd, - float bottomStart, float bottomEnd) { - RoundedClipRectModifierOperation.apply(mBuffer, - topStart, topEnd, bottomStart, bottomEnd); + public void addRoundClipRectModifier( + float topStart, float topEnd, float bottomStart, float bottomEnd) { + RoundedClipRectModifierOperation.apply(mBuffer, topStart, topEnd, bottomStart, bottomEnd); } - /** - * Add a clip rect modifier - */ + /** Add a clip rect modifier */ public void addClipRectModifier() { ClipRectModifierOperation.apply(mBuffer); } + public void addLoopStart(float count, float from, float step, int indexId) { + LoopOperation.apply(mBuffer, count, from, step, indexId); + } + + public void addLoopEnd() { + LoopEnd.apply(mBuffer); + } + + public void addStateLayout( + int componentId, int animationId, int horizontal, int vertical, int indexId) { + mLastComponentId = getComponentId(componentId); + StateLayout.apply(mBuffer, mLastComponentId, animationId, horizontal, vertical, indexId); + } + /** * Add a box start tag * @@ -1319,11 +1615,9 @@ public class RemoteComposeBuffer { * @param horizontal horizontal alignment * @param vertical vertical alignment */ - public void addBoxStart(int componentId, int animationId, - int horizontal, int vertical) { + public void addBoxStart(int componentId, int animationId, int horizontal, int vertical) { mLastComponentId = getComponentId(componentId); - BoxLayout.apply(mBuffer, mLastComponentId, animationId, - horizontal, vertical); + BoxLayout.apply(mBuffer, mLastComponentId, animationId, horizontal, vertical); } /** @@ -1335,11 +1629,10 @@ public class RemoteComposeBuffer { * @param vertical vertical alignment * @param spacedBy spacing between items */ - public void addRowStart(int componentId, int animationId, - int horizontal, int vertical, float spacedBy) { + public void addRowStart( + int componentId, int animationId, int horizontal, int vertical, float spacedBy) { mLastComponentId = getComponentId(componentId); - RowLayout.apply(mBuffer, mLastComponentId, animationId, - horizontal, vertical, spacedBy); + RowLayout.apply(mBuffer, mLastComponentId, animationId, horizontal, vertical, spacedBy); } /** @@ -1351,15 +1644,15 @@ public class RemoteComposeBuffer { * @param vertical vertical alignment * @param spacedBy spacing between items */ - public void addColumnStart(int componentId, int animationId, - int horizontal, int vertical, float spacedBy) { + public void addColumnStart( + int componentId, int animationId, int horizontal, int vertical, float spacedBy) { mLastComponentId = getComponentId(componentId); - ColumnLayout.apply(mBuffer, mLastComponentId, animationId, - horizontal, vertical, spacedBy); + ColumnLayout.apply(mBuffer, mLastComponentId, animationId, horizontal, vertical, spacedBy); } /** * Add a canvas start tag + * * @param componentId component id * @param animationId animation id */ @@ -1370,6 +1663,7 @@ public class RemoteComposeBuffer { /** * Add a canvas content start tag + * * @param componentId component id */ public void addCanvasContentStart(int componentId) { @@ -1377,17 +1671,13 @@ public class RemoteComposeBuffer { CanvasContent.apply(mBuffer, mLastComponentId); } - /** - * Add a root start tag - */ + /** Add a root start tag */ public void addRootStart() { mLastComponentId = getComponentId(-1); RootLayoutComponent.apply(mBuffer, mLastComponentId); } - /** - * Add a content start tag - */ + /** Add a content start tag */ public void addContentStart() { mLastComponentId = getComponentId(-1); LayoutComponentContent.apply(mBuffer, mLastComponentId); @@ -1395,6 +1685,7 @@ public class RemoteComposeBuffer { /** * Add a component width value + * * @param id id of the value */ public void addComponentWidthValue(int id) { @@ -1422,16 +1713,29 @@ public class RemoteComposeBuffer { * @param fontWeight font weight (1 to 1000, normal is 400) * @param fontFamily font family or null */ - public void addTextComponentStart(int componentId, int animationId, - int textId, int color, float fontSize, - int fontStyle, float fontWeight, String fontFamily) { + public void addTextComponentStart( + int componentId, + int animationId, + int textId, + int color, + float fontSize, + int fontStyle, + float fontWeight, + String fontFamily) { mLastComponentId = getComponentId(componentId); int fontFamilyId = -1; if (fontFamily != null) { fontFamilyId = addText(fontFamily); } - TextLayout.apply(mBuffer, mLastComponentId, animationId, textId, color, fontSize, - fontStyle, fontWeight, fontFamilyId); + TextLayout.apply( + mBuffer, + mLastComponentId, + animationId, + textId, + color, + fontSize, + fontStyle, + fontWeight, + fontFamilyId); } } - diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeOperation.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeOperation.java index c7ec33593286..e60695fc4a06 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeOperation.java @@ -15,6 +15,4 @@ */ package com.android.internal.widget.remotecompose.core; -public interface RemoteComposeOperation extends Operation { - -} +public interface RemoteComposeOperation extends Operation {} diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java index 839522e29fdb..51445f2ff31d 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java +++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java @@ -15,30 +15,24 @@ */ package com.android.internal.widget.remotecompose.core; -import static com.android.internal.widget.remotecompose.core.RemoteContext.ID_CONTINUOUS_SEC; -import static com.android.internal.widget.remotecompose.core.RemoteContext.ID_TIME_IN_MIN; -import static com.android.internal.widget.remotecompose.core.RemoteContext.ID_TIME_IN_SEC; -import static com.android.internal.widget.remotecompose.core.RemoteContext.ID_WINDOW_HEIGHT; -import static com.android.internal.widget.remotecompose.core.RemoteContext.ID_WINDOW_WIDTH; -import static com.android.internal.widget.remotecompose.core.operations.utilities.NanMap.START_ARRAY; -import static com.android.internal.widget.remotecompose.core.operations.utilities.NanMap.START_VAR; - import com.android.internal.widget.remotecompose.core.operations.utilities.ArrayAccess; import com.android.internal.widget.remotecompose.core.operations.utilities.CollectionsAccess; +import com.android.internal.widget.remotecompose.core.operations.utilities.DataMap; import com.android.internal.widget.remotecompose.core.operations.utilities.IntFloatMap; import com.android.internal.widget.remotecompose.core.operations.utilities.IntIntMap; import com.android.internal.widget.remotecompose.core.operations.utilities.IntMap; +import com.android.internal.widget.remotecompose.core.operations.utilities.NanMap; import java.util.ArrayList; import java.util.HashMap; /** - * Represents runtime state for a RemoteCompose document - * State includes things like the value of variables + * Represents runtime state for a RemoteCompose document State includes things like the value of + * variables */ public class RemoteComposeState implements CollectionsAccess { public static final int START_ID = 42; - private static final int MAX_FLOATS = 500; + // private static final int MAX_FLOATS = 500; private static final int MAX_COLORS = 200; private static final int MAX_DATA = 1000; @@ -48,6 +42,8 @@ public class RemoteComposeState implements CollectionsAccess { private final IntFloatMap mFloatMap = new IntFloatMap(); // efficient cache private final IntIntMap mIntegerMap = new IntIntMap(); // efficient cache private final IntIntMap mColorMap = new IntIntMap(); // efficient cache + private final IntMap<DataMap> mDataMapMap = new IntMap<>(); + private final IntMap<Object> mObjectMap = new IntMap<>(); private final boolean[] mColorOverride = new boolean[MAX_COLORS]; private final IntMap<ArrayAccess> mCollectionMap = new IntMap<>(); @@ -56,13 +52,12 @@ public class RemoteComposeState implements CollectionsAccess { private final boolean[] mIntegerOverride = new boolean[MAX_DATA]; private int mNextId = START_ID; - private int[] mIdMaps = new int[]{START_ID, START_VAR, START_ARRAY}; + private int[] mIdMaps = new int[] {START_ID, NanMap.START_VAR, NanMap.START_ARRAY}; private RemoteContext mRemoteContext = null; - /** - * Get Object based on id. The system will cache things like bitmaps - * Paths etc. They can be accessed with this command + * Get Object based on id. The system will cache things like bitmaps Paths etc. They can be + * accessed with this command * * @param id * @return @@ -81,9 +76,7 @@ public class RemoteComposeState implements CollectionsAccess { return mIntDataMap.get(id) != null; } - /** - * Return the id of an item from the cache. - */ + /** Return the id of an item from the cache. */ public int dataGetId(Object data) { Integer res = mDataIntMap.get(data); if (res == null) { @@ -93,8 +86,8 @@ public class RemoteComposeState implements CollectionsAccess { } /** - * Add an item to the cache. Generates an id for the item and adds it to the cache based on - * that id. + * Add an item to the cache. Generates an id for the item and adds it to the cache based on that + * id. */ public int cacheData(Object item) { int id = nextId(); @@ -104,8 +97,8 @@ public class RemoteComposeState implements CollectionsAccess { } /** - * Add an item to the cache. Generates an id for the item and adds it to the cache based on - * that id. + * Add an item to the cache. Generates an id for the item and adds it to the cache based on that + * id. */ public int cacheData(Object item, int type) { int id = nextId(type); @@ -114,23 +107,22 @@ public class RemoteComposeState implements CollectionsAccess { return id; } - /** - * Insert an item in the cache - */ + /** Insert an item in the cache */ public void cacheData(int id, Object item) { mDataIntMap.put(item, id); mIntDataMap.put(id, item); } - /** - * Insert an item in the cache - */ + /** Insert an item in the cache */ public void updateData(int id, Object item) { if (!mDataOverride[id]) { - mDataIntMap.remove(mIntDataMap.get(id)); - mDataIntMap.put(item, id); - mIntDataMap.put(id, item); - updateListeners(id); + Object previous = mIntDataMap.get(id); + if (previous != item) { + mDataIntMap.remove(previous); + mDataIntMap.put(item, id); + mIntDataMap.put(id, item); + updateListeners(id); + } } } @@ -141,16 +133,17 @@ public class RemoteComposeState implements CollectionsAccess { * @param item the new value */ public void overrideData(int id, Object item) { - mDataIntMap.remove(mIntDataMap.get(id)); - mDataIntMap.put(item, id); - mIntDataMap.put(id, item); - mDataOverride[id] = true; - updateListeners(id); + Object previous = mIntDataMap.get(id); + if (previous != item) { + mDataIntMap.remove(previous); + mDataIntMap.put(item, id); + mIntDataMap.put(id, item); + mDataOverride[id] = true; + updateListeners(id); + } } - /** - * Insert an item in the cache - */ + /** Insert an item in the cache */ public int cacheFloat(float item) { int id = nextId(); mFloatMap.put(id, item); @@ -158,25 +151,22 @@ public class RemoteComposeState implements CollectionsAccess { return id; } - /** - * Insert an item in the cache - */ + /** Insert an item in the cache */ public void cacheFloat(int id, float item) { mFloatMap.put(id, item); } - /** - * Insert an float item in the cache - */ - public void updateFloat(int id, float item) { - mFloatMap.put(id, item); - mIntegerMap.put(id, (int) item); - updateListeners(id); + /** Insert an float item in the cache */ + public void updateFloat(int id, float value) { + float previous = mFloatMap.get(id); + if (previous != value) { + mFloatMap.put(id, value); + mIntegerMap.put(id, (int) value); + updateListeners(id); + } } - /** - * Insert an item in the cache - */ + /** Insert an item in the cache */ public int cacheInteger(int item) { int id = nextId(); mIntegerMap.put(id, item); @@ -184,14 +174,15 @@ public class RemoteComposeState implements CollectionsAccess { return id; } - /** - * Insert an integer item in the cache - */ - public void updateInteger(int id, int item) { + /** Insert an integer item in the cache */ + public void updateInteger(int id, int value) { if (!mIntegerOverride[id]) { - mFloatMap.put(id, item); - mIntegerMap.put(id, item); - updateListeners(id); + int previous = mIntegerMap.get(id); + if (previous != value) { + mFloatMap.put(id, value); + mIntegerMap.put(id, value); + updateListeners(id); + } } } @@ -202,10 +193,13 @@ public class RemoteComposeState implements CollectionsAccess { * @param value the new value */ public void overrideInteger(int id, int value) { - mIntegerMap.put(id, value); - mFloatMap.put(id, value); - mIntegerOverride[id] = true; - updateListeners(id); + int previous = mIntegerMap.get(id); + if (previous != value) { + mIntegerMap.put(id, value); + mFloatMap.put(id, value); + mIntegerOverride[id] = true; + updateListeners(id); + } } /** @@ -262,8 +256,7 @@ public class RemoteComposeState implements CollectionsAccess { } /** - * Adds a colorOverride. - * This is a list of ids and their colors optimized for playback; + * Adds a colorOverride. This is a list of ids and their colors optimized for playback; * * @param id * @param color @@ -273,9 +266,7 @@ public class RemoteComposeState implements CollectionsAccess { mColorMap.put(id, color); } - /** - * Clear the color Overrides - */ + /** Clear the color Overrides */ public void clearColorOverride() { for (int i = 0; i < mColorOverride.length; i++) { mColorOverride[i] = false; @@ -310,16 +301,12 @@ public class RemoteComposeState implements CollectionsAccess { return !mIntWrittenMap.get(id); } - /** - * Method to mark that a value, represented by its id, has been written to the WireBuffer - */ + /** Method to mark that a value, represented by its id, has been written to the WireBuffer */ public void markWritten(int id) { mIntWrittenMap.put(id, true); } - /** - * Clear the record of the values that have been written to the WireBuffer. - */ + /** Clear the record of the values that have been written to the WireBuffer. */ public void reset() { mIntWrittenMap.clear(); mDataIntMap.clear(); @@ -388,13 +375,13 @@ public class RemoteComposeState implements CollectionsAccess { for (VariableSupport vs : mAllVarListeners) { vs.updateVariables(context); } - if (mVarListeners.get(ID_CONTINUOUS_SEC) != null) { + if (mVarListeners.get(RemoteContext.ID_CONTINUOUS_SEC) != null) { return 1; } - if (mVarListeners.get(ID_TIME_IN_SEC) != null) { + if (mVarListeners.get(RemoteContext.ID_TIME_IN_SEC) != null) { return 1000; } - if (mVarListeners.get(ID_TIME_IN_MIN) != null) { + if (mVarListeners.get(RemoteContext.ID_TIME_IN_MIN) != null) { return 1000 * 60; } return -1; @@ -406,7 +393,7 @@ public class RemoteComposeState implements CollectionsAccess { * @param width */ public void setWindowWidth(float width) { - updateFloat(ID_WINDOW_WIDTH, width); + updateFloat(RemoteContext.ID_WINDOW_WIDTH, width); } /** @@ -415,7 +402,7 @@ public class RemoteComposeState implements CollectionsAccess { * @param height */ public void setWindowHeight(float height) { - updateFloat(ID_WINDOW_HEIGHT, height); + updateFloat(RemoteContext.ID_WINDOW_HEIGHT, height); } public void addCollection(int id, ArrayAccess collection) { @@ -426,17 +413,39 @@ public class RemoteComposeState implements CollectionsAccess { public float getFloatValue(int id, int index) { return mCollectionMap.get(id & 0xFFFFF).getFloatValue(index); } + @Override public float[] getFloats(int id) { return mCollectionMap.get(id & 0xFFFFF).getFloats(); } @Override - public int getFloatsLength(int id) { - return mCollectionMap.get(id & 0xFFFFF).getFloatsLength(); + public int getId(int id, int index) { + return mCollectionMap.get(id & 0xFFFFF).getId(index); + } + + public void putDataMap(int id, DataMap map) { + mDataMapMap.put(id, map); + } + + public DataMap getDataMap(int id) { + return mDataMapMap.get(id); + } + + @Override + public int getListLength(int id) { + return mCollectionMap.get(id & 0xFFFFF).getLength(); } public void setContext(RemoteContext context) { mRemoteContext = context; } + + public void updateObject(int id, Object value) { + mObjectMap.put(id, value); + } + + public Object getObject(int id) { + return mObjectMap.get(id); + } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java index 0df0aa04ec9c..1066e7d9f617 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java +++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java @@ -22,6 +22,7 @@ import com.android.internal.widget.remotecompose.core.operations.Utils; import com.android.internal.widget.remotecompose.core.operations.layout.Component; import com.android.internal.widget.remotecompose.core.operations.utilities.ArrayAccess; import com.android.internal.widget.remotecompose.core.operations.utilities.CollectionsAccess; +import com.android.internal.widget.remotecompose.core.operations.utilities.DataMap; import java.time.LocalDateTime; import java.time.OffsetDateTime; @@ -31,9 +32,9 @@ import java.time.ZoneOffset; /** * Specify an abstract context used to playback RemoteCompose documents * - * This allows us to intercept the different operations in a document and react to them. + * <p>This allows us to intercept the different operations in a document and react to them. * - * We also contain a PaintContext, so that any operation can draw as needed. + * <p>We also contain a PaintContext, so that any operation can draw as needed. */ public abstract class RemoteContext { protected CoreDocument mDocument; @@ -73,8 +74,7 @@ public abstract class RemoteContext { } /** - * Load a path under an id. - * Paths can be use in clip drawPath and drawTweenPath + * Load a path under an id. Paths can be use in clip drawPath and drawTweenPath * * @param instanceId * @param floatPath @@ -85,7 +85,7 @@ public abstract class RemoteContext { * Associate a name with a give id. * * @param varName the name - * @param varId the id (color,integer,float etc.) + * @param varId the id (color,integer,float etc.) * @param varType thetype */ public abstract void loadVariableName(String varName, int varId, int varType); @@ -93,7 +93,7 @@ public abstract class RemoteContext { /** * Save a color under a given id * - * @param id the id of the color + * @param id the id of the color * @param color the color to set */ public abstract void loadColor(int id, int color); @@ -118,35 +118,33 @@ public abstract class RemoteContext { } /** - * Set the value of a named Color. - * This overrides the color in the document + * Set the value of a named Color. This overrides the color in the document * * @param colorName the name of the color to override - * @param color Override the default color + * @param color Override the default color */ public abstract void setNamedColorOverride(String colorName, int color); /** - * Set the value of a named String. - * This overrides the string in the document + * Set the value of a named String. This overrides the string in the document + * * @param stringName the name of the string to override * @param value Override the default string */ public abstract void setNamedStringOverride(String stringName, String value); - /** * Allows to clear a named String. * - * If an override exists, we revert back to the default value in the document. + * <p>If an override exists, we revert back to the default value in the document. * * @param stringName the name of the string to override */ public abstract void clearNamedStringOverride(String stringName); /** - * Set the value of a named Integer. - * This overrides the integer in the document + * Set the value of a named Integer. This overrides the integer in the document + * * @param integerName the name of the integer to override * @param value Override the default integer */ @@ -155,34 +153,41 @@ public abstract class RemoteContext { /** * Allows to clear a named Integer. * - * If an override exists, we revert back to the default value in the document. + * <p>If an override exists, we revert back to the default value in the document. * * @param integerName the name of the integer to override */ public abstract void clearNamedIntegerOverride(String integerName); - /** * Support Collections by registering this collection * - * @param id id of the collection + * @param id id of the collection * @param collection the collection under this id */ public abstract void addCollection(int id, ArrayAccess collection); + public abstract void putDataMap(int id, DataMap map); + + public abstract DataMap getDataMap(int id); + public abstract void runAction(int id, String metadata); public abstract void runNamedAction(int textId); + public abstract void putObject(int mId, Object command); + + public abstract Object getObject(int mId); /** * The context can be used in a few different mode, allowing operations to skip being executed: - * - UNSET : all operations will get executed - * - DATA : only operations dealing with DATA (eg loading a bitmap) should execute - * - PAINT : only operations painting should execute + * - UNSET : all operations will get executed - DATA : only operations dealing with DATA (eg + * loading a bitmap) should execute - PAINT : only operations painting should execute */ public enum ContextMode { - UNSET, DATA, PAINT + UNSET, + DATA, + PAINT } public int getTheme() { @@ -229,9 +234,13 @@ public abstract class RemoteContext { // Operations /////////////////////////////////////////////////////////////////////////////////////////////// - public void header(int majorVersion, int minorVersion, int patchVersion, - int width, int height, long capabilities - ) { + public void header( + int majorVersion, + int minorVersion, + int patchVersion, + int width, + int height, + long capabilities) { mRemoteComposeState.setWindowWidth(width); mRemoteComposeState.setWindowHeight(height); mDocument.setVersion(majorVersion, minorVersion, patchVersion); @@ -243,21 +252,14 @@ public abstract class RemoteContext { /** * Sets the way the player handles the content * - * @param scroll set the horizontal behavior (NONE|SCROLL_HORIZONTAL|SCROLL_VERTICAL) + * @param scroll set the horizontal behavior (NONE|SCROLL_HORIZONTAL|SCROLL_VERTICAL) * @param alignment set the alignment of the content (TOP|CENTER|BOTTOM|START|END) - * @param sizing set the type of sizing for the content (NONE|SIZING_LAYOUT|SIZING_SCALE) - * @param mode set the mode of sizing, either LAYOUT modes or SCALE modes - * the LAYOUT modes are: - * - LAYOUT_MATCH_PARENT - * - LAYOUT_WRAP_CONTENT - * or adding an horizontal mode and a vertical mode: - * - LAYOUT_HORIZONTAL_MATCH_PARENT - * - LAYOUT_HORIZONTAL_WRAP_CONTENT - * - LAYOUT_HORIZONTAL_FIXED - * - LAYOUT_VERTICAL_MATCH_PARENT - * - LAYOUT_VERTICAL_WRAP_CONTENT - * - LAYOUT_VERTICAL_FIXED - * The LAYOUT_*_FIXED modes will use the intrinsic document size + * @param sizing set the type of sizing for the content (NONE|SIZING_LAYOUT|SIZING_SCALE) + * @param mode set the mode of sizing, either LAYOUT modes or SCALE modes the LAYOUT modes are: + * - LAYOUT_MATCH_PARENT - LAYOUT_WRAP_CONTENT or adding an horizontal mode and a vertical + * mode: - LAYOUT_HORIZONTAL_MATCH_PARENT - LAYOUT_HORIZONTAL_WRAP_CONTENT - + * LAYOUT_HORIZONTAL_FIXED - LAYOUT_VERTICAL_MATCH_PARENT - LAYOUT_VERTICAL_WRAP_CONTENT - + * LAYOUT_VERTICAL_FIXED The LAYOUT_*_FIXED modes will use the intrinsic document size */ public void setRootContentBehavior(int scroll, int alignment, int sizing, int mode) { mDocument.setRootContentBehavior(scroll, alignment, sizing, mode); @@ -281,16 +283,16 @@ public abstract class RemoteContext { * Save a bitmap under an imageId * * @param imageId the id of the image - * @param width the width of the image - * @param height the height of the image - * @param bitmap the bytes that represent the image + * @param width the width of the image + * @param height the height of the image + * @param bitmap the bytes that represent the image */ public abstract void loadBitmap(int imageId, int width, int height, byte[] bitmap); /** * Save a string under a given id * - * @param id the id of the string + * @param id the id of the string * @param text the value to set */ public abstract void loadText(int id, String text); @@ -306,7 +308,7 @@ public abstract class RemoteContext { /** * Load a float * - * @param id id of the float + * @param id id of the float * @param value the value to set */ public abstract void loadFloat(int id, float value); @@ -314,21 +316,19 @@ public abstract class RemoteContext { /** * Load a integer * - * @param id id of the integer + * @param id id of the integer * @param value the value to set */ public abstract void loadInteger(int id, int value); - public abstract void overrideInteger(int id, int value); public abstract void overrideText(int id, int valueId); /** - * Load an animated float associated with an id - * Todo: Remove? + * Load an animated float associated with an id Todo: Remove? * - * @param id the id of the float + * @param id the id of the float * @param animatedFloat The animated float */ public abstract void loadAnimatedFloat(int id, FloatExpression animatedFloat); @@ -336,7 +336,7 @@ public abstract class RemoteContext { /** * Save a shader under and ID * - * @param id the id of the Shader + * @param id the id of the Shader * @param value the shader */ public abstract void loadShader(int id, ShaderData value); @@ -368,7 +368,7 @@ public abstract class RemoteContext { /** * called to notify system that a command is interested in a variable * - * @param id track when this id changes value + * @param id track when this id changes value * @param variableSupport call back when value changes */ public abstract void listensTo(int id, VariableSupport variableSupport); @@ -401,33 +401,25 @@ public abstract class RemoteContext { public static final int ID_WEEK_DAY = 11; public static final int ID_DAY_OF_MONTH = 12; - /** - * CONTINUOUS_SEC is seconds from midnight looping every hour 0-3600 - */ + /** CONTINUOUS_SEC is seconds from midnight looping every hour 0-3600 */ public static final float FLOAT_CONTINUOUS_SEC = Utils.asNan(ID_CONTINUOUS_SEC); - /** - * seconds run from Midnight=0 quantized to seconds hour 0..3599 - */ + + /** seconds run from Midnight=0 quantized to seconds hour 0..3599 */ public static final float FLOAT_TIME_IN_SEC = Utils.asNan(ID_TIME_IN_SEC); - /** - * minutes run from Midnight=0 quantized to minutes 0..1439 - */ + + /** minutes run from Midnight=0 quantized to minutes 0..1439 */ public static final float FLOAT_TIME_IN_MIN = Utils.asNan(ID_TIME_IN_MIN); - /** - * hours run from Midnight=0 quantized to Hours 0-23 - */ + + /** hours run from Midnight=0 quantized to Hours 0-23 */ public static final float FLOAT_TIME_IN_HR = Utils.asNan(ID_TIME_IN_HR); - /** - * Moth of Year quantized to MONTHS 1-12. 1 = January - */ + + /** Moth of Year quantized to MONTHS 1-12. 1 = January */ public static final float FLOAT_CALENDAR_MONTH = Utils.asNan(ID_CALENDAR_MONTH); - /** - * DAY OF THE WEEK 1-7. 1 = Monday - */ + + /** DAY OF THE WEEK 1-7. 1 = Monday */ public static final float FLOAT_WEEK_DAY = Utils.asNan(ID_WEEK_DAY); - /** - * DAY OF THE MONTH 1-31 - */ + + /** DAY OF THE MONTH 1-31 */ public static final float FLOAT_DAY_OF_MONTH = Utils.asNan(ID_DAY_OF_MONTH); public static final float FLOAT_WINDOW_WIDTH = Utils.asNan(ID_WINDOW_WIDTH); @@ -446,7 +438,8 @@ public abstract class RemoteContext { } public static float getTime(float fl) { - LocalDateTime dateTime = LocalDateTime.now(); + LocalDateTime dateTime = + LocalDateTime.now(ZoneId.systemDefault()); // TODO, pass in a timezone explicitly? // This define the time in the format // seconds run from Midnight=0 quantized to seconds hour 0..3599 // minutes run from Midnight=0 quantized to minutes 0..1439 @@ -464,7 +457,6 @@ public abstract class RemoteContext { float sec = currentSeconds + dateTime.getNano() * 1E-9f; int day_week = dateTime.getDayOfWeek().getValue(); - ZoneId zone = ZoneId.systemDefault(); OffsetDateTime offsetDateTime = dateTime.atZone(zone).toOffsetDateTime(); ZoneOffset offset = offsetDateTime.getOffset(); @@ -488,8 +480,6 @@ public abstract class RemoteContext { return fl; } - - public abstract void addClickArea( int id, int contentDescription, @@ -497,7 +487,5 @@ public abstract class RemoteContext { float top, float right, float bottom, - int metadataId - ); + int metadataId); } - diff --git a/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java b/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java index 04e04bbb9063..fa0cf3f455c4 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java +++ b/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java @@ -20,9 +20,7 @@ import java.time.OffsetDateTime; import java.time.ZoneId; import java.time.ZoneOffset; -/** - * This generates the standard system variables for time. - */ +/** This generates the standard system variables for time. */ public class TimeVariables { /** * This class populates all time variables in the system @@ -30,7 +28,8 @@ public class TimeVariables { * @param context */ public void updateTime(RemoteContext context) { - LocalDateTime dateTime = LocalDateTime.now(); + LocalDateTime dateTime = + LocalDateTime.now(ZoneId.systemDefault()); // TODO, pass in a timezone explicitly? // This define the time in the format // seconds run from Midnight=0 quantized to seconds hour 0..3599 // minutes run from Midnight=0 quantized to minutes 0..1439 @@ -47,7 +46,6 @@ public class TimeVariables { float sec = currentSeconds + dateTime.getNano() * 1E-9f; int day_week = dateTime.getDayOfWeek().getValue(); - ZoneId zone = ZoneId.systemDefault(); OffsetDateTime offsetDateTime = dateTime.atZone(zone).toOffsetDateTime(); ZoneOffset offset = offsetDateTime.getOffset(); @@ -60,6 +58,5 @@ public class TimeVariables { context.loadFloat(RemoteContext.ID_CALENDAR_MONTH, month); context.loadFloat(RemoteContext.ID_DAY_OF_MONTH, month); context.loadFloat(RemoteContext.ID_WEEK_DAY, day_week); - } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/VariableSupport.java b/core/java/com/android/internal/widget/remotecompose/core/VariableSupport.java index ee6d5798bdb2..51e58a1aeddd 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/VariableSupport.java +++ b/core/java/com/android/internal/widget/remotecompose/core/VariableSupport.java @@ -16,20 +16,21 @@ package com.android.internal.widget.remotecompose.core; /** - * Interface for operators that interact with variables - * Through this they register to listen to particular variables - * and are notified when they change + * Interface for operators that interact with variables Through this they register to listen to + * particular variables and are notified when they change */ public interface VariableSupport { /** - * Call to allow an operator to register interest in variables. - * Typically they call context.listensTo(id, this) + * Call to allow an operator to register interest in variables. Typically they call + * context.listensTo(id, this) + * * @param context */ void registerListening(RemoteContext context); /** * Called to be notified that the variables you are interested have changed. + * * @param context */ void updateVariables(RemoteContext context); diff --git a/core/java/com/android/internal/widget/remotecompose/core/WireBuffer.java b/core/java/com/android/internal/widget/remotecompose/core/WireBuffer.java index fc3202e2160d..c71b4901ca78 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/WireBuffer.java +++ b/core/java/com/android/internal/widget/remotecompose/core/WireBuffer.java @@ -17,9 +17,7 @@ package com.android.internal.widget.remotecompose.core; import java.util.Arrays; -/** - * The base communication buffer capable of encoding and decoding various types - */ +/** The base communication buffer capable of encoding and decoding various types */ public class WireBuffer { private static final int BUFFER_SIZE = 1024 * 1024 * 1; int mMaxSize; @@ -130,6 +128,7 @@ public class WireBuffer { int v2 = (mBuffer[mIndex++] & 0xFF) << 0; return v1 + v2; } + public int peekInt() { int tmp = mIndex; int v1 = (mBuffer[tmp++] & 0xFF) << 24; @@ -177,8 +176,8 @@ public class WireBuffer { public byte[] readBuffer(int maxSize) { int count = readInt(); if (count < 0 || count > maxSize) { - throw new RuntimeException("attempt read a buff of invalid size 0 <= " - + count + " > " + maxSize); + throw new RuntimeException( + "attempt read a buff of invalid size 0 <= " + count + " > " + maxSize); } byte[] b = Arrays.copyOfRange(mBuffer, mIndex, mIndex + count); mIndex += count; @@ -201,7 +200,7 @@ public class WireBuffer { public void writeBoolean(boolean value) { resize(1); - mBuffer[mIndex++] = (byte) ((value) ? 1 : 0); + mBuffer[mIndex++] = (byte) (value ? 1 : 0); mSize++; } @@ -256,7 +255,6 @@ public class WireBuffer { writeInt(b.length); for (int i = 0; i < b.length; i++) { mBuffer[mIndex++] = b[i]; - } mSize += b.length; } @@ -265,6 +263,4 @@ public class WireBuffer { byte[] buffer = content.getBytes(); writeBuffer(buffer); } - } - diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentationBuilder.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentationBuilder.java index ccbcdf6e615d..f6dfe2ebe171 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentationBuilder.java +++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentationBuilder.java @@ -17,6 +17,8 @@ package com.android.internal.widget.remotecompose.core.documentation; public interface DocumentationBuilder { void add(String value); - Operation operation(String category, int id, String name); - Operation wipOperation(String category, int id, String name); + + DocumentedOperation operation(String category, int id, String name); + + DocumentedOperation wipOperation(String category, int id, String name); } diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedOperation.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedOperation.java new file mode 100644 index 000000000000..c33ae244b923 --- /dev/null +++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedOperation.java @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.widget.remotecompose.core.documentation; + +import java.util.ArrayList; + +public class DocumentedOperation { + public static final int LAYOUT = 0; + public static final int INT = 0; + public static final int FLOAT = 1; + public static final int BOOLEAN = 2; + public static final int BUFFER = 4; + public static final int UTF8 = 5; + public static final int BYTE = 6; + public static final int VALUE = 7; + public static final int LONG = 8; + public static final int SHORT = 9; + + public static final int FLOAT_ARRAY = 10; + public static final int INT_ARRAY = 11; + + String mCategory; + int mId; + String mName; + String mDescription; + + boolean mWIP; + String mTextExamples; + + ArrayList<StringPair> mExamples = new ArrayList<>(); + ArrayList<OperationField> mFields = new ArrayList<>(); + String mVarSize = ""; + int mExamplesWidth = 100; + int mExamplesHeight = 100; + + public static String getType(int type) { + switch (type) { + case INT: + return "INT"; + case FLOAT: + return "FLOAT"; + case BOOLEAN: + return "BOOLEAN"; + case BUFFER: + return "BUFFER"; + case UTF8: + return "UTF8"; + case BYTE: + return "BYTE"; + case VALUE: + return "VALUE"; + case LONG: + return "LONG"; + case SHORT: + return "SHORT"; + case FLOAT_ARRAY: + return "FLOAT[]"; + case INT_ARRAY: + return "INT[]"; + } + return "UNKNOWN"; + } + + public DocumentedOperation(String category, int id, String name, boolean wip) { + mCategory = category; + mId = id; + mName = name; + mWIP = wip; + } + + public DocumentedOperation(String category, int id, String name) { + this(category, id, name, false); + } + + public ArrayList<OperationField> getFields() { + return mFields; + } + + public String getCategory() { + return mCategory; + } + + public int getId() { + return mId; + } + + public String getName() { + return mName; + } + + public boolean isWIP() { + return mWIP; + } + + public String getVarSize() { + return mVarSize; + } + + public int getSizeFields() { + int size = 0; + mVarSize = ""; + for (OperationField field : mFields) { + size += Math.max(0, field.getSize()); + if (field.getSize() < 0) { + mVarSize += " + " + field.getVarSize() + " x 4"; + } + } + return size; + } + + public String getDescription() { + return mDescription; + } + + public String getTextExamples() { + return mTextExamples; + } + + public ArrayList<StringPair> getExamples() { + return mExamples; + } + + public int getExamplesWidth() { + return mExamplesWidth; + } + + public int getExamplesHeight() { + return mExamplesHeight; + } + + public DocumentedOperation field(int type, String name, String description) { + mFields.add(new OperationField(type, name, description)); + return this; + } + + public DocumentedOperation field(int type, String name, String varSize, String description) { + mFields.add(new OperationField(type, name, varSize, description)); + return this; + } + + public DocumentedOperation possibleValues(String name, int value) { + if (!mFields.isEmpty()) { + mFields.get(mFields.size() - 1).possibleValue(name, "" + value); + } + return this; + } + + public DocumentedOperation description(String description) { + mDescription = description; + return this; + } + + public DocumentedOperation examples(String examples) { + mTextExamples = examples; + return this; + } + + public DocumentedOperation exampleImage(String name, String imagePath) { + mExamples.add(new StringPair(name, imagePath)); + return this; + } + + public DocumentedOperation examplesDimension(int width, int height) { + mExamplesWidth = width; + mExamplesHeight = height; + return this; + } +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/Operation.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/Operation.java index 9ccb2be9969a..f02a3852c92a 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/documentation/Operation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/Operation.java @@ -46,20 +46,30 @@ public class Operation { int mExamplesWidth = 100; int mExamplesHeight = 100; - public static String getType(int type) { switch (type) { - case (INT): return "INT"; - case (FLOAT): return "FLOAT"; - case (BOOLEAN): return "BOOLEAN"; - case (BUFFER): return "BUFFER"; - case (UTF8): return "UTF8"; - case (BYTE): return "BYTE"; - case (VALUE): return "VALUE"; - case (LONG): return "LONG"; - case (SHORT): return "SHORT"; - case (FLOAT_ARRAY): return "FLOAT[]"; - case (INT_ARRAY): return "INT[]"; + case INT: + return "INT"; + case FLOAT: + return "FLOAT"; + case BOOLEAN: + return "BOOLEAN"; + case BUFFER: + return "BUFFER"; + case UTF8: + return "UTF8"; + case BYTE: + return "BYTE"; + case VALUE: + return "VALUE"; + case LONG: + return "LONG"; + case SHORT: + return "SHORT"; + case FLOAT_ARRAY: + return "FLOAT[]"; + case INT_ARRAY: + return "INT[]"; } return "UNKNOWN"; } diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java index 0dd3039f5f4d..c77048391405 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java +++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java @@ -41,20 +41,23 @@ public class OperationField { public int getType() { return mType; } + public String getName() { return mName; } + public String getDescription() { return mDescription; } + public ArrayList<StringPair> getPossibleValues() { return mPossibleValues; } - public void possibleValue(String name, String value) { mPossibleValues.add(new StringPair(name, value)); } + public boolean hasEnumeratedValues() { return !mPossibleValues.isEmpty(); } @@ -65,14 +68,22 @@ public class OperationField { public int getSize() { switch (mType) { - case (Operation.BYTE) : return 1; - case (Operation.INT) : return 4; - case (Operation.FLOAT) : return 4; - case (Operation.LONG) : return 8; - case (Operation.SHORT) : return 2; - case (Operation.INT_ARRAY): return -1; - case (Operation.FLOAT_ARRAY): return -1; - default : return 0; + case DocumentedOperation.BYTE: + return 1; + case DocumentedOperation.INT: + return 4; + case DocumentedOperation.FLOAT: + return 4; + case DocumentedOperation.LONG: + return 8; + case DocumentedOperation.SHORT: + return 2; + case DocumentedOperation.INT_ARRAY: + return -1; + case DocumentedOperation.FLOAT_ARRAY: + return -1; + default: + return 0; } } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/StringPair.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/StringPair.java index 787bb54a5f0a..5b0cedbaf6af 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/documentation/StringPair.java +++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/StringPair.java @@ -14,6 +14,7 @@ * limitations under the License. */ package com.android.internal.widget.remotecompose.core.documentation; + public class StringPair { String mName; String mValue; @@ -26,6 +27,7 @@ public class StringPair { public String getName() { return mName; } + public String getValue() { return mValue; } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/BitmapData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/BitmapData.java index 58be641f608a..20ba8c313b47 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/BitmapData.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/BitmapData.java @@ -15,8 +15,8 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT_ARRAY; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT_ARRAY; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -24,14 +24,14 @@ import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.SerializableToString; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer; import java.util.List; /** - * Operation to deal with bitmap data - * On getting an Image during a draw call the bitmap is compressed and saved - * in playback the image is decompressed + * Operation to deal with bitmap data On getting an Image during a draw call the bitmap is + * compressed and saved in playback the image is decompressed */ public class BitmapData implements Operation, SerializableToString { private static final int OP_CODE = Operations.DATA_BITMAP; @@ -67,7 +67,6 @@ public class BitmapData implements Operation, SerializableToString { return "BITMAP DATA " + mImageId; } - public static String name() { return CLASS_NAME; } @@ -84,7 +83,6 @@ public class BitmapData implements Operation, SerializableToString { buffer.writeBuffer(bitmap); } - public static void read(WireBuffer buffer, List<Operation> operations) { int imageId = buffer.readInt(); int width = buffer.readInt(); @@ -99,19 +97,13 @@ public class BitmapData implements Operation, SerializableToString { operations.add(new BitmapData(imageId, width, height, bitmap)); } - public static void documentation(DocumentationBuilder doc) { - doc.operation("Data Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Data Operations", OP_CODE, CLASS_NAME) .description("Bitmap data") - .field(INT, "id", "id of bitmap data") - .field(INT, "width", - "width of the image") - .field(INT, "height", - "height of the image") - .field(INT_ARRAY, "values", "length", - "Array of ints"); + .field(DocumentedOperation.INT, "id", "id of bitmap data") + .field(INT, "width", "width of the image") + .field(INT, "height", "height of the image") + .field(INT_ARRAY, "values", "length", "Array of ints"); } @Override @@ -124,9 +116,10 @@ public class BitmapData implements Operation, SerializableToString { return indent + toString(); } + @Override public void serializeToString(int indent, StringSerializer serializer) { - serializer.append(indent, CLASS_NAME - + " id " + mImageId + " (" + mImageWidth + "x" + mImageHeight + ")"); + serializer.append( + indent, + CLASS_NAME + " id " + mImageId + " (" + mImageWidth + "x" + mImageHeight + ")"); } - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ClickArea.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ClickArea.java index e72e24a0b85a..8b9e5a8d7625 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/ClickArea.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ClickArea.java @@ -15,20 +15,17 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.RemoteComposeOperation; import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; -/** - * Add a click area to the document - */ +/** Add a click area to the document */ public class ClickArea implements RemoteComposeOperation { private static final int OP_CODE = Operations.CLICK_AREA; private static final String CLASS_NAME = "ClickArea"; @@ -43,8 +40,8 @@ public class ClickArea implements RemoteComposeOperation { /** * Add a click area to the document * - * @param id the id of the click area, which will be reported in the listener - * callback on the player + * @param id the id of the click area, which will be reported in the listener callback on the + * player * @param contentDescription the content description (used for accessibility, as a textID) * @param left left coordinate of the area bounds * @param top top coordinate of the area bounds @@ -52,10 +49,14 @@ public class ClickArea implements RemoteComposeOperation { * @param bottom bottom coordinate of the area bounds * @param metadata associated metadata, user-provided (as a textID, pointing to a string) */ - public ClickArea(int id, int contentDescription, - float left, float top, - float right, float bottom, - int metadata) { + public ClickArea( + int id, + int contentDescription, + float left, + float top, + float right, + float bottom, + int metadata) { this.mId = id; this.mContentDescription = contentDescription; this.mLeft = left; @@ -72,10 +73,27 @@ public class ClickArea implements RemoteComposeOperation { @Override public String toString() { - return "CLICK_AREA <" + mId + " <" + mContentDescription + "> " - + "<" + mMetadata + ">+" + mLeft + " " - + mTop + " " + mRight + " " + mBottom + "+" - + " (" + (mRight - mLeft) + " x " + (mBottom - mTop) + " }"; + return "CLICK_AREA <" + + mId + + " <" + + mContentDescription + + "> " + + "<" + + mMetadata + + ">+" + + mLeft + + " " + + mTop + + " " + + mRight + + " " + + mBottom + + "+" + + " (" + + (mRight - mLeft) + + " x " + + (mBottom - mTop) + + " }"; } @Override @@ -95,14 +113,19 @@ public class ClickArea implements RemoteComposeOperation { return CLASS_NAME; } - public static int id() { return OP_CODE; } - public static void apply(WireBuffer buffer, int id, int contentDescription, - float left, float top, float right, float bottom, - int metadata) { + public static void apply( + WireBuffer buffer, + int id, + int contentDescription, + float left, + float top, + float right, + float bottom, + int metadata) { buffer.start(OP_CODE); buffer.writeInt(id); buffer.writeInt(contentDescription); @@ -113,7 +136,6 @@ public class ClickArea implements RemoteComposeOperation { buffer.writeInt(metadata); } - public static void read(WireBuffer buffer, List<Operation> operations) { int id = buffer.readInt(); int contentDescription = buffer.readInt(); @@ -122,26 +144,21 @@ public class ClickArea implements RemoteComposeOperation { float right = buffer.readFloat(); float bottom = buffer.readFloat(); int metadata = buffer.readInt(); - ClickArea clickArea = new ClickArea(id, contentDescription, - left, top, right, bottom, metadata); + ClickArea clickArea = + new ClickArea(id, contentDescription, left, top, right, bottom, metadata); operations.add(clickArea); } - public static void documentation(DocumentationBuilder doc) { - doc.operation("Canvas Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Canvas Operations", OP_CODE, CLASS_NAME) .description("Define a region you can click on") - .field(FLOAT, "left", - "The left side of the region") - .field(FLOAT, "top", - "The top of the region") - .field(FLOAT, "right", - "The right side of the region") - .field(FLOAT, "bottom", - "The bottom of the region") - .field(FLOAT, "metadata", + .field(DocumentedOperation.FLOAT, "left", "The left side of the region") + .field(DocumentedOperation.FLOAT, "top", "The top of the region") + .field(DocumentedOperation.FLOAT, "right", "The right side of the region") + .field(DocumentedOperation.FLOAT, "bottom", "The bottom of the region") + .field( + DocumentedOperation.FLOAT, + "metadata", "user defined string accessible in callback"); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ClipPath.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ClipPath.java index d77d53cca963..96b600acc971 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/ClipPath.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ClipPath.java @@ -15,21 +15,19 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.PaintContext; import com.android.internal.widget.remotecompose.core.PaintOperation; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; /** - * Defines a path that clips a the subsequent drawing commands - * Use MatrixSave and MatrixRestore commands to remove clip - * TODO allow id 0 to mean null? + * Defines a path that clips a the subsequent drawing commands Use MatrixSave and MatrixRestore + * commands to remove clip TODO allow id 0 to mean null? */ public class ClipPath extends PaintOperation { private static final int OP_CODE = Operations.CLIP_PATH; @@ -68,7 +66,6 @@ public class ClipPath extends PaintOperation { return "ClipPath " + mId + ";"; } - public static void read(WireBuffer buffer, List<Operation> operations) { int pack = buffer.readInt(); int id = pack & 0xFFFFF; @@ -77,12 +74,10 @@ public class ClipPath extends PaintOperation { operations.add(op); } - public static String name() { return CLASS_NAME; } - public static int id() { return OP_CODE; } @@ -93,17 +88,13 @@ public class ClipPath extends PaintOperation { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Canvas Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Canvas Operations", OP_CODE, CLASS_NAME) .description("Intersect the current clip with the path") - .field(INT, "id", - "id of the path"); + .field(DocumentedOperation.INT, "id", "id of the path"); } - @Override public void paint(PaintContext context) { context.clipPath(mId, mRegionOp); } -}
\ No newline at end of file +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ClipRect.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ClipRect.java index ec9b6fe483c9..b101bfb2d151 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/ClipRect.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ClipRect.java @@ -15,24 +15,20 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.PaintContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; -/** - * Support clip with a rectangle - */ +/** Support clip with a rectangle */ public class ClipRect extends DrawBase4 { public static final int OP_CODE = Operations.CLIP_RECT; public static final String CLASS_NAME = "ClipRect"; - public static void read(WireBuffer buffer, List<Operation> operations) { Maker m = ClipRect::new; read(m, buffer, operations); @@ -46,36 +42,33 @@ public class ClipRect extends DrawBase4 { return CLASS_NAME; } - - protected void write(WireBuffer buffer, - float v1, - float v2, - float v3, - float v4) { + @Override + protected void write(WireBuffer buffer, float v1, float v2, float v3, float v4) { apply(buffer, v1, v2, v3, v4); } public static void documentation(DocumentationBuilder doc) { - doc.operation("Expressions Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Expressions Operations", OP_CODE, CLASS_NAME) .description("Intersect the current clip with rectangle") - .field(FLOAT, "left", + .field( + DocumentedOperation.FLOAT, + "left", "The left side of the rectangle to intersect with the current clip") - .field(FLOAT, "top", + .field( + DocumentedOperation.FLOAT, + "top", "The top of the rectangle to intersect with the current clip") - .field(FLOAT, "right", + .field( + DocumentedOperation.FLOAT, + "right", "The right side of the rectangle to intersect with the current clip") - .field(FLOAT, "bottom", + .field( + DocumentedOperation.FLOAT, + "bottom", "The bottom of the rectangle to intersect with the current clip"); } - - public ClipRect( - float left, - float top, - float right, - float bottom) { + public ClipRect(float left, float top, float right, float bottom) { super(left, top, right, bottom); mName = CLASS_NAME; } @@ -89,16 +82,12 @@ public class ClipRect extends DrawBase4 { * Writes out the clipRect to the buffer * * @param buffer buffer to write to - * @param x1 start x of DrawOval - * @param y1 start y of the DrawOval - * @param x2 end x of the DrawOval - * @param y2 end y of the DrawOval + * @param x1 start x of DrawOval + * @param y1 start y of the DrawOval + * @param x2 end x of the DrawOval + * @param y2 end y of the DrawOval */ - public static void apply(WireBuffer buffer, - float x1, - float y1, - float x2, - float y2) { + public static void apply(WireBuffer buffer, float x1, float y1, float x2, float y2) { write(buffer, OP_CODE, x1, y1, x2, y2); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java index 2562e18b386c..19d80daf0c8f 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java @@ -15,20 +15,18 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; -/** - * Operation that defines a simple Color based on ID - * Mainly for colors in theming. - */ +/** Operation that defines a simple Color based on ID Mainly for colors in theming. */ public class ColorConstant implements Operation { private static final int OP_CODE = Operations.COLOR_CONSTANT; private static final String CLASS_NAME = "ColorConstant"; @@ -78,14 +76,10 @@ public class ColorConstant implements Operation { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Expressions Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Expressions Operations", OP_CODE, CLASS_NAME) .description("Define a Color") - .field(INT, "id", - "Id of the color") - .field(INT, "color", - "32 bit ARGB color"); + .field(DocumentedOperation.INT, "id", "Id of the color") + .field(INT, "color", "32 bit ARGB color"); } @Override diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ColorExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorExpression.java index 96d667465e8f..b6041eaeacdc 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/ColorExpression.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorExpression.java @@ -15,8 +15,8 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -24,17 +24,13 @@ import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.VariableSupport; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; /** - * Operation to Colors - * Color modes - * mMode = 0 two colors and a tween - * mMode = 1 color1 is a colorID. - * mMode = 2 color2 is a colorID. - * mMode = 3 color1 & color2 are ids - * mMode = 4 H S V mode + * Operation to Colors Color modes mMode = 0 two colors and a tween mMode = 1 color1 is a colorID. + * mMode = 2 color2 is a colorID. mMode = 3 color1 & color2 are ids mMode = 4 H S V mode */ public class ColorExpression implements Operation, VariableSupport { private static final int OP_CODE = Operations.COLOR_EXPRESSIONS; @@ -45,7 +41,6 @@ public class ColorExpression implements Operation, VariableSupport { public int mColor2; public float mTween = 0.0f; - public float mHue = 0; // only in Mode 4 public float mSat = 0; public float mValue = 0; @@ -122,7 +117,6 @@ public class ColorExpression implements Operation, VariableSupport { } } - @Override public void registerListening(RemoteContext context) { if (mMode == 4) { @@ -151,8 +145,8 @@ public class ColorExpression implements Operation, VariableSupport { @Override public void apply(RemoteContext context) { if (mMode == 4) { - context.loadColor(mId, (mAlpha << 24) - | (0xFFFFFF & Utils.hsvToRgb(mOutHue, mOutSat, mOutValue))); + context.loadColor( + mId, (mAlpha << 24) | (0xFFFFFF & Utils.hsvToRgb(mOutHue, mOutSat, mOutValue))); return; } if (mOutTween == 0.0) { @@ -165,8 +159,7 @@ public class ColorExpression implements Operation, VariableSupport { mOutColor2 = context.getColor(mColor2); } - context.loadColor(mId, - Utils.interpolateColor(mOutColor1, mOutColor2, mOutTween)); + context.loadColor(mId, Utils.interpolateColor(mOutColor1, mOutColor2, mOutTween)); } } @@ -179,23 +172,34 @@ public class ColorExpression implements Operation, VariableSupport { @Override public String toString() { if (mMode == 4) { - return "ColorExpression[" + mId + "] = hsv (" + Utils.floatToString(mHue) - + ", " + Utils.floatToString(mSat) - + ", " + Utils.floatToString(mValue) + ")"; + return "ColorExpression[" + + mId + + "] = hsv (" + + Utils.floatToString(mHue) + + ", " + + Utils.floatToString(mSat) + + ", " + + Utils.floatToString(mValue) + + ")"; } String c1 = (mMode & 1) == 1 ? "[" + mColor1 + "]" : Utils.colorInt(mColor1); String c2 = (mMode & 2) == 2 ? "[" + mColor2 + "]" : Utils.colorInt(mColor2); - return "ColorExpression[" + mId + "] = tween(" + c1 - + ", " + c2 + ", " - + Utils.floatToString(mTween) + ")"; + return "ColorExpression[" + + mId + + "] = tween(" + + c1 + + ", " + + c2 + + ", " + + Utils.floatToString(mTween) + + ")"; } public static String name() { return CLASS_NAME; } - public static int id() { return OP_CODE; } @@ -204,22 +208,20 @@ public class ColorExpression implements Operation, VariableSupport { * Call to write a ColorExpression object on the buffer * * @param buffer - * @param id of the ColorExpression object - * @param mode if colors are id or actual values + * @param id of the ColorExpression object + * @param mode if colors are id or actual values * @param color1 * @param color2 * @param tween */ - public static void apply(WireBuffer buffer, - int id, int mode, - int color1, int color2, float tween) { + public static void apply( + WireBuffer buffer, int id, int mode, int color1, int color2, float tween) { buffer.start(OP_CODE); buffer.writeInt(id); buffer.writeInt(mode); buffer.writeInt(color1); buffer.writeInt(color2); buffer.writeFloat(tween); - } public static void read(WireBuffer buffer, List<Operation> operations) { @@ -233,29 +235,22 @@ public class ColorExpression implements Operation, VariableSupport { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Expressions Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Expressions Operations", OP_CODE, CLASS_NAME) .description("A Color defined by an expression") - .field(INT, "id", "Id of the color") + .field(DocumentedOperation.INT, "id", "Id of the color") .field(INT, "mode", "The use of the next 3 fields") .possibleValues("COLOR_COLOR_INTERPOLATE", 0) .possibleValues("COLOR_ID_INTERPOLATE", 1) .possibleValues("ID_COLOR_INTERPOLATE", 2) .possibleValues("ID_ID_INTERPOLATE", 3) .possibleValues("HSV", 4) - .field(INT, "color1", - "32 bit ARGB color") - .field(INT, "color2", - "32 bit ARGB color") - .field(FLOAT, "tween", - "32 bit ARGB color"); - + .field(INT, "color1", "32 bit ARGB color") + .field(INT, "color2", "32 bit ARGB color") + .field(FLOAT, "tween", "32 bit ARGB color"); } @Override public String deepToString(String indent) { return indent + toString(); } - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ComponentValue.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ComponentValue.java index 22fe673bc072..992972076839 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/ComponentValue.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ComponentValue.java @@ -15,7 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -23,6 +23,7 @@ import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.SerializableToString; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer; import java.util.List; @@ -82,15 +83,16 @@ public class ComponentValue implements Operation, SerializableToString { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Expressions Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Expressions Operations", OP_CODE, CLASS_NAME) .description("Encode a component-related value (eg its width, height etc.)") - .field(INT, "TYPE", + .field( + DocumentedOperation.INT, + "TYPE", "The type of value, either WIDTH(0) or HEIGHT(1)") - .field(INT, "COMPONENT_ID", - "The component id to reference") - .field(INT, "VALUE_ID", + .field(INT, "COMPONENT_ID", "The component id to reference") + .field( + INT, + "VALUE_ID", "The id of the RemoteFloat representing the described" + " component value, which can be used in expressions"); } @@ -105,14 +107,11 @@ public class ComponentValue implements Operation, SerializableToString { * Writes out the ComponentValue to the buffer * * @param buffer buffer to write to - * @param type type of value (WIDTH or HEIGHT) - * @param componentId component id to reference - * @param valueId remote float used to represent the component value + * @param type type of value (WIDTH or HEIGHT) + * @param componentId component id to reference + * @param valueId remote float used to represent the component value */ - public static void apply(WireBuffer buffer, - int type, - int componentId, - int valueId) { + public static void apply(WireBuffer buffer, int type, int componentId, int valueId) { buffer.start(OP_CODE); buffer.writeInt(type); buffer.writeInt(componentId); @@ -124,13 +123,20 @@ public class ComponentValue implements Operation, SerializableToString { return null; } + @Override public void serializeToString(int indent, StringSerializer serializer) { String type = "WIDTH"; if (mType == HEIGHT) { type = "HEIGHT"; } - serializer.append(indent, CLASS_NAME - + " value " + mValueId + " set to " - + type + " of Component " + mComponentID); + serializer.append( + indent, + CLASS_NAME + + " value " + + mValueId + + " set to " + + type + + " of Component " + + mComponentID); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DataListFloat.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DataListFloat.java index edcb5fef7766..00758694c254 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DataListFloat.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DataListFloat.java @@ -15,8 +15,8 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT_ARRAY; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT_ARRAY; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -24,6 +24,7 @@ import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.VariableSupport; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import com.android.internal.widget.remotecompose.core.operations.utilities.ArrayAccess; import java.util.Arrays; @@ -63,7 +64,7 @@ public class DataListFloat implements VariableSupport, ArrayAccess, Operation { @Override public String toString() { - return "DataListFloat[A_" + (mId & 0xFFFF) + "] " + Arrays.toString(mValues); + return "DataListFloat[" + Utils.idString(mId) + "] " + Arrays.toString(mValues); } public static void apply(WireBuffer buffer, int id, float[] values) { @@ -90,14 +91,11 @@ public class DataListFloat implements VariableSupport, ArrayAccess, Operation { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Data Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Data Operations", OP_CODE, CLASS_NAME) .description("a list of Floats") - .field(INT, "id", "id the array (2xxxxx)") + .field(DocumentedOperation.INT, "id", "id the array (2xxxxx)") .field(INT, "length", "number of floats") - .field(FLOAT_ARRAY, "values", "length", - "array of floats"); + .field(FLOAT_ARRAY, "values", "length", "array of floats"); } @Override @@ -121,7 +119,7 @@ public class DataListFloat implements VariableSupport, ArrayAccess, Operation { } @Override - public int getFloatsLength() { + public int getLength() { return mValues.length; } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DataListIds.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DataListIds.java index bde376e59d9c..c43dab4bbee0 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DataListIds.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DataListIds.java @@ -15,8 +15,8 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT_ARRAY; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT_ARRAY; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -24,39 +24,29 @@ import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.VariableSupport; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import com.android.internal.widget.remotecompose.core.operations.utilities.ArrayAccess; import java.util.Arrays; import java.util.List; -public class DataListIds implements VariableSupport, ArrayAccess, Operation { +public class DataListIds implements VariableSupport, ArrayAccess, Operation { private static final int OP_CODE = Operations.ID_LIST; private static final String CLASS_NAME = "IdListData"; int mId; int[] mIds; - float[] mValues; private static final int MAX_LIST = 2000; public DataListIds(int id, int[] ids) { mId = id; mIds = ids; - mValues = new float[ids.length]; } @Override - public void updateVariables(RemoteContext context) { - for (int i = 0; i < mIds.length; i++) { - int id = mIds[i]; - mValues[i] = context.getFloat(id); - } - } + public void updateVariables(RemoteContext context) {} @Override - public void registerListening(RemoteContext context) { - for (int mId : mIds) { - context.listensTo(mId, this); - } - } + public void registerListening(RemoteContext context) {} @Override public void write(WireBuffer buffer) { @@ -65,7 +55,7 @@ public class DataListIds implements VariableSupport, ArrayAccess, Operation { @Override public String toString() { - return "map " + "\"" + Arrays.toString(mIds) + "\""; + return "map[" + Utils.idString(mId) + "] \"" + Arrays.toString(mIds) + "\""; } public static void apply(WireBuffer buffer, int id, int[] ids) { @@ -92,15 +82,11 @@ public class DataListIds implements VariableSupport, ArrayAccess, Operation { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Data Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Data Operations", OP_CODE, CLASS_NAME) .description("a list of id's") - .field(INT, "id", "id the array") + .field(DocumentedOperation.INT, "id", "id the array") .field(INT, "length", "number of ids") - .field(INT_ARRAY, "ids[n]", "length", - "ids of other variables"); - + .field(INT_ARRAY, "ids[n]", "length", "ids of other variables"); } @Override @@ -115,16 +101,26 @@ public class DataListIds implements VariableSupport, ArrayAccess, Operation { @Override public float getFloatValue(int index) { - return mValues[index]; + return Float.NaN; + } + + @Override + public int getId(int index) { + return mIds[index]; } @Override public float[] getFloats() { - return mValues; + return null; + } + + @Override + public int getLength() { + return mIds.length; } @Override - public int getFloatsLength() { - return mValues.length; + public int getIntValue(int index) { + return 0; } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapIds.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapIds.java index 53143dcf8211..75db29d2781e 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapIds.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapIds.java @@ -15,78 +15,82 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.UTF8; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.UTF8; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.RemoteContext; -import com.android.internal.widget.remotecompose.core.VariableSupport; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; -import com.android.internal.widget.remotecompose.core.operations.utilities.ArrayAccess; +import com.android.internal.widget.remotecompose.core.operations.utilities.DataMap; import java.util.List; -public class DataMapIds implements VariableSupport, ArrayAccess, Operation { +/** This is a map of strings to type & Id */ +public class DataMapIds implements Operation { private static final int OP_CODE = Operations.ID_MAP; - private static final String CLASS_NAME = "IdMapData"; + private static final String CLASS_NAME = "DataMapIds"; int mId; - String[] mNames; - int[] mIds; - float[] mValues; - private static final int MAX_MAP = 2000; - - public DataMapIds(int id, String[] names, int[] ids) { - mId = id; - mNames = names; - mIds = ids; - mValues = new float[ids.length]; + DataMap mDataMap; - } + private static final int MAX_MAP = 2000; - @Override - public void updateVariables(RemoteContext context) { - for (int i = 0; i < mIds.length; i++) { - int id = mIds[i]; - mValues[i] = context.getFloat(id); + public static final byte TYPE_STRING = 0; + public static final byte TYPE_INT = 1; + public static final byte TYPE_FLOAT = 2; + public static final byte TYPE_LONG = 3; + public static final byte TYPE_BOOLEAN = 4; + + private String typeString(byte type) { + switch (type) { + case TYPE_STRING: + return "String"; + case TYPE_INT: + return "Int"; + case TYPE_FLOAT: + return "Float"; + case TYPE_LONG: + return "Long"; + case TYPE_BOOLEAN: + return "Boolean"; } + return "?"; } - @Override - public void registerListening(RemoteContext context) { - for (int mId : mIds) { - context.listensTo(mId, this); - } + public DataMapIds(int id, String[] names, byte[] types, int[] ids) { + mId = id; + mDataMap = new DataMap(names, types, ids); } @Override public void write(WireBuffer buffer) { - apply(buffer, mId, mNames, mIds); + apply(buffer, mId, mDataMap.mNames, mDataMap.mTypes, mDataMap.mIds); } @Override public String toString() { - StringBuilder builder = new StringBuilder("DataMapIds "); - for (int i = 0; i < mNames.length; i++) { + StringBuilder builder = new StringBuilder("DataMapIds[" + Utils.idString(mId) + "] "); + for (int i = 0; i < mDataMap.mNames.length; i++) { if (i != 0) { builder.append(" "); } - builder.append(mNames[i]); + builder.append(typeString(mDataMap.mTypes[i])); builder.append("["); - builder.append(mIds[i]); - builder.append("]"); - + builder.append(mDataMap.mNames[i]); + builder.append("]="); + builder.append(mDataMap.mIds[i]); } return builder.toString(); } - public static void apply(WireBuffer buffer, int id, String[] names, int[] ids) { + public static void apply(WireBuffer buffer, int id, String[] names, byte[] type, int[] ids) { buffer.start(OP_CODE); buffer.writeInt(id); buffer.writeInt(names.length); for (int i = 0; i < names.length; i++) { buffer.writeUTF8(names[i]); + buffer.writeByte(type == null ? 2 : type[i]); buffer.writeInt(ids[i]); } } @@ -99,25 +103,23 @@ public class DataMapIds implements VariableSupport, ArrayAccess, Operation { } String[] names = new String[len]; int[] ids = new int[len]; + byte[] types = new byte[len]; for (int i = 0; i < names.length; i++) { names[i] = buffer.readUTF8(); + types[i] = (byte) buffer.readByte(); ids[i] = buffer.readInt(); } - DataMapIds data = new DataMapIds(id, names, ids); + DataMapIds data = new DataMapIds(id, names, types, ids); operations.add(data); } public static void documentation(DocumentationBuilder doc) { - doc.operation("Data Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Data Operations", OP_CODE, CLASS_NAME) .description("Encode a collection of name id pairs") .field(INT, "id", "id the array") .field(INT, "length", "number of entries") - .field(INT, "names[0]", "length", - "path encoded as floats") - .field(UTF8, "id[0]", "length", - "path encoded as floats"); + .field(INT, "names[0]", "length", "path encoded as floats") + .field(UTF8, "id[0]", "length", "path encoded as floats"); } @Override @@ -127,21 +129,6 @@ public class DataMapIds implements VariableSupport, ArrayAccess, Operation { @Override public void apply(RemoteContext context) { - context.addCollection(mId, this); - } - - @Override - public float getFloatValue(int index) { - return mValues[index]; - } - - @Override - public float[] getFloats() { - return mValues; - } - - @Override - public int getFloatsLength() { - return mValues.length; + context.putDataMap(mId, mDataMap); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapLookup.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapLookup.java new file mode 100644 index 000000000000..fb5e5d1734e6 --- /dev/null +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapLookup.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.widget.remotecompose.core.operations; + +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; + +import com.android.internal.widget.remotecompose.core.Operation; +import com.android.internal.widget.remotecompose.core.Operations; +import com.android.internal.widget.remotecompose.core.RemoteContext; +import com.android.internal.widget.remotecompose.core.WireBuffer; +import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.operations.utilities.DataMap; +import com.android.internal.widget.remotecompose.core.types.BooleanConstant; +import com.android.internal.widget.remotecompose.core.types.LongConstant; + +import java.util.List; + +/** This can lookup in a map given a string writing the results to an id. */ +public class DataMapLookup implements Operation { + private static final int OP_CODE = Operations.DATA_MAP_LOOKUP; + private static final String CLASS_NAME = "DataMapLookup"; + public int mId; + public int mDataMapId; + public int mStringId; + + /** + * Create an access to a data map + * + * @param id of the output value + * @param dataMapId the id of the data map + * @param keyStringId the string to be looked up + */ + public DataMapLookup(int id, int dataMapId, int keyStringId) { + this.mId = id; + this.mDataMapId = dataMapId; + this.mStringId = keyStringId; + } + + @Override + public void write(WireBuffer buffer) { + apply(buffer, mId, mDataMapId, mStringId); + } + + @Override + public String toString() { + return "DataMapLookup[" + mId + "] = " + Utils.idString(mDataMapId) + " " + mStringId; + } + + /** + * The class name + * + * @return the name of the class + */ + public static String name() { + return CLASS_NAME; + } + + /** + * The opcode + * + * @return the opcode + */ + public static int id() { + return OP_CODE; + } + + /** + * Writes out the operation to the buffer + * + * @param buffer write command to this buffer + * @param id the id + * @param dataMapId the map to extract from + * @param keyStringId the map to extract from + */ + public static void apply(WireBuffer buffer, int id, int dataMapId, int keyStringId) { + buffer.start(OP_CODE); + buffer.writeInt(id); + buffer.writeInt(dataMapId); + buffer.writeInt(keyStringId); + } + + /** + * The read the buffer and create the command + * + * @param buffer buffer + * @param operations the created command is added to the list + */ + public static void read(WireBuffer buffer, List<Operation> operations) { + int id = buffer.readInt(); + int mapId = buffer.readInt(); + int stringId = buffer.readInt(); + operations.add(new DataMapLookup(id, mapId, stringId)); + } + + public static void documentation(DocumentationBuilder doc) { + doc.operation("Expressions Operations", OP_CODE, CLASS_NAME) + .description("A float and its associated id") + .field(INT, "id", "id of float") + .field(INT, "dataMapId", "32-bit float value") + .field(INT, "value", "32-bit float value"); + } + + @Override + public void apply(RemoteContext context) { + String str = context.getText(mStringId); + DataMap data = context.getDataMap(mDataMapId); + int pos = data.getPos(str); + byte type = data.getType(pos); + int dataId = data.getId(pos); + switch (type) { + case DataMapIds.TYPE_STRING: + context.loadText(mId, context.getText(dataId)); + break; + case DataMapIds.TYPE_INT: + context.loadInteger(mId, context.getInteger(dataId)); + break; + case DataMapIds.TYPE_FLOAT: + context.loadFloat(mId, context.getFloat(dataId)); + break; + case DataMapIds.TYPE_LONG: + LongConstant lc = (LongConstant) context.getObject(dataId); + context.loadInteger(mId, (int) lc.getValue()); + break; + case DataMapIds.TYPE_BOOLEAN: + BooleanConstant bc = (BooleanConstant) context.getObject(dataId); + context.loadInteger(mId, bc.getValue() ? 1 : 0); + break; + } + } + + @Override + public String deepToString(String indent) { + return indent + toString(); + } +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawArc.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawArc.java index d37722917b27..e078307f3bd9 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawArc.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawArc.java @@ -15,13 +15,12 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.PaintContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; @@ -40,6 +39,7 @@ public class DrawArc extends DrawBase6 { /** * Writes out the operation to the buffer + * * @param buffer the buffer to write to * @param v1 The left side of the Oval * @param v2 The top of the Oval @@ -48,13 +48,8 @@ public class DrawArc extends DrawBase6 { * @param v5 Starting angle (in degrees) where the arc begins * @param v6 Sweep angle (in degrees) measured clockwise */ - public static void apply(WireBuffer buffer, - float v1, - float v2, - float v3, - float v4, - float v5, - float v6) { + public static void apply( + WireBuffer buffer, float v1, float v2, float v3, float v4, float v5, float v6) { buffer.start(OP_CODE); buffer.writeFloat(v1); buffer.writeFloat(v2); @@ -64,47 +59,37 @@ public class DrawArc extends DrawBase6 { buffer.writeFloat(v6); } - protected void write(WireBuffer buffer, - float v1, - float v2, - float v3, - float v4, - float v5, - float v6) { + @Override + protected void write( + WireBuffer buffer, float v1, float v2, float v3, float v4, float v5, float v6) { apply(buffer, v1, v2, v3, v4, v5, v6); } public static void documentation(DocumentationBuilder doc) { - doc.operation("Canvas Operations", - OP_CODE, - CLASS_NAME) - .description("Draw the specified arc" - + "which will be scaled to fit inside the specified oval") - .field(FLOAT, "left", - "The left side of the Oval") - .field(FLOAT, "top", - "The top of the Oval") - .field(FLOAT, "right", - "The right side of the Oval") - .field(FLOAT, "bottom", - "The bottom of the Oval") - .field(FLOAT, "startAngle", + doc.operation("Canvas Operations", OP_CODE, CLASS_NAME) + .description( + "Draw the specified arc" + + "which will be scaled to fit inside the specified oval") + .field(DocumentedOperation.FLOAT, "left", "The left side of the Oval") + .field(DocumentedOperation.FLOAT, "top", "The top of the Oval") + .field(DocumentedOperation.FLOAT, "right", "The right side of the Oval") + .field(DocumentedOperation.FLOAT, "bottom", "The bottom of the Oval") + .field( + DocumentedOperation.FLOAT, + "startAngle", "Starting angle (in degrees) where the arc begins") - .field(FLOAT, "sweepAngle", + .field( + DocumentedOperation.FLOAT, + "sweepAngle", "Sweep angle (in degrees) measured clockwise"); } - - public DrawArc(float v1, - float v2, - float v3, - float v4, - float v5, - float v6) { + public DrawArc(float v1, float v2, float v3, float v4, float v5, float v6) { super(v1, v2, v3, v4, v5, v6); mName = "DrawArc"; } + @Override public void paint(PaintContext context) { context.drawArc(mV1, mV2, mV3, mV4, mV5, mV6); } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase2.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase2.java index 97eb76bfaaa9..c678cc4a36be 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase2.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase2.java @@ -25,11 +25,8 @@ import com.android.internal.widget.remotecompose.core.WireBuffer; import java.util.List; -/** - * Base class for commands that take 3 float - */ -public abstract class DrawBase2 extends PaintOperation - implements VariableSupport { +/** Base class for commands that take 3 float */ +public abstract class DrawBase2 extends PaintOperation implements VariableSupport { protected String mName = "DrawRectBase"; float mV1; float mV2; @@ -45,10 +42,8 @@ public abstract class DrawBase2 extends PaintOperation @Override public void updateVariables(RemoteContext context) { - mV1 = (Float.isNaN(mValue1)) - ? context.getFloat(Utils.idFromNan(mValue1)) : mValue1; - mV2 = (Float.isNaN(mValue2)) - ? context.getFloat(Utils.idFromNan(mValue2)) : mValue2; + mV1 = Float.isNaN(mValue1) ? context.getFloat(Utils.idFromNan(mValue1)) : mValue1; + mV2 = Float.isNaN(mValue2) ? context.getFloat(Utils.idFromNan(mValue2)) : mValue2; } @Override @@ -61,7 +56,6 @@ public abstract class DrawBase2 extends PaintOperation } } - @Override public void write(WireBuffer buffer) { write(buffer, mV1, mV2); @@ -70,8 +64,7 @@ public abstract class DrawBase2 extends PaintOperation protected abstract void write(WireBuffer buffer, float v1, float v2); protected interface Maker { - DrawBase2 create(float v1, - float v2); + DrawBase2 create(float v1, float v2); } @Override @@ -79,7 +72,6 @@ public abstract class DrawBase2 extends PaintOperation return mName + " " + floatToString(mV1) + " " + floatToString(mV2); } - public static void read(Maker maker, WireBuffer buffer, List<Operation> operations) { float v1 = buffer.readFloat(); float v2 = buffer.readFloat(); @@ -99,7 +91,6 @@ public abstract class DrawBase2 extends PaintOperation return null; } - /** * Writes out the operation to the buffer * @@ -108,13 +99,9 @@ public abstract class DrawBase2 extends PaintOperation * @param x1 * @param y1 */ - protected static void write(WireBuffer buffer, - int opCode, - float x1, - float y1) { + protected static void write(WireBuffer buffer, int opCode, float x1, float y1) { buffer.start(opCode); buffer.writeFloat(x1); buffer.writeFloat(y1); - } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase3.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase3.java index 2d1d3eb4b78c..e1108e906d8d 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase3.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase3.java @@ -25,11 +25,8 @@ import com.android.internal.widget.remotecompose.core.WireBuffer; import java.util.List; -/** - * Base class for commands that take 3 float - */ -public abstract class DrawBase3 extends PaintOperation - implements VariableSupport { +/** Base class for commands that take 3 float */ +public abstract class DrawBase3 extends PaintOperation implements VariableSupport { protected String mName = "DrawRectBase"; float mV1; @@ -39,10 +36,7 @@ public abstract class DrawBase3 extends PaintOperation float mValue2; float mValue3; - public DrawBase3( - float v1, - float v2, - float v3) { + public DrawBase3(float v1, float v2, float v3) { mValue1 = v1; mValue2 = v2; mValue3 = v3; @@ -54,12 +48,9 @@ public abstract class DrawBase3 extends PaintOperation @Override public void updateVariables(RemoteContext context) { - mV1 = (Utils.isVariable(mValue1)) - ? context.getFloat(Utils.idFromNan(mValue1)) : mValue1; - mV2 = (Utils.isVariable(mValue2)) - ? context.getFloat(Utils.idFromNan(mValue2)) : mValue2; - mV3 = (Utils.isVariable(mValue3)) - ? context.getFloat(Utils.idFromNan(mValue3)) : mValue3; + mV1 = Utils.isVariable(mValue1) ? context.getFloat(Utils.idFromNan(mValue1)) : mValue1; + mV2 = Utils.isVariable(mValue2) ? context.getFloat(Utils.idFromNan(mValue2)) : mValue2; + mV3 = Utils.isVariable(mValue3) ? context.getFloat(Utils.idFromNan(mValue3)) : mValue3; } @Override @@ -80,21 +71,21 @@ public abstract class DrawBase3 extends PaintOperation write(buffer, mV1, mV2, mV3); } - protected abstract void write(WireBuffer buffer, - float v1, - float v2, - float v3); + protected abstract void write(WireBuffer buffer, float v1, float v2, float v3); interface Maker { - DrawBase3 create(float v1, - float v2, - float v3); + DrawBase3 create(float v1, float v2, float v3); } @Override public String toString() { - return mName + " " + floatToString(mV1) + " " + floatToString(mV2) - + " " + floatToString(mV3); + return mName + + " " + + floatToString(mV1) + + " " + + floatToString(mV2) + + " " + + floatToString(mV3); } public static void read(Maker maker, WireBuffer buffer, List<Operation> operations) { @@ -106,17 +97,14 @@ public abstract class DrawBase3 extends PaintOperation } /** - * Construct and Operation from the 3 variables. - * This must be overridden by subclasses + * Construct and Operation from the 3 variables. This must be overridden by subclasses * * @param x1 * @param y1 * @param x2 * @return */ - public Operation construct(float x1, - float y1, - float x2) { + public Operation construct(float x1, float y1, float x2) { return null; } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase4.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase4.java index 943c5a44b5ac..09f0df985b5c 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase4.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase4.java @@ -25,11 +25,8 @@ import com.android.internal.widget.remotecompose.core.WireBuffer; import java.util.List; -/** - * Base class for draw commands that take 4 floats - */ -public abstract class DrawBase4 extends PaintOperation - implements VariableSupport { +/** Base class for draw commands that take 4 floats */ +public abstract class DrawBase4 extends PaintOperation implements VariableSupport { protected String mName = "DrawRectBase"; protected float mX1; protected float mY1; @@ -40,11 +37,7 @@ public abstract class DrawBase4 extends PaintOperation float mX2Value; float mY2Value; - public DrawBase4( - float x1, - float y1, - float x2, - float y2) { + public DrawBase4(float x1, float y1, float x2, float y2) { mX1Value = x1; mY1Value = y1; mX2Value = x2; @@ -58,14 +51,10 @@ public abstract class DrawBase4 extends PaintOperation @Override public void updateVariables(RemoteContext context) { - mX1 = (Float.isNaN(mX1Value)) - ? context.getFloat(Utils.idFromNan(mX1Value)) : mX1Value; - mY1 = (Float.isNaN(mY1Value)) - ? context.getFloat(Utils.idFromNan(mY1Value)) : mY1Value; - mX2 = (Float.isNaN(mX2Value)) - ? context.getFloat(Utils.idFromNan(mX2Value)) : mX2Value; - mY2 = (Float.isNaN(mY2Value)) - ? context.getFloat(Utils.idFromNan(mY2Value)) : mY2Value; + mX1 = Float.isNaN(mX1Value) ? context.getFloat(Utils.idFromNan(mX1Value)) : mX1Value; + mY1 = Float.isNaN(mY1Value) ? context.getFloat(Utils.idFromNan(mY1Value)) : mY1Value; + mX2 = Float.isNaN(mX2Value) ? context.getFloat(Utils.idFromNan(mX2Value)) : mX2Value; + mY2 = Float.isNaN(mY2Value) ? context.getFloat(Utils.idFromNan(mY2Value)) : mY2Value; } @Override @@ -89,23 +78,23 @@ public abstract class DrawBase4 extends PaintOperation write(buffer, mX1, mY1, mX2, mY2); } - protected abstract void write(WireBuffer buffer, - float v1, - float v2, - float v3, - float v4); + protected abstract void write(WireBuffer buffer, float v1, float v2, float v3, float v4); protected interface Maker { - DrawBase4 create(float v1, - float v2, - float v3, - float v4); + DrawBase4 create(float v1, float v2, float v3, float v4); } @Override public String toString() { - return mName + " " + floatToString(mX1Value, mX1) + " " + floatToString(mY1Value, mY1) - + " " + floatToString(mX2Value, mX2) + " " + floatToString(mY2Value, mY2); + return mName + + " " + + floatToString(mX1Value, mX1) + + " " + + floatToString(mY1Value, mY1) + + " " + + floatToString(mX2Value, mX2) + + " " + + floatToString(mY2Value, mY2); } public static void read(Maker maker, WireBuffer buffer, List<Operation> operations) { @@ -127,14 +116,10 @@ public abstract class DrawBase4 extends PaintOperation * @param y2 * @return */ - public Operation construct(float x1, - float y1, - float x2, - float y2) { + public Operation construct(float x1, float y1, float x2, float y2) { return null; } - /** * Writes out the operation to the buffer * @@ -145,12 +130,8 @@ public abstract class DrawBase4 extends PaintOperation * @param x2 * @param y2 */ - protected static void write(WireBuffer buffer, - int opCode, - float x1, - float y1, - float x2, - float y2) { + protected static void write( + WireBuffer buffer, int opCode, float x1, float y1, float x2, float y2) { buffer.start(opCode); buffer.writeFloat(x1); buffer.writeFloat(y1); @@ -158,4 +139,3 @@ public abstract class DrawBase4 extends PaintOperation buffer.writeFloat(y2); } } - diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase6.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase6.java index 767a36d03ace..e071d5f2096f 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase6.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase6.java @@ -15,8 +15,6 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.operations.Utils.floatToString; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.PaintOperation; import com.android.internal.widget.remotecompose.core.RemoteContext; @@ -25,11 +23,8 @@ import com.android.internal.widget.remotecompose.core.WireBuffer; import java.util.List; -/** - * Base class for draw commands the take 6 floats - */ -public abstract class DrawBase6 extends PaintOperation - implements VariableSupport { +/** Base class for draw commands the take 6 floats */ +public abstract class DrawBase6 extends PaintOperation implements VariableSupport { protected String mName = "DrawRectBase"; float mV1; float mV2; @@ -44,13 +39,7 @@ public abstract class DrawBase6 extends PaintOperation float mValue5; float mValue6; - public DrawBase6( - float v1, - float v2, - float v3, - float v4, - float v5, - float v6) { + public DrawBase6(float v1, float v2, float v3, float v4, float v5, float v6) { mValue1 = v1; mValue2 = v2; mValue3 = v3; @@ -68,18 +57,12 @@ public abstract class DrawBase6 extends PaintOperation @Override public void updateVariables(RemoteContext context) { - mV1 = (Float.isNaN(mValue1)) - ? context.getFloat(Utils.idFromNan(mValue1)) : mValue1; - mV2 = (Float.isNaN(mValue2)) - ? context.getFloat(Utils.idFromNan(mValue2)) : mValue2; - mV3 = (Float.isNaN(mValue3)) - ? context.getFloat(Utils.idFromNan(mValue3)) : mValue3; - mV4 = (Float.isNaN(mValue4)) - ? context.getFloat(Utils.idFromNan(mValue4)) : mValue4; - mV5 = (Float.isNaN(mValue5)) - ? context.getFloat(Utils.idFromNan(mValue5)) : mValue5; - mV6 = (Float.isNaN(mValue6)) - ? context.getFloat(Utils.idFromNan(mValue6)) : mValue6; + mV1 = Float.isNaN(mValue1) ? context.getFloat(Utils.idFromNan(mValue1)) : mValue1; + mV2 = Float.isNaN(mValue2) ? context.getFloat(Utils.idFromNan(mValue2)) : mValue2; + mV3 = Float.isNaN(mValue3) ? context.getFloat(Utils.idFromNan(mValue3)) : mValue3; + mV4 = Float.isNaN(mValue4) ? context.getFloat(Utils.idFromNan(mValue4)) : mValue4; + mV5 = Float.isNaN(mValue5) ? context.getFloat(Utils.idFromNan(mValue5)) : mValue5; + mV6 = Float.isNaN(mValue6) ? context.getFloat(Utils.idFromNan(mValue6)) : mValue6; } @Override @@ -109,27 +92,24 @@ public abstract class DrawBase6 extends PaintOperation write(buffer, mV1, mV2, mV3, mV4, mV5, mV6); } - protected abstract void write(WireBuffer buffer, - float v1, - float v2, - float v3, - float v4, - float v5, - float v6); + protected abstract void write( + WireBuffer buffer, float v1, float v2, float v3, float v4, float v5, float v6); @Override public String toString() { - return mName + " " + floatToString(mV1) + " " + floatToString(mV2) - + " " + floatToString(mV3) + " " + floatToString(mV4); + return mName + + " " + + Utils.floatToString(mV1) + + " " + + Utils.floatToString(mV2) + + " " + + Utils.floatToString(mV3) + + " " + + Utils.floatToString(mV4); } interface Maker { - DrawBase6 create(float v1, - float v2, - float v3, - float v4, - float v5, - float v6); + DrawBase6 create(float v1, float v2, float v3, float v4, float v5, float v6); } public static void read(Maker build, WireBuffer buffer, List<Operation> operations) { @@ -155,18 +135,11 @@ public abstract class DrawBase6 extends PaintOperation * @param v6 * @return */ - public Operation construct(float v1, - float v2, - float v3, - float v4, - float v5, - float v6) { + public Operation construct(float v1, float v2, float v3, float v4, float v5, float v6) { return null; } - public static String name() { return "DrawBase6"; } - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmap.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmap.java index 2748f4c3c369..0b43fd24556a 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmap.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmap.java @@ -15,8 +15,8 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -44,12 +44,7 @@ public class DrawBitmap extends PaintOperation implements VariableSupport { int mDescriptionId = 0; public DrawBitmap( - int imageId, - float left, - float top, - float right, - float bottom, - int descriptionId) { + int imageId, float left, float top, float right, float bottom, int descriptionId) { mLeft = left; mTop = top; mRight = right; @@ -60,14 +55,10 @@ public class DrawBitmap extends PaintOperation implements VariableSupport { @Override public void updateVariables(RemoteContext context) { - mOutputLeft = (Float.isNaN(mLeft)) - ? context.getFloat(Utils.idFromNan(mLeft)) : mLeft; - mOutputTop = (Float.isNaN(mTop)) - ? context.getFloat(Utils.idFromNan(mTop)) : mTop; - mOutputRight = (Float.isNaN(mRight)) - ? context.getFloat(Utils.idFromNan(mRight)) : mRight; - mOutputBottom = (Float.isNaN(mBottom)) - ? context.getFloat(Utils.idFromNan(mBottom)) : mBottom; + mOutputLeft = Float.isNaN(mLeft) ? context.getFloat(Utils.idFromNan(mLeft)) : mLeft; + mOutputTop = Float.isNaN(mTop) ? context.getFloat(Utils.idFromNan(mTop)) : mTop; + mOutputRight = Float.isNaN(mRight) ? context.getFloat(Utils.idFromNan(mRight)) : mRight; + mOutputBottom = Float.isNaN(mBottom) ? context.getFloat(Utils.idFromNan(mBottom)) : mBottom; } @Override @@ -93,8 +84,17 @@ public class DrawBitmap extends PaintOperation implements VariableSupport { @Override public String toString() { - return "DrawBitmap (desc=" + mDescriptionId + ")" + mLeft + " " + mTop - + " " + mRight + " " + mBottom + ";"; + return "DrawBitmap (desc=" + + mDescriptionId + + ")" + + mLeft + + " " + + mTop + + " " + + mRight + + " " + + mBottom + + ";"; } public static void read(WireBuffer buffer, List<Operation> operations) { @@ -117,13 +117,14 @@ public class DrawBitmap extends PaintOperation implements VariableSupport { return OP_CODE; } - public static void apply(WireBuffer buffer, - int id, - float left, - float top, - float right, - float bottom, - int descriptionId) { + public static void apply( + WireBuffer buffer, + int id, + float left, + float top, + float right, + float bottom, + int descriptionId) { buffer.start(Operations.DRAW_BITMAP); buffer.writeInt(id); buffer.writeFloat(left); @@ -134,26 +135,18 @@ public class DrawBitmap extends PaintOperation implements VariableSupport { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Draw Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Draw Operations", OP_CODE, CLASS_NAME) .description("Draw a bitmap") .field(INT, "id", "id of float") - .field(FLOAT, "left", - "The left side of the image") - .field(FLOAT, "top", - "The top of the image") - .field(FLOAT, "right", - "The right side of the image") - .field(FLOAT, "bottom", - "The bottom of the image") + .field(FLOAT, "left", "The left side of the image") + .field(FLOAT, "top", "The top of the image") + .field(FLOAT, "right", "The right side of the image") + .field(FLOAT, "bottom", "The bottom of the image") .field(INT, "descriptionId", "id of string"); } + @Override public void paint(PaintContext context) { - context.drawBitmap(mId, mOutputLeft, - mOutputTop, - mOutputRight, - mOutputBottom); + context.drawBitmap(mId, mOutputLeft, mOutputTop, mOutputRight, mOutputBottom); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapInt.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapInt.java index 561d52720a67..fc7482759369 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapInt.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapInt.java @@ -15,20 +15,17 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.PaintContext; import com.android.internal.widget.remotecompose.core.PaintOperation; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; -/** - * Operation to draw a given cached bitmap - */ +/** Operation to draw a given cached bitmap */ public class DrawBitmapInt extends PaintOperation { private static final int OP_CODE = Operations.DRAW_BITMAP_INT; private static final String CLASS_NAME = "DrawBitmapInt"; @@ -43,16 +40,17 @@ public class DrawBitmapInt extends PaintOperation { int mDstBottom; int mContentDescId = 0; - public DrawBitmapInt(int imageId, - int srcLeft, - int srcTop, - int srcRight, - int srcBottom, - int dstLeft, - int dstTop, - int dstRight, - int dstBottom, - int cdId) { + public DrawBitmapInt( + int imageId, + int srcLeft, + int srcTop, + int srcRight, + int srcBottom, + int dstLeft, + int dstTop, + int dstRight, + int dstBottom, + int cdId) { this.mImageId = imageId; this.mSrcLeft = srcLeft; this.mSrcTop = srcTop; @@ -67,18 +65,44 @@ public class DrawBitmapInt extends PaintOperation { @Override public void write(WireBuffer buffer) { - apply(buffer, mImageId, mSrcLeft, mSrcTop, mSrcRight, mSrcBottom, - mDstLeft, mDstTop, mDstRight, mDstBottom, mContentDescId); + apply( + buffer, + mImageId, + mSrcLeft, + mSrcTop, + mSrcRight, + mSrcBottom, + mDstLeft, + mDstTop, + mDstRight, + mDstBottom, + mContentDescId); } @Override public String toString() { - return "DRAW_BITMAP_INT " + mImageId + " on " + mSrcLeft + " " + mSrcTop - + " " + mSrcRight + " " + mSrcBottom + " " - + "- " + mDstLeft + " " + mDstTop + " " + mDstRight + " " + mDstBottom + ";"; + return "DRAW_BITMAP_INT " + + mImageId + + " on " + + mSrcLeft + + " " + + mSrcTop + + " " + + mSrcRight + + " " + + mSrcBottom + + " " + + "- " + + mDstLeft + + " " + + mDstTop + + " " + + mDstRight + + " " + + mDstBottom + + ";"; } - public static String name() { return CLASS_NAME; } @@ -87,10 +111,18 @@ public class DrawBitmapInt extends PaintOperation { return OP_CODE; } - public static void apply(WireBuffer buffer, int imageId, - int srcLeft, int srcTop, int srcRight, int srcBottom, - int dstLeft, int dstTop, int dstRight, int dstBottom, - int cdId) { + public static void apply( + WireBuffer buffer, + int imageId, + int srcLeft, + int srcTop, + int srcRight, + int srcBottom, + int dstLeft, + int dstTop, + int dstRight, + int dstBottom, + int cdId) { buffer.start(Operations.DRAW_BITMAP_INT); buffer.writeInt(imageId); buffer.writeInt(srcLeft); @@ -115,41 +147,41 @@ public class DrawBitmapInt extends PaintOperation { int dstRight = buffer.readInt(); int dstBottom = buffer.readInt(); int cdId = buffer.readInt(); - DrawBitmapInt op = new DrawBitmapInt(imageId, sLeft, srcTop, srcRight, srcBottom, - dstLeft, dstTop, dstRight, dstBottom, cdId); + DrawBitmapInt op = + new DrawBitmapInt( + imageId, sLeft, srcTop, srcRight, srcBottom, dstLeft, dstTop, dstRight, + dstBottom, cdId); operations.add(op); } - public static void documentation(DocumentationBuilder doc) { - doc.operation("Draw Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Draw Operations", OP_CODE, CLASS_NAME) .description("Draw a bitmap using integer coordinates") - .field(INT, "id", "id of bitmap") - .field(INT, "srcLeft", - "The left side of the image") - .field(INT, "srcTop", - "The top of the image") - .field(INT, "srcRight", - "The right side of the image") - .field(INT, "srcBottom", - "The bottom of the image") - .field(INT, "dstLeft", - "The left side of the image") - .field(INT, "dstTop", - "The top of the image") - .field(INT, "dstRight", - "The right side of the image") - .field(INT, "dstBottom", - "The bottom of the image") - .field(INT, "cdId", "id of string"); + .field(DocumentedOperation.INT, "id", "id of bitmap") + .field(DocumentedOperation.INT, "srcLeft", "The left side of the image") + .field(DocumentedOperation.INT, "srcTop", "The top of the image") + .field(DocumentedOperation.INT, "srcRight", "The right side of the image") + .field(DocumentedOperation.INT, "srcBottom", "The bottom of the image") + .field(DocumentedOperation.INT, "dstLeft", "The left side of the image") + .field(DocumentedOperation.INT, "dstTop", "The top of the image") + .field(DocumentedOperation.INT, "dstRight", "The right side of the image") + .field(DocumentedOperation.INT, "dstBottom", "The bottom of the image") + .field(DocumentedOperation.INT, "cdId", "id of string"); } @Override public void paint(PaintContext context) { - context.drawBitmap(mImageId, mSrcLeft, mSrcTop, mSrcRight, mSrcBottom, - mDstLeft, mDstTop, mDstRight, mDstBottom, mContentDescId); + context.drawBitmap( + mImageId, + mSrcLeft, + mSrcTop, + mSrcRight, + mSrcBottom, + mDstLeft, + mDstTop, + mDstRight, + mDstBottom, + mContentDescId); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapScaled.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapScaled.java new file mode 100644 index 000000000000..22742c63dd2d --- /dev/null +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapScaled.java @@ -0,0 +1,319 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.widget.remotecompose.core.operations; + +import com.android.internal.widget.remotecompose.core.Operation; +import com.android.internal.widget.remotecompose.core.Operations; +import com.android.internal.widget.remotecompose.core.PaintContext; +import com.android.internal.widget.remotecompose.core.PaintOperation; +import com.android.internal.widget.remotecompose.core.RemoteContext; +import com.android.internal.widget.remotecompose.core.VariableSupport; +import com.android.internal.widget.remotecompose.core.WireBuffer; +import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; +import com.android.internal.widget.remotecompose.core.operations.utilities.ImageScaling; + +import java.util.List; + +/** Operation to draw a given cached bitmap */ +public class DrawBitmapScaled extends PaintOperation implements VariableSupport { + private static final int OP_CODE = Operations.DRAW_BITMAP_SCALED; + private static final String CLASS_NAME = "DrawBitmapScaled"; + int mImageId; + float mSrcLeft, mOutSrcLeft; + float mSrcTop, mOutSrcTop; + float mSrcRight, mOutSrcRight; + float mSrcBottom, mOutSrcBottom; + float mDstLeft, mOutDstLeft; + float mDstTop, mOutDstTop; + float mDstRight, mOutDstRight; + float mDstBottom, mOutDstBottom; + int mContentDescId; + float mScaleFactor, mOutScaleFactor; + int mScaleType; + + ImageScaling mScaling = new ImageScaling(); + public static final int SCALE_NONE = ImageScaling.SCALE_NONE; + public static final int SCALE_INSIDE = ImageScaling.SCALE_INSIDE; + public static final int SCALE_FILL_WIDTH = ImageScaling.SCALE_FILL_WIDTH; + public static final int SCALE_FILL_HEIGHT = ImageScaling.SCALE_FILL_HEIGHT; + public static final int SCALE_FIT = ImageScaling.SCALE_FIT; + public static final int SCALE_CROP = ImageScaling.SCALE_CROP; + public static final int SCALE_FILL_BOUNDS = ImageScaling.SCALE_FILL_BOUNDS; + public static final int SCALE_FIXED_SCALE = ImageScaling.SCALE_FIXED_SCALE; + + public DrawBitmapScaled( + int imageId, + float srcLeft, + float srcTop, + float srcRight, + float srcBottom, + float dstLeft, + float dstTop, + float dstRight, + float dstBottom, + int type, + float scale, + int cdId) { + this.mImageId = imageId; + mOutSrcLeft = mSrcLeft = srcLeft; + mOutSrcTop = mSrcTop = srcTop; + mOutSrcRight = mSrcRight = srcRight; + mOutSrcBottom = mSrcBottom = srcBottom; + mOutDstLeft = mDstLeft = dstLeft; + mOutDstTop = mDstTop = dstTop; + mOutDstRight = mDstRight = dstRight; + mOutDstBottom = mDstBottom = dstBottom; + mScaleType = type; + mOutScaleFactor = mScaleFactor = scale; + this.mContentDescId = cdId; + } + + @Override + public void updateVariables(RemoteContext context) { + mOutSrcLeft = + Float.isNaN(mSrcLeft) ? context.getFloat(Utils.idFromNan(mSrcLeft)) : mSrcLeft; + mOutSrcTop = Float.isNaN(mSrcTop) ? context.getFloat(Utils.idFromNan(mSrcTop)) : mSrcTop; + mOutSrcRight = + Float.isNaN(mSrcRight) ? context.getFloat(Utils.idFromNan(mSrcRight)) : mSrcRight; + mOutSrcBottom = + Float.isNaN(mSrcBottom) + ? context.getFloat(Utils.idFromNan(mSrcBottom)) + : mSrcBottom; + mOutDstLeft = + Float.isNaN(mDstLeft) ? context.getFloat(Utils.idFromNan(mDstLeft)) : mDstLeft; + mOutDstTop = Float.isNaN(mDstTop) ? context.getFloat(Utils.idFromNan(mDstTop)) : mDstTop; + mOutDstRight = + Float.isNaN(mDstRight) ? context.getFloat(Utils.idFromNan(mDstRight)) : mDstRight; + mOutDstBottom = + Float.isNaN(mDstBottom) + ? context.getFloat(Utils.idFromNan(mDstBottom)) + : mDstBottom; + mOutScaleFactor = + Float.isNaN(mScaleFactor) + ? context.getFloat(Utils.idFromNan(mScaleFactor)) + : mScaleFactor; + } + + @Override + public void registerListening(RemoteContext context) { + register(context, mSrcLeft); + register(context, mSrcTop); + register(context, mSrcRight); + register(context, mSrcBottom); + register(context, mDstLeft); + register(context, mDstTop); + register(context, mDstRight); + register(context, mDstBottom); + register(context, mScaleFactor); + } + + private void register(RemoteContext context, float value) { + if (Float.isNaN(value)) { + context.listensTo(Utils.idFromNan(value), this); + } + } + + static String str(float v) { + String s = " " + (int) v; + return s.substring(s.length() - 3); + } + + void print(String str, float left, float top, float right, float bottom) { + String s = str; + s += str(left) + ", " + str(top) + ", " + str(right) + ", " + str(bottom) + ", "; + s += " [" + str(right - left) + " x " + str(bottom - top) + "]"; + System.out.println(s); + } + + @Override + public void write(WireBuffer buffer) { + apply( + buffer, + mImageId, + mSrcLeft, + mSrcTop, + mSrcRight, + mSrcBottom, + mDstLeft, + mDstTop, + mDstRight, + mDstBottom, + mScaleType, + mScaleFactor, + mContentDescId); + } + + @Override + public String toString() { + return "DrawBitmapScaled " + + mImageId + + " [" + + Utils.floatToString(mSrcLeft, mOutSrcLeft) + + " " + + Utils.floatToString(mSrcTop, mOutSrcTop) + + " " + + Utils.floatToString(mSrcRight, mOutSrcRight) + + " " + + Utils.floatToString(mSrcBottom, mOutSrcBottom) + + "] " + + "- [" + + Utils.floatToString(mDstLeft, mOutDstLeft) + + " " + + Utils.floatToString(mDstTop, mOutDstTop) + + " " + + Utils.floatToString(mDstRight, mOutDstRight) + + " " + + Utils.floatToString(mDstBottom, mOutDstBottom) + + "] " + + " " + + mScaleType + + " " + + Utils.floatToString(mScaleFactor, mOutScaleFactor); + } + + public static String name() { + return CLASS_NAME; + } + + public static int id() { + return OP_CODE; + } + + public static void apply( + WireBuffer buffer, + int imageId, + float srcLeft, + float srcTop, + float srcRight, + float srcBottom, + float dstLeft, + float dstTop, + float dstRight, + float dstBottom, + int scaleType, + float scaleFactor, + int cdId) { + buffer.start(OP_CODE); + buffer.writeInt(imageId); + + buffer.writeFloat(srcLeft); + buffer.writeFloat(srcTop); + buffer.writeFloat(srcRight); + buffer.writeFloat(srcBottom); + + buffer.writeFloat(dstLeft); + buffer.writeFloat(dstTop); + buffer.writeFloat(dstRight); + buffer.writeFloat(dstBottom); + + buffer.writeInt(scaleType); + buffer.writeFloat(scaleFactor); + buffer.writeInt(cdId); + } + + public static void read(WireBuffer buffer, List<Operation> operations) { + int imageId = buffer.readInt(); + + float sLeft = buffer.readFloat(); + float srcTop = buffer.readFloat(); + float srcRight = buffer.readFloat(); + float srcBottom = buffer.readFloat(); + + float dstLeft = buffer.readFloat(); + float dstTop = buffer.readFloat(); + float dstRight = buffer.readFloat(); + float dstBottom = buffer.readFloat(); + int scaleType = buffer.readInt(); + float scaleFactor = buffer.readFloat(); + int cdId = buffer.readInt(); + DrawBitmapScaled op = + new DrawBitmapScaled( + imageId, + sLeft, + srcTop, + srcRight, + srcBottom, + dstLeft, + dstTop, + dstRight, + dstBottom, + scaleType, + scaleFactor, + cdId); + + operations.add(op); + } + + public static void documentation(DocumentationBuilder doc) { + doc.operation("Draw Operations", OP_CODE, CLASS_NAME) + .description("Draw a bitmap using integer coordinates") + .field(DocumentedOperation.INT, "id", "id of bitmap") + .field(DocumentedOperation.FLOAT, "srcLeft", "The left side of the image") + .field(DocumentedOperation.FLOAT, "srcTop", "The top of the image") + .field(DocumentedOperation.FLOAT, "srcRight", "The right side of the image") + .field(DocumentedOperation.FLOAT, "srcBottom", "The bottom of the output") + .field(DocumentedOperation.FLOAT, "dstLeft", "The left side of the output") + .field(DocumentedOperation.FLOAT, "dstTop", "The top of the output") + .field(DocumentedOperation.FLOAT, "dstRight", "The right side of the output") + .field(DocumentedOperation.INT, "type", "type of auto scaling") + .field(DocumentedOperation.INT, "scaleFactor", "for allowed") + .field(DocumentedOperation.INT, "cdId", "id of string"); + } + + // private String typeToString(int type) { + // String[] typeString = { + // "none", + // "inside", + // "fill_width", + // "fill_height", + // "fit", + // "crop", + // "fill_bounds", + // "fixed_scale" + // }; + // return typeString[type]; + // } + + @Override + public void paint(PaintContext context) { + mScaling.setup( + mOutSrcLeft, + mOutSrcTop, + mOutSrcRight, + mOutSrcBottom, + mOutDstLeft, + mOutDstTop, + mOutDstRight, + mOutDstBottom, + mScaleType, + mOutScaleFactor); + context.save(); + context.clipRect(mOutDstLeft, mOutDstTop, mOutDstRight, mOutDstBottom); + context.drawBitmap( + mImageId, + (int) mOutSrcLeft, + (int) mOutSrcTop, + (int) mOutSrcRight, + (int) mOutSrcBottom, + (int) mScaling.mFinalDstLeft, + (int) mScaling.mFinalDstTop, + (int) mScaling.mFinalDstRight, + (int) mScaling.mFinalDstBottom, + mContentDescId); + context.restore(); + } +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawCircle.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawCircle.java index e39a19171cf0..04f095af29dc 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawCircle.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawCircle.java @@ -1,12 +1,26 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.PaintContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; @@ -28,29 +42,25 @@ public class DrawCircle extends DrawBase3 { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Canvas Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Canvas Operations", OP_CODE, CLASS_NAME) .description("Draw a Circle") - .field(FLOAT, "centerX", + .field( + DocumentedOperation.FLOAT, + "centerX", "The x-coordinate of the center of the circle to be drawn") - .field(FLOAT, "centerY", + .field( + DocumentedOperation.FLOAT, + "centerY", "The y-coordinate of the center of the circle to be drawn") - .field(FLOAT, "radius", - "The radius of the circle to be drawn"); + .field(DocumentedOperation.FLOAT, "radius", "The radius of the circle to be drawn"); } - protected void write(WireBuffer buffer, - float v1, - float v2, - float v3) { + @Override + protected void write(WireBuffer buffer, float v1, float v2, float v3) { apply(buffer, v1, v2, v3); } - public DrawCircle( - float left, - float top, - float right) { + public DrawCircle(float left, float top, float right) { super(left, top, right); mName = CLASS_NAME; } @@ -68,10 +78,7 @@ public class DrawCircle extends DrawBase3 { * @param y1 * @param x2 */ - public static void apply(WireBuffer buffer, - float x1, - float y1, - float x2) { + public static void apply(WireBuffer buffer, float x1, float y1, float x2) { buffer.start(OP_CODE); buffer.writeFloat(x1); buffer.writeFloat(y1); diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawLine.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawLine.java index a7276b56049f..dacbb0361761 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawLine.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawLine.java @@ -15,14 +15,13 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.PaintContext; import com.android.internal.widget.remotecompose.core.SerializableToString; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer; import java.util.List; @@ -36,7 +35,6 @@ public class DrawLine extends DrawBase4 implements SerializableToString { read(m, buffer, operations); } - public static int id() { return OP_CODE; } @@ -46,33 +44,32 @@ public class DrawLine extends DrawBase4 implements SerializableToString { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Canvas Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Canvas Operations", OP_CODE, CLASS_NAME) .description("Draw a line segment") - .field(FLOAT, "startX", + .field( + DocumentedOperation.FLOAT, + "startX", "The x-coordinate of the start point of the line") - .field(FLOAT, "startY", + .field( + DocumentedOperation.FLOAT, + "startY", "The y-coordinate of the start point of the line") - .field(FLOAT, "endX", + .field( + DocumentedOperation.FLOAT, + "endX", "The x-coordinate of the end point of the line") - .field(FLOAT, "endY", + .field( + DocumentedOperation.FLOAT, + "endY", "The y-coordinate of the end point of the line"); } - protected void write(WireBuffer buffer, - float v1, - float v2, - float v3, - float v4) { + @Override + protected void write(WireBuffer buffer, float v1, float v2, float v3, float v4) { apply(buffer, v1, v2, v3, v4); } - public DrawLine( - float left, - float top, - float right, - float bottom) { + public DrawLine(float left, float top, float right, float bottom) { super(left, top, right, bottom); mName = "DrawLine"; } @@ -91,14 +88,11 @@ public class DrawLine extends DrawBase4 implements SerializableToString { * @param x2 end x of the line * @param y2 end y of the line */ - public static void apply(WireBuffer buffer, - float x1, - float y1, - float x2, - float y2) { + public static void apply(WireBuffer buffer, float x1, float y1, float x2, float y2) { write(buffer, OP_CODE, x1, y1, x2, y2); } + @Override public void serializeToString(int indent, StringSerializer serializer) { String x1 = "" + mX1; if (Float.isNaN(mX1Value)) { @@ -116,8 +110,6 @@ public class DrawLine extends DrawBase4 implements SerializableToString { if (Float.isNaN(mY2Value)) { y2 = "[" + Utils.idFromNan(mY2Value) + " = " + mY2 + "]"; } - serializer.append(indent, CLASS_NAME - + "(" + x1 + ", " + y1 + ", " + x2 + ", " + y2 + ")" - ); + serializer.append(indent, CLASS_NAME + "(" + x1 + ", " + y1 + ", " + x2 + ", " + y2 + ")"); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawOval.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawOval.java index 01761efbb9ed..5d498e81c9d2 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawOval.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawOval.java @@ -15,13 +15,12 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.PaintContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; @@ -43,25 +42,16 @@ public class DrawOval extends DrawBase4 { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Canvas Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Canvas Operations", OP_CODE, CLASS_NAME) .description("Draw the specified oval") - .field(FLOAT, "left", - "The left side of the oval") - .field(FLOAT, "top", - "The top of the oval") - .field(FLOAT, "right", - "The right side of the oval") - .field(FLOAT, "bottom", - "The bottom of the oval"); + .field(DocumentedOperation.FLOAT, "left", "The left side of the oval") + .field(DocumentedOperation.FLOAT, "top", "The top of the oval") + .field(DocumentedOperation.FLOAT, "right", "The right side of the oval") + .field(DocumentedOperation.FLOAT, "bottom", "The bottom of the oval"); } - protected void write(WireBuffer buffer, - float v1, - float v2, - float v3, - float v4) { + @Override + protected void write(WireBuffer buffer, float v1, float v2, float v3, float v4) { apply(buffer, v1, v2, v3, v4); } @@ -70,11 +60,7 @@ public class DrawOval extends DrawBase4 { apply(buffer, mX1, mY1, mX2, mY2); } - public DrawOval( - float left, - float top, - float right, - float bottom) { + public DrawOval(float left, float top, float right, float bottom) { super(left, top, right, bottom); mName = CLASS_NAME; } @@ -83,6 +69,7 @@ public class DrawOval extends DrawBase4 { public void paint(PaintContext context) { context.drawOval(mX1, mY1, mX2, mY2); } + /** * Writes out the DrawOval to the buffer * @@ -92,11 +79,7 @@ public class DrawOval extends DrawBase4 { * @param x2 end x of the DrawOval * @param y2 end y of the DrawOval */ - public static void apply(WireBuffer buffer, - float x1, - float y1, - float x2, - float y2) { + public static void apply(WireBuffer buffer, float x1, float y1, float x2, float y2) { write(buffer, OP_CODE, x1, y1, x2, y2); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawPath.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawPath.java index bc2c53a9a5ba..ccbf3d9e3091 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawPath.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawPath.java @@ -15,14 +15,13 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.PaintContext; import com.android.internal.widget.remotecompose.core.PaintOperation; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; @@ -54,12 +53,10 @@ public class DrawPath extends PaintOperation { operations.add(op); } - public static String name() { return CLASS_NAME; } - public static int id() { return Operations.DRAW_PATH; } @@ -70,14 +67,11 @@ public class DrawPath extends PaintOperation { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Draw Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Draw Operations", OP_CODE, CLASS_NAME) .description("Draw a bitmap using integer coordinates") - .field(INT, "id", "id of path"); + .field(DocumentedOperation.INT, "id", "id of path"); } - @Override public void paint(PaintContext context) { context.drawPath(mId, mStart, mEnd); diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRect.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRect.java index ad17fe743b76..644011b8a214 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRect.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRect.java @@ -15,19 +15,16 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.PaintContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; -/** - * Draw a Rectangle - */ +/** Draw a Rectangle */ public class DrawRect extends DrawBase4 { private static final int OP_CODE = Operations.DRAW_RECT; private static final String CLASS_NAME = "DrawRect"; @@ -37,7 +34,6 @@ public class DrawRect extends DrawBase4 { read(m, buffer, operations); } - public static int id() { return OP_CODE; } @@ -47,34 +43,20 @@ public class DrawRect extends DrawBase4 { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Canvas Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Canvas Operations", OP_CODE, CLASS_NAME) .description("Draw the specified rectangle") - .field(FLOAT, "left", - "The left side of the rectangle") - .field(FLOAT, "top", - "The top of the rectangle") - .field(FLOAT, "right", - "The right side of the rectangle") - .field(FLOAT, "bottom", - "The bottom of the rectangle"); + .field(DocumentedOperation.FLOAT, "left", "The left side of the rectangle") + .field(DocumentedOperation.FLOAT, "top", "The top of the rectangle") + .field(DocumentedOperation.FLOAT, "right", "The right side of the rectangle") + .field(DocumentedOperation.FLOAT, "bottom", "The bottom of the rectangle"); } - - protected void write(WireBuffer buffer, - float v1, - float v2, - float v3, - float v4) { + @Override + protected void write(WireBuffer buffer, float v1, float v2, float v3, float v4) { apply(buffer, v1, v2, v3, v4); } - public DrawRect( - float left, - float top, - float right, - float bottom) { + public DrawRect(float left, float top, float right, float bottom) { super(left, top, right, bottom); mName = CLASS_NAME; } @@ -88,16 +70,12 @@ public class DrawRect extends DrawBase4 { * Writes out the DrawRect to the buffer * * @param buffer buffer to write to - * @param x1 left x of rect - * @param y1 top y of the rect - * @param x2 right x of the rect - * @param y2 bottom y of the rect + * @param x1 left x of rect + * @param y1 top y of the rect + * @param x2 right x of the rect + * @param y2 bottom y of the rect */ - public static void apply(WireBuffer buffer, - float x1, - float y1, - float x2, - float y2) { + public static void apply(WireBuffer buffer, float x1, float y1, float x2, float y2) { write(buffer, OP_CODE, x1, y1, x2, y2); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRoundRect.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRoundRect.java index 908e03a5191c..64a3b283505b 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRoundRect.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRoundRect.java @@ -15,24 +15,20 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.PaintContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; -/** - * Draw a rounded rectangle - */ +/** Draw a rounded rectangle */ public class DrawRoundRect extends DrawBase6 { private static final int OP_CODE = Operations.DRAW_ROUND_RECT; private static final String CLASS_NAME = "DrawRoundRect"; - public static void read(WireBuffer buffer, List<Operation> operations) { Maker m = DrawRoundRect::new; read(m, buffer, operations); @@ -53,13 +49,8 @@ public class DrawRoundRect extends DrawBase6 { * @param v5 The x-radius of the oval used to round the corners * @param v6 The y-radius of the oval used to round the corners */ - public static void apply(WireBuffer buffer, - float v1, - float v2, - float v3, - float v4, - float v5, - float v6) { + public static void apply( + WireBuffer buffer, float v1, float v2, float v3, float v4, float v5, float v6) { buffer.start(OP_CODE); buffer.writeFloat(v1); buffer.writeFloat(v2); @@ -69,50 +60,36 @@ public class DrawRoundRect extends DrawBase6 { buffer.writeFloat(v6); } - protected void write(WireBuffer buffer, - float v1, - float v2, - float v3, - float v4, - float v5, - float v6) { + @Override + protected void write( + WireBuffer buffer, float v1, float v2, float v3, float v4, float v5, float v6) { apply(buffer, v1, v2, v3, v4, v5, v6); } public static void documentation(DocumentationBuilder doc) { - doc.operation("Canvas Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Canvas Operations", OP_CODE, CLASS_NAME) .description("Draw the specified round-rect") - .field(FLOAT, "left", - "The left side of the rect") - .field(FLOAT, "top", - "The top of the rect") - .field(FLOAT, "right", - "The right side of the rect") - .field(FLOAT, "bottom", - "The bottom of the rect") - .field(FLOAT, "rx", + .field(DocumentedOperation.FLOAT, "left", "The left side of the rect") + .field(DocumentedOperation.FLOAT, "top", "The top of the rect") + .field(DocumentedOperation.FLOAT, "right", "The right side of the rect") + .field(DocumentedOperation.FLOAT, "bottom", "The bottom of the rect") + .field( + DocumentedOperation.FLOAT, + "rx", "The x-radius of the oval used to round the corners") - .field(FLOAT, "sweepAngle", + .field( + DocumentedOperation.FLOAT, + "sweepAngle", "The y-radius of the oval used to round the corners"); } - - public DrawRoundRect(float v1, - float v2, - float v3, - float v4, - float v5, - float v6) { + public DrawRoundRect(float v1, float v2, float v3, float v4, float v5, float v6) { super(v1, v2, v3, v4, v5, v6); mName = CLASS_NAME; } @Override public void paint(PaintContext context) { - context.drawRoundRect(mV1, mV2, mV3, mV4, mV5, mV6 - ); + context.drawRoundRect(mV1, mV2, mV3, mV4, mV5, mV6); } - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawSector.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawSector.java new file mode 100644 index 000000000000..3cb191647c33 --- /dev/null +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawSector.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.widget.remotecompose.core.operations; + +import com.android.internal.widget.remotecompose.core.Operation; +import com.android.internal.widget.remotecompose.core.Operations; +import com.android.internal.widget.remotecompose.core.PaintContext; +import com.android.internal.widget.remotecompose.core.WireBuffer; +import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; + +import java.util.List; + +public class DrawSector extends DrawBase6 { + public static final int OP_CODE = Operations.DRAW_SECTOR; + private static final String CLASS_NAME = "DrawSector"; + + public static void read(WireBuffer buffer, List<Operation> operations) { + Maker m = DrawSector::new; + read(m, buffer, operations); + } + + public static int id() { + return OP_CODE; + } + + /** + * Writes out the operation to the buffer + * + * @param buffer the buffer to write to + * @param v1 The left side of the Oval + * @param v2 The top of the Oval + * @param v3 The right side of the Oval + * @param v4 The bottom of the Oval + * @param v5 Starting angle (in degrees) where the arc begins + * @param v6 Sweep angle (in degrees) measured clockwise + */ + public static void apply( + WireBuffer buffer, float v1, float v2, float v3, float v4, float v5, float v6) { + buffer.start(OP_CODE); + buffer.writeFloat(v1); + buffer.writeFloat(v2); + buffer.writeFloat(v3); + buffer.writeFloat(v4); + buffer.writeFloat(v5); + buffer.writeFloat(v6); + } + + @Override + protected void write( + WireBuffer buffer, float v1, float v2, float v3, float v4, float v5, float v6) { + apply(buffer, v1, v2, v3, v4, v5, v6); + } + + public static void documentation(DocumentationBuilder doc) { + doc.operation("Canvas Operations", OP_CODE, CLASS_NAME) + .description( + "Draw the specified sector (pie shape)" + + "which will be scaled to fit inside the specified oval") + .field(DocumentedOperation.FLOAT, "left", "The left side of the Oval") + .field(DocumentedOperation.FLOAT, "top", "The top of the Oval") + .field(DocumentedOperation.FLOAT, "right", "The right side of the Oval") + .field(DocumentedOperation.FLOAT, "bottom", "The bottom of the Oval") + .field( + DocumentedOperation.FLOAT, + "startAngle", + "Starting angle (in degrees) where the arc begins") + .field( + DocumentedOperation.FLOAT, + "sweepAngle", + "Sweep angle (in degrees) measured clockwise"); + } + + public DrawSector(float v1, float v2, float v3, float v4, float v5, float v6) { + super(v1, v2, v3, v4, v5, v6); + mName = "DrawSector"; + } + + @Override + public void paint(PaintContext context) { + context.drawSector(mV1, mV2, mV3, mV4, mV5, mV6); + } +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawText.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawText.java index 60dddc2d610e..bcb7852e6615 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawText.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawText.java @@ -15,9 +15,6 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.BOOLEAN; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; import static com.android.internal.widget.remotecompose.core.operations.Utils.floatToString; import com.android.internal.widget.remotecompose.core.Operation; @@ -28,12 +25,11 @@ import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.VariableSupport; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; -/** - * Draw Text - */ +/** Draw Text */ public class DrawText extends PaintOperation implements VariableSupport { private static final int OP_CODE = Operations.DRAW_TEXT_RUN; private static final String CLASS_NAME = "DrawText"; @@ -48,14 +44,15 @@ public class DrawText extends PaintOperation implements VariableSupport { float mOutY = 0f; boolean mRtl = false; - public DrawText(int textID, - int start, - int end, - int contextStart, - int contextEnd, - float x, - float y, - boolean rtl) { + public DrawText( + int textID, + int start, + int end, + int contextStart, + int contextEnd, + float x, + float y, + boolean rtl) { mTextID = textID; mStart = start; mEnd = end; @@ -68,10 +65,8 @@ public class DrawText extends PaintOperation implements VariableSupport { @Override public void updateVariables(RemoteContext context) { - mOutX = (Float.isNaN(mX)) - ? context.getFloat(Utils.idFromNan(mX)) : mX; - mOutY = (Float.isNaN(mY)) - ? context.getFloat(Utils.idFromNan(mY)) : mY; + mOutX = Float.isNaN(mX) ? context.getFloat(Utils.idFromNan(mX)) : mX; + mOutY = Float.isNaN(mY) ? context.getFloat(Utils.idFromNan(mY)) : mY; } @Override @@ -87,13 +82,20 @@ public class DrawText extends PaintOperation implements VariableSupport { @Override public void write(WireBuffer buffer) { apply(buffer, mTextID, mStart, mEnd, mContextStart, mContextEnd, mX, mY, mRtl); - } @Override public String toString() { - return "DrawTextRun [" + mTextID + "] " + mStart + ", " + mEnd + ", " - + floatToString(mX, mOutX) + ", " + floatToString(mY, mOutY); + return "DrawTextRun [" + + mTextID + + "] " + + mStart + + ", " + + mEnd + + ", " + + floatToString(mX, mOutX) + + ", " + + floatToString(mY, mOutY); } public static void read(WireBuffer buffer, List<Operation> operations) { @@ -114,7 +116,6 @@ public class DrawText extends PaintOperation implements VariableSupport { return CLASS_NAME; } - public static int id() { return OP_CODE; } @@ -122,25 +123,26 @@ public class DrawText extends PaintOperation implements VariableSupport { /** * Writes out the operation to the buffer * - * @param buffer write the command to the buffer - * @param textID id of the text - * @param start Start position - * @param end end position + * @param buffer write the command to the buffer + * @param textID id of the text + * @param start Start position + * @param end end position * @param contextStart start of the context - * @param contextEnd end of the context - * @param x position of where to draw - * @param y position of where to draw - * @param rtl is it Right to Left text + * @param contextEnd end of the context + * @param x position of where to draw + * @param y position of where to draw + * @param rtl is it Right to Left text */ - public static void apply(WireBuffer buffer, - int textID, - int start, - int end, - int contextStart, - int contextEnd, - float x, - float y, - boolean rtl) { + public static void apply( + WireBuffer buffer, + int textID, + int start, + int end, + int contextStart, + int contextEnd, + float x, + float y, + boolean rtl) { buffer.start(Operations.DRAW_TEXT_RUN); buffer.writeInt(textID); buffer.writeInt(start); @@ -152,33 +154,30 @@ public class DrawText extends PaintOperation implements VariableSupport { buffer.writeBoolean(rtl); } - public static void documentation(DocumentationBuilder doc) { - doc.operation("Draw Operations", - id(), - CLASS_NAME) + doc.operation("Draw Operations", id(), CLASS_NAME) .description("Draw a run of text, all in a single direction") - .field(INT, "textId", "id of bitmap") - .field(INT, "start", + .field(DocumentedOperation.INT, "textId", "id of bitmap") + .field( + DocumentedOperation.INT, + "start", "The start of the text to render. -1=end of string") - .field(INT, "end", - "The end of the text to render") - .field(INT, "contextStart", + .field(DocumentedOperation.INT, "end", "The end of the text to render") + .field( + DocumentedOperation.INT, + "contextStart", "the index of the start of the shaping context") - .field(INT, "contextEnd", + .field( + DocumentedOperation.INT, + "contextEnd", "the index of the end of the shaping context") - .field(FLOAT, "x", - "The x position at which to draw the text") - .field(FLOAT, "y", - "The y position at which to draw the text") - .field(BOOLEAN, "RTL", - "Whether the run is in RTL direction"); + .field(DocumentedOperation.FLOAT, "x", "The x position at which to draw the text") + .field(DocumentedOperation.FLOAT, "y", "The y position at which to draw the text") + .field(DocumentedOperation.BOOLEAN, "RTL", "Whether the run is in RTL direction"); } - @Override public void paint(PaintContext context) { - context.drawTextRun(mTextID, mStart, mEnd, mContextStart, - mContextEnd, mOutX, mOutY, mRtl); + context.drawTextRun(mTextID, mStart, mEnd, mContextStart, mContextEnd, mOutX, mOutY, mRtl); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextAnchored.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextAnchored.java index 242bc2575cee..95a87667dfab 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextAnchored.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextAnchored.java @@ -15,9 +15,6 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.PaintContext; @@ -26,12 +23,11 @@ import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.VariableSupport; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; -/** - * Draw Text in Anchored to a point - */ +/** Draw Text in Anchored to a point */ public class DrawTextAnchored extends PaintOperation implements VariableSupport { private static final int OP_CODE = Operations.DRAW_TEXT_ANCHOR; private static final String CLASS_NAME = "DrawTextAnchored"; @@ -49,12 +45,7 @@ public class DrawTextAnchored extends PaintOperation implements VariableSupport public static final int ANCHOR_TEXT_RTL = 1; public static final int ANCHOR_MONOSPACE_MEASURE = 2; - public DrawTextAnchored(int textID, - float x, - float y, - float panX, - float panY, - int flags) { + public DrawTextAnchored(int textID, float x, float y, float panX, float panY, int flags) { mTextID = textID; mX = x; mY = y; @@ -67,14 +58,10 @@ public class DrawTextAnchored extends PaintOperation implements VariableSupport @Override public void updateVariables(RemoteContext context) { - mOutX = (Float.isNaN(mX)) - ? context.getFloat(Utils.idFromNan(mX)) : mX; - mOutY = (Float.isNaN(mY)) - ? context.getFloat(Utils.idFromNan(mY)) : mY; - mOutPanX = (Float.isNaN(mPanX)) - ? context.getFloat(Utils.idFromNan(mPanX)) : mPanX; - mOutPanY = (Float.isNaN(mPanY)) - ? context.getFloat(Utils.idFromNan(mPanY)) : mPanY; + mOutX = Float.isNaN(mX) ? context.getFloat(Utils.idFromNan(mX)) : mX; + mOutY = Float.isNaN(mY) ? context.getFloat(Utils.idFromNan(mY)) : mY; + mOutPanX = Float.isNaN(mPanX) ? context.getFloat(Utils.idFromNan(mPanX)) : mPanX; + mOutPanY = Float.isNaN(mPanY) ? context.getFloat(Utils.idFromNan(mPanY)) : mPanY; } @Override @@ -95,18 +82,22 @@ public class DrawTextAnchored extends PaintOperation implements VariableSupport @Override public void write(WireBuffer buffer) { - apply(buffer, mTextID, mX, - mY, - mPanX, - mPanY, - mFlags); + apply(buffer, mTextID, mX, mY, mPanX, mPanY, mFlags); } @Override public String toString() { - return "DrawTextAnchored [" + mTextID + "] " + floatToStr(mX) + ", " - + floatToStr(mY) + ", " - + floatToStr(mPanX) + ", " + floatToStr(mPanY) + ", " + return "DrawTextAnchored [" + + mTextID + + "] " + + floatToStr(mX) + + ", " + + floatToStr(mY) + + ", " + + floatToStr(mPanX) + + ", " + + floatToStr(mPanY) + + ", " + Integer.toBinaryString(mFlags); } @@ -125,10 +116,7 @@ public class DrawTextAnchored extends PaintOperation implements VariableSupport float panY = buffer.readFloat(); int flags = buffer.readInt(); - DrawTextAnchored op = new DrawTextAnchored(textID, - x, y, - panX, panY, - flags); + DrawTextAnchored op = new DrawTextAnchored(textID, x, y, panX, panY, flags); operations.add(op); } @@ -152,13 +140,8 @@ public class DrawTextAnchored extends PaintOperation implements VariableSupport * @param panY The pan from top(-1) to bottom(1) 0 being centered * @param flags Change the behaviour */ - public static void apply(WireBuffer buffer, - int textID, - float x, - float y, - float panX, - float panY, - int flags) { + public static void apply( + WireBuffer buffer, int textID, float x, float y, float panX, float panY, int flags) { buffer.start(OP_CODE); buffer.writeInt(textID); buffer.writeFloat(x); @@ -169,25 +152,22 @@ public class DrawTextAnchored extends PaintOperation implements VariableSupport } public static void documentation(DocumentationBuilder doc) { - doc.operation("Draw Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Draw Operations", OP_CODE, CLASS_NAME) .description("Draw text centered about an anchor point") - .field(INT, "textId", "id of bitmap") - .field(FLOAT, "x", - "The x-position of the anchor point") - .field(FLOAT, "y", - "The y-position of the anchor point") - .field(FLOAT, "panX", + .field(DocumentedOperation.INT, "textId", "id of bitmap") + .field(DocumentedOperation.FLOAT, "x", "The x-position of the anchor point") + .field(DocumentedOperation.FLOAT, "y", "The y-position of the anchor point") + .field( + DocumentedOperation.FLOAT, + "panX", "The pan from left(-1) to right(1) 0 being centered") - .field(FLOAT, "panY", + .field( + DocumentedOperation.FLOAT, + "panY", "The pan from top(-1) to bottom(1) 0 being centered") - .field(INT, "flags", - "Change the behaviour"); - + .field(DocumentedOperation.INT, "flags", "Change the behaviour"); } - float[] mBounds = new float[4]; private float getHorizontalOffset() { @@ -196,8 +176,7 @@ public class DrawTextAnchored extends PaintOperation implements VariableSupport float textWidth = scale * (mBounds[2] - mBounds[0]); float boxWidth = 0; - return (boxWidth - textWidth) * (1 + mOutPanX) / 2.f - - (scale * mBounds[0]); + return (boxWidth - textWidth) * (1 + mOutPanX) / 2.f - (scale * mBounds[0]); } private float getVerticalOffset() { @@ -205,18 +184,18 @@ public class DrawTextAnchored extends PaintOperation implements VariableSupport float scale = 1.0f; float boxHeight = 0; float textHeight = scale * (mBounds[3] - mBounds[1]); - return (boxHeight - textHeight) * (1 - mOutPanY) / 2 - - (scale * mBounds[1]); + return (boxHeight - textHeight) * (1 - mOutPanY) / 2 - (scale * mBounds[1]); } @Override public void paint(PaintContext context) { - int flags = ((mFlags & ANCHOR_MONOSPACE_MEASURE) != 0) - ? PaintContext.TEXT_MEASURE_MONOSPACE_WIDTH : 0; + int flags = + ((mFlags & ANCHOR_MONOSPACE_MEASURE) != 0) + ? PaintContext.TEXT_MEASURE_MONOSPACE_WIDTH + : 0; context.getTextBounds(mTextID, 0, -1, flags, mBounds); float x = mOutX + getHorizontalOffset(); - float y = (Float.isNaN(mOutPanY)) ? mOutY : mOutY + getVerticalOffset(); - context.drawTextRun(mTextID, 0, -1, 0, 1, x, y, - (mFlags & ANCHOR_TEXT_RTL) == 1); + float y = Float.isNaN(mOutPanY) ? mOutY : mOutY + getVerticalOffset(); + context.drawTextRun(mTextID, 0, -1, 0, 1, x, y, (mFlags & ANCHOR_TEXT_RTL) == 1); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextOnPath.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextOnPath.java index d69362bd7a7d..aefd6f397ebf 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextOnPath.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextOnPath.java @@ -15,10 +15,6 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; -import static com.android.internal.widget.remotecompose.core.operations.Utils.floatToString; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.PaintContext; @@ -27,13 +23,12 @@ import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.VariableSupport; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; -/** - * Draw text along a path. - */ -public class DrawTextOnPath extends PaintOperation implements VariableSupport { +/** Draw text along a path. */ +public class DrawTextOnPath extends PaintOperation implements VariableSupport { private static final int OP_CODE = Operations.DRAW_TEXT_ON_PATH; private static final String CLASS_NAME = "DrawTextOnPath"; int mPathId; @@ -46,18 +41,16 @@ public class DrawTextOnPath extends PaintOperation implements VariableSupport { public DrawTextOnPath(int textId, int pathId, float hOffset, float vOffset) { mPathId = pathId; mTextId = textId; - mOutHOffset = mHOffset = vOffset; - mOutVOffset = mVOffset = hOffset; + mOutHOffset = mHOffset = hOffset; + mOutVOffset = mVOffset = vOffset; } - @Override public void updateVariables(RemoteContext context) { - mOutHOffset = (Float.isNaN(mHOffset)) - ? context.getFloat(Utils.idFromNan(mHOffset)) : mHOffset; - mOutVOffset = (Float.isNaN(mVOffset)) - ? context.getFloat(Utils.idFromNan(mVOffset)) : mVOffset; - + mOutHOffset = + Float.isNaN(mHOffset) ? context.getFloat(Utils.idFromNan(mHOffset)) : mHOffset; + mOutVOffset = + Float.isNaN(mVOffset) ? context.getFloat(Utils.idFromNan(mVOffset)) : mVOffset; } @Override @@ -77,16 +70,21 @@ public class DrawTextOnPath extends PaintOperation implements VariableSupport { @Override public String toString() { - return "DrawTextOnPath [" + mTextId + "] [" + mPathId + "] " - + floatToString(mHOffset, mOutHOffset) + ", " - + floatToString(mVOffset, mOutVOffset); + return "DrawTextOnPath [" + + mTextId + + "] [" + + mPathId + + "] " + + Utils.floatToString(mHOffset, mOutHOffset) + + ", " + + Utils.floatToString(mVOffset, mOutVOffset); } public static void read(WireBuffer buffer, List<Operation> operations) { int textId = buffer.readInt(); int pathId = buffer.readInt(); - float hOffset = buffer.readFloat(); float vOffset = buffer.readFloat(); + float hOffset = buffer.readFloat(); DrawTextOnPath op = new DrawTextOnPath(textId, pathId, hOffset, vOffset); operations.add(op); } @@ -95,33 +93,26 @@ public class DrawTextOnPath extends PaintOperation implements VariableSupport { return "DrawTextOnPath"; } - public static int id() { return Operations.DRAW_TEXT_ON_PATH; } - public static void apply(WireBuffer buffer, int textId, int pathId, - float hOffset, float vOffset) { + public static void apply( + WireBuffer buffer, int textId, int pathId, float hOffset, float vOffset) { buffer.start(OP_CODE); buffer.writeInt(textId); buffer.writeInt(pathId); - buffer.writeFloat(hOffset); buffer.writeFloat(vOffset); + buffer.writeFloat(hOffset); } public static void documentation(DocumentationBuilder doc) { - doc.operation("Draw Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Draw Operations", OP_CODE, CLASS_NAME) .description("Draw text along path object") - .field(INT, "textId", - "id of the text") - .field(INT, "pathId", - "id of the path") - .field(FLOAT, "xOffset", - "x Shift of the text") - .field(FLOAT, "yOffset", - "y Shift of the text"); + .field(DocumentedOperation.INT, "textId", "id of the text") + .field(DocumentedOperation.INT, "pathId", "id of the path") + .field(DocumentedOperation.FLOAT, "xOffset", "x Shift of the text") + .field(DocumentedOperation.FLOAT, "yOffset", "y Shift of the text"); } @Override diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTweenPath.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTweenPath.java index 354726319c45..b6d45d95f2c0 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTweenPath.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTweenPath.java @@ -15,8 +15,6 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; import static com.android.internal.widget.remotecompose.core.operations.Utils.floatToString; import com.android.internal.widget.remotecompose.core.Operation; @@ -27,6 +25,7 @@ import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.VariableSupport; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; @@ -42,12 +41,7 @@ public class DrawTweenPath extends PaintOperation implements VariableSupport { int mPath1Id; int mPath2Id; - public DrawTweenPath( - int path1Id, - int path2Id, - float tween, - float start, - float stop) { + public DrawTweenPath(int path1Id, int path2Id, float tween, float start, float stop) { mOutTween = mTween = tween; mOutStart = mStart = start; mOutStop = mStop = stop; @@ -57,12 +51,9 @@ public class DrawTweenPath extends PaintOperation implements VariableSupport { @Override public void updateVariables(RemoteContext context) { - mOutTween = (Float.isNaN(mTween)) - ? context.getFloat(Utils.idFromNan(mTween)) : mTween; - mOutStart = (Float.isNaN(mStart)) - ? context.getFloat(Utils.idFromNan(mStart)) : mStart; - mOutStop = (Float.isNaN(mStop)) - ? context.getFloat(Utils.idFromNan(mStop)) : mStop; + mOutTween = Float.isNaN(mTween) ? context.getFloat(Utils.idFromNan(mTween)) : mTween; + mOutStart = Float.isNaN(mStart) ? context.getFloat(Utils.idFromNan(mStart)) : mStart; + mOutStop = Float.isNaN(mStop) ? context.getFloat(Utils.idFromNan(mStop)) : mStop; } @Override @@ -80,49 +71,44 @@ public class DrawTweenPath extends PaintOperation implements VariableSupport { @Override public void write(WireBuffer buffer) { - apply(buffer, mPath1Id, - mPath2Id, - mTween, - mStart, - mStop); + apply(buffer, mPath1Id, mPath2Id, mTween, mStart, mStop); } @Override public String toString() { - return "DrawTweenPath " + mPath1Id + " " + mPath2Id - + " " + floatToString(mTween, mOutTween) + " " - + floatToString(mStart, mOutStart) + " " - + "- " + floatToString(mStop, mOutStop); + return "DrawTweenPath " + + mPath1Id + + " " + + mPath2Id + + " " + + floatToString(mTween, mOutTween) + + " " + + floatToString(mStart, mOutStart) + + " " + + "- " + + floatToString(mStop, mOutStop); } - public static void read(WireBuffer buffer, List<Operation> operations) { int path1Id = buffer.readInt(); int path2Id = buffer.readInt(); float tween = buffer.readFloat(); float start = buffer.readFloat(); float stop = buffer.readFloat(); - DrawTweenPath op = new DrawTweenPath(path1Id, path2Id, - tween, start, stop); + DrawTweenPath op = new DrawTweenPath(path1Id, path2Id, tween, start, stop); operations.add(op); } - public static String name() { return "DrawTweenPath"; } - public static int id() { return Operations.DRAW_TWEEN_PATH; } - public static void apply(WireBuffer buffer, - int path1Id, - int path2Id, - float tween, - float start, - float stop) { + public static void apply( + WireBuffer buffer, int path1Id, int path2Id, float tween, float start, float stop) { buffer.start(OP_CODE); buffer.writeInt(path1Id); buffer.writeInt(path2Id); @@ -131,33 +117,18 @@ public class DrawTweenPath extends PaintOperation implements VariableSupport { buffer.writeFloat(stop); } - public static void documentation(DocumentationBuilder doc) { - doc.operation("Draw Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Draw Operations", OP_CODE, CLASS_NAME) .description("Draw text along path object") - .field(INT, "pathId1", - "id of path 1") - .field(INT, "pathId2", - "id of path 2") - .field(FLOAT, "tween", - "interpolate between the two paths") - .field(FLOAT, "start", - "trim the start of the path") - .field(FLOAT, "yOffset", - "trim the end of the path"); - + .field(DocumentedOperation.INT, "pathId1", "id of path 1") + .field(DocumentedOperation.INT, "pathId2", "id of path 2") + .field(DocumentedOperation.FLOAT, "tween", "interpolate between the two paths") + .field(DocumentedOperation.FLOAT, "start", "trim the start of the path") + .field(DocumentedOperation.FLOAT, "yOffset", "trim the end of the path"); } - @Override public void paint(PaintContext context) { - context.drawTweenPath(mPath1Id, - mPath2Id, - mOutTween, - mOutStart, - mOutStop); + context.drawTweenPath(mPath1Id, mPath2Id, mOutTween, mOutStart, mOutStop); } - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatConstant.java b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatConstant.java index 31b8ff6db58b..765e150e81af 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatConstant.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatConstant.java @@ -15,21 +15,19 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; -/** - * Operation to deal with Text data - */ -public class FloatConstant implements Operation { +/** Operation to deal with Text data */ +public class FloatConstant implements com.android.internal.widget.remotecompose.core.Operation { private static final int OP_CODE = Operations.DATA_FLOAT; private static final String CLASS_NAME = "FloatConstant"; public int mTextId; @@ -54,7 +52,6 @@ public class FloatConstant implements Operation { return CLASS_NAME; } - public static int id() { return OP_CODE; } @@ -63,8 +60,8 @@ public class FloatConstant implements Operation { * Writes out the operation to the buffer * * @param buffer write command to this buffer - * @param id the id - * @param value the value of the float + * @param id the id + * @param value the value of the float */ public static void apply(WireBuffer buffer, int id, float value) { buffer.start(OP_CODE); @@ -80,14 +77,10 @@ public class FloatConstant implements Operation { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Expressions Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Expressions Operations", OP_CODE, CLASS_NAME) .description("A float and its associated id") - .field(INT, "id", "id of float") - .field(FLOAT, "value", - "32-bit float value"); - + .field(DocumentedOperation.INT, "id", "id of float") + .field(FLOAT, "value", "32-bit float value"); } @Override diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java index e3df1eb0da26..d71793364a33 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java @@ -15,10 +15,10 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT_ARRAY; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.SHORT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT_ARRAY; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.SHORT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -26,19 +26,17 @@ import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.VariableSupport; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import com.android.internal.widget.remotecompose.core.operations.utilities.AnimatedFloatExpression; import com.android.internal.widget.remotecompose.core.operations.utilities.NanMap; import com.android.internal.widget.remotecompose.core.operations.utilities.easing.FloatAnimation; -import java.util.Arrays; import java.util.List; /** - * Operation to deal with AnimatedFloats - * This is designed to be an optimized calculation for things like - * injecting the width of the component int draw rect - * As well as supporting generalized animation floats. - * The floats represent a RPN style calculator + * Operation to deal with AnimatedFloats This is designed to be an optimized calculation for things + * like injecting the width of the component int draw rect As well as supporting generalized + * animation floats. The floats represent a RPN style calculator */ public class FloatExpression implements Operation, VariableSupport { private static final int OP_CODE = Operations.ANIMATED_FLOAT; @@ -49,6 +47,7 @@ public class FloatExpression implements Operation, VariableSupport { public FloatAnimation mFloatAnimation; public float[] mPreCalcValue; private float mLastChange = Float.NaN; + private float mLastCalculatedValue = Float.NaN; AnimatedFloatExpression mExp = new AnimatedFloatExpression(); public static final int MAX_EXPRESSION_SIZE = 32; @@ -70,12 +69,12 @@ public class FloatExpression implements Operation, VariableSupport { boolean value_changed = false; for (int i = 0; i < mSrcValue.length; i++) { float v = mSrcValue[i]; - if (Float.isNaN(v) && !AnimatedFloatExpression.isMathOperator(v) + if (Float.isNaN(v) + && !AnimatedFloatExpression.isMathOperator(v) && !NanMap.isDataVariable(v)) { float newValue = context.getFloat(Utils.idFromNan(v)); if (mFloatAnimation != null) { if (mPreCalcValue[i] != newValue) { - mLastChange = context.getAnimationTime(); value_changed = true; mPreCalcValue[i] = newValue; } @@ -86,8 +85,18 @@ public class FloatExpression implements Operation, VariableSupport { mPreCalcValue[i] = mSrcValue[i]; } } + float v = mLastCalculatedValue; + if (value_changed) { // inputs changed check if output changed + v = mExp.eval(mPreCalcValue, mPreCalcValue.length); + if (v != mLastCalculatedValue) { + mLastChange = context.getAnimationTime(); + mLastCalculatedValue = v; + } else { + value_changed = false; + } + } + if (value_changed && mFloatAnimation != null) { - float v = mExp.eval(Arrays.copyOf(mPreCalcValue, mPreCalcValue.length)); if (Float.isNaN(mFloatAnimation.getTargetValue())) { mFloatAnimation.setInitialValue(v); } else { @@ -100,7 +109,8 @@ public class FloatExpression implements Operation, VariableSupport { @Override public void registerListening(RemoteContext context) { for (float v : mSrcValue) { - if (Float.isNaN(v) && !AnimatedFloatExpression.isMathOperator(v) + if (Float.isNaN(v) + && !AnimatedFloatExpression.isMathOperator(v) && !NanMap.isDataVariable(v)) { context.listensTo(Utils.idFromNan(v), this); } @@ -118,8 +128,9 @@ public class FloatExpression implements Operation, VariableSupport { float f = mFloatAnimation.get(t - mLastChange); context.loadFloat(mId, f); } else { - context.loadFloat(mId, mExp.eval(context.getCollectionsAccess(), - Arrays.copyOf(mPreCalcValue, mPreCalcValue.length))); + context.loadFloat( + mId, + mExp.eval(context.getCollectionsAccess(), mPreCalcValue, mPreCalcValue.length)); } } @@ -137,11 +148,17 @@ public class FloatExpression implements Operation, VariableSupport { } } if (mPreCalcValue == null) { - return "FloatExpression[" + mId + "] = (" - + AnimatedFloatExpression.toString(mSrcValue, labels) + ")"; + return "FloatExpression[" + + mId + + "] = (" + + AnimatedFloatExpression.toString(mSrcValue, labels) + + ")"; } - return "FloatExpression[" + mId + "] = (" - + AnimatedFloatExpression.toString(mPreCalcValue, labels) + ")"; + return "FloatExpression[" + + mId + + "] = (" + + AnimatedFloatExpression.toString(mPreCalcValue, labels) + + ")"; } public static String name() { @@ -155,9 +172,9 @@ public class FloatExpression implements Operation, VariableSupport { /** * Writes out the operation to the buffer * - * @param buffer The buffer to write to - * @param id the id of the resulting float - * @param value the float expression array + * @param buffer The buffer to write to + * @param id the id of the resulting float + * @param value the float expression array * @param animation the animation expression array */ public static void apply(WireBuffer buffer, int id, float[] value, float[] animation) { @@ -178,7 +195,6 @@ public class FloatExpression implements Operation, VariableSupport { buffer.writeFloat(v); } } - } public static void read(WireBuffer buffer, List<Operation> operations) { @@ -207,16 +223,20 @@ public class FloatExpression implements Operation, VariableSupport { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Expressions Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Expressions Operations", OP_CODE, CLASS_NAME) .description("A Float expression") - .field(INT, "id", "The id of the Color") + .field(DocumentedOperation.INT, "id", "The id of the Color") .field(SHORT, "expression_length", "expression length") .field(SHORT, "animation_length", "animation description length") - .field(FLOAT_ARRAY, "expression", "expression_length", + .field( + FLOAT_ARRAY, + "expression", + "expression_length", "Sequence of Floats representing and expression") - .field(FLOAT_ARRAY, "AnimationSpec", "animation_length", + .field( + FLOAT_ARRAY, + "AnimationSpec", + "animation_length", "Sequence of Floats representing animation curve") .field(FLOAT, "duration", "> time in sec") .field(INT, "bits", "> WRAP|INITALVALUE | TYPE ") @@ -229,5 +249,4 @@ public class FloatExpression implements Operation, VariableSupport { public String deepToString(String indent) { return indent + toString(); } - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java b/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java index 099bce886b22..4f8516f5235d 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java @@ -15,8 +15,8 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.LONG; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.LONG; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -29,9 +29,9 @@ import java.util.List; /** * Describe some basic information for a RemoteCompose document - * <p> - * It encodes the version of the document (following semantic versioning) as well - * as the dimensions of the document in pixels. + * + * <p>It encodes the version of the document (following semantic versioning) as well as the + * dimensions of the document in pixels. */ public class Header implements RemoteComposeOperation { private static final int OP_CODE = Operations.HEADER; @@ -50,21 +50,26 @@ public class Header implements RemoteComposeOperation { float mDensity; long mCapabilities; - /** - * It encodes the version of the document (following semantic versioning) as well - * as the dimensions of the document in pixels. + * It encodes the version of the document (following semantic versioning) as well as the + * dimensions of the document in pixels. * * @param majorVersion the major version of the RemoteCompose document API * @param minorVersion the minor version of the RemoteCompose document API * @param patchVersion the patch version of the RemoteCompose document API - * @param width the width of the RemoteCompose document - * @param height the height of the RemoteCompose document - * @param density the density at which the document was originally created + * @param width the width of the RemoteCompose document + * @param height the height of the RemoteCompose document + * @param density the density at which the document was originally created * @param capabilities bitmask field storing needed capabilities (unused for now) */ - public Header(int majorVersion, int minorVersion, int patchVersion, - int width, int height, float density, long capabilities) { + public Header( + int majorVersion, + int minorVersion, + int patchVersion, + int width, + int height, + float density, + long capabilities) { this.mMajorVersion = majorVersion; this.mMinorVersion = minorVersion; this.mPatchVersion = patchVersion; @@ -81,9 +86,19 @@ public class Header implements RemoteComposeOperation { @Override public String toString() { - return "HEADER v" + mMajorVersion + "." - + mMinorVersion + "." + mPatchVersion + ", " - + mWidth + " x " + mHeight + " [" + mCapabilities + "]"; + return "HEADER v" + + mMajorVersion + + "." + + mMinorVersion + + "." + + mPatchVersion + + ", " + + mWidth + + " x " + + mHeight + + " [" + + mCapabilities + + "]"; } @Override @@ -104,8 +119,8 @@ public class Header implements RemoteComposeOperation { return OP_CODE; } - public static void apply(WireBuffer buffer, int width, int height, - float density, long capabilities) { + public static void apply( + WireBuffer buffer, int width, int height, float density, long capabilities) { buffer.start(OP_CODE); buffer.writeInt(MAJOR_VERSION); // major version number of the protocol buffer.writeInt(MINOR_VERSION); // minor version number of the protocol @@ -125,15 +140,23 @@ public class Header implements RemoteComposeOperation { // float density = buffer.readFloat(); float density = 1f; long capabilities = buffer.readLong(); - Header header = new Header(majorVersion, minorVersion, patchVersion, - width, height, density, capabilities); + Header header = + new Header( + majorVersion, + minorVersion, + patchVersion, + width, + height, + density, + capabilities); operations.add(header); } public static void documentation(DocumentationBuilder doc) { doc.operation("Protocol Operations", OP_CODE, CLASS_NAME) - .description("Document metadata, containing the version," - + " original size & density, capabilities mask") + .description( + "Document metadata, containing the version," + + " original size & density, capabilities mask") .field(INT, "MAJOR_VERSION", "Major version") .field(INT, "MINOR_VERSION", "Minor version") .field(INT, "PATCH_VERSION", "Patch version") @@ -142,5 +165,4 @@ public class Header implements RemoteComposeOperation { // .field(FLOAT, "DENSITY", "Major version") .field(LONG, "CAPABILITIES", "Major version"); } - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/IntegerExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/IntegerExpression.java index 11730f358eaf..c9a850875011 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/IntegerExpression.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/IntegerExpression.java @@ -15,8 +15,8 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT_ARRAY; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT_ARRAY; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -24,17 +24,16 @@ import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.VariableSupport; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import com.android.internal.widget.remotecompose.core.operations.utilities.IntegerExpressionEvaluator; import java.util.Arrays; import java.util.List; /** - * Operation to deal with AnimatedFloats - * This is designed to be an optimized calculation for things like - * injecting the width of the component int draw rect - * As well as supporting generalized animation floats. - * The floats represent a RPN style calculator + * Operation to deal with AnimatedFloats This is designed to be an optimized calculation for things + * like injecting the width of the component int draw rect As well as supporting generalized + * animation floats. The floats represent a RPN style calculator */ public class IntegerExpression implements Operation, VariableSupport { private static final int OP_CODE = Operations.INTEGER_EXPRESSION; @@ -45,7 +44,7 @@ public class IntegerExpression implements Operation, VariableSupport { public int[] mSrcValue; public int[] mPreCalcValue; private float mLastChange = Float.NaN; - public static final int MAX_STRING_SIZE = 4000; + public static final int MAX_SIZE = 320; IntegerExpressionEvaluator mExp = new IntegerExpressionEvaluator(); public IntegerExpression(int id, int mask, int[] value) { @@ -70,7 +69,6 @@ public class IntegerExpression implements Operation, VariableSupport { } } - @Override public void registerListening(RemoteContext context) { for (int i = 0; i < mSrcValue.length; i++) { @@ -91,6 +89,21 @@ public class IntegerExpression implements Operation, VariableSupport { context.loadInteger(mId, v); } + /** + * Evaluate the expression + * + * @param context current context + * @return the resulting value + */ + public int evaluate(RemoteContext context) { + updateVariables(context); + float t = context.getAnimationTime(); + if (Float.isNaN(mLastChange)) { + mLastChange = t; + } + return mExp.eval(mPreMask, Arrays.copyOf(mPreCalcValue, mPreCalcValue.length)); + } + @Override public void write(WireBuffer buffer) { apply(buffer, mId, mMask, mSrcValue); @@ -99,6 +112,9 @@ public class IntegerExpression implements Operation, VariableSupport { @Override public String toString() { StringBuilder s = new StringBuilder(); + if (mPreCalcValue == null) { + return ""; + } for (int i = 0; i < mPreCalcValue.length; i++) { if (i != 0) { s.append(" "); @@ -128,9 +144,9 @@ public class IntegerExpression implements Operation, VariableSupport { * Writes out the operation to the buffer * * @param buffer buffer to write to - * @param id the id of the integer - * @param mask the mask bits of ints & operators or variables - * @param value array of integers to be evaluated + * @param id the id of the integer + * @param mask the mask bits of ints & operators or variables + * @param value array of integers to be evaluated */ public static void apply(WireBuffer buffer, int id, int mask, int[] value) { buffer.start(OP_CODE); @@ -146,7 +162,9 @@ public class IntegerExpression implements Operation, VariableSupport { int id = buffer.readInt(); int mask = buffer.readInt(); int len = buffer.readInt(); - + if (len > MAX_SIZE) { + throw new RuntimeException("buffer corrupt integer expression " + len); + } int[] values = new int[len]; for (int i = 0; i < values.length; i++) { values[i] = buffer.readInt(); @@ -156,17 +174,12 @@ public class IntegerExpression implements Operation, VariableSupport { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Data Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Data Operations", OP_CODE, CLASS_NAME) .description("Expression that computes an integer") - .field(INT, "id", "id of integer") - .field(INT, "mask", - "bits representing operators or other id's") - .field(INT, "length", - "length of array") - .field(INT_ARRAY, "values", "length", - "Array of ints"); + .field(DocumentedOperation.INT, "id", "id of integer") + .field(INT, "mask", "bits representing operators or other id's") + .field(INT, "length", "length of array") + .field(INT_ARRAY, "values", "length", "Array of ints"); } @Override @@ -177,8 +190,8 @@ public class IntegerExpression implements Operation, VariableSupport { /** * given the "i" position in the mask is this an ID * - * @param mask 32 bit mask used for defining numbers vs other - * @param i the bit in question + * @param mask 32 bit mask used for defining numbers vs other + * @param i the bit in question * @param value the value * @return true if this is an ID */ diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRestore.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRestore.java index f3f9a5142a24..04f8a503adff 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRestore.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRestore.java @@ -27,15 +27,14 @@ import java.util.List; public class MatrixRestore extends PaintOperation { private static final int OP_CODE = Operations.MATRIX_RESTORE; private static final String CLASS_NAME = "MatrixRestore"; - public MatrixRestore() { - } + + public MatrixRestore() {} @Override public void write(WireBuffer buffer) { apply(buffer); } - public static void read(WireBuffer buffer, List<Operation> operations) { MatrixRestore op = new MatrixRestore(); operations.add(op); @@ -46,12 +45,10 @@ public class MatrixRestore extends PaintOperation { return "MatrixRestore"; } - public static String name() { return CLASS_NAME; } - public static int id() { return OP_CODE; } @@ -61,13 +58,10 @@ public class MatrixRestore extends PaintOperation { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Canvas Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Canvas Operations", OP_CODE, CLASS_NAME) .description("Restore the matrix and clip"); } - @Override public void paint(PaintContext context) { context.matrixRestore(); diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRotate.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRotate.java index 9cc82fc05e69..df10f329630a 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRotate.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRotate.java @@ -15,13 +15,12 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.PaintContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; @@ -30,12 +29,13 @@ public class MatrixRotate extends DrawBase3 { private static final String CLASS_NAME = "MatrixRotate"; public static void read(WireBuffer buffer, List<Operation> operations) { - Maker m = new Maker() { - @Override - public DrawBase3 create(float v1, float v2, float v3) { - return new MatrixRotate(v1, v2, v3); - } - }; + Maker m = + new Maker() { + @Override + public DrawBase3 create(float v1, float v2, float v3) { + return new MatrixRotate(v1, v2, v3); + } + }; read(m, buffer, operations); } @@ -48,20 +48,15 @@ public class MatrixRotate extends DrawBase3 { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Canvas Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Canvas Operations", OP_CODE, CLASS_NAME) .description("apply rotation to matrix") - .field(FLOAT, "rotate", "Angle to rotate") - .field(FLOAT, "pivotX", "X Pivot point") - .field(FLOAT, "pivotY", "Y Pivot point"); + .field(DocumentedOperation.FLOAT, "rotate", "Angle to rotate") + .field(DocumentedOperation.FLOAT, "pivotX", "X Pivot point") + .field(DocumentedOperation.FLOAT, "pivotY", "Y Pivot point"); } - - protected void write(WireBuffer buffer, - float v1, - float v2, - float v3) { + @Override + protected void write(WireBuffer buffer, float v1, float v2, float v3) { apply(buffer, v1, v2, v3); } @@ -83,10 +78,7 @@ public class MatrixRotate extends DrawBase3 { * @param y1 X Pivot point * @param x2 Y Pivot point */ - public static void apply(WireBuffer buffer, - float x1, - float y1, - float x2) { + public static void apply(WireBuffer buffer, float x1, float y1, float x2) { buffer.start(OP_CODE); buffer.writeFloat(x1); buffer.writeFloat(y1); diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSave.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSave.java index a47ed6b9f99a..67612c7fd2f4 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSave.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSave.java @@ -47,7 +47,6 @@ public class MatrixSave extends PaintOperation { return CLASS_NAME; } - public static int id() { return OP_CODE; } @@ -57,9 +56,7 @@ public class MatrixSave extends PaintOperation { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Canvas Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Canvas Operations", OP_CODE, CLASS_NAME) .description("Save the matrix and clip to a stack"); } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixScale.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixScale.java index 769e798eb6b2..26c898acb67b 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixScale.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixScale.java @@ -15,13 +15,12 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.PaintContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; @@ -42,28 +41,18 @@ public class MatrixScale extends DrawBase4 { return CLASS_NAME; } - - protected void write(WireBuffer buffer, - float v1, - float v2, - float v3, - float v4) { + @Override + protected void write(WireBuffer buffer, float v1, float v2, float v3, float v4) { apply(buffer, v1, v2, v3, v4); } public static void documentation(DocumentationBuilder doc) { - doc.operation("Canvas Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Canvas Operations", OP_CODE, CLASS_NAME) .description("Draw the specified Oval") - .field(FLOAT, "scaleX", - "The amount to scale in X") - .field(FLOAT, "scaleY", - "The amount to scale in Y") - .field(FLOAT, "pivotX", - "The x-coordinate for the pivot point") - .field(FLOAT, "pivotY", - "The y-coordinate for the pivot point"); + .field(DocumentedOperation.FLOAT, "scaleX", "The amount to scale in X") + .field(DocumentedOperation.FLOAT, "scaleY", "The amount to scale in Y") + .field(DocumentedOperation.FLOAT, "pivotX", "The x-coordinate for the pivot point") + .field(DocumentedOperation.FLOAT, "pivotY", "The y-coordinate for the pivot point"); } public MatrixScale(float scaleX, float scaleY, float centerX, float centerY) { @@ -80,16 +69,12 @@ public class MatrixScale extends DrawBase4 { * Writes out the DrawOval to the buffer * * @param buffer buffer to write to - * @param x1 start x of DrawOval - * @param y1 start y of the DrawOval - * @param x2 end x of the DrawOval - * @param y2 end y of the DrawOval + * @param x1 start x of DrawOval + * @param y1 start y of the DrawOval + * @param x2 end x of the DrawOval + * @param y2 end y of the DrawOval */ - public static void apply(WireBuffer buffer, - float x1, - float y1, - float x2, - float y2) { + public static void apply(WireBuffer buffer, float x1, float y1, float x2, float y2) { write(buffer, OP_CODE, x1, y1, x2, y2); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSkew.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSkew.java index 34f71b4d1a91..d64117871eaa 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSkew.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSkew.java @@ -15,7 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -29,7 +29,6 @@ public class MatrixSkew extends DrawBase2 { public static final int OP_CODE = Operations.MATRIX_SKEW; public static final String CLASS_NAME = "MatrixSkew"; - public static void read(WireBuffer buffer, List<Operation> operations) { Maker m = MatrixSkew::new; read(m, buffer, operations); @@ -43,25 +42,18 @@ public class MatrixSkew extends DrawBase2 { return CLASS_NAME; } - - protected void write(WireBuffer buffer, - float v1, - float v2) { + @Override + protected void write(WireBuffer buffer, float v1, float v2) { apply(buffer, v1, v2); } public static void documentation(DocumentationBuilder doc) { - doc.operation("Canvas Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Canvas Operations", OP_CODE, CLASS_NAME) .description("Current matrix with the specified skew.") - .field(FLOAT, "skewX", - "The amount to skew in X") - .field(FLOAT, "skewY", - "The amount to skew in Y"); + .field(FLOAT, "skewX", "The amount to skew in X") + .field(FLOAT, "skewY", "The amount to skew in Y"); } - public MatrixSkew(float skewX, float skewY) { super(skewX, skewY); mName = CLASS_NAME; @@ -76,13 +68,10 @@ public class MatrixSkew extends DrawBase2 { * Writes out the DrawOval to the buffer * * @param buffer buffer to write to - * @param x1 start x of DrawOval - * @param y1 start y of the DrawOval + * @param x1 start x of DrawOval + * @param y1 start y of the DrawOval */ - public static void apply(WireBuffer buffer, - float x1, - float y1 - ) { + public static void apply(WireBuffer buffer, float x1, float y1) { write(buffer, OP_CODE, x1, y1); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixTranslate.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixTranslate.java index 8561343c0015..e008292f1107 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixTranslate.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixTranslate.java @@ -15,13 +15,12 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.PaintContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; @@ -42,22 +41,16 @@ public class MatrixTranslate extends DrawBase2 { return CLASS_NAME; } - protected void write(WireBuffer buffer, - float v1, - float v2) { + @Override + protected void write(WireBuffer buffer, float v1, float v2) { apply(buffer, v1, v2); } public static void documentation(DocumentationBuilder doc) { - doc.operation("Canvas Operations", - OP_CODE, - "MatrixTranslate") + doc.operation("Canvas Operations", OP_CODE, "MatrixTranslate") .description("Preconcat the current matrix with the specified translation") - .field(FLOAT, "dx", - "The distance to translate in X") - .field(FLOAT, "dy", - "The distance to translate in Y"); - + .field(DocumentedOperation.FLOAT, "dx", "The distance to translate in X") + .field(DocumentedOperation.FLOAT, "dy", "The distance to translate in Y"); } public MatrixTranslate(float translateX, float translateY) { @@ -74,12 +67,10 @@ public class MatrixTranslate extends DrawBase2 { * Writes out the DrawOval to the buffer * * @param buffer buffer to write to - * @param x1 start x of DrawOval - * @param y1 start y of the DrawOval + * @param x1 start x of DrawOval + * @param y1 start y of the DrawOval */ - public static void apply(WireBuffer buffer, - float x1, - float y1) { + public static void apply(WireBuffer buffer, float x1, float y1) { write(buffer, OP_CODE, x1, y1); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java b/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java index 2cf83cd6caec..fa6e2712a0bb 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java @@ -15,20 +15,19 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.UTF8; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.UTF8; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; -/** - * Operation to deal with Text data - */ +/** Operation to deal with Text data */ public class NamedVariable implements Operation { private static final int OP_CODE = Operations.NAMED_VARIABLE; private static final String CLASS_NAME = "NamedVariable"; @@ -39,6 +38,7 @@ public class NamedVariable implements Operation { public static final int COLOR_TYPE = 2; public static final int FLOAT_TYPE = 1; public static final int STRING_TYPE = 0; + public static final int IMAGE_TYPE = 3; public NamedVariable(int varId, int varType, String name) { this.mVarId = varId; @@ -53,8 +53,12 @@ public class NamedVariable implements Operation { @Override public String toString() { - return "VariableName[" + mVarId + "] = \"" - + Utils.trimString(mVarName, 10) + "\" type=" + mVarType; + return "VariableName[" + + mVarId + + "] = \"" + + Utils.trimString(mVarName, 10) + + "\" type=" + + mVarType; } public static String name() { @@ -80,7 +84,7 @@ public class NamedVariable implements Operation { buffer.writeUTF8(text); } - public static void read(WireBuffer buffer, List<Operation> operations) { + public static void read(WireBuffer buffer, List<Operation> operations) { int varId = buffer.readInt(); int varType = buffer.readInt(); String text = buffer.readUTF8(MAX_STRING_SIZE); @@ -88,11 +92,9 @@ public class NamedVariable implements Operation { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Data Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Data Operations", OP_CODE, CLASS_NAME) .description("Add a string name for an ID") - .field(INT, "varId", "id to label") + .field(DocumentedOperation.INT, "varId", "id to label") .field(INT, "varType", "The type of variable") .field(UTF8, "name", "String"); } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/PaintData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/PaintData.java index ae7a89279320..095a0106b3d7 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/PaintData.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/PaintData.java @@ -15,8 +15,8 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT_ARRAY; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT_ARRAY; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -36,8 +36,7 @@ public class PaintData extends PaintOperation implements VariableSupport { public PaintBundle mPaintData = new PaintBundle(); public static final int MAX_STRING_SIZE = 4000; - public PaintData() { - } + public PaintData() {} @Override public void updateVariables(RemoteContext context) { @@ -59,7 +58,6 @@ public class PaintData extends PaintOperation implements VariableSupport { return "PaintData " + "\"" + mPaintData + "\""; } - public static String name() { return CLASS_NAME; } @@ -80,13 +78,10 @@ public class PaintData extends PaintOperation implements VariableSupport { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Data Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Data Operations", OP_CODE, CLASS_NAME) .description("Encode a Paint ") .field(INT, "length", "id string") - .field(INT_ARRAY, "paint", "length", - "path encoded as floats"); + .field(INT_ARRAY, "paint", "length", "path encoded as floats"); } @Override diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java index 91352d914a99..13d5a49a584b 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java @@ -15,8 +15,8 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT_ARRAY; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT_ARRAY; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -24,6 +24,7 @@ import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.VariableSupport; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.Arrays; import java.util.List; @@ -46,8 +47,7 @@ public class PathData implements Operation, VariableSupport { for (int i = 0; i < mFloatPath.length; i++) { float v = mFloatPath[i]; if (Utils.isVariable(v)) { - mOutputPath[i] = (Float.isNaN(v)) - ? context.getFloat(Utils.idFromNan(v)) : v; + mOutputPath[i] = Float.isNaN(v) ? context.getFloat(Utils.idFromNan(v)) : v; } else { mOutputPath[i] = v; } @@ -79,30 +79,15 @@ public class PathData implements Operation, VariableSupport { } /** - * public float[] getFloatPath(PaintContext context) { - * float[] ret = mRetFloats; // Assume retFloats is declared elsewhere - * if (ret == null) { - * return mFloatPath; // Assume floatPath is declared elsewhere - * } - * float[] localRef = mRef; // Assume ref is of type Float[] - * if (localRef == null) { - * for (int i = 0; i < mFloatPath.length; i++) { - * ret[i] = mFloatPath[i]; - * } - * } else { - * for (int i = 0; i < mFloatPath.length; i++) { - * float lr = localRef[i]; - * if (Float.isNaN(lr)) { - * ret[i] = Utils.getActualValue(lr); - * } else { - * ret[i] = mFloatPath[i]; - * } - * } - * } - * return ret; - * } + * public float[] getFloatPath(PaintContext context) { float[] ret = mRetFloats; // Assume + * retFloats is declared elsewhere if (ret == null) { return mFloatPath; // Assume floatPath is + * declared elsewhere } float[] localRef = mRef; // Assume ref is of type Float[] if (localRef + * == null) { for (int i = 0; i < mFloatPath.length; i++) { ret[i] = mFloatPath[i]; } } else { + * for (int i = 0; i < mFloatPath.length; i++) { float lr = localRef[i]; if (Float.isNaN(lr)) { + * ret[i] = Utils.getActualValue(lr); } else { ret[i] = mFloatPath[i]; } } } return ret; } */ public static final int MOVE = 10; + public static final int LINE = 11; public static final int QUADRATIC = 12; public static final int CONIC = 13; @@ -145,17 +130,13 @@ public class PathData implements Operation, VariableSupport { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Data Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Data Operations", OP_CODE, CLASS_NAME) .description("Encode a Path ") - .field(INT, "id", "id string") + .field(DocumentedOperation.INT, "id", "id string") .field(INT, "length", "id string") - .field(FLOAT_ARRAY, "pathData", "length", - "path encoded as floats"); + .field(FLOAT_ARRAY, "pathData", "length", "path encoded as floats"); } - public static String pathString(float[] path) { if (path == null) { return "null"; @@ -208,5 +189,4 @@ public class PathData implements Operation, VariableSupport { public void apply(RemoteContext context) { context.loadPathData(mInstanceId, mOutputPath); } - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java index 33f997fc7266..4a8f5324b74e 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java @@ -15,22 +15,21 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.RemoteComposeOperation; import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; /** * Describe some basic information for a RemoteCompose document - * <p> - * It encodes the version of the document (following semantic versioning) as well - * as the dimensions of the document in pixels. + * + * <p>It encodes the version of the document (following semantic versioning) as well as the + * dimensions of the document in pixels. */ public class RootContentBehavior implements RemoteComposeOperation { private static final int OP_CODE = Operations.ROOT_CONTENT_BEHAVIOR; @@ -67,8 +66,8 @@ public class RootContentBehavior implements RemoteComposeOperation { public static final int ALIGNMENT_START = 16; public static final int ALIGNMENT_HORIZONTAL_CENTER = 32; public static final int ALIGNMENT_END = 64; - public static final int ALIGNMENT_CENTER = ALIGNMENT_HORIZONTAL_CENTER - + ALIGNMENT_VERTICAL_CENTER; + public static final int ALIGNMENT_CENTER = + ALIGNMENT_HORIZONTAL_CENTER + ALIGNMENT_VERTICAL_CENTER; /////////////////////////////////////////////////////////////////////////////////////////////// // Layout mode @@ -98,21 +97,14 @@ public class RootContentBehavior implements RemoteComposeOperation { /** * Sets the way the player handles the content * - * @param scroll set the horizontal behavior (NONE|SCROLL_HORIZONTAL|SCROLL_VERTICAL) + * @param scroll set the horizontal behavior (NONE|SCROLL_HORIZONTAL|SCROLL_VERTICAL) * @param alignment set the alignment of the content (TOP|CENTER|BOTTOM|START|END) - * @param sizing set the type of sizing for the content (NONE|SIZING_LAYOUT|SIZING_SCALE) - * @param mode set the mode of sizing, either LAYOUT modes or SCALE modes - * the LAYOUT modes are: - * - LAYOUT_MATCH_PARENT - * - LAYOUT_WRAP_CONTENT - * or adding an horizontal mode and a vertical mode: - * - LAYOUT_HORIZONTAL_MATCH_PARENT - * - LAYOUT_HORIZONTAL_WRAP_CONTENT - * - LAYOUT_HORIZONTAL_FIXED - * - LAYOUT_VERTICAL_MATCH_PARENT - * - LAYOUT_VERTICAL_WRAP_CONTENT - * - LAYOUT_VERTICAL_FIXED - * The LAYOUT_*_FIXED modes will use the intrinsic document size + * @param sizing set the type of sizing for the content (NONE|SIZING_LAYOUT|SIZING_SCALE) + * @param mode set the mode of sizing, either LAYOUT modes or SCALE modes the LAYOUT modes are: + * - LAYOUT_MATCH_PARENT - LAYOUT_WRAP_CONTENT or adding an horizontal mode and a vertical + * mode: - LAYOUT_HORIZONTAL_MATCH_PARENT - LAYOUT_HORIZONTAL_WRAP_CONTENT - + * LAYOUT_HORIZONTAL_FIXED - LAYOUT_VERTICAL_MATCH_PARENT - LAYOUT_VERTICAL_WRAP_CONTENT - + * LAYOUT_VERTICAL_FIXED The LAYOUT_*_FIXED modes will use the intrinsic document size */ public RootContentBehavior(int scroll, int alignment, int sizing, int mode) { switch (scroll) { @@ -121,41 +113,43 @@ public class RootContentBehavior implements RemoteComposeOperation { case SCROLL_VERTICAL: mScroll = scroll; break; - default: { + default: System.out.println(TAG + "incorrect scroll value " + scroll); - } } if (alignment == ALIGNMENT_CENTER) { mAlignment = alignment; } else { int horizontalContentAlignment = alignment & 0xF0; int verticalContentAlignment = alignment & 0xF; - boolean validHorizontalAlignment = horizontalContentAlignment == ALIGNMENT_START - || horizontalContentAlignment == ALIGNMENT_HORIZONTAL_CENTER - || horizontalContentAlignment == ALIGNMENT_END; - boolean validVerticalAlignment = verticalContentAlignment == ALIGNMENT_TOP - || verticalContentAlignment == ALIGNMENT_VERTICAL_CENTER - || verticalContentAlignment == ALIGNMENT_BOTTOM; + boolean validHorizontalAlignment = + horizontalContentAlignment == ALIGNMENT_START + || horizontalContentAlignment == ALIGNMENT_HORIZONTAL_CENTER + || horizontalContentAlignment == ALIGNMENT_END; + boolean validVerticalAlignment = + verticalContentAlignment == ALIGNMENT_TOP + || verticalContentAlignment == ALIGNMENT_VERTICAL_CENTER + || verticalContentAlignment == ALIGNMENT_BOTTOM; if (validHorizontalAlignment && validVerticalAlignment) { mAlignment = alignment; } else { - System.out.println(TAG + "incorrect alignment " - + " h: " + horizontalContentAlignment - + " v: " + verticalContentAlignment); + System.out.println( + TAG + + "incorrect alignment " + + " h: " + + horizontalContentAlignment + + " v: " + + verticalContentAlignment); } } switch (sizing) { - case SIZING_LAYOUT: { + case SIZING_LAYOUT: System.out.println(TAG + "sizing_layout is not yet supported"); - } - break; - case SIZING_SCALE: { + break; + case SIZING_SCALE: mSizing = sizing; - } - break; - default: { + break; + default: System.out.println(TAG + "incorrect sizing value " + sizing); - } } if (mSizing == SIZING_LAYOUT) { if (mode != NONE) { @@ -171,9 +165,8 @@ public class RootContentBehavior implements RemoteComposeOperation { case SCALE_FILL_BOUNDS: mMode = mode; break; - default: { + default: System.out.println(TAG + "incorrect mode for scale sizing, mode: " + mode); - } } } } @@ -185,8 +178,12 @@ public class RootContentBehavior implements RemoteComposeOperation { @Override public String toString() { - return "ROOT_CONTENT_BEHAVIOR scroll: " + mScroll - + " sizing: " + mSizing + " mode: " + mMode; + return "ROOT_CONTENT_BEHAVIOR scroll: " + + mScroll + + " sizing: " + + mSizing + + " mode: " + + mMode; } @Override @@ -199,12 +196,10 @@ public class RootContentBehavior implements RemoteComposeOperation { return toString(); } - public static String name() { return CLASS_NAME; } - public static int id() { return OP_CODE; } @@ -217,7 +212,6 @@ public class RootContentBehavior implements RemoteComposeOperation { buffer.writeInt(mode); } - public static void read(WireBuffer buffer, List<Operation> operations) { int scroll = buffer.readInt(); int alignment = buffer.readInt(); @@ -228,30 +222,27 @@ public class RootContentBehavior implements RemoteComposeOperation { operations.add(rootContentBehavior); } - public static void documentation(DocumentationBuilder doc) { - doc.operation("Protocol Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Protocol Operations", OP_CODE, CLASS_NAME) .description("Describes the behaviour of the root") - .field(INT, "scroll", "scroll") + .field(DocumentedOperation.INT, "scroll", "scroll") .possibleValues("SCROLL_HORIZONTAL", SCROLL_HORIZONTAL) .possibleValues("SCROLL_VERTICAL", SCROLL_VERTICAL) - .field(INT, "alignment", "alignment") + .field(DocumentedOperation.INT, "alignment", "alignment") .possibleValues("ALIGNMENT_TOP", ALIGNMENT_TOP) .possibleValues("ALIGNMENT_VERTICAL_CENTER", ALIGNMENT_VERTICAL_CENTER) .possibleValues("ALIGNMENT_BOTTOM", ALIGNMENT_BOTTOM) .possibleValues("ALIGNMENT_START", ALIGNMENT_START) .possibleValues("ALIGNMENT_START", ALIGNMENT_START) .possibleValues("ALIGNMENT_END", ALIGNMENT_END) - .field(INT, "sizing", "sizing") + .field(DocumentedOperation.INT, "sizing", "sizing") .possibleValues("SCALE_INSIDE", SCALE_INSIDE) .possibleValues("SCALE_FIT", SCALE_FIT) .possibleValues("SCALE_FILL_WIDTH", SCALE_FILL_WIDTH) .possibleValues("SCALE_FILL_HEIGHT", SCALE_FILL_HEIGHT) .possibleValues("SCALE_CROP", SCALE_CROP) .possibleValues("SCALE_FILL_BOUNDS", SCALE_FILL_BOUNDS) - .field(INT, "mode", "mode") + .field(DocumentedOperation.INT, "mode", "mode") .possibleValues("LAYOUT_HORIZONTAL_MATCH_PARENT", LAYOUT_HORIZONTAL_MATCH_PARENT) .possibleValues("LAYOUT_HORIZONTAL_WRAP_CONTENT", LAYOUT_HORIZONTAL_WRAP_CONTENT) .possibleValues("LAYOUT_HORIZONTAL_FIXED", LAYOUT_HORIZONTAL_FIXED) @@ -260,6 +251,5 @@ public class RootContentBehavior implements RemoteComposeOperation { .possibleValues("LAYOUT_VERTICAL_FIXED", LAYOUT_VERTICAL_FIXED) .possibleValues("LAYOUT_MATCH_PARENT", LAYOUT_MATCH_PARENT) .possibleValues("LAYOUT_WRAP_CONTENT", LAYOUT_WRAP_CONTENT); - } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java index e1533eefae53..bff902926fd3 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java @@ -15,20 +15,17 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; - import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.RemoteComposeOperation; import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; -/** - * Describe a content description for the document - */ +/** Describe a content description for the document */ public class RootContentDescription implements RemoteComposeOperation { private static final int OP_CODE = Operations.ROOT_CONTENT_DESCRIPTION; private static final String CLASS_NAME = "RootContentDescription"; @@ -82,13 +79,9 @@ public class RootContentDescription implements RemoteComposeOperation { operations.add(header); } - public static void documentation(DocumentationBuilder doc) { - doc.operation("Protocol Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Protocol Operations", OP_CODE, CLASS_NAME) .description("Content description of root") - .field(INT, "id", "id of Int"); - + .field(DocumentedOperation.INT, "id", "id of Int"); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ShaderData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ShaderData.java index c4dde6e0d358..7ec7879bf8b2 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/ShaderData.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ShaderData.java @@ -15,12 +15,12 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.BYTE; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT_ARRAY; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT_ARRAY; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.SHORT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.UTF8; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.BYTE; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT_ARRAY; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT_ARRAY; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.SHORT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.UTF8; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -28,15 +28,15 @@ import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.VariableSupport; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.Arrays; import java.util.HashMap; import java.util.List; /** - * Operation to deal with bitmap data - * On getting an Image during a draw call the bitmap is compressed and saved - * in playback the image is decompressed + * Operation to deal with bitmap data On getting an Image during a draw call the bitmap is + * compressed and saved in playback the image is decompressed */ public class ShaderData implements Operation, VariableSupport { private static final int OP_CODE = Operations.DATA_SHADER; @@ -48,11 +48,12 @@ public class ShaderData implements Operation, VariableSupport { HashMap<String, int[]> mUniformIntMap = null; HashMap<String, Integer> mUniformBitmapMap = null; - public ShaderData(int shaderID, - int shaderTextId, - HashMap<String, float[]> floatMap, - HashMap<String, int[]> intMap, - HashMap<String, Integer> bitmapMap) { + public ShaderData( + int shaderID, + int shaderTextId, + HashMap<String, float[]> floatMap, + HashMap<String, int[]> intMap, + HashMap<String, Integer> bitmapMap) { mShaderID = shaderID; mShaderTextId = shaderTextId; if (floatMap != null) { @@ -77,7 +78,6 @@ public class ShaderData implements Operation, VariableSupport { mUniformBitmapMap.put(name, bitmapMap.get(name)); } } - } public int getShaderTextId() { @@ -107,7 +107,7 @@ public class ShaderData implements Operation, VariableSupport { /** * get the name of all know uniform integers * - * @return Name of all integer uniforms + * @return Name of all integer uniforms */ public String[] getUniformIntegerNames() { if (mUniformIntMap == null) return new String[0]; @@ -146,8 +146,13 @@ public class ShaderData implements Operation, VariableSupport { @Override public void write(WireBuffer buffer) { - apply(buffer, mShaderID, mShaderTextId, - mUniformFloatMap, mUniformIntMap, mUniformBitmapMap); + apply( + buffer, + mShaderID, + mShaderTextId, + mUniformFloatMap, + mUniformIntMap, + mUniformBitmapMap); } @Override @@ -202,10 +207,13 @@ public class ShaderData implements Operation, VariableSupport { * @param intMap the map of int uniforms * @param bitmapMap the map of bitmap uniforms */ - public static void apply(WireBuffer buffer, int shaderID, int shaderTextId, - HashMap<String, float[]> floatMap, - HashMap<String, int[]> intMap, - HashMap<String, Integer> bitmapMap) { + public static void apply( + WireBuffer buffer, + int shaderID, + int shaderTextId, + HashMap<String, float[]> floatMap, + HashMap<String, int[]> intMap, + HashMap<String, Integer> bitmapMap) { buffer.start(OP_CODE); buffer.writeInt(shaderID); @@ -248,7 +256,6 @@ public class ShaderData implements Operation, VariableSupport { } } - public static void read(WireBuffer buffer, List<Operation> operations) { int shaderID = buffer.readInt(); int shaderTextId = buffer.readInt(); @@ -298,16 +305,13 @@ public class ShaderData implements Operation, VariableSupport { bitmapMap.put(name, val); } } - operations.add(new ShaderData(shaderID, shaderTextId, - floatMap, intMap, bitmapMap)); + operations.add(new ShaderData(shaderID, shaderTextId, floatMap, intMap, bitmapMap)); } public static void documentation(DocumentationBuilder doc) { - doc.operation("Data Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Data Operations", OP_CODE, CLASS_NAME) .description("Shader") - .field(INT, "shaderID", "id of shader") + .field(DocumentedOperation.INT, "shaderID", "id of shader") .field(BYTE, " floatSize", "number of float uniforms") .field(BYTE, " intSize", "number of int uniform") .field(SHORT, " intSize", "number of int uniform") @@ -319,7 +323,6 @@ public class ShaderData implements Operation, VariableSupport { .field(INT_ARRAY, "VALUE", "int uniform (max 4)") .field(UTF8, "bitmapName", "name of bitmap") .field(INT, "VALUE", "id of bitmap"); - } @Override diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextData.java index b49cb7664495..638324950f88 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextData.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextData.java @@ -15,8 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.UTF8; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.UTF8; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -24,13 +23,12 @@ import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.SerializableToString; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer; import java.util.List; -/** - * Operation to deal with Text data - */ +/** Operation to deal with Text data */ public class TextData implements Operation, SerializableToString { private static final int OP_CODE = Operations.DATA_TEXT; private static final String CLASS_NAME = "TextData"; @@ -50,15 +48,13 @@ public class TextData implements Operation, SerializableToString { @Override public String toString() { - return "TextData[" + mTextId + "] = \"" - + Utils.trimString(mText, 10) + "\""; + return "TextData[" + mTextId + "] = \"" + Utils.trimString(mText, 10) + "\""; } public static String name() { return CLASS_NAME; } - public static int id() { return OP_CODE; } @@ -69,7 +65,6 @@ public class TextData implements Operation, SerializableToString { buffer.writeUTF8(text); } - public static void read(WireBuffer buffer, List<Operation> operations) { int textId = buffer.readInt(); @@ -77,18 +72,13 @@ public class TextData implements Operation, SerializableToString { operations.add(new TextData(textId, text)); } - public static void documentation(DocumentationBuilder doc) { - doc.operation("Data Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Data Operations", OP_CODE, CLASS_NAME) .description("Encode a string ") - .field(INT, "id", "id string") - .field(UTF8, "text", - "encode text as a string"); + .field(DocumentedOperation.INT, "id", "id string") + .field(UTF8, "text", "encode text as a string"); } - @Override public void apply(RemoteContext context) { context.loadText(mTextId, mText); @@ -101,8 +91,7 @@ public class TextData implements Operation, SerializableToString { @Override public void serializeToString(int indent, StringSerializer serializer) { - serializer.append(indent, getSerializedName() + "<" + mTextId - + "> = \"" + mText + "\""); + serializer.append(indent, getSerializedName() + "<" + mTextId + "> = \"" + mText + "\""); } private String getSerializedName() { diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextFromFloat.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextFromFloat.java index 8f235dcca28c..0d966d10384a 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextFromFloat.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextFromFloat.java @@ -15,8 +15,8 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.SHORT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.SHORT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -24,14 +24,15 @@ import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.VariableSupport; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import com.android.internal.widget.remotecompose.core.operations.utilities.StringUtils; import java.util.List; /** - * Operation convert floats to text - * This command is structured [command][textID][before,after][flags] - * before and after define number of digits before and after the decimal point + * Operation convert floats to text This command is structured + * [command][textID][before,after][flags] before and after define number of digits before and after + * the decimal point */ public class TextFromFloat implements Operation, VariableSupport { private static final int OP_CODE = Operations.TEXT_FROM_FLOAT; @@ -49,12 +50,12 @@ public class TextFromFloat implements Operation, VariableSupport { public static final int PAD_AFTER_SPACE = 0; // pad past point with space public static final int PAD_AFTER_NONE = 1; // do not pad past last digit public static final int PAD_AFTER_ZERO = 3; // pad with 0 past last digit - public static final int PAD_PRE_SPACE = 0; // pad before number with spaces - public static final int PAD_PRE_NONE = 4; // pad before number with 0s - public static final int PAD_PRE_ZERO = 12; // do not pad before number + public static final int PAD_PRE_SPACE = 0; // pad before number with spaces + public static final int PAD_PRE_NONE = 4; // pad before number with 0s + public static final int PAD_PRE_ZERO = 12; // do not pad before number - public TextFromFloat(int textId, float value, short digitsBefore, - short digitsAfter, int flags) { + public TextFromFloat( + int textId, float value, short digitsBefore, short digitsAfter, int flags) { this.mTextId = textId; this.mValue = value; this.mDigitsAfter = digitsAfter; @@ -87,17 +88,23 @@ public class TextFromFloat implements Operation, VariableSupport { @Override public void write(WireBuffer buffer) { - apply(buffer, mTextId, mValue, mDigitsAfter, mDigitsBefore, mFlags); + apply(buffer, mTextId, mValue, mDigitsBefore, mDigitsAfter, mFlags); } @Override public String toString() { - return "TextFromFloat[" + mTextId + "] = " - + Utils.floatToString(mValue) + " " + mDigitsBefore - + "." + mDigitsAfter + " " + mFlags; + return "TextFromFloat[" + + mTextId + + "] = " + + Utils.floatToString(mValue) + + " " + + mDigitsBefore + + "." + + mDigitsAfter + + " " + + mFlags; } - @Override public void updateVariables(RemoteContext context) { if (Float.isNaN(mValue)) { @@ -123,22 +130,25 @@ public class TextFromFloat implements Operation, VariableSupport { /** * Writes out the operation to the buffer * - * @param buffer buffer to write to - * @param textId the id of the output text - * @param value the float value to be turned into strings + * @param buffer buffer to write to + * @param textId the id of the output text + * @param value the float value to be turned into strings * @param digitsBefore the digits before the decimal point - * @param digitsAfter the digits after the decimal point - * @param flags flags that control if and how to fill the empty spots + * @param digitsAfter the digits after the decimal point + * @param flags flags that control if and how to fill the empty spots */ - public static void apply(WireBuffer buffer, int textId, - float value, short digitsBefore, - short digitsAfter, int flags) { + public static void apply( + WireBuffer buffer, + int textId, + float value, + short digitsBefore, + short digitsAfter, + int flags) { buffer.start(OP_CODE); buffer.writeInt(textId); buffer.writeFloat(value); buffer.writeInt((digitsBefore << 16) | digitsAfter); buffer.writeInt(flags); - } public static void read(WireBuffer buffer, List<Operation> operations) { @@ -153,27 +163,19 @@ public class TextFromFloat implements Operation, VariableSupport { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Expressions Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Expressions Operations", OP_CODE, CLASS_NAME) .description("Draw text along path object") - .field(INT, "textId", - "id of the text generated") - .field(INT, "value", - "Value to add") - .field(SHORT, "prePoint", - "digits before the decimal point") - .field(SHORT, "pstPoint", - "digit after the decimal point") + .field(DocumentedOperation.INT, "textId", "id of the text generated") + .field(INT, "value", "Value to add") + .field(SHORT, "prePoint", "digits before the decimal point") + .field(SHORT, "pstPoint", "digit after the decimal point") .field(INT, "flags", "options on padding"); } - @Override public void apply(RemoteContext context) { float v = mOutValue; - String s = StringUtils.floatToString(v, mDigitsBefore, - mDigitsAfter, mPre, mAfter); + String s = StringUtils.floatToString(v, mDigitsBefore, mDigitsAfter, mPre, mAfter); context.loadText(mTextId, s); } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLength.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLength.java new file mode 100644 index 000000000000..e148fb9849fc --- /dev/null +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLength.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.widget.remotecompose.core.operations; + +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; + +import com.android.internal.widget.remotecompose.core.Operation; +import com.android.internal.widget.remotecompose.core.Operations; +import com.android.internal.widget.remotecompose.core.RemoteContext; +import com.android.internal.widget.remotecompose.core.WireBuffer; +import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; + +import java.util.List; + +/** Operation to measure the length of the text */ +public class TextLength implements Operation { + private static final int OP_CODE = Operations.TEXT_LENGTH; + private static final String CLASS_NAME = "TextLength"; + public int mLengthId; + public int mTextId; + + public TextLength(int lengthId, int textId) { + this.mLengthId = lengthId; + this.mTextId = textId; + } + + @Override + public void write(WireBuffer buffer) { + apply(buffer, mLengthId, mTextId); + } + + @Override + public String toString() { + return CLASS_NAME + "[" + mLengthId + "] = " + mTextId; + } + + public static String name() { + return CLASS_NAME; + } + + public static int id() { + return OP_CODE; + } + + /** + * Writes out the operation to the buffer + * + * @param buffer write command to this buffer + * @param lengthId the id to output + * @param textId the id of the text to measure + */ + public static void apply(WireBuffer buffer, int lengthId, int textId) { + buffer.start(OP_CODE); + buffer.writeInt(lengthId); + buffer.writeInt(textId); + } + + public static void read(WireBuffer buffer, List<Operation> operations) { + int lengthId = buffer.readInt(); + int textId = buffer.readInt(); + operations.add(new TextLength(lengthId, textId)); + } + + public static void documentation(DocumentationBuilder doc) { + doc.operation("Expressions Operations", OP_CODE, CLASS_NAME) + .description("get the length of the text and store in float table") + .field(INT, "id", "id of float length") + .field(INT, "value", "index of text"); + } + + @Override + public void apply(RemoteContext context) { + context.loadFloat(mLengthId, context.getText(mTextId).length()); + } + + @Override + public String deepToString(String indent) { + return indent + toString(); + } +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookup.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookup.java new file mode 100644 index 000000000000..b04d698fa36c --- /dev/null +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookup.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.widget.remotecompose.core.operations; + +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; + +import com.android.internal.widget.remotecompose.core.Operation; +import com.android.internal.widget.remotecompose.core.Operations; +import com.android.internal.widget.remotecompose.core.RemoteContext; +import com.android.internal.widget.remotecompose.core.VariableSupport; +import com.android.internal.widget.remotecompose.core.WireBuffer; +import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; + +import java.util.List; + +/** + * Operation convert floats to text This command is structured + * [command][textID][before,after][flags] before and after define number of digits before and after + * the decimal point + */ +public class TextLookup implements Operation, VariableSupport { + private static final int OP_CODE = Operations.TEXT_LOOKUP; + private static final String CLASS_NAME = "TextFromFloat"; + public int mTextId; + public int mDataSetId; + public float mOutIndex, mIndex; + + public static final int MAX_STRING_SIZE = 4000; + + public TextLookup(int textId, int dataSetId, float index) { + this.mTextId = textId; + this.mDataSetId = dataSetId; + this.mOutIndex = this.mIndex = index; + } + + @Override + public void write(WireBuffer buffer) { + apply(buffer, mTextId, mDataSetId, mIndex); + } + + @Override + public String toString() { + return "TextLookup[" + + Utils.idString(mTextId) + + "] = " + + Utils.idString(mDataSetId) + + " " + + Utils.floatToString(mIndex); + } + + @Override + public void updateVariables(RemoteContext context) { + if (Float.isNaN(mIndex)) { + mOutIndex = context.getFloat(Utils.idFromNan(mIndex)); + } + } + + @Override + public void registerListening(RemoteContext context) { + if (Float.isNaN(mIndex)) { + context.listensTo(Utils.idFromNan(mIndex), this); + } + } + + public static String name() { + return CLASS_NAME; + } + + public static int id() { + return OP_CODE; + } + + /** + * Writes out the operation to the buffer + * + * @param buffer buffer to write to + * @param textId the id of the output text + * @param dataSet float pointer to the array/list to turn int a string + * @param index index of element to return + */ + public static void apply(WireBuffer buffer, int textId, int dataSet, float index) { + buffer.start(OP_CODE); + buffer.writeInt(textId); + buffer.writeInt(dataSet); + buffer.writeFloat(index); + } + + public static void read(WireBuffer buffer, List<Operation> operations) { + int textId = buffer.readInt(); + int dataSetId = buffer.readInt(); + float index = buffer.readFloat(); + operations.add(new TextLookup(textId, dataSetId, index)); + } + + public static void documentation(DocumentationBuilder doc) { + doc.operation("Expressions Operations", OP_CODE, CLASS_NAME) + .description("Look an array and turn into a text object") + .field(INT, "textId", "id of the text generated") + .field(FLOAT, "dataSet", "float pointer to the array/list to turn int a string") + .field(FLOAT, "index", "index of element to return"); + } + + @Override + public void apply(RemoteContext context) { + int id = context.getCollectionsAccess().getId(mDataSetId, (int) mOutIndex); + context.loadText(mTextId, context.getText(id)); + } + + @Override + public String deepToString(String indent) { + return indent + toString(); + } +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookupInt.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookupInt.java new file mode 100644 index 000000000000..171bea249273 --- /dev/null +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookupInt.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.widget.remotecompose.core.operations; + +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; + +import com.android.internal.widget.remotecompose.core.Operation; +import com.android.internal.widget.remotecompose.core.Operations; +import com.android.internal.widget.remotecompose.core.RemoteContext; +import com.android.internal.widget.remotecompose.core.VariableSupport; +import com.android.internal.widget.remotecompose.core.WireBuffer; +import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; + +import java.util.List; + +/** Operation convert int index of a list to text */ +public class TextLookupInt implements Operation, VariableSupport { + private static final int OP_CODE = Operations.TEXT_LOOKUP_INT; + private static final String CLASS_NAME = "TextFromINT"; + public int mTextId; + public int mDataSetId; + public int mOutIndex; + public int mIndex; + + public static final int MAX_STRING_SIZE = 4000; + + public TextLookupInt(int textId, int dataSetId, int indexId) { + this.mTextId = textId; + this.mDataSetId = dataSetId; + this.mOutIndex = this.mIndex = indexId; + } + + @Override + public void write(WireBuffer buffer) { + apply(buffer, mTextId, mDataSetId, mIndex); + } + + @Override + public String toString() { + return "TextLookupInt[" + + Utils.idString(mTextId) + + "] = " + + Utils.idString(mDataSetId) + + " " + + mIndex; + } + + @Override + public void updateVariables(RemoteContext context) { + mOutIndex = context.getInteger(mIndex); + } + + @Override + public void registerListening(RemoteContext context) { + context.listensTo(mIndex, this); + } + + public static String name() { + return CLASS_NAME; + } + + public static int id() { + return OP_CODE; + } + + /** + * Writes out the operation to the buffer + * + * @param buffer buffer to write to + * @param textId the id of the output text + * @param dataSet float pointer to the array/list to turn int a string + * @param indexId index of element to return + */ + public static void apply(WireBuffer buffer, int textId, int dataSet, int indexId) { + buffer.start(OP_CODE); + buffer.writeInt(textId); + buffer.writeInt(dataSet); + buffer.writeInt(indexId); + } + + public static void read(WireBuffer buffer, List<Operation> operations) { + int textId = buffer.readInt(); + int dataSetId = buffer.readInt(); + int indexId = buffer.readInt(); + operations.add(new TextLookupInt(textId, dataSetId, indexId)); + } + + public static void documentation(DocumentationBuilder doc) { + doc.operation("Expressions Operations", OP_CODE, CLASS_NAME) + .description("Look up an array and turn into a text object") + .field(DocumentedOperation.INT, "textId", "id of the text generated") + .field(INT, "dataSetId", "id to the array/list to turn int a string") + .field(INT, "index", "index of the element to return"); + } + + @Override + public void apply(RemoteContext context) { + int id = context.getCollectionsAccess().getId(mDataSetId, (int) mOutIndex); + context.loadText(mTextId, context.getText(id)); + } + + @Override + public String deepToString(String indent) { + return indent + toString(); + } +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextMeasure.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextMeasure.java new file mode 100644 index 000000000000..0281d6980e0f --- /dev/null +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextMeasure.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.widget.remotecompose.core.operations; + +import static com.android.internal.widget.remotecompose.core.PaintContext.TEXT_MEASURE_FONT_HEIGHT; +import static com.android.internal.widget.remotecompose.core.PaintContext.TEXT_MEASURE_MONOSPACE_WIDTH; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; + +import com.android.internal.widget.remotecompose.core.Operation; +import com.android.internal.widget.remotecompose.core.Operations; +import com.android.internal.widget.remotecompose.core.PaintContext; +import com.android.internal.widget.remotecompose.core.PaintOperation; +import com.android.internal.widget.remotecompose.core.WireBuffer; +import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; + +import java.util.List; + +/** Operation to Measure Text data */ +public class TextMeasure extends PaintOperation { + private static final int OP_CODE = Operations.TEXT_MEASURE; + private static final String CLASS_NAME = "TextMeasure"; + public int mId; + public int mTextId; + public int mType; + + public static final int MEASURE_WIDTH = 0; + public static final int MEASURE_HEIGHT = 1; + public static final int MEASURE_LEFT = 2; + public static final int MEASURE_RIGHT = 3; + public static final int MEASURE_TOP = 4; + public static final int MEASURE_BOTTOM = 5; + + /** a << 8 shifted {@link PaintContext#getTextBounds} */ + public static final int MEASURE_MONOSPACE_FLAG = TEXT_MEASURE_MONOSPACE_WIDTH << 8; + + public static final int MEASURE_MAX_HEIGHT_FLAG = TEXT_MEASURE_FONT_HEIGHT << 8; + + public TextMeasure(int id, int textId, int type) { + this.mId = id; + this.mTextId = textId; + this.mType = type; + } + + @Override + public void write(WireBuffer buffer) { + apply(buffer, mId, mTextId, mType); + } + + @Override + public String toString() { + return "FloatConstant[" + mId + "] = " + mTextId + " " + mType; + } + + public static String name() { + return CLASS_NAME; + } + + public static int id() { + return OP_CODE; + } + + /** + * Writes out the operation to the buffer + * + * @param buffer write command to this buffer + * @param id the id + * @param textId the id + * @param type the value of the float + */ + public static void apply(WireBuffer buffer, int id, int textId, int type) { + buffer.start(OP_CODE); + buffer.writeInt(id); + buffer.writeInt(textId); + buffer.writeInt(type); + } + + public static void read(WireBuffer buffer, List<Operation> operations) { + int id = buffer.readInt(); + int textId = buffer.readInt(); + int type = buffer.readInt(); + operations.add(new TextMeasure(id, textId, type)); + } + + public static void documentation(DocumentationBuilder doc) { + doc.operation("Expressions Operations", OP_CODE, CLASS_NAME) + .description("A float and its associated id") + .field(INT, "id", "id of float result of the measure") + .field(INT, "textId", "id of text") + .field(INT, "type", "type: measure 0=width,1=height"); + } + + @Override + public String deepToString(String indent) { + return indent + toString(); + } + + float[] mBounds = new float[4]; + + @Override + public void paint(PaintContext context) { + int val = mType & 255; + int flags = mType >> 8; + context.getTextBounds(mTextId, 0, -1, flags, mBounds); + switch (val) { + case MEASURE_WIDTH: + context.getContext().loadFloat(mId, mBounds[2] - mBounds[0]); + break; + case MEASURE_HEIGHT: + context.getContext().loadFloat(mId, mBounds[3] - mBounds[1]); + break; + case MEASURE_LEFT: + context.getContext().loadFloat(mId, mBounds[0]); + break; + case MEASURE_TOP: + context.getContext().loadFloat(mId, mBounds[1]); + break; + case MEASURE_RIGHT: + context.getContext().loadFloat(mId, mBounds[2]); + + break; + case MEASURE_BOTTOM: + context.getContext().loadFloat(mId, mBounds[3]); + + break; + } + } +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextMerge.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextMerge.java index dd7822308a94..78cc674a22e9 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextMerge.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextMerge.java @@ -15,19 +15,18 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; -/** - * Operation to deal with Text data - */ +/** Operation to deal with Text data */ public class TextMerge implements Operation { private static final int OP_CODE = Operations.TEXT_MERGE; private static final String CLASS_NAME = "TextMerge"; @@ -51,7 +50,6 @@ public class TextMerge implements Operation { return "TextMerge[" + mTextId + "] = [" + mSrcId1 + " ] + [ " + mSrcId2 + "]"; } - public static String name() { return CLASS_NAME; } @@ -84,16 +82,11 @@ public class TextMerge implements Operation { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Data Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Data Operations", OP_CODE, CLASS_NAME) .description("Merge two string into one") - .field(INT, "textId", - "id of the text") - .field(INT, "srcTextId1", - "id of the path") - .field(INT, "srcTextId1", - "x Shift of the text"); + .field(DocumentedOperation.INT, "textId", "id of the text") + .field(INT, "srcTextId1", "id of the path") + .field(INT, "srcTextId1", "x Shift of the text"); } @Override diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java b/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java index 52ae7fe5ab4b..845f25d0cd67 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java @@ -15,7 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -27,10 +27,9 @@ import com.android.internal.widget.remotecompose.core.documentation.Documentatio import java.util.List; /** - * Set a current theme, applied to the following operations in the document. - * This can be used to "tag" the subsequent operations to a given theme. On playback, - * we can then filter operations depending on the chosen theme. - * + * Set a current theme, applied to the following operations in the document. This can be used to + * "tag" the subsequent operations to a given theme. On playback, we can then filter operations + * depending on the chosen theme. */ public class Theme implements RemoteComposeOperation { private static final int OP_CODE = Operations.THEME; @@ -43,10 +42,7 @@ public class Theme implements RemoteComposeOperation { /** * we can then filter operations depending on the chosen theme. * - * @param theme the theme we are interested in: - * - Theme.UNSPECIFIED - * - Theme.DARK - * - Theme.LIGHT + * @param theme the theme we are interested in: - Theme.UNSPECIFIED - Theme.DARK - Theme.LIGHT */ public Theme(int theme) { this.mTheme = theme; @@ -76,7 +72,6 @@ public class Theme implements RemoteComposeOperation { return CLASS_NAME; } - public static int id() { return OP_CODE; } @@ -86,7 +81,6 @@ public class Theme implements RemoteComposeOperation { buffer.writeInt(theme); } - public static void read(WireBuffer buffer, List<Operation> operations) { int theme = buffer.readInt(); operations.add(new Theme(theme)); diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java b/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java index 6e858c7e0215..8ebb40cab806 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java @@ -15,9 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations; -/** - * Utilities to be used across all core operations - */ +/** Utilities to be used across all core operations */ public class Utils { public static float asNan(int v) { return Float.intBitsToFloat(v | -0x800000); @@ -28,8 +26,16 @@ public class Utils { return b & 0x3FFFFF; } + public static long idFromLong(long v) { + return v - 0x100000000L; + } + public static String idStringFromNan(float value) { int b = Float.floatToRawIntBits(value) & 0x3FFFFF; + return idString(b); + } + + public static String idString(int b) { return (b > 0xFFFFF) ? "A_" + (b & 0xFFFFF) : "" + b; } @@ -38,8 +44,7 @@ public class Utils { } /** - * trim a string to n characters if needing to trim - * end in "..." + * trim a string to n characters if needing to trim end in "..." * * @param str * @param n @@ -54,6 +59,7 @@ public class Utils { /** * print the id and the value of a float + * * @param idvalue * @param value * @return @@ -70,6 +76,7 @@ public class Utils { /** * Convert float to string but render nan id in brackets [n] + * * @param value * @return */ @@ -85,17 +92,25 @@ public class Utils { /** * Debugging util to print a message and include the file/line it came from + * * @param str */ public static void log(String str) { StackTraceElement s = new Throwable().getStackTrace()[1]; - System.out.println("(" + s.getFileName() - + ":" + s.getLineNumber() + "). " - + s.getMethodName() + "() " + str); + System.out.println( + "(" + + s.getFileName() + + ":" + + s.getLineNumber() + + "). " + + s.getMethodName() + + "() " + + str); } /** * Debugging util to print the stack + * * @param str * @param n */ @@ -104,8 +119,8 @@ public class Utils { for (int i = 1; i < n + 1; i++) { StackTraceElement s = st[i]; String space = new String(new char[i]).replace('\0', ' '); - System.out.println(space + "(" + s.getFileName() - + ":" + s.getLineNumber() + ")." + str); + System.out.println( + space + "(" + s.getFileName() + ":" + s.getLineNumber() + ")." + str); } } @@ -136,8 +151,8 @@ public class Utils { } /** - * Interpolate two colors. - * gamma corrected colors are interpolated in the form c1 * (1-t) + c2 * t + * Interpolate two colors. gamma corrected colors are interpolated in the form c1 * (1-t) + c2 * + * t * * @param c1 * @param c2 @@ -183,7 +198,6 @@ public class Utils { int outb = clamp((int) ((float) Math.pow(f_b, 1.0 / 2.2) * 255.0f)); int outa = clamp((int) (f_a * 255.0f)); - return (outa << 24 | outr << 16 | outg << 8 | outb); } @@ -205,9 +219,9 @@ public class Utils { /** * convert hue saturation and value to RGB * - * @param hue 0..1 + * @param hue 0..1 * @param saturation 0..1 0=on the gray scale - * @param value 0..1 0=black + * @param value 0..1 0=black * @return */ public static int hsvToRgb(float hue, float saturation, float value) { @@ -230,7 +244,6 @@ public class Utils { return 0XFF000000 | (t << 16) + (p << 8) + v; case 5: return 0XFF000000 | (v << 16) + (p << 8) + q; - } return 0; } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ActionOperation.java index 7588c794190d..bdc2a886ffd6 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ActionOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ActionOperation.java @@ -20,11 +20,10 @@ import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer; -/** - * Operations representing actions on the document - */ +/** Operations representing actions on the document */ public interface ActionOperation extends Operation { void serializeToString(int indent, StringSerializer serializer); - void runAction(RemoteContext context, CoreDocument document, - Component component, float x, float y); + + void runAction( + RemoteContext context, CoreDocument document, Component component, float x, float y); } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java index fd3501732e51..9d80d3cc40b0 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java @@ -15,7 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -24,13 +24,17 @@ import com.android.internal.widget.remotecompose.core.documentation.Documentatio import java.util.List; -/** - * Represents the content of a CanvasLayout (i.e. contains the canvas commands) - */ +/** Represents the content of a CanvasLayout (i.e. contains the canvas commands) */ public class CanvasContent extends Component implements ComponentStartOperation { - public CanvasContent(int componentId, float x, float y, - float width, float height, Component parent, int animationId) { + public CanvasContent( + int componentId, + float x, + float y, + float width, + float height, + Component parent, + int animationId) { super(parent, componentId, animationId, x, y, width, height); } @@ -42,7 +46,8 @@ public class CanvasContent extends Component implements ComponentStartOperation return Operations.LAYOUT_CANVAS_CONTENT; } - @Override protected String getSerializedName() { + @Override + protected String getSerializedName() { return "CANVAS_CONTENT"; } @@ -53,8 +58,7 @@ public class CanvasContent extends Component implements ComponentStartOperation public static void read(WireBuffer buffer, List<Operation> operations) { int componentId = buffer.readInt(); - operations.add(new CanvasContent( - componentId, 0, 0, 0, 0, null, -1)); + operations.add(new CanvasContent(componentId, 0, 0, 0, 0, null, -1)); } public static void documentation(DocumentationBuilder doc) { diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierEnd.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierEnd.java index f7c6ce24df14..fe726ac78791 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierEnd.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierEnd.java @@ -57,14 +57,14 @@ public class ClickModifierEnd implements Operation { buffer.start(id()); } - public static void read(WireBuffer buffer, List<Operation> operations) { operations.add(new ClickModifierEnd()); } public static void documentation(DocumentationBuilder doc) { doc.operation("Layout Operations", id(), name()) - .description("End tag for click modifiers. This operation marks the end" - + "of a click modifier"); + .description( + "End tag for click modifiers. This operation marks the end" + + "of a click modifier"); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java index d75f70b674c5..d5ff07df54cd 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java @@ -35,14 +35,11 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.easin import java.util.ArrayList; import java.util.List; -/** - * Represents a click modifier + actions - */ +/** Represents a click modifier + actions */ public class ClickModifierOperation extends PaintOperation implements ModifierOperation, DecoratorComponent { private static final int OP_CODE = Operations.MODIFIER_CLICK; - long mAnimateRippleStart = 0; float mAnimateRippleX = 0f; float mAnimateRippleY = 0f; @@ -60,6 +57,7 @@ public class ClickModifierOperation extends PaintOperation mAnimateRippleX = x; mAnimateRippleY = y; } + public ArrayList<Operation> mList = new ArrayList<>(); public ArrayList<Operation> getList() { @@ -107,14 +105,14 @@ public class ClickModifierOperation extends PaintOperation context.savePaint(); mPaint.reset(); - FloatAnimation anim1 = new FloatAnimation(Easing.CUBIC_STANDARD, 1f, - null, Float.NaN, Float.NaN); + FloatAnimation anim1 = + new FloatAnimation(Easing.CUBIC_STANDARD, 1f, null, Float.NaN, Float.NaN); anim1.setInitialValue(0f); anim1.setTargetValue(1f); float tween = anim1.get(progress); - FloatAnimation anim2 = new FloatAnimation(Easing.CUBIC_STANDARD, 0.5f, - null, Float.NaN, Float.NaN); + FloatAnimation anim2 = + new FloatAnimation(Easing.CUBIC_STANDARD, 0.5f, null, Float.NaN, Float.NaN); anim2.setInitialValue(0f); anim2.setTargetValue(1f); float tweenRadius = anim2.get(progress); @@ -149,8 +147,11 @@ public class ClickModifierOperation extends PaintOperation } @Override - public void onClick(RemoteContext context, CoreDocument document, - Component component, float x, float y) { + public void onClick( + RemoteContext context, CoreDocument document, Component component, float x, float y) { + if (!component.isVisible()) { + return; + } locationInWindow[0] = 0f; locationInWindow[1] = 0f; component.getLocationInWindow(locationInWindow); @@ -176,7 +177,8 @@ public class ClickModifierOperation extends PaintOperation public static void documentation(DocumentationBuilder doc) { doc.operation("Layout Operations", OP_CODE, name()) - .description("Click modifier. This operation contains" - + " a list of action executed on click"); + .description( + "Click modifier. This operation contains" + + " a list of action executed on click"); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java index fca0b1344a10..96dffca2042f 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java @@ -38,9 +38,7 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.Strin import java.util.ArrayList; import java.util.HashSet; -/** - * Generic Component class - */ +/** Generic Component class */ public class Component extends PaintOperation implements Measurable, SerializableToString { private static final boolean DEBUG = false; @@ -64,7 +62,6 @@ public class Component extends PaintOperation implements Measurable, Serializabl PaintBundle mPaint = new PaintBundle(); protected HashSet<ComponentValue> mComponentValues = new HashSet<>(); - public ArrayList<Operation> getList() { return mList; } @@ -120,27 +117,27 @@ public class Component extends PaintOperation implements Measurable, Serializabl */ private void updateComponentValues(RemoteContext context) { if (DEBUG) { - System.out.println("UPDATE COMPONENT VALUES (" - + mComponentValues.size() - + ") FOR " + mComponentId); + System.out.println( + "UPDATE COMPONENT VALUES (" + + mComponentValues.size() + + ") FOR " + + mComponentId); } for (ComponentValue v : mComponentValues) { switch (v.getType()) { - case ComponentValue.WIDTH: { + case ComponentValue.WIDTH: context.loadFloat(v.getValueId(), mWidth); if (DEBUG) { System.out.println("Updating WIDTH for " + mComponentId + " to " + mWidth); } - } - break; - case ComponentValue.HEIGHT: { + break; + case ComponentValue.HEIGHT: context.loadFloat(v.getValueId(), mHeight); if (DEBUG) { - System.out.println("Updating HEIGHT for " + mComponentId - + " to " + mHeight); + System.out.println( + "Updating HEIGHT for " + mComponentId + " to " + mHeight); } - } - break; + break; } } } @@ -153,8 +150,14 @@ public class Component extends PaintOperation implements Measurable, Serializabl mAnimationId = id; } - public Component(Component parent, int componentId, int animationId, - float x, float y, float width, float height) { + public Component( + Component parent, + int componentId, + int animationId, + float x, + float y, + float width, + float height) { this.mComponentId = componentId; this.mX = x; this.mY = y; @@ -164,15 +167,20 @@ public class Component extends PaintOperation implements Measurable, Serializabl this.mAnimationId = animationId; } - public Component(int componentId, float x, float y, float width, float height, - Component parent) { + public Component( + int componentId, float x, float y, float width, float height, Component parent) { this(parent, componentId, -1, x, y, width, height); } public Component(Component component) { - this(component.mParent, component.mComponentId, component.mAnimationId, - component.mX, component.mY, component.mWidth, component.mHeight - ); + this( + component.mParent, + component.mComponentId, + component.mAnimationId, + component.mX, + component.mY, + component.mWidth, + component.mHeight); mList.addAll(component.mList); finalizeCreation(); } @@ -199,8 +207,8 @@ public class Component extends PaintOperation implements Measurable, Serializabl } /** - * This traverses the component tree and make sure to - * update variables referencing the component dimensions as needed. + * This traverses the component tree and make sure to update variables referencing the component + * dimensions as needed. * * @param context the current context */ @@ -223,9 +231,9 @@ public class Component extends PaintOperation implements Measurable, Serializabl } public enum Visibility { + GONE, VISIBLE, - INVISIBLE, - GONE + INVISIBLE } public boolean isVisible() { @@ -239,15 +247,43 @@ public class Component extends PaintOperation implements Measurable, Serializabl } public void setVisibility(Visibility visibility) { - if (visibility != mVisibility) { + if (visibility != mVisibility || visibility != mScheduledVisibility) { mScheduledVisibility = visibility; invalidateMeasure(); } } @Override - public void measure(PaintContext context, float minWidth, float maxWidth, - float minHeight, float maxHeight, MeasurePass measure) { + public boolean suitableForTransition(Operation o) { + if (!(o instanceof Component)) { + return false; + } + if (mList.size() != ((Component) o).mList.size()) { + return false; + } + for (int i = 0; i < mList.size(); i++) { + Operation o1 = mList.get(i); + Operation o2 = ((Component) o).mList.get(i); + if (o1 instanceof Component && o2 instanceof Component) { + if (!((Component) o1).suitableForTransition(o2)) { + return false; + } + } + if (o1 instanceof PaintOperation && !((PaintOperation) o1).suitableForTransition(o2)) { + return false; + } + } + return true; + } + + @Override + public void measure( + PaintContext context, + float minWidth, + float maxWidth, + float minHeight, + float maxHeight, + MeasurePass measure) { ComponentMeasure m = measure.get(this); m.setW(mWidth); m.setH(mHeight); @@ -256,19 +292,34 @@ public class Component extends PaintOperation implements Measurable, Serializabl @Override public void layout(RemoteContext context, MeasurePass measure) { ComponentMeasure m = measure.get(this); - if (!mFirstLayout && context.isAnimationEnabled() + if (!mFirstLayout + && context.isAnimationEnabled() && !(this instanceof LayoutComponentContent)) { if (mAnimateMeasure == null) { - ComponentMeasure origin = new ComponentMeasure(mComponentId, - mX, mY, mWidth, mHeight, mVisibility); - ComponentMeasure target = new ComponentMeasure(mComponentId, - m.getX(), m.getY(), m.getW(), m.getH(), m.getVisibility()); - mAnimateMeasure = new AnimateMeasure(context.currentTime, this, - origin, target, - mAnimationSpec.getMotionDuration(), mAnimationSpec.getVisibilityDuration(), - mAnimationSpec.getEnterAnimation(), mAnimationSpec.getExitAnimation(), - mAnimationSpec.getMotionEasingType(), - mAnimationSpec.getVisibilityEasingType()); + ComponentMeasure origin = + new ComponentMeasure(mComponentId, mX, mY, mWidth, mHeight, mVisibility); + ComponentMeasure target = + new ComponentMeasure( + mComponentId, + m.getX(), + m.getY(), + m.getW(), + m.getH(), + m.getVisibility()); + if (!target.same(origin)) { + mAnimateMeasure = + new AnimateMeasure( + context.currentTime, + this, + origin, + target, + mAnimationSpec.getMotionDuration(), + mAnimationSpec.getVisibilityDuration(), + mAnimationSpec.getEnterAnimation(), + mAnimationSpec.getExitAnimation(), + mAnimationSpec.getMotionEasingType(), + mAnimationSpec.getVisibilityEasingType()); + } } else { mAnimateMeasure.updateTarget(m, context.currentTime); } @@ -323,19 +374,48 @@ public class Component extends PaintOperation implements Measurable, Serializabl @Override public String toString() { - return "COMPONENT(<" + mComponentId + "> " + getClass().getSimpleName() - + ") [" + mX + "," + mY + " - " + mWidth + " x " + mHeight + "] " + textContent() - + " Visibility (" + mVisibility + ") "; + return "COMPONENT(<" + + mComponentId + + "> " + + getClass().getSimpleName() + + ") [" + + mX + + "," + + mY + + " - " + + mWidth + + " x " + + mHeight + + "] " + + textContent() + + " Visibility (" + + mVisibility + + ") "; } protected String getSerializedName() { return "COMPONENT"; } + @Override public void serializeToString(int indent, StringSerializer serializer) { - serializer.append(indent, getSerializedName() + " [" + mComponentId - + ":" + mAnimationId + "] = " - + "[" + mX + ", " + mY + ", " + mWidth + ", " + mHeight + "] " + serializer.append( + indent, + getSerializedName() + + " [" + + mComponentId + + ":" + + mAnimationId + + "] = " + + "[" + + mX + + ", " + + mY + + ", " + + mWidth + + ", " + + mHeight + + "] " + mVisibility // + " [" + mNeedsMeasure + ", " + mNeedsRepaint + "]" ); @@ -346,9 +426,7 @@ public class Component extends PaintOperation implements Measurable, Serializabl // nothing } - /** - * Returns the top-level RootLayoutComponent - */ + /** Returns the top-level RootLayoutComponent */ public RootLayoutComponent getRoot() throws Exception { if (this instanceof RootLayoutComponent) { return (RootLayoutComponent) this; @@ -378,8 +456,8 @@ public class Component extends PaintOperation implements Measurable, Serializabl } /** - * Mark itself as needing to be remeasured, and walk back up the tree - * to mark each parents as well. + * Mark itself as needing to be remeasured, and walk back up the tree to mark each parents as + * well. */ public void invalidateMeasure() { needsRepaint(); @@ -411,7 +489,7 @@ public class Component extends PaintOperation implements Measurable, Serializabl public String textContent() { StringBuilder builder = new StringBuilder(); - for (Operation op : mList) { + for (Operation ignored : mList) { String letter = ""; // if (op instanceof DrawTextRun) { // letter = "[" + ((DrawTextRun) op).text + "]"; diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java index 71decd74a40b..c83ee487a8ea 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java @@ -61,14 +61,14 @@ public class ComponentEnd implements Operation { return 1 + 4 + 4 + 4; } - public static void read(WireBuffer buffer, List<Operation> operations) { operations.add(new ComponentEnd()); } public static void documentation(DocumentationBuilder doc) { doc.operation("Layout Operations", id(), name()) - .description("End tag for components / layouts. This operation marks the end" - + "of a component"); + .description( + "End tag for components / layouts. This operation marks the end" + + "of a component"); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java index 32ef5ce8b278..72cc9b6d2613 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java @@ -15,8 +15,8 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -75,8 +75,19 @@ public class ComponentStart implements ComponentStartOperation { @Override public String toString() { - return "COMPONENT_START (type " + mType + " " + typeDescription(mType) - + ") - (" + mX + ", " + mY + " - " + mWidth + " x " + mHeight + ")"; + return "COMPONENT_START (type " + + mType + + " " + + typeDescription(mType) + + ") - (" + + mX + + ", " + + mY + + " - " + + mWidth + + " x " + + mHeight + + ")"; } @Override @@ -149,8 +160,8 @@ public class ComponentStart implements ComponentStartOperation { return Operations.COMPONENT_START; } - public static void apply(WireBuffer buffer, int type, int componentId, - float width, float height) { + public static void apply( + WireBuffer buffer, int type, int componentId, float width, float height) { buffer.start(Operations.COMPONENT_START); buffer.writeInt(type); buffer.writeInt(componentId); @@ -172,8 +183,8 @@ public class ComponentStart implements ComponentStartOperation { public static void documentation(DocumentationBuilder doc) { doc.operation("Layout Operations", id(), name()) - .description("Basic component encapsulating draw commands." - + "This is not resizable.") + .description( + "Basic component encapsulating draw commands." + "This is not resizable.") .field(INT, "TYPE", "Type of components") .field(INT, "COMPONENT_ID", "unique id for this component") .field(FLOAT, "WIDTH", "width of the component") diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStartOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStartOperation.java index 67964efe816f..abf2356a3e49 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStartOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStartOperation.java @@ -17,5 +17,4 @@ package com.android.internal.widget.remotecompose.core.operations.layout; import com.android.internal.widget.remotecompose.core.Operation; -public interface ComponentStartOperation extends Operation { -} +public interface ComponentStartOperation extends Operation {} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/DecoratorComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/DecoratorComponent.java index 71bf83913cfb..314650fcd597 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/DecoratorComponent.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/DecoratorComponent.java @@ -24,6 +24,7 @@ import com.android.internal.widget.remotecompose.core.RemoteContext; */ public interface DecoratorComponent { void layout(RemoteContext context, float width, float height); - void onClick(RemoteContext context, CoreDocument document, - Component component, float x, float y); + + void onClick( + RemoteContext context, CoreDocument document, Component component, float x, float y); } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java index f4c213159882..8172502d092f 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java @@ -32,9 +32,7 @@ import com.android.internal.widget.remotecompose.core.operations.layout.modifier import java.util.ArrayList; -/** - * Component with modifiers and children - */ +/** Component with modifiers and children */ public class LayoutComponent extends Component { protected WidthModifierOperation mWidthModifier = null; @@ -54,8 +52,14 @@ public class LayoutComponent extends Component { protected ComponentModifiers mComponentModifiers = new ComponentModifiers(); protected ArrayList<Component> mChildrenComponents = new ArrayList<>(); - public LayoutComponent(Component parent, int componentId, int animationId, - float x, float y, float width, float height) { + public LayoutComponent( + Component parent, + int componentId, + int animationId, + float x, + float y, + float width, + float height) { super(parent, componentId, animationId, x, y, width, height); } @@ -91,7 +95,6 @@ public class LayoutComponent extends Component { return mPaddingBottom; } - public WidthModifierOperation getWidthModifier() { return mWidthModifier; } @@ -237,10 +240,7 @@ public class LayoutComponent extends Component { context.restore(); } - - /** - * Traverse the modifiers to compute indicated dimension - */ + /** Traverse the modifiers to compute indicated dimension */ public float computeModifierDefinedWidth() { float s = 0f; float e = 0f; @@ -283,9 +283,7 @@ public class LayoutComponent extends Component { return s + e; } - /** - * Traverse the modifiers to compute indicated dimension - */ + /** Traverse the modifiers to compute indicated dimension */ public float computeModifierDefinedHeight() { float t = 0f; float b = 0f; @@ -328,4 +326,7 @@ public class LayoutComponent extends Component { return t + b; } + public ArrayList<Component> getChildrenComponents() { + return mChildrenComponents; + } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java index 5b3b54d3c423..66fd053c4b5e 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java @@ -15,7 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -24,13 +24,17 @@ import com.android.internal.widget.remotecompose.core.documentation.Documentatio import java.util.List; -/** - * Represents the content of a LayoutComponent (i.e. the children components) - */ +/** Represents the content of a LayoutComponent (i.e. the children components) */ public class LayoutComponentContent extends Component implements ComponentStartOperation { - public LayoutComponentContent(int componentId, float x, float y, - float width, float height, Component parent, int animationId) { + public LayoutComponentContent( + int componentId, + float x, + float y, + float width, + float height, + Component parent, + int animationId) { super(parent, componentId, animationId, x, y, width, height); } @@ -42,7 +46,8 @@ public class LayoutComponentContent extends Component implements ComponentStartO return Operations.LAYOUT_CONTENT; } - @Override protected String getSerializedName() { + @Override + protected String getSerializedName() { return "CONTENT"; } @@ -53,16 +58,16 @@ public class LayoutComponentContent extends Component implements ComponentStartO public static void read(WireBuffer buffer, List<Operation> operations) { int componentId = buffer.readInt(); - operations.add(new LayoutComponentContent( - componentId, 0, 0, 0, 0, null, -1)); + operations.add(new LayoutComponentContent(componentId, 0, 0, 0, 0, null, -1)); } public static void documentation(DocumentationBuilder doc) { doc.operation("Layout Operations", id(), name()) .field(INT, "COMPONENT_ID", "unique id for this component") - .description("Container for components. BoxLayout, RowLayout and ColumnLayout " - + "expects a LayoutComponentContent as a child, encapsulating the " - + "components that needs to be laid out."); + .description( + "Container for components. BoxLayout, RowLayout and ColumnLayout " + + "expects a LayoutComponentContent as a child, encapsulating the " + + "components that needs to be laid out."); } @Override diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopEnd.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopEnd.java new file mode 100644 index 000000000000..3086d6aaa777 --- /dev/null +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopEnd.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.widget.remotecompose.core.operations.layout; + +import com.android.internal.widget.remotecompose.core.Operation; +import com.android.internal.widget.remotecompose.core.Operations; +import com.android.internal.widget.remotecompose.core.RemoteContext; +import com.android.internal.widget.remotecompose.core.WireBuffer; +import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; + +import java.util.List; + +public class LoopEnd implements Operation { + + @Override + public void write(WireBuffer buffer) { + apply(buffer); + } + + @Override + public String toString() { + return "LOOP_END"; + } + + @Override + public void apply(RemoteContext context) { + // nothing + } + + @Override + public String deepToString(String indent) { + return (indent != null ? indent : "") + toString(); + } + + public static String name() { + return "LoopEnd"; + } + + public static int id() { + return Operations.LOOP_END; + } + + public static void apply(WireBuffer buffer) { + buffer.start(id()); + } + + public static void read(WireBuffer buffer, List<Operation> operations) { + operations.add(new LoopEnd()); + } + + public static void documentation(DocumentationBuilder doc) { + doc.operation("Operations", id(), name()).description("End tag for loops"); + } +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java new file mode 100644 index 000000000000..691000810c20 --- /dev/null +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.widget.remotecompose.core.operations.layout; + +import com.android.internal.widget.remotecompose.core.Operation; +import com.android.internal.widget.remotecompose.core.Operations; +import com.android.internal.widget.remotecompose.core.PaintContext; +import com.android.internal.widget.remotecompose.core.PaintOperation; +import com.android.internal.widget.remotecompose.core.VariableSupport; +import com.android.internal.widget.remotecompose.core.WireBuffer; +import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; + +import java.util.ArrayList; +import java.util.List; + +/** Represents a loop of operations */ +public class LoopOperation extends PaintOperation { + private static final int OP_CODE = Operations.LOOP_START; + + public ArrayList<Operation> mList = new ArrayList<>(); + + int mIndexVariableId; + float mUntil = 12; + float mFrom = 0; + float mStep = 1; + + public LoopOperation(int count, int indexId) { + mUntil = count; + mIndexVariableId = indexId; + } + + public LoopOperation(float count, float from, float step, int indexId) { + mUntil = count; + mFrom = from; + mStep = step; + mIndexVariableId = indexId; + } + + public ArrayList<Operation> getList() { + return mList; + } + + @Override + public void write(WireBuffer buffer) { + apply(buffer, mUntil, mFrom, mStep, mIndexVariableId); + } + + @Override + public String toString() { + return "LoopOperation"; + } + + @Override + public String deepToString(String indent) { + return (indent != null ? indent : "") + toString(); + } + + @Override + public void paint(PaintContext context) { + if (mIndexVariableId == 0) { + for (float i = mFrom; i < mUntil; i += mStep) { + for (Operation op : mList) { + op.apply(context.getContext()); + } + } + } else { + for (float i = mFrom; i < mUntil; i += mStep) { + context.getContext().loadFloat(mIndexVariableId, i); + for (Operation op : mList) { + if (op instanceof VariableSupport) { + ((VariableSupport) op).updateVariables(context.getContext()); + } + op.apply(context.getContext()); + } + } + } + } + + public static String name() { + return "Loop"; + } + + public static void apply(WireBuffer buffer, float count, float from, float step, int indexId) { + buffer.start(OP_CODE); + buffer.writeFloat(count); + buffer.writeFloat(from); + buffer.writeFloat(step); + buffer.writeInt(indexId); + } + + public static void read(WireBuffer buffer, List<Operation> operations) { + float count = buffer.readFloat(); + float from = buffer.readFloat(); + float step = buffer.readFloat(); + int indexId = buffer.readInt(); + operations.add(new LoopOperation(count, from, step, indexId)); + } + + public static void documentation(DocumentationBuilder doc) { + doc.operation("Operations", OP_CODE, name()) + .description("Loop. This operation execute" + " a list of action in a loop"); + } +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java index bf1a4963d4c4..680bb0b064d1 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java @@ -15,7 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -32,38 +32,66 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.Strin import java.util.List; -/** - * Represents the root layout component. Entry point to the component tree layout/paint. - */ +/** Represents the root layout component. Entry point to the component tree layout/paint. */ public class RootLayoutComponent extends Component implements ComponentStartOperation { int mCurrentId = -1; - public RootLayoutComponent(int componentId, float x, float y, - float width, float height, Component parent, int animationId) { + public RootLayoutComponent( + int componentId, + float x, + float y, + float width, + float height, + Component parent, + int animationId) { super(parent, componentId, animationId, x, y, width, height); } - public RootLayoutComponent(int componentId, float x, float y, - float width, float height, Component parent) { + public RootLayoutComponent( + int componentId, float x, float y, float width, float height, Component parent) { super(parent, componentId, -1, x, y, width, height); } @Override public String toString() { - return "ROOT " + mComponentId + " (" + mX + ", " + mY + " - " - + mWidth + " x " + mHeight + ") " + mVisibility; + return "ROOT " + + mComponentId + + " (" + + mX + + ", " + + mY + + " - " + + mWidth + + " x " + + mHeight + + ") " + + mVisibility; } @Override public void serializeToString(int indent, StringSerializer serializer) { - serializer.append(indent, "ROOT [" + mComponentId + ":" + mAnimationId - + "] = [" + mX + ", " + mY + ", " + mWidth + ", " + mHeight + "] " + mVisibility); + serializer.append( + indent, + "ROOT [" + + mComponentId + + ":" + + mAnimationId + + "] = [" + + mX + + ", " + + mY + + ", " + + mWidth + + ", " + + mHeight + + "] " + + mVisibility); } /** - * Traverse the hierarchy and assign generated ids to component without ids. - * Most components would already have ids assigned during the document creation, but this - * allow us to take care of any components added during the inflation. + * Traverse the hierarchy and assign generated ids to component without ids. Most components + * would already have ids assigned during the document creation, but this allow us to take care + * of any components added during the inflation. * * @param lastId the last known generated id */ @@ -84,9 +112,7 @@ public class RootLayoutComponent extends Component implements ComponentStartOper } } - /** - * This will measure then layout the tree of components - */ + /** This will measure then layout the tree of components */ public void layout(RemoteContext context) { if (!mNeedsMeasure) { return; @@ -100,8 +126,7 @@ public class RootLayoutComponent extends Component implements ComponentStartOper for (Operation op : mList) { if (op instanceof Measurable) { Measurable m = (Measurable) op; - m.measure(context.getPaintContext(), - 0f, mWidth, 0f, mHeight, measurePass); + m.measure(context.getPaintContext(), 0f, mWidth, 0f, mHeight, measurePass); m.layout(context, measurePass); } } @@ -161,15 +186,16 @@ public class RootLayoutComponent extends Component implements ComponentStartOper public static void read(WireBuffer buffer, List<Operation> operations) { int componentId = buffer.readInt(); - operations.add(new RootLayoutComponent( - componentId, 0, 0, 0, 0, null, -1)); + operations.add(new RootLayoutComponent(componentId, 0, 0, 0, 0, null, -1)); } public static void documentation(DocumentationBuilder doc) { doc.operation("Layout Operations", id(), name()) .field(INT, "COMPONENT_ID", "unique id for this component") - .description("Root element for a document. Other components / layout managers " - + "are children in the component tree starting from this Root component."); + .description( + "Root element for a document. Other components / layout managers are" + + " children in the component tree starting from" + + "this Root component."); } @Override diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java index 1ada733e2cb2..e45058528859 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java @@ -28,7 +28,7 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.easin /** * Basic interpolation manager between two ComponentMeasures * - * Handles position, size and visibility + * <p>Handles position, size and visibility */ public class AnimateMeasure { long mStartTime = System.currentTimeMillis(); @@ -44,18 +44,24 @@ public class AnimateMeasure { float mP = 0f; float mVp = 0f; - FloatAnimation mMotionEasing = new FloatAnimation(mMotionEasingType, - mDuration / 1000f, null, 0f, Float.NaN); - FloatAnimation mVisibilityEasing = new FloatAnimation(mVisibilityEasingType, - mDurationVisibilityChange / 1000f, - null, 0f, Float.NaN); + FloatAnimation mMotionEasing = + new FloatAnimation(mMotionEasingType, mDuration / 1000f, null, 0f, Float.NaN); + FloatAnimation mVisibilityEasing = + new FloatAnimation( + mVisibilityEasingType, mDurationVisibilityChange / 1000f, null, 0f, Float.NaN); ParticleAnimation mParticleAnimation; - public AnimateMeasure(long startTime, Component component, ComponentMeasure original, - ComponentMeasure target, int duration, int durationVisibilityChange, - AnimationSpec.ANIMATION enterAnimation, - AnimationSpec.ANIMATION exitAnimation, - int motionEasingType, int visibilityEasingType) { + public AnimateMeasure( + long startTime, + Component component, + ComponentMeasure original, + ComponentMeasure target, + int duration, + int durationVisibilityChange, + AnimationSpec.ANIMATION enterAnimation, + AnimationSpec.ANIMATION exitAnimation, + int motionEasingType, + int visibilityEasingType) { this.mStartTime = startTime; this.mComponent = component; this.mOriginal = original; @@ -64,18 +70,28 @@ public class AnimateMeasure { this.mDurationVisibilityChange = durationVisibilityChange; this.mEnterAnimation = enterAnimation; this.mExitAnimation = exitAnimation; + this.mMotionEasingType = motionEasingType; + this.mVisibilityEasingType = visibilityEasingType; + + float motionDuration = mDuration / 1000f; + float visibilityDuration = mDurationVisibilityChange / 1000f; + + mMotionEasing = new FloatAnimation(mMotionEasingType, motionDuration, null, 0f, Float.NaN); + mVisibilityEasing = + new FloatAnimation(mVisibilityEasingType, visibilityDuration, null, 0f, Float.NaN); mMotionEasing.setTargetValue(1f); mVisibilityEasing.setTargetValue(1f); + component.mVisibility = target.getVisibility(); } public void update(long currentTime) { long elapsed = currentTime - mStartTime; - mP = Math.min(elapsed / (float) mDuration, 1f); - //mP = motionEasing.get(mP); - mVp = Math.min(elapsed / (float) mDurationVisibilityChange, 1f); - // mVp = mVisibilityEasing.get(mVp); + float motionProgress = elapsed / (float) mDuration; + float visibilityProgress = elapsed / (float) mDurationVisibilityChange; + mP = mMotionEasing.get(motionProgress); + mVp = mVisibilityEasing.get(visibilityProgress); } public PaintBundle paint = new PaintBundle(); @@ -117,8 +133,11 @@ public class AnimateMeasure { paint.reset(); paint.setColor(0f, 0f, 0f, 1f - mVp); context.applyPaint(paint); - context.saveLayer(mComponent.getX(), mComponent.getY(), - mComponent.getWidth(), mComponent.getHeight()); + context.saveLayer( + mComponent.getX(), + mComponent.getY(), + mComponent.getWidth(), + mComponent.getHeight()); mComponent.paintingComponent(context); context.restore(); context.restorePaint(); @@ -127,8 +146,11 @@ public class AnimateMeasure { case SLIDE_LEFT: context.save(); context.translate(-mVp * mComponent.getParent().getWidth(), 0f); - context.saveLayer(mComponent.getX(), mComponent.getY(), - mComponent.getWidth(), mComponent.getHeight()); + context.saveLayer( + mComponent.getX(), + mComponent.getY(), + mComponent.getWidth(), + mComponent.getHeight()); mComponent.paintingComponent(context); context.restore(); context.restore(); @@ -140,8 +162,11 @@ public class AnimateMeasure { paint.setColor(0f, 0f, 0f, 1f); context.applyPaint(paint); context.translate(mVp * mComponent.getParent().getWidth(), 0f); - context.saveLayer(mComponent.getX(), mComponent.getY(), - mComponent.getWidth(), mComponent.getHeight()); + context.saveLayer( + mComponent.getX(), + mComponent.getY(), + mComponent.getWidth(), + mComponent.getHeight()); mComponent.paintingComponent(context); context.restore(); context.restorePaint(); @@ -149,20 +174,24 @@ public class AnimateMeasure { break; case SLIDE_TOP: context.save(); - context.translate(0f, - -mVp * mComponent.getParent().getHeight()); - context.saveLayer(mComponent.getX(), mComponent.getY(), - mComponent.getWidth(), mComponent.getHeight()); + context.translate(0f, -mVp * mComponent.getParent().getHeight()); + context.saveLayer( + mComponent.getX(), + mComponent.getY(), + mComponent.getWidth(), + mComponent.getHeight()); mComponent.paintingComponent(context); context.restore(); context.restore(); break; case SLIDE_BOTTOM: context.save(); - context.translate(0f, - mVp * mComponent.getParent().getHeight()); - context.saveLayer(mComponent.getX(), mComponent.getY(), - mComponent.getWidth(), mComponent.getHeight()); + context.translate(0f, mVp * mComponent.getParent().getHeight()); + context.saveLayer( + mComponent.getX(), + mComponent.getY(), + mComponent.getWidth(), + mComponent.getHeight()); mComponent.paintingComponent(context); context.restore(); context.restore(); @@ -189,8 +218,11 @@ public class AnimateMeasure { paint.reset(); paint.setColor(0f, 0f, 0f, mVp); context.applyPaint(paint); - context.saveLayer(mComponent.getX(), mComponent.getY(), - mComponent.getWidth(), mComponent.getHeight()); + context.saveLayer( + mComponent.getX(), + mComponent.getY(), + mComponent.getWidth(), + mComponent.getHeight()); mComponent.paintingComponent(context); context.restore(); context.restorePaint(); @@ -202,8 +234,11 @@ public class AnimateMeasure { paint.reset(); paint.setColor(0f, 0f, 0f, mVp); context.applyPaint(paint); - context.saveLayer(mComponent.getX(), mComponent.getY(), - mComponent.getWidth(), mComponent.getHeight()); + context.saveLayer( + mComponent.getX(), + mComponent.getY(), + mComponent.getWidth(), + mComponent.getHeight()); mComponent.paintingComponent(context); context.restore(); context.restorePaint(); @@ -211,40 +246,48 @@ public class AnimateMeasure { break; case SLIDE_LEFT: context.save(); - context.translate( - (1f - mVp) * mComponent.getParent().getWidth(), 0f); - context.saveLayer(mComponent.getX(), mComponent.getY(), - mComponent.getWidth(), mComponent.getHeight()); + context.translate((1f - mVp) * mComponent.getParent().getWidth(), 0f); + context.saveLayer( + mComponent.getX(), + mComponent.getY(), + mComponent.getWidth(), + mComponent.getHeight()); mComponent.paintingComponent(context); context.restore(); context.restore(); break; case SLIDE_RIGHT: context.save(); - context.translate( - -(1f - mVp) * mComponent.getParent().getWidth(), 0f); - context.saveLayer(mComponent.getX(), mComponent.getY(), - mComponent.getWidth(), mComponent.getHeight()); + context.translate(-(1f - mVp) * mComponent.getParent().getWidth(), 0f); + context.saveLayer( + mComponent.getX(), + mComponent.getY(), + mComponent.getWidth(), + mComponent.getHeight()); mComponent.paintingComponent(context); context.restore(); context.restore(); break; case SLIDE_TOP: context.save(); - context.translate(0f, - (1f - mVp) * mComponent.getParent().getHeight()); - context.saveLayer(mComponent.getX(), mComponent.getY(), - mComponent.getWidth(), mComponent.getHeight()); + context.translate(0f, (1f - mVp) * mComponent.getParent().getHeight()); + context.saveLayer( + mComponent.getX(), + mComponent.getY(), + mComponent.getWidth(), + mComponent.getHeight()); mComponent.paintingComponent(context); context.restore(); context.restore(); break; case SLIDE_BOTTOM: context.save(); - context.translate(0f, - -(1f - mVp) * mComponent.getParent().getHeight()); - context.saveLayer(mComponent.getX(), mComponent.getY(), - mComponent.getWidth(), mComponent.getHeight()); + context.translate(0f, -(1f - mVp) * mComponent.getParent().getHeight()); + context.saveLayer( + mComponent.getX(), + mComponent.getY(), + mComponent.getWidth(), + mComponent.getHeight()); mComponent.paintingComponent(context); context.restore(); context.restore(); @@ -300,11 +343,22 @@ public class AnimateMeasure { mOriginal.setY(getY()); mOriginal.setW(getWidth()); mOriginal.setH(getHeight()); - mTarget.setX(measure.getX()); - mTarget.setY(measure.getY()); - mTarget.setW(measure.getW()); - mTarget.setH(measure.getH()); - mTarget.setVisibility(measure.getVisibility()); - mStartTime = currentTime; + float targetX = mTarget.getX(); + float targetY = mTarget.getY(); + float targetW = mTarget.getW(); + float targetH = mTarget.getH(); + Component.Visibility targetVisibility = mTarget.getVisibility(); + if (targetX != measure.getX() + || targetY != measure.getY() + || targetW != measure.getW() + || targetH != measure.getH() + || targetVisibility != measure.getVisibility()) { + mTarget.setX(measure.getX()); + mTarget.setY(measure.getY()); + mTarget.setW(measure.getW()); + mTarget.setH(measure.getH()); + mTarget.setVisibility(measure.getVisibility()); + mStartTime = currentTime; + } } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java index 0f7db36e8e01..35533cb95190 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java @@ -15,7 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.animation; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -26,9 +26,7 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.easin import java.util.List; -/** - * Basic component animation spec - */ +/** Basic component animation spec */ public class AnimationSpec implements Operation { int mAnimationId = -1; int mMotionDuration = 300; @@ -38,9 +36,14 @@ public class AnimationSpec implements Operation { ANIMATION mEnterAnimation = ANIMATION.FADE_IN; ANIMATION mExitAnimation = ANIMATION.FADE_OUT; - public AnimationSpec(int animationId, int motionDuration, int motionEasingType, - int visibilityDuration, int visibilityEasingType, - ANIMATION enterAnimation, ANIMATION exitAnimation) { + public AnimationSpec( + int animationId, + int motionDuration, + int motionEasingType, + int visibilityDuration, + int visibilityEasingType, + ANIMATION enterAnimation, + ANIMATION exitAnimation) { this.mAnimationId = animationId; this.mMotionDuration = motionDuration; this.mMotionEasingType = motionEasingType; @@ -51,9 +54,14 @@ public class AnimationSpec implements Operation { } public AnimationSpec() { - this(-1, 300, GeneralEasing.CUBIC_STANDARD, - 300, GeneralEasing.CUBIC_STANDARD, - ANIMATION.FADE_IN, ANIMATION.FADE_OUT); + this( + -1, + 600, + GeneralEasing.CUBIC_STANDARD, + 500, + GeneralEasing.CUBIC_STANDARD, + ANIMATION.FADE_IN, + ANIMATION.FADE_OUT); } public int getAnimationId() { @@ -102,8 +110,15 @@ public class AnimationSpec implements Operation { @Override public void write(WireBuffer buffer) { - apply(buffer, mAnimationId, mMotionDuration, mMotionEasingType, - mVisibilityDuration, mVisibilityEasingType, mEnterAnimation, mExitAnimation); + apply( + buffer, + mAnimationId, + mMotionDuration, + mMotionEasingType, + mVisibilityDuration, + mVisibilityEasingType, + mEnterAnimation, + mExitAnimation); } @Override @@ -151,10 +166,15 @@ public class AnimationSpec implements Operation { } } - public static void apply(WireBuffer buffer, int animationId, int motionDuration, - int motionEasingType, int visibilityDuration, - int visibilityEasingType, ANIMATION enterAnimation, - ANIMATION exitAnimation) { + public static void apply( + WireBuffer buffer, + int animationId, + int motionDuration, + int motionEasingType, + int visibilityDuration, + int visibilityEasingType, + ANIMATION enterAnimation, + ANIMATION exitAnimation) { buffer.start(Operations.ANIMATION_SPEC); buffer.writeInt(animationId); buffer.writeInt(motionDuration); @@ -173,20 +193,25 @@ public class AnimationSpec implements Operation { int visibilityEasingType = buffer.readInt(); ANIMATION enterAnimation = intToAnimation(buffer.readInt()); ANIMATION exitAnimation = intToAnimation(buffer.readInt()); - AnimationSpec op = new AnimationSpec(animationId, motionDuration, motionEasingType, - visibilityDuration, visibilityEasingType, enterAnimation, exitAnimation); + AnimationSpec op = + new AnimationSpec( + animationId, + motionDuration, + motionEasingType, + visibilityDuration, + visibilityEasingType, + enterAnimation, + exitAnimation); operations.add(op); } + public static void documentation(DocumentationBuilder doc) { - doc.operation("Layout Operations", - id(), - name()) + doc.operation("Layout Operations", id(), name()) .description("define the animation") .field(INT, "animationId", "") .field(INT, "motionDuration", "") .field(INT, "motionEasingType", "") .field(INT, "visibilityDuration", "") .field(INT, "visibilityEasingType", ""); - } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/ParticleAnimation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/ParticleAnimation.java index 5c5d05658f65..686643fbe1bc 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/ParticleAnimation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/ParticleAnimation.java @@ -27,9 +27,13 @@ public class ParticleAnimation { HashMap<Integer, ArrayList<Particle>> mAllParticles = new HashMap<>(); PaintBundle mPaint = new PaintBundle(); - public void animate(PaintContext context, Component component, - ComponentMeasure start, ComponentMeasure end, - float progress) { + + public void animate( + PaintContext context, + Component component, + ComponentMeasure start, + ComponentMeasure end, + float progress) { ArrayList<Particle> particles = mAllParticles.get(component.getComponentId()); if (particles == null) { particles = new ArrayList<Particle>(); @@ -37,9 +41,9 @@ public class ParticleAnimation { float x = (float) Math.random(); float y = (float) Math.random(); float radius = (float) Math.random(); - float r = 250f; - float g = 250f; - float b = 250f; + float r = 220f; + float g = 220f; + float b = 220f; particles.add(new Particle(x, y, radius, r, g, b)); } mAllParticles.put(component.getComponentId(), particles); @@ -49,12 +53,17 @@ public class ParticleAnimation { for (int i = 0; i < particles.size(); i++) { Particle particle = particles.get(i); mPaint.reset(); - mPaint.setColor(particle.r, particle.g, particle.b, - 200 * (1 - progress)); + mPaint.setColor( + particle.r / 255f, + particle.g / 255f, + particle.b / 255f, + (200 * (1 - progress)) / 255f); context.applyPaint(mPaint); float dx = start.getX() + component.getWidth() * particle.x; - float dy = start.getY() + component.getHeight() * particle.y - + progress * 0.01f * component.getHeight(); + float dy = + start.getY() + + component.getHeight() * particle.y + + progress * 0.01f * component.getHeight(); float dr = (component.getHeight() + 60) * 0.15f * particle.radius + (30 * progress); context.drawCircle(dx, dy, dr); } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java index 88a49a666cd7..047a968785c4 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java @@ -15,7 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.managers; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -30,9 +30,7 @@ import com.android.internal.widget.remotecompose.core.operations.layout.measure. import java.util.List; -/** - * Simple Box layout implementation - */ +/** Simple Box layout implementation */ public class BoxLayout extends LayoutManager implements ComponentStartOperation { public static final int START = 1; @@ -41,37 +39,68 @@ public class BoxLayout extends LayoutManager implements ComponentStartOperation public static final int TOP = 4; public static final int BOTTOM = 5; - int mHorizontalPositioning; int mVerticalPositioning; - public BoxLayout(Component parent, int componentId, int animationId, - float x, float y, float width, float height, - int horizontalPositioning, int verticalPositioning) { + public BoxLayout( + Component parent, + int componentId, + int animationId, + float x, + float y, + float width, + float height, + int horizontalPositioning, + int verticalPositioning) { super(parent, componentId, animationId, x, y, width, height); mHorizontalPositioning = horizontalPositioning; mVerticalPositioning = verticalPositioning; } - public BoxLayout(Component parent, int componentId, int animationId, - int horizontalPositioning, int verticalPositioning) { - this(parent, componentId, animationId, 0, 0, 0, 0, - horizontalPositioning, verticalPositioning); + public BoxLayout( + Component parent, + int componentId, + int animationId, + int horizontalPositioning, + int verticalPositioning) { + this( + parent, + componentId, + animationId, + 0, + 0, + 0, + 0, + horizontalPositioning, + verticalPositioning); } @Override public String toString() { - return "BOX [" + mComponentId + ":" + mAnimationId + "] (" + mX + ", " - + mY + " - " + mWidth + " x " + mHeight + ") " + mVisibility; + return "BOX [" + + mComponentId + + ":" + + mAnimationId + + "] (" + + mX + + ", " + + mY + + " - " + + mWidth + + " x " + + mHeight + + ") " + + mVisibility; } + @Override protected String getSerializedName() { return "BOX"; } @Override - public void computeWrapSize(PaintContext context, float maxWidth, float maxHeight, - MeasurePass measure, Size size) { + public void computeWrapSize( + PaintContext context, float maxWidth, float maxHeight, MeasurePass measure, Size size) { for (Component c : mChildrenComponents) { c.measure(context, 0f, maxWidth, 0f, maxHeight, measure); ComponentMeasure m = measure.get(c); @@ -84,16 +113,20 @@ public class BoxLayout extends LayoutManager implements ComponentStartOperation } @Override - public void computeSize(PaintContext context, float minWidth, float maxWidth, - float minHeight, float maxHeight, MeasurePass measure) { + public void computeSize( + PaintContext context, + float minWidth, + float maxWidth, + float minHeight, + float maxHeight, + MeasurePass measure) { for (Component child : mChildrenComponents) { child.measure(context, minWidth, maxWidth, minHeight, maxHeight, measure); } } @Override - public void internalLayoutMeasure(PaintContext context, - MeasurePass measure) { + public void internalLayoutMeasure(PaintContext context, MeasurePass measure) { ComponentMeasure selfMeasure = measure.get(this); float selfWidth = selfMeasure.getW() - mPaddingLeft - mPaddingRight; float selfHeight = selfMeasure.getH() - mPaddingTop - mPaddingBottom; @@ -136,8 +169,12 @@ public class BoxLayout extends LayoutManager implements ComponentStartOperation return Operations.LAYOUT_BOX; } - public static void apply(WireBuffer buffer, int componentId, int animationId, - int horizontalPositioning, int verticalPositioning) { + public static void apply( + WireBuffer buffer, + int componentId, + int animationId, + int horizontalPositioning, + int verticalPositioning) { buffer.start(Operations.LAYOUT_BOX); buffer.writeInt(componentId); buffer.writeInt(animationId); @@ -150,24 +187,32 @@ public class BoxLayout extends LayoutManager implements ComponentStartOperation int animationId = buffer.readInt(); int horizontalPositioning = buffer.readInt(); int verticalPositioning = buffer.readInt(); - operations.add(new BoxLayout(null, componentId, animationId, - horizontalPositioning, verticalPositioning)); + operations.add( + new BoxLayout( + null, + componentId, + animationId, + horizontalPositioning, + verticalPositioning)); } public static void documentation(DocumentationBuilder doc) { doc.operation("Layout Operations", id(), name()) - .description("Box layout implementation.\n\n" - + "Child components are laid out independently from one another,\n" - + " and painted in their hierarchy order (first children drawn" - + "before the latter). Horizontal and Vertical positioning" - + "are supported.") + .description( + "Box layout implementation.\n\n" + + "Child components are laid out independently from one another,\n" + + " and painted in their hierarchy order (first children drawn" + + "before the latter). Horizontal and Vertical positioning" + + "are supported.") .examplesDimension(150, 100) .exampleImage("Top", "layout-BoxLayout-start-top.png") .exampleImage("Center", "layout-BoxLayout-center-center.png") .exampleImage("Bottom", "layout-BoxLayout-end-bottom.png") .field(INT, "COMPONENT_ID", "unique id for this component") - .field(INT, "ANIMATION_ID", "id used to match components," - + " for animation purposes") + .field( + INT, + "ANIMATION_ID", + "id used to match components," + " for animation purposes") .field(INT, "HORIZONTAL_POSITIONING", "horizontal positioning value") .possibleValues("START", BoxLayout.START) .possibleValues("CENTER", BoxLayout.CENTER) @@ -178,10 +223,8 @@ public class BoxLayout extends LayoutManager implements ComponentStartOperation .possibleValues("BOTTOM", BoxLayout.BOTTOM); } - @Override public void write(WireBuffer buffer) { - apply(buffer, mComponentId, mAnimationId, - mHorizontalPositioning, mVerticalPositioning); + apply(buffer, mComponentId, mAnimationId, mHorizontalPositioning, mVerticalPositioning); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CanvasLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CanvasLayout.java index bce7a77abb36..f79976715ab3 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CanvasLayout.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CanvasLayout.java @@ -15,7 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.managers; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -29,8 +29,14 @@ import com.android.internal.widget.remotecompose.core.operations.layout.measure. import java.util.List; public class CanvasLayout extends BoxLayout { - public CanvasLayout(Component parent, int componentId, int animationId, - float x, float y, float width, float height) { + public CanvasLayout( + Component parent, + int componentId, + int animationId, + float x, + float y, + float width, + float height) { super(parent, componentId, animationId, x, y, width, height, 0, 0); } @@ -40,10 +46,23 @@ public class CanvasLayout extends BoxLayout { @Override public String toString() { - return "CANVAS [" + mComponentId + ":" + mAnimationId + "] (" + mX + ", " - + mY + " - " + mWidth + " x " + mHeight + ") " + mVisibility; + return "CANVAS [" + + mComponentId + + ":" + + mAnimationId + + "] (" + + mX + + ", " + + mY + + " - " + + mWidth + + " x " + + mHeight + + ") " + + mVisibility; } + @Override protected String getSerializedName() { return "CANVAS"; } @@ -72,13 +91,14 @@ public class CanvasLayout extends BoxLayout { doc.operation("Layout Operations", id(), name()) .description("Canvas implementation. Encapsulate draw operations.\n\n") .field(INT, "COMPONENT_ID", "unique id for this component") - .field(INT, "ANIMATION_ID", "id used to match components," - + " for animation purposes"); + .field( + INT, + "ANIMATION_ID", + "id used to match components," + " for animation purposes"); } @Override - public void internalLayoutMeasure(PaintContext context, - MeasurePass measure) { + public void internalLayoutMeasure(PaintContext context, MeasurePass measure) { ComponentMeasure selfMeasure = measure.get(this); float selfWidth = selfMeasure.getW() - mPaddingLeft - mPaddingRight; float selfHeight = selfMeasure.getH() - mPaddingTop - mPaddingBottom; diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java index 48d966ebe9a7..402b784343ad 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java @@ -15,8 +15,8 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.managers; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -34,8 +34,7 @@ import com.android.internal.widget.remotecompose.core.operations.layout.utils.De import java.util.List; /** - * Simple Column layout implementation - * - also supports weight and horizontal/vertical positioning + * Simple Column layout implementation - also supports weight and horizontal/vertical positioning */ public class ColumnLayout extends LayoutManager implements ComponentStartOperation { public static final int START = 1; @@ -51,69 +50,122 @@ public class ColumnLayout extends LayoutManager implements ComponentStartOperati int mVerticalPositioning; float mSpacedBy = 0f; - public ColumnLayout(Component parent, int componentId, int animationId, - float x, float y, float width, float height, - int horizontalPositioning, int verticalPositioning, float spacedBy) { + public ColumnLayout( + Component parent, + int componentId, + int animationId, + float x, + float y, + float width, + float height, + int horizontalPositioning, + int verticalPositioning, + float spacedBy) { super(parent, componentId, animationId, x, y, width, height); mHorizontalPositioning = horizontalPositioning; mVerticalPositioning = verticalPositioning; mSpacedBy = spacedBy; } - public ColumnLayout(Component parent, int componentId, int animationId, - int horizontalPositioning, int verticalPositioning, float spacedBy) { - this(parent, componentId, animationId, 0, 0, 0, 0, - horizontalPositioning, verticalPositioning, spacedBy); + public ColumnLayout( + Component parent, + int componentId, + int animationId, + int horizontalPositioning, + int verticalPositioning, + float spacedBy) { + this( + parent, + componentId, + animationId, + 0, + 0, + 0, + 0, + horizontalPositioning, + verticalPositioning, + spacedBy); } @Override public String toString() { - return "COLUMN [" + mComponentId + ":" + mAnimationId + "] (" + mX + ", " - + mY + " - " + mWidth + " x " + mHeight + ") " + mVisibility; + return "COLUMN [" + + mComponentId + + ":" + + mAnimationId + + "] (" + + mX + + ", " + + mY + + " - " + + mWidth + + " x " + + mHeight + + ") " + + mVisibility; } + @Override protected String getSerializedName() { return "COLUMN"; } @Override - public void computeWrapSize(PaintContext context, float maxWidth, float maxHeight, - MeasurePass measure, Size size) { + public void computeWrapSize( + PaintContext context, float maxWidth, float maxHeight, MeasurePass measure, Size size) { DebugLog.s(() -> "COMPUTE WRAP SIZE in " + this + " (" + mComponentId + ")"); + int visibleChildrens = 0; for (Component c : mChildrenComponents) { - c.measure(context, 0f, maxWidth, - 0f, maxHeight, measure); + c.measure(context, 0f, maxWidth, 0f, maxHeight, measure); ComponentMeasure m = measure.get(c); - size.setWidth(Math.max(size.getWidth(), m.getW())); - size.setHeight(size.getHeight() + m.getH()); + if (m.getVisibility() != Visibility.GONE) { + size.setWidth(Math.max(size.getWidth(), m.getW())); + size.setHeight(size.getHeight() + m.getH()); + visibleChildrens++; + } } if (!mChildrenComponents.isEmpty()) { - size.setHeight(size.getHeight() - + (mSpacedBy * (mChildrenComponents.size() - 1))); + size.setHeight(size.getHeight() + (mSpacedBy * (visibleChildrens - 1))); } DebugLog.e(); } @Override - public void computeSize(PaintContext context, float minWidth, float maxWidth, - float minHeight, float maxHeight, MeasurePass measure) { + public void computeSize( + PaintContext context, + float minWidth, + float maxWidth, + float minHeight, + float maxHeight, + MeasurePass measure) { DebugLog.s(() -> "COMPUTE SIZE in " + this + " (" + mComponentId + ")"); float mh = maxHeight; for (Component child : mChildrenComponents) { child.measure(context, minWidth, maxWidth, minHeight, mh, measure); ComponentMeasure m = measure.get(child); - mh -= m.getH(); + if (m.getVisibility() != Visibility.GONE) { + mh -= m.getH(); + } } DebugLog.e(); } @Override - public void internalLayoutMeasure(PaintContext context, - MeasurePass measure) { + public void internalLayoutMeasure(PaintContext context, MeasurePass measure) { ComponentMeasure selfMeasure = measure.get(this); - DebugLog.s(() -> "INTERNAL LAYOUT " + this + " (" + mComponentId + ") children: " - + mChildrenComponents.size() + " size (" + selfMeasure.getW() - + " x " + selfMeasure.getH() + ")"); + DebugLog.s( + () -> + "INTERNAL LAYOUT " + + this + + " (" + + mComponentId + + ") children: " + + mChildrenComponents.size() + + " size (" + + selfMeasure.getW() + + " x " + + selfMeasure.getH() + + ")"); if (mChildrenComponents.isEmpty()) { DebugLog.e(); return; @@ -127,6 +179,9 @@ public class ColumnLayout extends LayoutManager implements ComponentStartOperati float totalWeights = 0f; for (Component child : mChildrenComponents) { ComponentMeasure childMeasure = measure.get(child); + if (childMeasure.getVisibility() == Visibility.GONE) { + continue; + } if (child instanceof LayoutComponent && ((LayoutComponent) child).getHeightModifier().hasWeight()) { hasWeights = true; @@ -141,21 +196,34 @@ public class ColumnLayout extends LayoutManager implements ComponentStartOperati if (child instanceof LayoutComponent && ((LayoutComponent) child).getHeightModifier().hasWeight()) { ComponentMeasure childMeasure = measure.get(child); + if (childMeasure.getVisibility() == Visibility.GONE) { + continue; + } float weight = ((LayoutComponent) child).getHeightModifier().getValue(); childMeasure.setH((weight * availableSpace) / totalWeights); - child.measure(context, childMeasure.getW(), - childMeasure.getW(), childMeasure.getH(), childMeasure.getH(), measure); + child.measure( + context, + childMeasure.getW(), + childMeasure.getW(), + childMeasure.getH(), + childMeasure.getH(), + measure); } } } childrenHeight = 0f; + int visibleChildrens = 0; for (Component child : mChildrenComponents) { ComponentMeasure childMeasure = measure.get(child); + if (childMeasure.getVisibility() == Visibility.GONE) { + continue; + } childrenWidth = Math.max(childrenWidth, childMeasure.getW()); childrenHeight += childMeasure.getH(); + visibleChildrens++; } - childrenHeight += mSpacedBy * (mChildrenComponents.size() - 1); + childrenHeight += mSpacedBy * (visibleChildrens - 1); float tx = 0f; float ty = 0f; @@ -175,24 +243,33 @@ public class ColumnLayout extends LayoutManager implements ComponentStartOperati case SPACE_BETWEEN: for (Component child : mChildrenComponents) { ComponentMeasure childMeasure = measure.get(child); + if (childMeasure.getVisibility() == Visibility.GONE) { + continue; + } total += childMeasure.getH(); } - verticalGap = (selfHeight - total) / (mChildrenComponents.size() - 1); + verticalGap = (selfHeight - total) / (visibleChildrens - 1); break; case SPACE_EVENLY: for (Component child : mChildrenComponents) { ComponentMeasure childMeasure = measure.get(child); + if (childMeasure.getVisibility() == Visibility.GONE) { + continue; + } total += childMeasure.getH(); } - verticalGap = (selfHeight - total) / (mChildrenComponents.size() + 1); + verticalGap = (selfHeight - total) / (visibleChildrens + 1); ty = verticalGap; break; case SPACE_AROUND: for (Component child : mChildrenComponents) { ComponentMeasure childMeasure = measure.get(child); + if (childMeasure.getVisibility() == Visibility.GONE) { + continue; + } total += childMeasure.getH(); } - verticalGap = (selfHeight - total) / (mChildrenComponents.size()); + verticalGap = (selfHeight - total) / visibleChildrens; ty = verticalGap / 2f; break; } @@ -211,6 +288,9 @@ public class ColumnLayout extends LayoutManager implements ComponentStartOperati } childMeasure.setX(tx); childMeasure.setY(ty); + if (childMeasure.getVisibility() == Visibility.GONE) { + continue; + } ty += childMeasure.getH(); if (mVerticalPositioning == SPACE_BETWEEN || mVerticalPositioning == SPACE_AROUND @@ -230,8 +310,13 @@ public class ColumnLayout extends LayoutManager implements ComponentStartOperati return Operations.LAYOUT_COLUMN; } - public static void apply(WireBuffer buffer, int componentId, int animationId, - int horizontalPositioning, int verticalPositioning, float spacedBy) { + public static void apply( + WireBuffer buffer, + int componentId, + int animationId, + int horizontalPositioning, + int verticalPositioning, + float spacedBy) { buffer.start(Operations.LAYOUT_COLUMN); buffer.writeInt(componentId); buffer.writeInt(animationId); @@ -246,15 +331,22 @@ public class ColumnLayout extends LayoutManager implements ComponentStartOperati int horizontalPositioning = buffer.readInt(); int verticalPositioning = buffer.readInt(); float spacedBy = buffer.readFloat(); - operations.add(new ColumnLayout(null, componentId, animationId, - horizontalPositioning, verticalPositioning, spacedBy)); + operations.add( + new ColumnLayout( + null, + componentId, + animationId, + horizontalPositioning, + verticalPositioning, + spacedBy)); } public static void documentation(DocumentationBuilder doc) { doc.operation("Layout Operations", id(), name()) - .description("Column layout implementation, positioning components one" - + " after the other vertically.\n\n" - + "It supports weight and horizontal/vertical positioning.") + .description( + "Column layout implementation, positioning components one" + + " after the other vertically.\n\n" + + "It supports weight and horizontal/vertical positioning.") .examplesDimension(100, 400) .exampleImage("Top", "layout-ColumnLayout-start-top.png") .exampleImage("Center", "layout-ColumnLayout-start-center.png") @@ -263,8 +355,10 @@ public class ColumnLayout extends LayoutManager implements ComponentStartOperati .exampleImage("SpaceAround", "layout-ColumnLayout-start-space-around.png") .exampleImage("SpaceBetween", "layout-ColumnLayout-start-space-between.png") .field(INT, "COMPONENT_ID", "unique id for this component") - .field(INT, "ANIMATION_ID", "id used to match components," - + " for animation purposes") + .field( + INT, + "ANIMATION_ID", + "id used to match components," + " for animation purposes") .field(INT, "HORIZONTAL_POSITIONING", "horizontal positioning value") .possibleValues("START", ColumnLayout.START) .possibleValues("CENTER", ColumnLayout.CENTER) @@ -281,7 +375,12 @@ public class ColumnLayout extends LayoutManager implements ComponentStartOperati @Override public void write(WireBuffer buffer) { - apply(buffer, mComponentId, mAnimationId, - mHorizontalPositioning, mVerticalPositioning, mSpacedBy); + apply( + buffer, + mComponentId, + mAnimationId, + mHorizontalPositioning, + mVerticalPositioning, + mSpacedBy); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java index 3a366172a51f..308ed64ee8ea 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java @@ -24,53 +24,58 @@ import com.android.internal.widget.remotecompose.core.operations.layout.measure. import com.android.internal.widget.remotecompose.core.operations.layout.measure.MeasurePass; import com.android.internal.widget.remotecompose.core.operations.layout.measure.Size; -/** - * Base class for layout managers -- resizable components. - */ +/** Base class for layout managers -- resizable components. */ public abstract class LayoutManager extends LayoutComponent implements Measurable { Size mCachedWrapSize = new Size(0f, 0f); - public LayoutManager(Component parent, int componentId, int animationId, - float x, float y, float width, float height) { + public LayoutManager( + Component parent, + int componentId, + int animationId, + float x, + float y, + float width, + float height) { super(parent, componentId, animationId, x, y, width, height); } - /** - * Implemented by subclasses to provide a layout/measure pass - */ - public void internalLayoutMeasure(PaintContext context, - MeasurePass measure) { + /** Implemented by subclasses to provide a layout/measure pass */ + public void internalLayoutMeasure(PaintContext context, MeasurePass measure) { // nothing here } - /** - * Subclasses can implement this to provide wrap sizing - */ - public void computeWrapSize(PaintContext context, float maxWidth, float maxHeight, - MeasurePass measure, Size size) { + /** Subclasses can implement this to provide wrap sizing */ + public void computeWrapSize( + PaintContext context, float maxWidth, float maxHeight, MeasurePass measure, Size size) { // nothing here } - /** - * Subclasses can implement this when not in wrap sizing - */ - public void computeSize(PaintContext context, float minWidth, float maxWidth, - float minHeight, float maxHeight, MeasurePass measure) { + /** Subclasses can implement this when not in wrap sizing */ + public void computeSize( + PaintContext context, + float minWidth, + float maxWidth, + float minHeight, + float maxHeight, + MeasurePass measure) { // nothing here } - /** - * Base implementation of the measure resolution - */ + /** Base implementation of the measure resolution */ @Override - public void measure(PaintContext context, float minWidth, float maxWidth, - float minHeight, float maxHeight, MeasurePass measure) { + public void measure( + PaintContext context, + float minWidth, + float maxWidth, + float minHeight, + float maxHeight, + MeasurePass measure) { boolean hasWrap = true; - float measuredWidth = Math.min(maxWidth, - computeModifierDefinedWidth() - mMarginLeft - mMarginRight); - float measuredHeight = Math.min(maxHeight, - computeModifierDefinedHeight() - mMarginTop - mMarginBottom); + float measuredWidth = + Math.min(maxWidth, computeModifierDefinedWidth() - mMarginLeft - mMarginRight); + float measuredHeight = + Math.min(maxHeight, computeModifierDefinedHeight() - mMarginTop - mMarginBottom); float insetMaxWidth = maxWidth - mMarginLeft - mMarginRight; float insetMaxHeight = maxHeight - mMarginTop - mMarginBottom; if (mWidthModifier.isWrap() || mHeightModifier.isWrap()) { @@ -129,9 +134,7 @@ public abstract class LayoutManager extends LayoutComponent implements Measurabl internalLayoutMeasure(context, measure); } - /** - * basic layout of internal components - */ + /** basic layout of internal components */ @Override public void layout(RemoteContext context, MeasurePass measure) { super.layout(context, measure); @@ -143,4 +146,18 @@ public abstract class LayoutManager extends LayoutComponent implements Measurabl } this.mNeedsMeasure = false; } + + /** + * Only layout self, not children + * + * @param context + * @param measure + */ + public void selfLayout(RemoteContext context, MeasurePass measure) { + super.layout(context, measure); + ComponentMeasure self = measure.get(this); + + mComponentModifiers.layout(context, self.getW(), self.getH()); + this.mNeedsMeasure = false; + } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java index 5e452f363c06..b29a05c27e5f 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java @@ -15,8 +15,8 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.managers; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -33,10 +33,7 @@ import com.android.internal.widget.remotecompose.core.operations.layout.utils.De import java.util.List; -/** - * Simple Row layout implementation - * - also supports weight and horizontal/vertical positioning - */ +/** Simple Row layout implementation - also supports weight and horizontal/vertical positioning */ public class RowLayout extends LayoutManager implements ComponentStartOperation { public static final int START = 1; public static final int CENTER = 2; @@ -51,68 +48,122 @@ public class RowLayout extends LayoutManager implements ComponentStartOperation int mVerticalPositioning; float mSpacedBy = 0f; - public RowLayout(Component parent, int componentId, int animationId, - float x, float y, float width, float height, - int horizontalPositioning, int verticalPositioning, float spacedBy) { + public RowLayout( + Component parent, + int componentId, + int animationId, + float x, + float y, + float width, + float height, + int horizontalPositioning, + int verticalPositioning, + float spacedBy) { super(parent, componentId, animationId, x, y, width, height); mHorizontalPositioning = horizontalPositioning; mVerticalPositioning = verticalPositioning; mSpacedBy = spacedBy; } - public RowLayout(Component parent, int componentId, int animationId, - int horizontalPositioning, int verticalPositioning, float spacedBy) { - this(parent, componentId, animationId, 0, 0, 0, 0, - horizontalPositioning, verticalPositioning, spacedBy); + public RowLayout( + Component parent, + int componentId, + int animationId, + int horizontalPositioning, + int verticalPositioning, + float spacedBy) { + this( + parent, + componentId, + animationId, + 0, + 0, + 0, + 0, + horizontalPositioning, + verticalPositioning, + spacedBy); } @Override public String toString() { - return "ROW [" + mComponentId + ":" + mAnimationId + "] (" + mX + ", " - + mY + " - " + mWidth + " x " + mHeight + ") " + mVisibility; + return "ROW [" + + mComponentId + + ":" + + mAnimationId + + "] (" + + mX + + ", " + + mY + + " - " + + mWidth + + " x " + + mHeight + + ") " + + mVisibility; } + @Override protected String getSerializedName() { return "ROW"; } @Override - public void computeWrapSize(PaintContext context, float maxWidth, float maxHeight, - MeasurePass measure, Size size) { + public void computeWrapSize( + PaintContext context, float maxWidth, float maxHeight, MeasurePass measure, Size size) { DebugLog.s(() -> "COMPUTE WRAP SIZE in " + this + " (" + mComponentId + ")"); + // int visibleChildrens = 0; for (Component c : mChildrenComponents) { c.measure(context, 0f, maxWidth, 0f, maxHeight, measure); ComponentMeasure m = measure.get(c); - size.setWidth(size.getWidth() + m.getW()); - size.setHeight(Math.max(size.getHeight(), m.getH())); + if (m.getVisibility() != Visibility.GONE) { + size.setWidth(size.getWidth() + m.getW()); + size.setHeight(Math.max(size.getHeight(), m.getH())); + // visibleChildrens++; + } } if (!mChildrenComponents.isEmpty()) { - size.setWidth(size.getWidth() - + (mSpacedBy * (mChildrenComponents.size() - 1))); + size.setWidth(size.getWidth() + (mSpacedBy * (mChildrenComponents.size() - 1))); } DebugLog.e(); } @Override - public void computeSize(PaintContext context, float minWidth, float maxWidth, - float minHeight, float maxHeight, MeasurePass measure) { + public void computeSize( + PaintContext context, + float minWidth, + float maxWidth, + float minHeight, + float maxHeight, + MeasurePass measure) { DebugLog.s(() -> "COMPUTE SIZE in " + this + " (" + mComponentId + ")"); float mw = maxWidth; for (Component child : mChildrenComponents) { child.measure(context, minWidth, mw, minHeight, maxHeight, measure); ComponentMeasure m = measure.get(child); - mw -= m.getW(); + if (m.getVisibility() != Visibility.GONE) { + mw -= m.getW(); + } } DebugLog.e(); } @Override - public void internalLayoutMeasure(PaintContext context, - MeasurePass measure) { + public void internalLayoutMeasure(PaintContext context, MeasurePass measure) { ComponentMeasure selfMeasure = measure.get(this); - DebugLog.s(() -> "INTERNAL LAYOUT " + this + " (" + mComponentId + ") children: " - + mChildrenComponents.size() + " size (" + selfMeasure.getW() - + " x " + selfMeasure.getH() + ")"); + DebugLog.s( + () -> + "INTERNAL LAYOUT " + + this + + " (" + + mComponentId + + ") children: " + + mChildrenComponents.size() + + " size (" + + selfMeasure.getW() + + " x " + + selfMeasure.getH() + + ")"); if (mChildrenComponents.isEmpty()) { DebugLog.e(); return; @@ -126,6 +177,9 @@ public class RowLayout extends LayoutManager implements ComponentStartOperation float totalWeights = 0f; for (Component child : mChildrenComponents) { ComponentMeasure childMeasure = measure.get(child); + if (childMeasure.getVisibility() == Visibility.GONE) { + continue; + } if (child instanceof LayoutComponent && ((LayoutComponent) child).getWidthModifier().hasWeight()) { hasWeights = true; @@ -143,21 +197,34 @@ public class RowLayout extends LayoutManager implements ComponentStartOperation if (child instanceof LayoutComponent && ((LayoutComponent) child).getWidthModifier().hasWeight()) { ComponentMeasure childMeasure = measure.get(child); + if (childMeasure.getVisibility() == Visibility.GONE) { + continue; + } float weight = ((LayoutComponent) child).getWidthModifier().getValue(); childMeasure.setW((weight * availableSpace) / totalWeights); - child.measure(context, childMeasure.getW(), - childMeasure.getW(), childMeasure.getH(), childMeasure.getH(), measure); + child.measure( + context, + childMeasure.getW(), + childMeasure.getW(), + childMeasure.getH(), + childMeasure.getH(), + measure); } } } childrenWidth = 0f; + int visibleChildrens = 0; for (Component child : mChildrenComponents) { ComponentMeasure childMeasure = measure.get(child); + if (childMeasure.getVisibility() == Visibility.GONE) { + continue; + } childrenWidth += childMeasure.getW(); childrenHeight = Math.max(childrenHeight, childMeasure.getH()); + visibleChildrens++; } - childrenWidth += mSpacedBy * (mChildrenComponents.size() - 1); + childrenWidth += mSpacedBy * (visibleChildrens - 1); float tx = 0f; float ty = 0f; @@ -178,24 +245,33 @@ public class RowLayout extends LayoutManager implements ComponentStartOperation case SPACE_BETWEEN: for (Component child : mChildrenComponents) { ComponentMeasure childMeasure = measure.get(child); + if (childMeasure.getVisibility() == Visibility.GONE) { + continue; + } total += childMeasure.getW(); } - horizontalGap = (selfWidth - total) / (mChildrenComponents.size() - 1); + horizontalGap = (selfWidth - total) / (visibleChildrens - 1); break; case SPACE_EVENLY: for (Component child : mChildrenComponents) { ComponentMeasure childMeasure = measure.get(child); + if (childMeasure.getVisibility() == Visibility.GONE) { + continue; + } total += childMeasure.getW(); } - horizontalGap = (selfWidth - total) / (mChildrenComponents.size() + 1); + horizontalGap = (selfWidth - total) / (visibleChildrens + 1); tx = horizontalGap; break; case SPACE_AROUND: for (Component child : mChildrenComponents) { ComponentMeasure childMeasure = measure.get(child); + if (childMeasure.getVisibility() == Visibility.GONE) { + continue; + } total += childMeasure.getW(); } - horizontalGap = (selfWidth - total) / (mChildrenComponents.size()); + horizontalGap = (selfWidth - total) / visibleChildrens; tx = horizontalGap / 2f; break; } @@ -215,6 +291,9 @@ public class RowLayout extends LayoutManager implements ComponentStartOperation } childMeasure.setX(tx); childMeasure.setY(ty); + if (childMeasure.getVisibility() == Visibility.GONE) { + continue; + } tx += childMeasure.getW(); if (mHorizontalPositioning == SPACE_BETWEEN || mHorizontalPositioning == SPACE_AROUND @@ -234,8 +313,13 @@ public class RowLayout extends LayoutManager implements ComponentStartOperation return Operations.LAYOUT_ROW; } - public static void apply(WireBuffer buffer, int componentId, int animationId, - int horizontalPositioning, int verticalPositioning, float spacedBy) { + public static void apply( + WireBuffer buffer, + int componentId, + int animationId, + int horizontalPositioning, + int verticalPositioning, + float spacedBy) { buffer.start(Operations.LAYOUT_ROW); buffer.writeInt(componentId); buffer.writeInt(animationId); @@ -250,15 +334,22 @@ public class RowLayout extends LayoutManager implements ComponentStartOperation int horizontalPositioning = buffer.readInt(); int verticalPositioning = buffer.readInt(); float spacedBy = buffer.readFloat(); - operations.add(new RowLayout(null, componentId, animationId, - horizontalPositioning, verticalPositioning, spacedBy)); + operations.add( + new RowLayout( + null, + componentId, + animationId, + horizontalPositioning, + verticalPositioning, + spacedBy)); } public static void documentation(DocumentationBuilder doc) { doc.operation("Layout Operations", id(), name()) - .description("Row layout implementation, positioning components one" - + " after the other horizontally.\n\n" - + "It supports weight and horizontal/vertical positioning.") + .description( + "Row layout implementation, positioning components one" + + " after the other horizontally.\n\n" + + "It supports weight and horizontal/vertical positioning.") .examplesDimension(400, 100) .exampleImage("Start", "layout-RowLayout-start-top.png") .exampleImage("Center", "layout-RowLayout-center-top.png") @@ -267,8 +358,10 @@ public class RowLayout extends LayoutManager implements ComponentStartOperation .exampleImage("SpaceAround", "layout-RowLayout-space-around-top.png") .exampleImage("SpaceBetween", "layout-RowLayout-space-between-top.png") .field(INT, "COMPONENT_ID", "unique id for this component") - .field(INT, "ANIMATION_ID", "id used to match components," - + " for animation purposes") + .field( + INT, + "ANIMATION_ID", + "id used to match components," + " for animation purposes") .field(INT, "HORIZONTAL_POSITIONING", "horizontal positioning value") .possibleValues("START", RowLayout.START) .possibleValues("CENTER", RowLayout.CENTER) @@ -285,7 +378,12 @@ public class RowLayout extends LayoutManager implements ComponentStartOperation @Override public void write(WireBuffer buffer) { - apply(buffer, mComponentId, mAnimationId, - mHorizontalPositioning, mVerticalPositioning, mSpacedBy); + apply( + buffer, + mComponentId, + mAnimationId, + mHorizontalPositioning, + mVerticalPositioning, + mSpacedBy); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/StateLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/StateLayout.java new file mode 100644 index 000000000000..b5c728135f76 --- /dev/null +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/StateLayout.java @@ -0,0 +1,565 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.widget.remotecompose.core.operations.layout.managers; + +import com.android.internal.widget.remotecompose.core.CoreDocument; +import com.android.internal.widget.remotecompose.core.Operation; +import com.android.internal.widget.remotecompose.core.Operations; +import com.android.internal.widget.remotecompose.core.PaintContext; +import com.android.internal.widget.remotecompose.core.PaintOperation; +import com.android.internal.widget.remotecompose.core.RemoteContext; +import com.android.internal.widget.remotecompose.core.WireBuffer; +import com.android.internal.widget.remotecompose.core.operations.layout.Component; +import com.android.internal.widget.remotecompose.core.operations.layout.ComponentStartOperation; +import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponent; +import com.android.internal.widget.remotecompose.core.operations.layout.measure.ComponentMeasure; +import com.android.internal.widget.remotecompose.core.operations.layout.measure.MeasurePass; +import com.android.internal.widget.remotecompose.core.operations.layout.measure.Size; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * State-based animated layout + * + * <p>States are defined as child layouts. This layout handles interpolating between the different + * state in order to provide an automatic transition. + */ +public class StateLayout extends LayoutManager implements ComponentStartOperation { + + public int measuredLayoutIndex = 0; + public int currentLayoutIndex = 0; + public int previousLayoutIndex = 0; + private int mIndexId = 0; + + // This keep track of all the components associated with a given Id, + // (the key being the id), and the set of components corresponds to the set of states + // TODO: we should be able to optimize this + public Map<Integer, Component[]> statePaintedComponents = new HashMap<>(); + + public int MAX_CACHE_ELEMENTS = 16; + public int[] cacheListElementsId = new int[MAX_CACHE_ELEMENTS]; + + public boolean inTransition = false; + + public StateLayout( + Component parent, + int componentId, + int animationId, + float x, + float y, + float width, + float height, + int indexId) { + super(parent, componentId, animationId, x, y, width, height); + // if (layoutInfo.visibleLayoutIndex != null) { + // layoutInfo.visibleLayoutIndex!!.addChangeListener(this) + // } + mIndexId = indexId; + } + + @Override + public void inflate() { + super.inflate(); + hideLayoutsOtherThan(currentLayoutIndex); + } + + public void findAnimatedComponents() { + for (int i = 0; i < mChildrenComponents.size(); i++) { + Component cs = mChildrenComponents.get(i); + if (cs instanceof LayoutComponent) { + LayoutComponent state = (LayoutComponent) cs; + state.setX(0f); + state.setY(0f); + ArrayList<Component> childrenComponents = state.getChildrenComponents(); + for (int j = 0; j < childrenComponents.size(); j++) { + Component child = childrenComponents.get(j); + if (child.getAnimationId() != -1) { + if (!statePaintedComponents.containsKey(child.getAnimationId())) { + statePaintedComponents.put( + child.getAnimationId(), + new Component[mChildrenComponents.size()]); + } + statePaintedComponents.get(child.getAnimationId())[i] = child; + } + } + } + } + collapsePaintedComponents(); + } + + public void collapsePaintedComponents() { + int numStates = mChildrenComponents.size(); + for (Integer id : statePaintedComponents.keySet()) { + Component[] list = statePaintedComponents.get(id); + int numComponents = list.length; + if (numComponents > 1 && list[0] != null) { + Component c1 = list[0]; + boolean same = true; + for (int i = 1; i < list.length; i++) { + Component c2 = list[i]; + if (c2 == null || !c1.suitableForTransition(c2)) { + same = false; + break; + } + } + if (same) { + // TODO: Fix, shouldn't want to recopy all components + for (int i = 0; i < numStates; i++) { + list[i] = c1; + } + } + } + } + } + + @Override + public void computeSize( + PaintContext context, + float minWidth, + float maxWidth, + float minHeight, + float maxHeight, + MeasurePass measure) { + LayoutManager layout = getLayout(currentLayoutIndex); + layout.computeSize(context, minWidth, maxWidth, minHeight, maxHeight, measure); + } + + @Override + public void internalLayoutMeasure( + PaintContext context, + // layoutInfo: LayoutInfo, + MeasurePass measure) { + LayoutManager layout = getLayout(currentLayoutIndex); + // layout.internalLayoutMeasure(context, layoutInfo, measure) + layout.internalLayoutMeasure(context, measure); + } + + /** Subclasses can implement this to provide wrap sizing */ + @Override + public void computeWrapSize( + PaintContext context, float maxWidth, float maxHeight, MeasurePass measure, Size size) { + LayoutManager layout = getLayout(currentLayoutIndex); + layout.computeWrapSize(context, maxWidth, maxHeight, measure, size); + } + + @Override + public void onClick(RemoteContext context, CoreDocument document, float x, float y) { + if (!contains(x, y)) { + return; + } + LayoutManager layout = getLayout(currentLayoutIndex); + layout.onClick(context, document, x, y); + } + + @Override + public void layout(RemoteContext context, MeasurePass measure) { + ComponentMeasure self = measure.get(this); + super.selfLayout(context, measure); + + // We can simply layout the current layout... + LayoutManager layout = getLayout(currentLayoutIndex); + + // Pass through the measure information from the state layout to the currently + // selected component that this being laid out. + ComponentMeasure layoutMeasure = measure.get(layout.getComponentId()); + layoutMeasure.copyFrom(self); + + layout.layout(context, measure); + + // but if we are in a transition, we might have to layout previous widgets + if (inTransition && previousLayoutIndex != currentLayoutIndex) { + LayoutManager previous = getLayout(previousLayoutIndex); + for (Component c : previous.getChildrenComponents()) { + int id = c.getComponentId(); + if (c.getAnimationId() != -1) { + id = c.getAnimationId(); + Component[] rc = statePaintedComponents.get(id); + for (Component ac : rc) { + if (ac != null) { + ac.layout(context, measure); + } + } + } + if (measure.contains(id)) { + c.layout(context, measure); + } + } + } + + mFirstLayout = false; + } + + @Override + public void measure( + PaintContext context, + float minWidth, + float maxWidth, + float minHeight, + float maxHeight, + MeasurePass measure) { + // The general approach for this widget is to do most of the work/setup in measure. + // layout and paint then simply use what's been setup in the measure phase. + + // First, let's initialize the statePaintedComponents array; + // it contains for each animation id a set of components associated, one for each state. + // For now to keep things simple, all components sets have the same size (== number of + // states) + if (statePaintedComponents.isEmpty()) { + findAnimatedComponents(); + } + + // TODO : FIRST LAYOUT ANIMATE THE GONE ELEMENT, RESIZING IT. We should be able to fix it + // if we resize things before animting. + + LayoutManager layout = getLayout(currentLayoutIndex); + + // ok so *before* we do the layout, we should make sure to set the *new* widgets (that + // share the same id) to be at the same bounds / position as the current displayed ones + if (inTransition && currentLayoutIndex != previousLayoutIndex) { + LayoutManager previousLayout = getLayout(previousLayoutIndex); + for (Component c : layout.getChildrenComponents()) { + int id = c.getAnimationId(); + if (id == -1) { + continue; + } + for (Component pc : previousLayout.getChildrenComponents()) { + if (pc.getAnimationId() == id) { + Component prev = + statePaintedComponents.get(c.getAnimationId())[previousLayoutIndex]; + if (c != prev) { + c.measure( + context, + prev.getWidth(), + prev.getWidth(), + prev.getHeight(), + prev.getHeight(), + measure); + c.layout(context.getContext(), measure); + c.setX(prev.getX()); + c.setY(prev.getY()); + c.mVisibility = Visibility.GONE; + } + break; + } + } + } + } + + // Alright, now that things are set in place, let's go ahead and measure the new world... + layout.measure(context, minWidth, maxWidth, minHeight, maxHeight, measure); + + // recopy to animationIds the values + for (Component c : layout.getChildrenComponents()) { + ComponentMeasure cm = measure.get(c); + if (c.getAnimationId() != -1) { + // First, we grab the current component for an animation id, and get its measure, + // then set this measure to the measure for the animation id + ComponentMeasure m = measure.get(c.getAnimationId()); + m.copyFrom(cm); + + m.setVisibility(Visibility.VISIBLE); + + // Then for each components sharing the id in all the states... + Component[] components = statePaintedComponents.get(c.getAnimationId()); + for (int idx = 0; idx < components.length; idx++) { + Component ac = components[idx]; + if (ac != null) { + ComponentMeasure m2 = measure.get(ac.getComponentId()); + + // ... we set their measures to be the measure of the current component + if (c != ac) { + m2.copyFrom(cm); + } + + // Finally let's make sure that for all components we set their visibility + if (idx == currentLayoutIndex) { + m2.setVisibility(Visibility.VISIBLE); + } else { + if (c != ac) { + m2.setVisibility(Visibility.GONE); + } + } + + // if the component isn't the current one, we should measure it + if (c != ac) { + ac.measure(context, m.getW(), m.getW(), m.getH(), m.getH(), measure); + } + } + } + } else { + // TODO: Ideally unify the visibility handing so that we also work in terms of + // component and not panel visibility. Ideally do not change the .visibility + // attribute at all and actually use the "current index" to decide whether to + // draw or not. + cm.setVisibility(Visibility.VISIBLE); + } + } + + // Make sure to mark the components that are not in the new layout as being GONE + if (previousLayoutIndex != currentLayoutIndex) { + LayoutManager previousLayout = getLayout(previousLayoutIndex); + for (Component c : previousLayout.getChildrenComponents()) { + int id = c.getComponentId(); + if (c.getAnimationId() != -1) { + id = c.getAnimationId(); + } + if (!measure.contains(id)) { + ComponentMeasure m = measure.get(c.getComponentId()); + m.setX(c.getX()); + m.setY(c.getY()); + m.setW(c.getWidth()); + m.setH(c.getHeight()); + m.setVisibility(Visibility.GONE); + } + } + } + + ComponentMeasure m = measure.get(layout); + ComponentMeasure own = measure.get(this); + own.copyFrom(m); + measuredLayoutIndex = currentLayoutIndex; + } + + public void hideLayoutsOtherThan(int idx) { + int index = 0; + for (Component pane : mChildrenComponents) { + if (pane instanceof LayoutComponent) { + if (index != idx) { + pane.mVisibility = Visibility.GONE; + } else { + pane.mVisibility = Visibility.VISIBLE; + } + index++; + } + } + } + + public LayoutManager getLayout(int idx) { + int index = 0; + for (Component pane : mChildrenComponents) { + if (pane instanceof LayoutComponent) { + if (index == idx) { + return (LayoutManager) pane; + } + index++; + } + } + return (LayoutManager) mChildrenComponents.get(0); + } + + @Override + public void paint(PaintContext context) { + if (mIndexId != 0) { + int newValue = context.getContext().mRemoteComposeState.getInteger(mIndexId); + if (newValue != currentLayoutIndex) { + previousLayoutIndex = currentLayoutIndex; + currentLayoutIndex = newValue; + inTransition = true; + System.out.println("currentLayout index is $currentLayoutIndex"); + // executeValueSetActions(getLayout(currentLayoutIndex)); + invalidateMeasure(); + } + } + System.out.println("PAINTING LAYOUT STATELAYOUT, CURRENT INDEX " + currentLayoutIndex); + // Make sure to mark any components that are not in either the current or previous layout + // as being GONE. + int index = 0; + for (Component pane : mChildrenComponents) { + if (pane instanceof LayoutComponent) { + if (index != currentLayoutIndex && index != previousLayoutIndex) { + pane.mVisibility = Visibility.GONE; + } + if (index == currentLayoutIndex && pane.mVisibility != Visibility.VISIBLE) { + pane.mVisibility = Visibility.VISIBLE; + } + index++; + } + } + + LayoutManager currentLayout = getLayout(measuredLayoutIndex); + boolean needsToPaintTransition = inTransition && previousLayoutIndex != measuredLayoutIndex; + if (needsToPaintTransition) { + // in case we have switched to a new state, during the transition + // we might still need to display the previous components that are not part of + // the new state (to enable them to run their exit animation) + + LayoutManager previousLayout = getLayout(previousLayoutIndex); + int numPreviousComponents = previousLayout.getChildrenComponents().size(); + if (numPreviousComponents > MAX_CACHE_ELEMENTS) { + MAX_CACHE_ELEMENTS *= 2; + cacheListElementsId = new int[MAX_CACHE_ELEMENTS]; + } + // Make sure to apply the animation if there... + previousLayout.applyAnimationAsNeeded(context); + + // Let's grab all the ids for the components of the previous layout... + int idIndex = 0; + for (Component c : previousLayout.getChildrenComponents()) { + cacheListElementsId[idIndex] = c.getPaintId(); + idIndex++; + } + // ...then remove them if they are in the new layout + int count = idIndex; + for (Component c : currentLayout.getChildrenComponents()) { + int id = c.getPaintId(); + for (int i = 0; i < idIndex; i++) { + if (cacheListElementsId[i] == id) { + cacheListElementsId[i] = -1; + count--; + } + } + } + // If we have components not present in the new state, paint them + if (count > 0) { + context.save(); + context.translate(previousLayout.getX(), previousLayout.getY()); + for (Component c : previousLayout.getChildrenComponents()) { + int id = c.getPaintId(); + for (int i = 0; i < idIndex; i++) { + if (cacheListElementsId[i] == id) { + context.translate( + previousLayout.getMarginLeft(), previousLayout.getMarginTop()); + c.paint(context); + context.translate( + -currentLayout.getMarginLeft(), -currentLayout.getMarginTop()); + break; + } + } + } + context.restore(); + } + + // Make sure to apply the animation if there... + currentLayout.applyAnimationAsNeeded(context); + } + + // We paint all the components and operations of the current layout + context.save(); + context.translate(currentLayout.getX(), currentLayout.getY()); + for (Operation op : currentLayout.getList()) { + if (op instanceof Component && ((Component) op).getAnimationId() != -1) { + Component[] stateComponents = + statePaintedComponents.get(((Component) op).getAnimationId()); + Component component = stateComponents[measuredLayoutIndex]; + if (needsToPaintTransition) { + // We might have two components to paint, as in case two different + // components share the same id, we'll fade the previous components out + // and fade in the new one + Component previousComponent = stateComponents[previousLayoutIndex]; + if (previousComponent != null && component != previousComponent) { + context.translate( + currentLayout.getMarginLeft(), currentLayout.getMarginTop()); + previousComponent.paint(context); + context.translate( + -currentLayout.getMarginLeft(), -currentLayout.getMarginTop()); + } + } + context.translate(currentLayout.getMarginLeft(), currentLayout.getMarginTop()); + component.paint(context); + context.translate(-currentLayout.getMarginLeft(), -currentLayout.getMarginTop()); + } else if (op instanceof PaintOperation) { + ((PaintOperation) op).paint(context); + } + } + context.restore(); + + if (needsToPaintTransition) { + checkEndOfTransition(); + } + } + + public void checkEndOfTransition() { + LayoutManager currentLayout = getLayout(measuredLayoutIndex); + LayoutManager previousLayout = getLayout(previousLayoutIndex); + if (inTransition + && currentLayout.mAnimateMeasure == null + && previousLayout.mAnimateMeasure == null) { + inTransition = false; + LayoutManager previous = getLayout(previousLayoutIndex); + if (previous != currentLayout && previous.mVisibility != Visibility.GONE) { + previous.mVisibility = Visibility.GONE; + previous.needsRepaint(); + } + } + } + + // override fun onValueChanged(origamiValue: OrigamiValue<out Int>, oldValue: Int?, newValue: + // Int) { + // if (newValue != currentLayoutIndex) { + // previousLayoutIndex = currentLayoutIndex + // currentLayoutIndex = newValue + // inTransition = true + // println("currentLayout index is $currentLayoutIndex") + // executeValueSetActions(getLayout(currentLayoutIndex)) + // invalidateMeasure() + // } + // } + + // fun executeValueSetActions(layout: LayoutManager) { + // // FIXME : quick hack to support ValueSetClickActions, need to make that a little more + // // robust! + // for (op in layout.list) { + // if (op is LayoutComponent) { + // for (op2 in op.list) { + // if (op2 is OperationsList) { + // for (op3 in op2.list) { + // if (op3 is ValueSetClickAction<*, *>) { + // op3.onClick() + // } + // } + // } + // } + // } + // } + // } + + @Override + public String toString() { + return "STATE_LAYOUT"; + } + + // companion object { + // fun documentation(doc: OrigamiDocumentation) {} + // } + + public static void apply( + WireBuffer buffer, + int componentId, + int animationId, + int horizontalPositioning, + int verticalPositioning, + int indexId) { + buffer.start(Operations.LAYOUT_STATE); + buffer.writeInt(componentId); + buffer.writeInt(animationId); + buffer.writeInt(horizontalPositioning); + buffer.writeInt(verticalPositioning); + buffer.writeInt(indexId); + } + + public static void read(WireBuffer buffer, List<Operation> operations) { + int componentId = buffer.readInt(); + int animationId = buffer.readInt(); + buffer.readInt(); // horizontalPositioning + buffer.readInt(); // verticalPositioning + int indexId = buffer.readInt(); + operations.add( + new StateLayout(null, componentId, animationId, 0f, 0f, 100f, 100f, indexId)); + } +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java index 23705003179c..c1cabcd09c39 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java @@ -15,8 +15,8 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.managers; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -34,9 +34,7 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.Strin import java.util.List; -/** - * Text component, referencing a text id - */ +/** Text component, referencing a text id */ public class TextLayout extends LayoutManager implements ComponentStartOperation, VariableSupport { private static final boolean DEBUG = false; @@ -86,10 +84,20 @@ public class TextLayout extends LayoutManager implements ComponentStartOperation needsRepaint(); } - public TextLayout(Component parent, int componentId, int animationId, - float x, float y, float width, float height, - int textId, int color, float fontSize, - int fontStyle, float fontWeight, int fontFamilyId) { + public TextLayout( + Component parent, + int componentId, + int animationId, + float x, + float y, + float width, + float height, + int textId, + int color, + float fontSize, + int fontStyle, + float fontWeight, + int fontFamilyId) { super(parent, componentId, animationId, x, y, width, height); mTextId = textId; mColor = color; @@ -99,11 +107,30 @@ public class TextLayout extends LayoutManager implements ComponentStartOperation mFontFamilyId = fontFamilyId; } - public TextLayout(Component parent, int componentId, int animationId, - int textId, int color, float fontSize, - int fontStyle, float fontWeight, int fontFamilyId) { - this(parent, componentId, animationId, 0, 0, 0, 0, - textId, color, fontSize, fontStyle, fontWeight, fontFamilyId); + public TextLayout( + Component parent, + int componentId, + int animationId, + int textId, + int color, + float fontSize, + int fontStyle, + float fontWeight, + int fontFamilyId) { + this( + parent, + componentId, + animationId, + 0, + 0, + 0, + 0, + textId, + color, + fontSize, + fontStyle, + fontWeight, + fontFamilyId); } public PaintBundle mPaint = new PaintBundle(); @@ -151,26 +178,57 @@ public class TextLayout extends LayoutManager implements ComponentStartOperation @Override public String toString() { - return "TEXT_LAYOUT [" + mComponentId + ":" + mAnimationId + "] (" + mX + ", " - + mY + " - " + mWidth + " x " + mHeight + ") " + mVisibility; + return "TEXT_LAYOUT [" + + mComponentId + + ":" + + mAnimationId + + "] (" + + mX + + ", " + + mY + + " - " + + mWidth + + " x " + + mHeight + + ") " + + mVisibility; } + @Override protected String getSerializedName() { return "TEXT_LAYOUT"; } @Override public void serializeToString(int indent, StringSerializer serializer) { - serializer.append(indent, getSerializedName() + " [" + mComponentId - + ":" + mAnimationId + "] = " - + "[" + mX + ", " + mY + ", " + mWidth + ", " + mHeight + "] " - + mVisibility + " (" + mTextId + ":\"" + mCachedString + "\")" - ); + serializer.append( + indent, + getSerializedName() + + " [" + + mComponentId + + ":" + + mAnimationId + + "] = " + + "[" + + mX + + ", " + + mY + + ", " + + mWidth + + ", " + + mHeight + + "] " + + mVisibility + + " (" + + mTextId + + ":\"" + + mCachedString + + "\")"); } @Override - public void computeWrapSize(PaintContext context, float maxWidth, float maxHeight, - MeasurePass measure, Size size) { + public void computeWrapSize( + PaintContext context, float maxWidth, float maxHeight, MeasurePass measure, Size size) { context.savePaint(); mPaint.reset(); mPaint.setTextSize(mFontSize); @@ -196,9 +254,16 @@ public class TextLayout extends LayoutManager implements ComponentStartOperation return Operations.LAYOUT_TEXT; } - public static void apply(WireBuffer buffer, int componentId, int animationId, - int textId, int color, float fontSize, int fontStyle, - float fontWeight, int fontFamilyId) { + public static void apply( + WireBuffer buffer, + int componentId, + int animationId, + int textId, + int color, + float fontSize, + int fontStyle, + float fontWeight, + int fontFamilyId) { buffer.start(id()); buffer.writeInt(componentId); buffer.writeInt(animationId); @@ -219,16 +284,27 @@ public class TextLayout extends LayoutManager implements ComponentStartOperation int fontStyle = buffer.readInt(); float fontWeight = buffer.readFloat(); int fontFamilyId = buffer.readInt(); - operations.add(new TextLayout(null, componentId, animationId, textId, color, fontSize, - fontStyle, fontWeight, fontFamilyId)); + operations.add( + new TextLayout( + null, + componentId, + animationId, + textId, + color, + fontSize, + fontStyle, + fontWeight, + fontFamilyId)); } public static void documentation(DocumentationBuilder doc) { doc.operation("Layout Operations", id(), name()) .description("Text layout implementation.\n\n") .field(INT, "COMPONENT_ID", "unique id for this component") - .field(INT, "ANIMATION_ID", "id used to match components," - + " for animation purposes") + .field( + INT, + "ANIMATION_ID", + "id used to match components," + " for animation purposes") .field(INT, "COLOR", "text color") .field(FLOAT, "FONT_SIZE", "font size") .field(INT, "FONT_STYLE", "font style (0 = normal, 1 = italic)") @@ -238,8 +314,15 @@ public class TextLayout extends LayoutManager implements ComponentStartOperation @Override public void write(WireBuffer buffer) { - apply(buffer, mComponentId, mAnimationId, - mTextId, mColor, mFontSize, mFontStyle, - mFontWeight, mFontFamilyId); + apply( + buffer, + mComponentId, + mAnimationId, + mTextId, + mColor, + mFontSize, + mFontStyle, + mFontWeight, + mFontFamilyId); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/ComponentMeasure.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/ComponentMeasure.java index 8dc10d5b0159..285425f99765 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/ComponentMeasure.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/ComponentMeasure.java @@ -13,13 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.android.internal.widget.remotecompose.core.operations.layout.measure; + import com.android.internal.widget.remotecompose.core.operations.layout.Component; -/** - * Encapsulate the result of a measure pass for a component - */ +/** Encapsulate the result of a measure pass for a component */ public class ComponentMeasure { int mId = -1; float mX; @@ -31,24 +29,31 @@ public class ComponentMeasure { public void setX(float value) { mX = value; } + public void setY(float value) { mY = value; } + public void setW(float value) { mW = value; } + public void setH(float value) { mH = value; } + public float getX() { return mX; } + public float getY() { return mY; } + public float getW() { return mW; } + public float getH() { return mH; } @@ -61,8 +66,8 @@ public class ComponentMeasure { mVisibility = visibility; } - public ComponentMeasure(int id, float x, float y, float w, float h, - Component.Visibility visibility) { + public ComponentMeasure( + int id, float x, float y, float w, float h, Component.Visibility visibility) { this.mId = id; this.mX = x; this.mY = y; @@ -76,8 +81,12 @@ public class ComponentMeasure { } public ComponentMeasure(Component component) { - this(component.getComponentId(), component.getX(), component.getY(), - component.getWidth(), component.getHeight(), + this( + component.getComponentId(), + component.getX(), + component.getY(), + component.getWidth(), + component.getHeight(), component.mVisibility); } @@ -88,4 +97,8 @@ public class ComponentMeasure { mH = m.mH; mVisibility = m.mVisibility; } + + public boolean same(ComponentMeasure m) { + return mX == m.mX && mY == m.mY && mW == m.mW && mH == m.mH && mVisibility == m.mVisibility; + } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java index d167d9bf45cb..b48c2d5ae88b 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java @@ -13,33 +13,33 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.android.internal.widget.remotecompose.core.operations.layout.measure; import com.android.internal.widget.remotecompose.core.PaintContext; import com.android.internal.widget.remotecompose.core.RemoteContext; -/** - * Interface describing the measure/layout contract for components - */ +/** Interface describing the measure/layout contract for components */ public interface Measurable { /** - * Measure a component and store the result of the measure in the provided MeasurePass. - * This does not apply the measure to the component. + * Measure a component and store the result of the measure in the provided MeasurePass. This + * does not apply the measure to the component. */ - void measure(PaintContext context, float minWidth, float maxWidth, - float minHeight, float maxHeight, MeasurePass measure); + void measure( + PaintContext context, + float minWidth, + float maxWidth, + float minHeight, + float maxHeight, + MeasurePass measure); - /** - * Apply a given measure to the component - */ + /** Apply a given measure to the component */ void layout(RemoteContext context, MeasurePass measure); /** * Return true if the component needs to be remeasured + * * @return true if need to remeasured, false otherwise */ boolean needsMeasure(); - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/MeasurePass.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/MeasurePass.java index 6801debb9c28..8d01fea03690 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/MeasurePass.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/MeasurePass.java @@ -20,8 +20,8 @@ import com.android.internal.widget.remotecompose.core.operations.layout.Componen import java.util.HashMap; /** - * Represents the result of a measure pass on the entire hierarchy - * TODO: optimize to use a flat array vs the current hashmap + * Represents the result of a measure pass on the entire hierarchy TODO: optimize to use a flat + * array vs the current hashmap */ public class MeasurePass { HashMap<Integer, ComponentMeasure> mList = new HashMap<>(); @@ -43,8 +43,9 @@ public class MeasurePass { public ComponentMeasure get(Component c) { if (!mList.containsKey(c.getComponentId())) { - ComponentMeasure measure = new ComponentMeasure(c.getComponentId(), - c.getX(), c.getY(), c.getWidth(), c.getHeight()); + ComponentMeasure measure = + new ComponentMeasure( + c.getComponentId(), c.getX(), c.getY(), c.getWidth(), c.getHeight()); mList.put(c.getComponentId(), measure); return measure; } @@ -53,8 +54,8 @@ public class MeasurePass { public ComponentMeasure get(int id) { if (!mList.containsKey(id)) { - ComponentMeasure measure = new ComponentMeasure(id, - 0f, 0f, 0f, 0f, Component.Visibility.GONE); + ComponentMeasure measure = + new ComponentMeasure(id, 0f, 0f, 0f, 0f, Component.Visibility.GONE); mList.put(id, measure); return measure; } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Size.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Size.java index b11d8e82e7d1..53f4a71ccd6e 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Size.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Size.java @@ -15,12 +15,11 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.measure; -/** - * Basic data class representing a component size, used during layout computations. - */ +/** Basic data class representing a component size, used during layout computations. */ public class Size { float mWidth; float mHeight; + public Size(float width, float height) { this.mWidth = width; this.mHeight = height; diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java index f3e6a8e0aa22..64e40f7c591c 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java @@ -15,7 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.modifiers; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -28,9 +28,7 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.Strin import java.util.List; -/** - * Component size-aware background draw - */ +/** Component size-aware background draw */ public class BackgroundModifierOperation extends DecoratorModifierOperation { private static final int OP_CODE = Operations.MODIFIER_BACKGROUND; private static final String CLASS_NAME = "BackgroundModifierOperation"; @@ -46,9 +44,16 @@ public class BackgroundModifierOperation extends DecoratorModifierOperation { public PaintBundle mPaint = new PaintBundle(); - public BackgroundModifierOperation(float x, float y, float width, float height, - float r, float g, float b, float a, - int shapeType) { + public BackgroundModifierOperation( + float x, + float y, + float width, + float height, + float r, + float g, + float b, + float a, + int shapeType) { this.mX = x; this.mY = y; this.mWidth = width; @@ -67,10 +72,27 @@ public class BackgroundModifierOperation extends DecoratorModifierOperation { @Override public void serializeToString(int indent, StringSerializer serializer) { - serializer.append(indent, "BACKGROUND = [" + mX + ", " - + mY + ", " + mWidth + ", " + mHeight - + "] color [" + mR + ", " + mG + ", " + mB + ", " + mA - + "] shape [" + mShapeType + "]"); + serializer.append( + indent, + "BACKGROUND = [" + + mX + + ", " + + mY + + ", " + + mWidth + + ", " + + mHeight + + "] color [" + + mR + + ", " + + mG + + ", " + + mB + + ", " + + mA + + "] shape [" + + mShapeType + + "]"); } @Override @@ -92,8 +114,17 @@ public class BackgroundModifierOperation extends DecoratorModifierOperation { return OP_CODE; } - public static void apply(WireBuffer buffer, float x, float y, float width, float height, - float r, float g, float b, float a, int shapeType) { + public static void apply( + WireBuffer buffer, + float x, + float y, + float width, + float height, + float r, + float g, + float b, + float a, + int shapeType) { buffer.start(OP_CODE); buffer.writeFloat(x); buffer.writeFloat(y); @@ -118,11 +149,9 @@ public class BackgroundModifierOperation extends DecoratorModifierOperation { float a = buffer.readFloat(); // shape type int shapeType = buffer.readInt(); - operations.add(new BackgroundModifierOperation(x, y, width, height, - r, g, b, a, shapeType)); + operations.add(new BackgroundModifierOperation(x, y, width, height, r, g, b, a, shapeType)); } - @Override public void paint(PaintContext context) { context.savePaint(); @@ -133,16 +162,13 @@ public class BackgroundModifierOperation extends DecoratorModifierOperation { if (mShapeType == ShapeType.RECTANGLE) { context.drawRect(0f, 0f, mWidth, mHeight); } else if (mShapeType == ShapeType.CIRCLE) { - context.drawCircle(mWidth / 2f, mHeight / 2f, - Math.min(mWidth, mHeight) / 2f); + context.drawCircle(mWidth / 2f, mHeight / 2f, Math.min(mWidth, mHeight) / 2f); } context.restorePaint(); } public static void documentation(DocumentationBuilder doc) { - doc.operation("Modifier Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Modifier Operations", OP_CODE, CLASS_NAME) .description("define the Background Modifier") .field(FLOAT, "x", "") .field(FLOAT, "y", "") diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java index 4c83ec4e627e..92c0a733d8a1 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java @@ -15,7 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.modifiers; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -28,9 +28,7 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.Strin import java.util.List; -/** - * Component size-aware border draw - */ +/** Component size-aware border draw */ public class BorderModifierOperation extends DecoratorModifierOperation { private static final int OP_CODE = Operations.MODIFIER_BORDER; public static final String CLASS_NAME = "BorderModifierOperation"; @@ -49,9 +47,18 @@ public class BorderModifierOperation extends DecoratorModifierOperation { public PaintBundle paint = new PaintBundle(); - public BorderModifierOperation(float x, float y, float width, float height, - float borderWidth, float roundedCorner, - float r, float g, float b, float a, int shapeType) { + public BorderModifierOperation( + float x, + float y, + float width, + float height, + float borderWidth, + float roundedCorner, + float r, + float g, + float b, + float a, + int shapeType) { this.mX = x; this.mY = y; this.mWidth = width; @@ -67,17 +74,51 @@ public class BorderModifierOperation extends DecoratorModifierOperation { @Override public void serializeToString(int indent, StringSerializer serializer) { - serializer.append(indent, "BORDER = [" + mX + ", " + mY + ", " - + mWidth + ", " + mHeight + "] " - + "color [" + mR + ", " + mG + ", " + mB + ", " + mA + "] " - + "border [" + mBorderWidth + ", " + mRoundedCorner + "] " - + "shape [" + mShapeType + "]"); + serializer.append( + indent, + "BORDER = [" + + mX + + ", " + + mY + + ", " + + mWidth + + ", " + + mHeight + + "] " + + "color [" + + mR + + ", " + + mG + + ", " + + mB + + ", " + + mA + + "] " + + "border [" + + mBorderWidth + + ", " + + mRoundedCorner + + "] " + + "shape [" + + mShapeType + + "]"); } @Override public void write(WireBuffer buffer) { - apply(buffer, mX, mY, mWidth, mHeight, mBorderWidth, mRoundedCorner, - mR, mG, mB, mA, mShapeType); + apply( + buffer, + mX, + mY, + mWidth, + mHeight, + mBorderWidth, + mRoundedCorner, + mR, + mG, + mB, + mA, + mShapeType); } @Override @@ -88,12 +129,29 @@ public class BorderModifierOperation extends DecoratorModifierOperation { @Override public String toString() { - return "BorderModifierOperation(" + mX + "," + mY + " - " + mWidth + " x " + mHeight + ") " - + "borderWidth(" + mBorderWidth + ") " - + "color(" + mR + "," + mG + "," + mB + "," + mA + ")"; + return "BorderModifierOperation(" + + mX + + "," + + mY + + " - " + + mWidth + + " x " + + mHeight + + ") " + + "borderWidth(" + + mBorderWidth + + ") " + + "color(" + + mR + + "," + + mG + + "," + + mB + + "," + + mA + + ")"; } - public static String name() { return CLASS_NAME; } @@ -102,10 +160,19 @@ public class BorderModifierOperation extends DecoratorModifierOperation { return OP_CODE; } - public static void apply(WireBuffer buffer, float x, float y, float width, float height, - float borderWidth, float roundedCorner, - float r, float g, float b, float a, - int shapeType) { + public static void apply( + WireBuffer buffer, + float x, + float y, + float width, + float height, + float borderWidth, + float roundedCorner, + float r, + float g, + float b, + float a, + int shapeType) { buffer.start(OP_CODE); buffer.writeFloat(x); buffer.writeFloat(y); @@ -134,11 +201,10 @@ public class BorderModifierOperation extends DecoratorModifierOperation { float a = buffer.readFloat(); // shape type int shapeType = buffer.readInt(); - operations.add(new BorderModifierOperation(x, y, width, height, bw, - rc, r, g, b, a, shapeType)); + operations.add( + new BorderModifierOperation(x, y, width, height, bw, rc, r, g, b, a, shapeType)); } - @Override public void paint(PaintContext context) { context.savePaint(); @@ -160,9 +226,7 @@ public class BorderModifierOperation extends DecoratorModifierOperation { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Modifier Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Modifier Operations", OP_CODE, CLASS_NAME) .description("define the Border Modifier") .field(FLOAT, "x", "") .field(FLOAT, "y", "") diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java index 7cb7925692ab..0d8aeaa2f06a 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java @@ -27,9 +27,7 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.Strin import java.util.List; -/** - * Support modifier clip with a rectangle - */ +/** Support modifier clip with a rectangle */ public class ClipRectModifierOperation extends DecoratorModifierOperation { public static final String CLASS_NAME = "ClipRectModifierOperation"; private static final int OP_CODE = Operations.MODIFIER_CLIP_RECT; @@ -48,15 +46,14 @@ public class ClipRectModifierOperation extends DecoratorModifierOperation { } @Override - public void onClick(RemoteContext context, CoreDocument document, - Component component, float x, float y) { + public void onClick( + RemoteContext context, CoreDocument document, Component component, float x, float y) { // nothing } @Override public void serializeToString(int indent, StringSerializer serializer) { - serializer.append( - indent, "CLIP_RECT = [" + mWidth + ", " + mHeight + "]"); + serializer.append(indent, "CLIP_RECT = [" + mWidth + ", " + mHeight + "]"); } @Override @@ -68,7 +65,6 @@ public class ClipRectModifierOperation extends DecoratorModifierOperation { return CLASS_NAME; } - public static int id() { return OP_CODE; } @@ -77,16 +73,12 @@ public class ClipRectModifierOperation extends DecoratorModifierOperation { buffer.start(OP_CODE); } - public static void read(WireBuffer buffer, List<Operation> operations) { operations.add(new ClipRectModifierOperation()); } - public static void documentation(DocumentationBuilder doc) { - doc.operation("Canvas Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Canvas Operations", OP_CODE, CLASS_NAME) .description("Draw the specified round-rect"); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java index f55c94126001..95786a8b62b0 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java @@ -29,9 +29,7 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.Strin import java.util.ArrayList; -/** - * Maintain a list of modifiers - */ +/** Maintain a list of modifiers */ public class ComponentModifiers extends PaintOperation implements DecoratorComponent { ArrayList<ModifierOperation> mList = new ArrayList<>(); @@ -49,7 +47,7 @@ public class ComponentModifiers extends PaintOperation implements DecoratorCompo @Override public String toString() { - String str = "ComponentModifiers \n"; + String str = "ComponentModifiers \n"; for (ModifierOperation modifierOperation : mList) { str += " " + modifierOperation.toString() + "\n"; } @@ -125,8 +123,9 @@ public class ComponentModifiers extends PaintOperation implements DecoratorCompo mList.addAll(operations); } - public void onClick(RemoteContext context, CoreDocument document, - Component component, float x, float y) { + @Override + public void onClick( + RemoteContext context, CoreDocument document, Component component, float x, float y) { for (ModifierOperation op : mList) { if (op instanceof DecoratorComponent) { ((DecoratorComponent) op).onClick(context, document, component, x, y); diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentVisibilityOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentVisibilityOperation.java index 9c190730706a..312d016029fb 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentVisibilityOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentVisibilityOperation.java @@ -15,7 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.modifiers; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.CoreDocument; import com.android.internal.widget.remotecompose.core.Operation; @@ -31,11 +31,9 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.Strin import java.util.List; -/** - * Allows setting visibility on a component - */ -public class ComponentVisibilityOperation implements ModifierOperation, - VariableSupport, DecoratorComponent { +/** Allows setting visibility on a component */ +public class ComponentVisibilityOperation + implements ModifierOperation, VariableSupport, DecoratorComponent { private static final int OP_CODE = Operations.MODIFIER_VISIBILITY; int mVisibilityId; @@ -61,19 +59,15 @@ public class ComponentVisibilityOperation implements ModifierOperation, } @Override - public void apply(RemoteContext context) { - } + public void apply(RemoteContext context) {} @Override public String deepToString(String indent) { return (indent != null ? indent : "") + toString(); } - @Override - public void write(WireBuffer buffer) { - - } + public void write(WireBuffer buffer) {} public static void apply(WireBuffer buffer, int valueId) { buffer.start(OP_CODE); @@ -87,8 +81,9 @@ public class ComponentVisibilityOperation implements ModifierOperation, public static void documentation(DocumentationBuilder doc) { doc.operation("Layout Operations", OP_CODE, "ComponentVisibility") - .description("This operation allows setting a component" - + "visibility from a provided value") + .description( + "This operation allows setting a component" + + "visibility from a provided value") .field(INT, "VALUE_ID", "Value ID representing the visibility"); } @@ -119,13 +114,9 @@ public class ComponentVisibilityOperation implements ModifierOperation, } @Override - public void layout(RemoteContext context, float width, float height) { - - } + public void layout(RemoteContext context, float width, float height) {} @Override - public void onClick(RemoteContext context, CoreDocument document, - Component component, float x, float y) { - - } + public void onClick( + RemoteContext context, CoreDocument document, Component component, float x, float y) {} } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DecoratorModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DecoratorModifierOperation.java index 70a572845c23..41e18cbafbe6 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DecoratorModifierOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DecoratorModifierOperation.java @@ -22,15 +22,15 @@ import com.android.internal.widget.remotecompose.core.operations.layout.Componen import com.android.internal.widget.remotecompose.core.operations.layout.DecoratorComponent; /** - * Represents a decorator modifier (lightweight component), ie a modifier - * that impacts the visual output (background, border...) + * Represents a decorator modifier (lightweight component), ie a modifier that impacts the visual + * output (background, border...) */ public abstract class DecoratorModifierOperation extends PaintOperation implements ModifierOperation, DecoratorComponent { @Override - public void onClick(RemoteContext context, CoreDocument document, - Component component, float x, float y) { + public void onClick( + RemoteContext context, CoreDocument document, Component component, float x, float y) { // nothing } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java index f085ffb6c73b..408bebcfb7d9 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java @@ -20,13 +20,16 @@ import com.android.internal.widget.remotecompose.core.VariableSupport; import com.android.internal.widget.remotecompose.core.operations.Utils; import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer; -/** - * Base class for dimension modifiers - */ +/** Base class for dimension modifiers */ public abstract class DimensionModifierOperation implements ModifierOperation, VariableSupport { public enum Type { - EXACT, FILL, WRAP, WEIGHT, INTRINSIC_MIN, INTRINSIC_MAX; + EXACT, + FILL, + WRAP, + WEIGHT, + INTRINSIC_MIN, + INTRINSIC_MAX; static Type fromInt(int value) { switch (value) { @@ -67,10 +70,8 @@ public abstract class DimensionModifierOperation implements ModifierOperation, V @Override public void updateVariables(RemoteContext context) { if (mType == Type.EXACT) { - mOutValue = (Float.isNaN(mValue)) - ? context.getFloat(Utils.idFromNan(mValue)) : mValue; + mOutValue = Float.isNaN(mValue) ? context.getFloat(Utils.idFromNan(mValue)) : mValue; } - } @Override @@ -80,10 +81,8 @@ public abstract class DimensionModifierOperation implements ModifierOperation, V context.listensTo(Utils.idFromNan(mValue), this); } } - } - public boolean hasWeight() { return mType == Type.WEIGHT; } @@ -108,7 +107,6 @@ public abstract class DimensionModifierOperation implements ModifierOperation, V mOutValue = mValue = value; } - public String serializedName() { return "DIMENSION"; } @@ -121,8 +119,7 @@ public abstract class DimensionModifierOperation implements ModifierOperation, V } @Override - public void apply(RemoteContext context) { - } + public void apply(RemoteContext context) {} @Override public String deepToString(String indent) { diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java index a0f576a412f8..d3613f844981 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java @@ -15,8 +15,8 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.modifiers; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -25,9 +25,7 @@ import com.android.internal.widget.remotecompose.core.documentation.Documentatio import java.util.List; -/** - * Set the height dimension on a component - */ +/** Set the height dimension on a component */ public class HeightModifierOperation extends DimensionModifierOperation { private static final int OP_CODE = Operations.MODIFIER_HEIGHT; public static final String CLASS_NAME = "HeightModifierOperation"; @@ -81,9 +79,7 @@ public class HeightModifierOperation extends DimensionModifierOperation { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Modifier Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Modifier Operations", OP_CODE, CLASS_NAME) .description("define the animation") .field(INT, "type", "") .field(FLOAT, "value", ""); diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostActionOperation.java index d405b2b2a6a7..ac42470a6f8f 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostActionOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostActionOperation.java @@ -15,7 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.modifiers; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.CoreDocument; import com.android.internal.widget.remotecompose.core.Operation; @@ -29,9 +29,7 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.Strin import java.util.List; -/** - * Capture a host action information. This can be triggered on eg. a click. - */ +/** Capture a host action information. This can be triggered on eg. a click. */ public class HostActionOperation implements ActionOperation { private static final int OP_CODE = Operations.HOST_ACTION; @@ -60,23 +58,19 @@ public class HostActionOperation implements ActionOperation { } @Override - public void apply(RemoteContext context) { - } + public void apply(RemoteContext context) {} @Override public String deepToString(String indent) { return (indent != null ? indent : "") + toString(); } - @Override - public void write(WireBuffer buffer) { - - } + public void write(WireBuffer buffer) {} @Override - public void runAction(RemoteContext context, CoreDocument document, - Component component, float x, float y) { + public void runAction( + RemoteContext context, CoreDocument document, Component component, float x, float y) { context.runAction(mActionId, ""); } @@ -95,5 +89,4 @@ public class HostActionOperation implements ActionOperation { .description("Host action. This operation represents a host action") .field(INT, "ACTION_ID", "Host Action ID"); } - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostNamedActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostNamedActionOperation.java index 35f202bd6ed3..b674a582fc14 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostNamedActionOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostNamedActionOperation.java @@ -15,7 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.modifiers; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.CoreDocument; import com.android.internal.widget.remotecompose.core.Operation; @@ -29,9 +29,7 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.Strin import java.util.List; -/** - * Capture a host action information. This can be triggered on eg. a click. - */ +/** Capture a host action information. This can be triggered on eg. a click. */ public class HostNamedActionOperation implements ActionOperation { private static final int OP_CODE = Operations.HOST_NAMED_ACTION; @@ -56,23 +54,19 @@ public class HostNamedActionOperation implements ActionOperation { } @Override - public void apply(RemoteContext context) { - } + public void apply(RemoteContext context) {} @Override public String deepToString(String indent) { return (indent != null ? indent : "") + toString(); } - @Override - public void write(WireBuffer buffer) { - - } + public void write(WireBuffer buffer) {} @Override - public void runAction(RemoteContext context, CoreDocument document, - Component component, float x, float y) { + public void runAction( + RemoteContext context, CoreDocument document, Component component, float x, float y) { context.runNamedAction(mTextId); } @@ -91,5 +85,4 @@ public class HostNamedActionOperation implements ActionOperation { .description("Host Named action. This operation represents a host action") .field(INT, "TEXT_ID", "Named Host Action Text ID"); } - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ModifierOperation.java index 5299719f674f..50f098e25f6a 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ModifierOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ModifierOperation.java @@ -18,9 +18,7 @@ package com.android.internal.widget.remotecompose.core.operations.layout.modifie import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer; -/** - * Represents a modifier - */ +/** Represents a modifier */ public interface ModifierOperation extends Operation { void serializeToString(int indent, StringSerializer serializer); } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java index 668db3b71027..e0ec1a60ef7e 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java @@ -15,7 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.modifiers; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -27,8 +27,8 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.Strin import java.util.List; /** - * Represents a padding modifier. - * Padding modifiers can be chained and will impact following modifiers. + * Represents a padding modifier. Padding modifiers can be chained and will impact following + * modifiers. */ public class PaddingModifierOperation implements ModifierOperation { private static final int OP_CODE = Operations.MODIFIER_PADDING; @@ -84,13 +84,12 @@ public class PaddingModifierOperation implements ModifierOperation { @Override public void serializeToString(int indent, StringSerializer serializer) { - serializer.append(indent, "PADDING = [" + mLeft + ", " + mTop + ", " - + mRight + ", " + mBottom + "]"); + serializer.append( + indent, "PADDING = [" + mLeft + ", " + mTop + ", " + mRight + ", " + mBottom + "]"); } @Override - public void apply(RemoteContext context) { - } + public void apply(RemoteContext context) {} @Override public String deepToString(String indent) { @@ -99,8 +98,15 @@ public class PaddingModifierOperation implements ModifierOperation { @Override public String toString() { - return "PaddingModifierOperation(" + mLeft + ", " + mTop - + ", " + mRight + ", " + mBottom + ")"; + return "PaddingModifierOperation(" + + mLeft + + ", " + + mTop + + ", " + + mRight + + ", " + + mBottom + + ")"; } public static String name() { @@ -111,8 +117,7 @@ public class PaddingModifierOperation implements ModifierOperation { return Operations.MODIFIER_PADDING; } - public static void apply(WireBuffer buffer, - float left, float top, float right, float bottom) { + public static void apply(WireBuffer buffer, float left, float top, float right, float bottom) { buffer.start(Operations.MODIFIER_PADDING); buffer.writeFloat(left); buffer.writeFloat(top); @@ -129,9 +134,7 @@ public class PaddingModifierOperation implements ModifierOperation { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Modifier Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Modifier Operations", OP_CODE, CLASS_NAME) .description("define the Padding Modifier") .field(FLOAT, "left", "") .field(FLOAT, "top", "") diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java index 9b662bf5eca7..dc95fe7774aa 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java @@ -15,7 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.modifiers; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT; import com.android.internal.widget.remotecompose.core.CoreDocument; import com.android.internal.widget.remotecompose.core.Operation; @@ -31,9 +31,7 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.Strin import java.util.List; -/** - * Support clip with a rounded rectangle - */ +/** Support clip with a rounded rectangle */ public class RoundedClipRectModifierOperation extends DrawBase4 implements ModifierOperation, DecoratorComponent { public static final int OP_CODE = Operations.MODIFIER_ROUNDED_CLIP_RECT; @@ -52,44 +50,41 @@ public class RoundedClipRectModifierOperation extends DrawBase4 return CLASS_NAME; } - - protected void write(WireBuffer buffer, - float v1, - float v2, - float v3, - float v4) { + @Override + protected void write(WireBuffer buffer, float v1, float v2, float v3, float v4) { apply(buffer, v1, v2, v3, v4); } public static void documentation(DocumentationBuilder doc) { - doc.operation("Modifier Operations", - id(), - "RoundedClipRectModifierOperation") + doc.operation("Modifier Operations", id(), "RoundedClipRectModifierOperation") .description("clip with rectangle") - .field(FLOAT, "topStart", + .field( + FLOAT, + "topStart", "The topStart radius of the rectangle to " + "intersect with the current clip") - .field(FLOAT, "topEnd", + .field( + FLOAT, + "topEnd", "The topEnd radius of the rectangle to " + "intersect with the current clip") - .field(FLOAT, "bottomStart", + .field( + FLOAT, + "bottomStart", "The bottomStart radius of the rectangle to " + "intersect with the current clip") - .field(FLOAT, "bottomEnd", + .field( + FLOAT, + "bottomEnd", "The bottomEnd radius of the rectangle to " + "intersect with the current clip"); } - float mWidth; float mHeight; - public RoundedClipRectModifierOperation( - float topStart, - float topEnd, - float bottomStart, - float bottomEnd) { + float topStart, float topEnd, float bottomStart, float bottomEnd) { super(topStart, topEnd, bottomStart, bottomEnd); mName = CLASS_NAME; } @@ -106,33 +101,41 @@ public class RoundedClipRectModifierOperation extends DrawBase4 } @Override - public void onClick(RemoteContext context, CoreDocument document, - Component component, float x, float y) { + public void onClick( + RemoteContext context, CoreDocument document, Component component, float x, float y) { // nothing } @Override public void serializeToString(int indent, StringSerializer serializer) { serializer.append( - indent, "ROUNDED_CLIP_RECT = [" + mWidth + ", " + mHeight - + ", " + mX1 + ", " + mY1 - + ", " + mX2 + ", " + mY2 + "]"); + indent, + "ROUNDED_CLIP_RECT = [" + + mWidth + + ", " + + mHeight + + ", " + + mX1 + + ", " + + mY1 + + ", " + + mX2 + + ", " + + mY2 + + "]"); } /** * Writes out the rounded rect clip to the buffer * - * @param buffer buffer to write to - * @param topStart topStart radius - * @param topEnd topEnd radius - * @param bottomStart bottomStart radius - * @param bottomEnd bottomEnd radius + * @param buffer buffer to write to + * @param topStart topStart radius + * @param topEnd topEnd radius + * @param bottomStart bottomStart radius + * @param bottomEnd bottomEnd radius */ - public static void apply(WireBuffer buffer, - float topStart, - float topEnd, - float bottomStart, - float bottomEnd) { + public static void apply( + WireBuffer buffer, float topStart, float topEnd, float bottomStart, float bottomEnd) { write(buffer, OP_CODE, topStart, topEnd, bottomStart, bottomEnd); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ShapeType.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ShapeType.java index e425b4e0cc0a..0cd062eb25c3 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ShapeType.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ShapeType.java @@ -15,9 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.modifiers; -/** - * Known shapes, used for modifiers (clip/background/border) - */ +/** Known shapes, used for modifiers (clip/background/border) */ public class ShapeType { public static int RECTANGLE = 0; public static int CIRCLE = 1; diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerChangeActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerChangeActionOperation.java index 3f19c9b1bc4b..8876720c9990 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerChangeActionOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerChangeActionOperation.java @@ -15,7 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.modifiers; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.CoreDocument; import com.android.internal.widget.remotecompose.core.Operation; @@ -29,9 +29,7 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.Strin import java.util.List; -/** - * Apply a value change on an integer variable. - */ +/** Apply a value change on an integer variable. */ public class ValueIntegerChangeActionOperation implements ActionOperation { private static final int OP_CODE = Operations.VALUE_INTEGER_CHANGE_ACTION; @@ -54,28 +52,23 @@ public class ValueIntegerChangeActionOperation implements ActionOperation { @Override public void serializeToString(int indent, StringSerializer serializer) { - serializer.append(indent, serializedName() - + " = " + mTargetValueId + " -> " + mValue); + serializer.append(indent, serializedName() + " = " + mTargetValueId + " -> " + mValue); } @Override - public void apply(RemoteContext context) { - } + public void apply(RemoteContext context) {} @Override public String deepToString(String indent) { return (indent != null ? indent : "") + toString(); } - @Override - public void write(WireBuffer buffer) { - - } + public void write(WireBuffer buffer) {} @Override - public void runAction(RemoteContext context, CoreDocument document, - Component component, float x, float y) { + public void runAction( + RemoteContext context, CoreDocument document, Component component, float x, float y) { context.overrideInteger(mTargetValueId, mValue); } @@ -93,11 +86,10 @@ public class ValueIntegerChangeActionOperation implements ActionOperation { public static void documentation(DocumentationBuilder doc) { doc.operation("Layout Operations", OP_CODE, "ValueIntegerChangeActionOperation") - .description("ValueIntegerChange action. " - + " This operation represents a value change for the given id") + .description( + "ValueIntegerChange action. " + + " This operation represents a value change for the given id") .field(INT, "TARGET_VALUE_ID", "Value ID") - .field(INT, "VALUE", "integer value to be assigned to the target") - ; + .field(INT, "VALUE", "integer value to be assigned to the target"); } - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerExpressionChangeActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerExpressionChangeActionOperation.java new file mode 100644 index 000000000000..fb5e911e8bc6 --- /dev/null +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerExpressionChangeActionOperation.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.widget.remotecompose.core.operations.layout.modifiers; + +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; + +import com.android.internal.widget.remotecompose.core.CoreDocument; +import com.android.internal.widget.remotecompose.core.Operation; +import com.android.internal.widget.remotecompose.core.Operations; +import com.android.internal.widget.remotecompose.core.RemoteContext; +import com.android.internal.widget.remotecompose.core.WireBuffer; +import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.operations.layout.ActionOperation; +import com.android.internal.widget.remotecompose.core.operations.layout.Component; +import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer; + +import java.util.List; + +/** Apply a value change on an integer variable. */ +public class ValueIntegerExpressionChangeActionOperation implements ActionOperation { + private static final int OP_CODE = Operations.VALUE_INTEGER_EXPRESSION_CHANGE_ACTION; + + long mTargetValueId = -1; + long mValueExpressionId = -1; + + public ValueIntegerExpressionChangeActionOperation(long id, long value) { + mTargetValueId = id; + mValueExpressionId = value; + } + + @Override + public String toString() { + return "ValueIntegerExpressionChangeActionOperation(" + mTargetValueId + ")"; + } + + public String serializedName() { + return "VALUE_INTEGER_EXPRESSION_CHANGE"; + } + + @Override + public void serializeToString(int indent, StringSerializer serializer) { + serializer.append( + indent, serializedName() + " = " + mTargetValueId + " -> " + mValueExpressionId); + } + + @Override + public void apply(RemoteContext context) {} + + @Override + public String deepToString(String indent) { + return (indent != null ? indent : "") + toString(); + } + + @Override + public void write(WireBuffer buffer) {} + + @Override + public void runAction( + RemoteContext context, CoreDocument document, Component component, float x, float y) { + document.evaluateIntExpression(mValueExpressionId, (int) mTargetValueId, context); + } + + public static void apply(WireBuffer buffer, long valueId, long value) { + buffer.start(OP_CODE); + buffer.writeLong(valueId); + buffer.writeLong(value); + } + + public static void read(WireBuffer buffer, List<Operation> operations) { + long valueId = buffer.readLong(); + long value = buffer.readLong(); + operations.add(new ValueIntegerExpressionChangeActionOperation(valueId, value)); + } + + public static void documentation(DocumentationBuilder doc) { + doc.operation("Layout Operations", OP_CODE, "ValueIntegerExpressionChangeActionOperation") + .description( + "ValueIntegerExpressionChange action. " + + " This operation represents a value change for the given id") + .field(INT, "TARGET_VALUE_ID", "Value ID") + .field(INT, "VALUE_ID", "id of the value to be assigned to the target"); + } +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueStringChangeActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueStringChangeActionOperation.java index e2542e529383..a64a492a8cc1 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueStringChangeActionOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueStringChangeActionOperation.java @@ -15,7 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.modifiers; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.CoreDocument; import com.android.internal.widget.remotecompose.core.Operation; @@ -29,9 +29,7 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.Strin import java.util.List; -/** - * Apply a value change on a string variable. - */ +/** Apply a value change on a string variable. */ public class ValueStringChangeActionOperation implements ActionOperation { private static final int OP_CODE = Operations.VALUE_STRING_CHANGE_ACTION; @@ -62,8 +60,7 @@ public class ValueStringChangeActionOperation implements ActionOperation { } @Override - public void apply(RemoteContext context) { - } + public void apply(RemoteContext context) {} @Override public String deepToString(String indent) { @@ -71,13 +68,11 @@ public class ValueStringChangeActionOperation implements ActionOperation { } @Override - public void write(WireBuffer buffer) { - - } + public void write(WireBuffer buffer) {} @Override - public void runAction(RemoteContext context, CoreDocument document, - Component component, float x, float y) { + public void runAction( + RemoteContext context, CoreDocument document, Component component, float x, float y) { context.overrideText(mTargetValueId, mValueId); } @@ -95,13 +90,14 @@ public class ValueStringChangeActionOperation implements ActionOperation { public static void documentation(DocumentationBuilder doc) { doc.operation("Layout Operations", OP_CODE, "ValueStringChangeActionOperation") - .description("ValueStrin gChange action. " - + " This operation represents a String change (referenced by id) " - + "for the given string id") + .description( + "ValueStrin gChange action. " + + " This operation represents a String change (referenced by id) " + + "for the given string id") .field(INT, "TARGET_ID", "Target Value ID") - .field(INT, "VALUE_ID", "Value ID to be assigned to the target " - + "value as a string") - ; + .field( + INT, + "VALUE_ID", + "Value ID to be assigned to the target " + "value as a string"); } - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java index 7fd5e51add18..62403b3e5e7e 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java @@ -15,8 +15,8 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.modifiers; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; @@ -25,14 +25,11 @@ import com.android.internal.widget.remotecompose.core.documentation.Documentatio import java.util.List; -/** - * Set the width dimension on a component - */ +/** Set the width dimension on a component */ public class WidthModifierOperation extends DimensionModifierOperation { private static final int OP_CODE = Operations.MODIFIER_WIDTH; public static final String CLASS_NAME = "WidthModifierOperation"; - public static String name() { return CLASS_NAME; } @@ -82,9 +79,7 @@ public class WidthModifierOperation extends DimensionModifierOperation { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Modifier Operations", - OP_CODE, - CLASS_NAME) + doc.operation("Modifier Operations", OP_CODE, CLASS_NAME) .description("define the animation") .field(INT, "type", "") .field(FLOAT, "value", ""); diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java index 7ccf7f48af24..4849b12c65b1 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java @@ -17,9 +17,7 @@ package com.android.internal.widget.remotecompose.core.operations.layout.utils; import java.util.ArrayList; -/** - * Internal utility debug class - */ +/** Internal utility debug class */ public class DebugLog { public static final boolean DEBUG_LAYOUT_ON = false; @@ -109,8 +107,12 @@ public class DebugLog { if (node instanceof LogNode) { builder.append(indentation).append(" ").append(node.name).append("\n"); } else { - builder.append(indentation).append("-- ").append(node.name) - .append(" : ").append(node.endString).append("\n"); + builder.append(indentation) + .append("-- ") + .append(node.name) + .append(" : ") + .append(node.endString) + .append("\n"); } } } @@ -124,4 +126,3 @@ public class DebugLog { } } } - diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/StringValueSupplier.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/StringValueSupplier.java index 79ef16bf25da..701167abb8f0 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/StringValueSupplier.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/StringValueSupplier.java @@ -15,12 +15,11 @@ */ package com.android.internal.widget.remotecompose.core.operations.layout.utils; -/** - * Basic interface for a lambda (used for logging) - */ +/** Basic interface for a lambda (used for logging) */ public interface StringValueSupplier { /** * returns a string value + * * @return a string */ String getString(); diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintBundle.java b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintBundle.java index 6c8049a97f1e..e714947c6a5c 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintBundle.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintBundle.java @@ -23,9 +23,7 @@ import com.android.internal.widget.remotecompose.core.operations.Utils; import java.util.Arrays; -/** - * Paint Bundle represents a delta of changes to a paint object - */ +/** Paint Bundle represents a delta of changes to a paint object */ public class PaintBundle { int[] mArray = new int[200]; int[] mOutArray = null; @@ -33,6 +31,7 @@ public class PaintBundle { /** * Apply changes to a PaintChanges interface + * * @param paintContext * @param p */ @@ -46,10 +45,9 @@ public class PaintBundle { int cmd = mOutArray[i++]; mask = mask | (1 << (cmd - 1)); switch (cmd & 0xFFFF) { - case TEXT_SIZE: { + case TEXT_SIZE: p.setTextSize(Float.intBitsToFloat(mOutArray[i++])); break; - } case TYPEFACE: int style = (cmd >> 16); int weight = style & 0x3ff; @@ -59,99 +57,86 @@ public class PaintBundle { p.setTypeFace(font_type, weight, italic); break; case COLOR_ID: // mOutArray should have already decoded it - case COLOR: { + case COLOR: p.setColor(mOutArray[i++]); break; - } - case STROKE_WIDTH: { + case STROKE_WIDTH: p.setStrokeWidth(Float.intBitsToFloat(mOutArray[i++])); break; - } - case STROKE_MITER: { + case STROKE_MITER: p.setStrokeMiter(Float.intBitsToFloat(mOutArray[i++])); break; - } - case STROKE_CAP: { + case STROKE_CAP: p.setStrokeCap(cmd >> 16); break; - } - case STYLE: { + case STYLE: p.setStyle(cmd >> 16); break; - } - case SHADER: { + case SHADER: p.setShader(mOutArray[i++]); break; - } - case STROKE_JOIN: { + case STROKE_JOIN: p.setStrokeJoin(cmd >> 16); break; - } - case IMAGE_FILTER_QUALITY: { + case IMAGE_FILTER_QUALITY: p.setImageFilterQuality(cmd >> 16); break; - } - case BLEND_MODE: { + case BLEND_MODE: p.setBlendMode(cmd >> 16); break; - } - case FILTER_BITMAP: { + case FILTER_BITMAP: p.setFilterBitmap(!((cmd >> 16) == 0)); break; - } - case GRADIENT: { + case GRADIENT: i = callSetGradient(cmd, mOutArray, i, p); break; - } - case COLOR_FILTER: { + case COLOR_FILTER_ID: + case COLOR_FILTER: p.setColorFilter(mOutArray[i++], cmd >> 16); break; - } - case ALPHA: { + case ALPHA: p.setAlpha(Float.intBitsToFloat(mOutArray[i++])); break; - } + case CLEAR_COLOR_FILTER: + p.clear(0x1L << PaintBundle.COLOR_FILTER); + break; } } - - mask = (~mask) & PaintChanges.VALID_BITS; - - p.clear(mask); } - private String toName(int id) { - switch (id) { - case TEXT_SIZE: - return "TEXT_SIZE"; - case COLOR: - return "COLOR"; - case STROKE_WIDTH: - return "STROKE_WIDTH"; - case STROKE_MITER: - return "STROKE_MITER"; - case TYPEFACE: - return "TYPEFACE"; - case STROKE_CAP: - return "CAP"; - case STYLE: - return "STYLE"; - case SHADER: - return "SHADER"; - case IMAGE_FILTER_QUALITY: - return "IMAGE_FILTER_QUALITY"; - case BLEND_MODE: - return "BLEND_MODE"; - case FILTER_BITMAP: - return "FILTER_BITMAP"; - case GRADIENT: - return "GRADIENT_LINEAR"; - case ALPHA: - return "ALPHA"; - case COLOR_FILTER: - return "COLOR_FILTER"; - } - return "????" + id + "????"; - } + // private String toName(int id) { + // switch (id) { + // case TEXT_SIZE: + // return "TEXT_SIZE"; + // case COLOR: + // return "COLOR"; + // case STROKE_WIDTH: + // return "STROKE_WIDTH"; + // case STROKE_MITER: + // return "STROKE_MITER"; + // case TYPEFACE: + // return "TYPEFACE"; + // case STROKE_CAP: + // return "CAP"; + // case STYLE: + // return "STYLE"; + // case SHADER: + // return "SHADER"; + // case IMAGE_FILTER_QUALITY: + // return "IMAGE_FILTER_QUALITY"; + // case BLEND_MODE: + // return "BLEND_MODE"; + // case FILTER_BITMAP: + // return "FILTER_BITMAP"; + // case GRADIENT: + // return "GRADIENT_LINEAR"; + // case ALPHA: + // return "ALPHA"; + // case COLOR_FILTER: + // return "COLOR_FILTER"; + // } + // return "????" + id + "????"; + // } private static String colorInt(int color) { String str = "000000000000" + Integer.toHexString(color); @@ -185,103 +170,189 @@ public class PaintBundle { int cmd = mArray[i++]; int type = cmd & 0xFFFF; switch (type) { - - case TEXT_SIZE: { - ret.append(" TextSize(" - + asFloatStr(mArray[i++])); - } - - break; - case TYPEFACE: { + case TEXT_SIZE: + ret.append(" TextSize(" + asFloatStr(mArray[i++])); + break; + case TYPEFACE: int style = (cmd >> 16); int weight = style & 0x3ff; boolean italic = (style >> 10) > 0; int font_type = mArray[i++]; - ret.append(" TypeFace(" + (font_type + ", " - + weight + ", " + italic)); - } - break; - case COLOR: { + ret.append(" TypeFace(" + (font_type + ", " + weight + ", " + italic)); + break; + case COLOR: ret.append(" Color(" + colorInt(mArray[i++])); - } - break; - case COLOR_ID: { + break; + case COLOR_ID: ret.append(" ColorId([" + mArray[i++] + "]"); - } - break; - case STROKE_WIDTH: { - ret.append(" StrokeWidth(" - + (asFloatStr(mArray[i++]))); - } - break; - case STROKE_MITER: { - ret.append(" StrokeMiter(" - + (asFloatStr(mArray[i++]))); - } - break; - case STROKE_CAP: { - ret.append(" StrokeCap(" - + (cmd >> 16)); - } - break; - case STYLE: { + break; + case STROKE_WIDTH: + ret.append(" StrokeWidth(" + asFloatStr(mArray[i++])); + break; + case STROKE_MITER: + ret.append(" StrokeMiter(" + asFloatStr(mArray[i++])); + break; + case STROKE_CAP: + ret.append(" StrokeCap(" + (cmd >> 16)); + break; + case STYLE: ret.append(" Style(" + (cmd >> 16)); - } - break; - case COLOR_FILTER: { - ret.append(" ColorFilter(color=" - + colorInt(mArray[i++]) - + ", mode=" + blendModeString(cmd >> 16)); - } - break; - case SHADER: { + break; + case COLOR_FILTER: + ret.append( + " ColorFilter(color=" + + colorInt(mArray[i++]) + + ", mode=" + + blendModeString(cmd >> 16)); + break; + case COLOR_FILTER_ID: + ret.append( + " ColorFilterID(color=[" + + mArray[i++] + + "], mode=" + + blendModeString(cmd >> 16)); + break; + case CLEAR_COLOR_FILTER: + ret.append(" clearColorFilter"); + break; + case SHADER: ret.append(" Shader(" + mArray[i++]); - } - break; - case ALPHA: { - ret.append(" Alpha(" - + (asFloatStr(mArray[i++]))); - } - break; - case IMAGE_FILTER_QUALITY: { + break; + case ALPHA: + ret.append(" Alpha(" + asFloatStr(mArray[i++])); + break; + case IMAGE_FILTER_QUALITY: ret.append(" ImageFilterQuality(" + (cmd >> 16)); - } - break; - case BLEND_MODE: { + break; + case BLEND_MODE: ret.append(" BlendMode(" + blendModeString(cmd >> 16)); + break; + case FILTER_BITMAP: + ret.append(" FilterBitmap(" + !(cmd >> 16 == 0)); + break; + case STROKE_JOIN: + ret.append(" StrokeJoin(" + (cmd >> 16)); + break; + case ANTI_ALIAS: + ret.append(" AntiAlias(" + (cmd >> 16)); + break; + case GRADIENT: + i = callPrintGradient(cmd, mArray, i, ret); + } + ret.append("),\n"); + } + return ret.toString(); + } + + private void registerFloat(int iv, RemoteContext context, VariableSupport support) { + float v = Float.intBitsToFloat(iv); + if (Float.isNaN(v)) { + context.listensTo(Utils.idFromNan(v), support); + } + } + + int callRegisterGradient( + int cmd, int[] array, int i, RemoteContext context, VariableSupport support) { + int ret = i; + int type = (cmd >> 16); + int control = array[ret++]; + int len = 0xFF & control; // maximum 256 colors + int register = 0xFFFF & (control >> 16); + int tileMode = 0; + switch (type) { + /* see {@link #setLinearGradient} */ + case LINEAR_GRADIENT: + if (len > 0) { + + for (int j = 0; j < len; j++) { + int color = array[ret++]; + if ((register & (1 << j)) != 0) { + context.listensTo(color, support); + } + } } - break; - case FILTER_BITMAP: { - ret.append(" FilterBitmap(" - + (!((cmd >> 16) == 0))); + len = array[ret++]; + + if (len > 0) { + + for (int j = 0; j < len; j++) { + registerFloat(array[ret++], context, support); + } } + + // start x + registerFloat(array[ret++], context, support); + // start y + registerFloat(array[ret++], context, support); + // end x + registerFloat(array[ret++], context, support); + // end y + registerFloat(array[ret++], context, support); + tileMode = array[ret++]; break; - case STROKE_JOIN: { - ret.append(" StrokeJoin(" + (cmd >> 16)); + /* see {@link #setRadialGradient} */ + case RADIAL_GRADIENT: + if (len > 0) { + + for (int j = 0; j < len; j++) { + int color = array[ret++]; + if ((register & (1 << j)) != 0) { + context.listensTo(color, support); + } + } } - break; - case ANTI_ALIAS: { - ret.append(" AntiAlias(" + (cmd >> 16)); + len = array[ret++]; // stops + for (int j = 0; j < len; j++) { + registerFloat(array[ret++], context, support); } + + // center x + registerFloat(array[ret++], context, support); + // center y + registerFloat(array[ret++], context, support); + // radius + registerFloat(array[ret++], context, support); + + tileMode = array[ret++]; // tile Mode break; - case GRADIENT: { - i = callPrintGradient(cmd, mArray, i, ret); + /* see {@link #setSweepGradient} */ + case SWEEP_GRADIENT: + if (len > 0) { + + for (int j = 0; j < len; j++) { + int color = array[ret++]; + if ((register & (1 << j)) != 0) { + context.listensTo(color, support); + } + } } - } - ret.append("),\n"); + + len = array[ret++]; // stops + for (int j = 0; j < len; j++) { + registerFloat(array[ret++], context, support); + } + // center x + registerFloat(array[ret++], context, support); + // center y + registerFloat(array[ret++], context, support); + break; + default: + System.out.println("error "); } - return ret.toString(); + + return ret; } int callPrintGradient(int cmd, int[] array, int i, StringBuilder p) { int ret = i; int type = (cmd >> 16); + int tileMode = 0; + int len = array[ret++]; + int[] colors = null; + String[] stops = null; switch (type) { - - case 0: { + case 0: p.append(" LinearGradient(\n"); - int len = array[ret++]; - int[] colors = null; if (len > 0) { colors = new int[len]; for (int j = 0; j < colors.length; j++) { @@ -289,7 +360,6 @@ public class PaintBundle { } } len = array[ret++]; - String[] stops = null; if (len > 0) { stops = new String[len]; for (int j = 0; j < stops.length; j++) { @@ -305,24 +375,18 @@ public class PaintBundle { p.append(" end = "); p.append("[" + asFloatStr(array[ret++])); p.append(", " + asFloatStr(array[ret++]) + "],\n"); - int tileMode = array[ret++]; + tileMode = array[ret++]; p.append(" tileMode = " + tileMode + "\n "); - } - - break; - case 1: { + break; + case 1: p.append(" RadialGradient(\n"); - int len = array[ret++]; - int[] colors = null; if (len > 0) { colors = new int[len]; for (int j = 0; j < colors.length; j++) { colors[j] = array[ret++]; - } } len = array[ret++]; - String[] stops = null; if (len > 0) { stops = new String[len]; for (int j = 0; j < stops.length; j++) { @@ -337,24 +401,18 @@ public class PaintBundle { p.append(", " + asFloatStr(array[ret++]) + "],\n"); p.append(" radius ="); p.append(" " + asFloatStr(array[ret++]) + ",\n"); - int tileMode = array[ret++]; + tileMode = array[ret++]; p.append(" tileMode = " + tileMode + "\n "); - } - - break; - case 2: { + break; + case 2: p.append(" SweepGradient(\n"); - int len = array[ret++]; - int[] colors = null; if (len > 0) { colors = new int[len]; for (int j = 0; j < colors.length; j++) { colors[j] = array[ret++]; - } } len = array[ret++]; - String[] stops = null; if (len > 0) { stops = new String[len]; for (int j = 0; j < stops.length; j++) { @@ -365,13 +423,10 @@ public class PaintBundle { p.append(" stops = " + Arrays.toString(stops) + ",\n"); p.append(" center = "); p.append("[" + asFloatStr(array[ret++])); - p.append(", " - + asFloatStr(array[ret++]) + "],\n "); - } - break; - default: { + p.append(", " + asFloatStr(array[ret++]) + "],\n "); + break; + default: p.append("GRADIENT_??????!!!!"); - } } return ret; @@ -381,7 +436,8 @@ public class PaintBundle { int ret = i; int gradientType = (cmd >> 16); - int len = array[ret++]; + int len = 0xFF & array[ret++]; // maximum 256 colors + int[] colors = null; if (len > 0) { colors = new int[len]; @@ -402,33 +458,30 @@ public class PaintBundle { return ret; } - switch (gradientType) { + int tileMode = 0; + float centerX = 0f; + float centerY = 0f; - case LINEAR_GRADIENT: { + switch (gradientType) { + case LINEAR_GRADIENT: float startX = Float.intBitsToFloat(array[ret++]); float startY = Float.intBitsToFloat(array[ret++]); float endX = Float.intBitsToFloat(array[ret++]); float endY = Float.intBitsToFloat(array[ret++]); - int tileMode = array[ret++]; - p.setLinearGradient(colors, stops, startX, - startY, endX, endY, tileMode); - } - - break; - case RADIAL_GRADIENT: { - float centerX = Float.intBitsToFloat(array[ret++]); - float centerY = Float.intBitsToFloat(array[ret++]); + tileMode = array[ret++]; + p.setLinearGradient(colors, stops, startX, startY, endX, endY, tileMode); + break; + case RADIAL_GRADIENT: + centerX = Float.intBitsToFloat(array[ret++]); + centerY = Float.intBitsToFloat(array[ret++]); float radius = Float.intBitsToFloat(array[ret++]); - int tileMode = array[ret++]; - p.setRadialGradient(colors, stops, centerX, centerY, - radius, tileMode); - } - break; - case SWEEP_GRADIENT: { - float centerX = Float.intBitsToFloat(array[ret++]); - float centerY = Float.intBitsToFloat(array[ret++]); + tileMode = array[ret++]; + p.setRadialGradient(colors, stops, centerX, centerY, radius, tileMode); + break; + case SWEEP_GRADIENT: + centerX = Float.intBitsToFloat(array[ret++]); + centerY = Float.intBitsToFloat(array[ret++]); p.setSweepGradient(colors, stops, centerX, centerY); - } } return ret; @@ -453,9 +506,9 @@ public class PaintBundle { mPos = len; } - public static final int TEXT_SIZE = 1; // float + public static final int TEXT_SIZE = 1; // float - public static final int COLOR = 4; // int + public static final int COLOR = 4; // int public static final int STROKE_WIDTH = 5; // float public static final int STROKE_MITER = 6; public static final int STROKE_CAP = 7; // int @@ -470,7 +523,9 @@ public class PaintBundle { public static final int TYPEFACE = 16; public static final int FILTER_BITMAP = 17; public static final int BLEND_MODE = 18; - public static final int COLOR_ID = 19; // int + public static final int COLOR_ID = 19; + public static final int COLOR_FILTER_ID = 20; + public static final int CLEAR_COLOR_FILTER = 21; public static final int BLEND_MODE_CLEAR = 0; public static final int BLEND_MODE_SRC = 1; @@ -524,27 +579,28 @@ public class PaintBundle { /** * sets a shader that draws a linear gradient along a line. * - * @param startX The x-coordinate for the start of the gradient line - * @param startY The y-coordinate for the start of the gradient line - * @param endX The x-coordinate for the end of the gradient line - * @param endY The y-coordinate for the end of the gradient line - * @param colors The sRGB colors to be distributed along the gradient line - * @param stops May be null. The relative positions [0..1] of - * each corresponding color in the colors array. If this is null, - * the colors are distributed evenly along the gradient line. + * @param startX The x-coordinate for the start of the gradient line + * @param startY The y-coordinate for the start of the gradient line + * @param endX The x-coordinate for the end of the gradient line + * @param endY The y-coordinate for the end of the gradient line + * @param colors The sRGB colors to be distributed along the gradient line + * @param stops May be null. The relative positions [0..1] of each corresponding color in the + * colors array. If this is null, the colors are distributed evenly along the gradient line. * @param tileMode The Shader tiling mode */ - public void setLinearGradient(int[] colors, - float[] stops, - float startX, - float startY, - float endX, - float endY, - int tileMode) { - int startPos = mPos; + public void setLinearGradient( + int[] colors, + int idMask, + float[] stops, + float startX, + float startY, + float endX, + float endY, + int tileMode) { + // int startPos = mPos; int len; mArray[mPos++] = GRADIENT | (LINEAR_GRADIENT << 16); - mArray[mPos++] = len = (colors == null) ? 0 : colors.length; + mArray[mPos++] = (idMask << 16) | (len = (colors == null) ? 0 : colors.length); for (int i = 0; i < len; i++) { mArray[mPos++] = colors[i]; } @@ -565,20 +621,18 @@ public class PaintBundle { * * @param centerX The x-coordinate of the center * @param centerY The y-coordinate of the center - * @param colors The sRGB colors to be distributed around the center. - * There must be at least 2 colors in the array. - * @param stops May be NULL. The relative position of - * each corresponding color in the colors array, beginning - * with 0 and ending with 1.0. If the values are not - * monotonic, the drawing may produce unexpected results. - * If positions is NULL, then the colors are automatically - * spaced evenly. + * @param colors The sRGB colors to be distributed around the center. There must be at least 2 + * colors in the array. + * @param stops May be NULL. The relative position of each corresponding color in the colors + * array, beginning with 0 and ending with 1.0. If the values are not monotonic, the drawing + * may produce unexpected results. If positions is NULL, then the colors are automatically + * spaced evenly. */ - public void setSweepGradient(int[] colors, float[] stops, float centerX, float centerY) { - int startPos = mPos; + public void setSweepGradient( + int[] colors, int idMask, float[] stops, float centerX, float centerY) { int len; mArray[mPos++] = GRADIENT | (SWEEP_GRADIENT << 16); - mArray[mPos++] = len = (colors == null) ? 0 : colors.length; + mArray[mPos++] = (idMask << 16) | (len = (colors == null) ? 0 : colors.length); for (int i = 0; i < len; i++) { mArray[mPos++] = colors[i]; } @@ -594,29 +648,28 @@ public class PaintBundle { /** * Sets a shader that draws a radial gradient given the center and radius. * - * @param centerX The x-coordinate of the center of the radius - * @param centerY The y-coordinate of the center of the radius - * @param radius Must be positive. The radius of the gradient. - * @param colors The sRGB colors distributed between the center and edge - * @param stops May be <code>null</code>. - * Valid values are between <code>0.0f</code> and - * <code>1.0f</code>. The relative position of each - * corresponding color in - * the colors array. If <code>null</code>, colors are - * distributed evenly - * between the center and edge of the circle. + * @param centerX The x-coordinate of the center of the radius + * @param centerY The y-coordinate of the center of the radius + * @param radius Must be positive. The radius of the gradient. + * @param colors The sRGB colors distributed between the center and edge + * @param stops May be <code>null</code>. Valid values are between <code>0.0f</code> and <code> + * 1.0f</code>. The relative position of each corresponding color in the colors array. If + * <code>null</code>, colors are distributed evenly between the center and edge of the + * circle. * @param tileMode The Shader tiling mode */ - public void setRadialGradient(int[] colors, - float[] stops, - float centerX, - float centerY, - float radius, - int tileMode) { - int startPos = mPos; + public void setRadialGradient( + int[] colors, + int idMask, + float[] stops, + float centerX, + float centerY, + float radius, + int tileMode) { + // int startPos = mPos; int len; mArray[mPos++] = GRADIENT | (RADIAL_GRADIENT << 16); - mArray[mPos++] = len = (colors == null) ? 0 : colors.length; + mArray[mPos++] = (idMask << 16) | (len = (colors == null) ? 0 : colors.length); for (int i = 0; i < len; i++) { mArray[mPos++] = colors[i]; } @@ -629,14 +682,13 @@ public class PaintBundle { mArray[mPos++] = Float.floatToRawIntBits(centerY); mArray[mPos++] = Float.floatToRawIntBits(radius); mArray[mPos++] = tileMode; - } /** * Create a color filter that uses the specified color and Porter-Duff mode. * * @param color The ARGB source color used with the Porter-Duff mode - * @param mode The porter-duff mode that is applied + * @param mode The porter-duff mode that is applied */ public void setColorFilter(int color, int mode) { mArray[mPos] = COLOR_FILTER | (mode << 16); @@ -645,12 +697,29 @@ public class PaintBundle { } /** + * Create a color filter that uses the specified color and Porter-Duff mode. + * + * @param color The id source color used with the Porter-Duff mode + * @param mode The porter-duff mode that is applied + */ + public void setColorFilterId(int color, int mode) { + mArray[mPos] = COLOR_FILTER_ID | (mode << 16); + mPos++; + mArray[mPos++] = color; + } + + /** This sets the color filter to null */ + public void clearColorFilter() { + mArray[mPos] = CLEAR_COLOR_FILTER; + mPos++; + } + + /** * Set the paint's text size. This value must be > 0 * * @param size set the paint's text size in pixel units. */ public void setTextSize(float size) { - int p = mPos; mArray[mPos] = TEXT_SIZE; mPos++; mArray[mPos] = Float.floatToRawIntBits(size); @@ -659,22 +728,21 @@ public class PaintBundle { /** * @param fontType 0 = default 1 = sans serif 2 = serif 3 = monospace - * @param weight 100-1000 - * @param italic tur + * @param weight 100-1000 + * @param italic tur */ public void setTextStyle(int fontType, int weight, boolean italic) { - int style = (weight & 0x3FF) | (italic ? 2048 : 0); // pack the weight and italic + int style = (weight & 0x3FF) | (italic ? 2048 : 0); // pack the weight and italic mArray[mPos++] = TYPEFACE | (style << 16); mArray[mPos++] = fontType; } /** - * Set the width for stroking. - * Pass 0 to stroke in hairline mode. - * Hairlines always draws a single pixel independent of the canvas's matrix. + * Set the width for stroking. Pass 0 to stroke in hairline mode. Hairlines always draws a + * single pixel independent of the canvas's matrix. * - * @param width set the paint's stroke width, used whenever the paint's - * style is Stroke or StrokeAndFill. + * @param width set the paint's stroke width, used whenever the paint's style is Stroke or + * StrokeAndFill. */ public void setStrokeWidth(float width) { mArray[mPos] = STROKE_WIDTH; @@ -685,6 +753,7 @@ public class PaintBundle { /** * Set the Color based on Color + * * @param color */ public void setColor(int color) { @@ -696,6 +765,7 @@ public class PaintBundle { /** * Set the color based the R,G,B,A values + * * @param r red (0 to 255) * @param g green (0 to 255) * @param b blue (0 to 255) @@ -708,6 +778,7 @@ public class PaintBundle { /** * Set the color based the R,G,B,A values + * * @param r red (0.0 to 1.0) * @param g green (0.0 to 1.0) * @param b blue (0.0 to 1.0) @@ -719,6 +790,7 @@ public class PaintBundle { /** * Set the Color based on ID + * * @param color */ public void setColorId(int color) { @@ -728,12 +800,11 @@ public class PaintBundle { mPos++; } - /** * Set the paint's Cap. * - * @param cap set the paint's line cap style, used whenever the paint's - * style is Stroke or StrokeAndFill. + * @param cap set the paint's line cap style, used whenever the paint's style is Stroke or + * StrokeAndFill. */ public void setStrokeCap(int cap) { mArray[mPos] = STROKE_CAP | (cap << 16); @@ -742,6 +813,7 @@ public class PaintBundle { /** * Set the style STROKE and/or FILL + * * @param style */ public void setStyle(int style) { @@ -751,6 +823,7 @@ public class PaintBundle { /** * Set the shader id to use + * * @param shaderId */ public void setShader(int shaderId) { @@ -760,9 +833,7 @@ public class PaintBundle { mPos++; } - /** - * Set the Alpha value - */ + /** Set the Alpha value */ public void setAlpha(float alpha) { mArray[mPos] = ALPHA; mPos++; @@ -771,11 +842,11 @@ public class PaintBundle { } /** - * Set the paint's stroke miter value. This is used to control the behavior - * of miter joins when the joins angle is sharp. This value must be >= 0. + * Set the paint's stroke miter value. This is used to control the behavior of miter joins when + * the joins angle is sharp. This value must be >= 0. * - * @param miter set the miter limit on the paint, used whenever the paint's - * style is Stroke or StrokeAndFill. + * @param miter set the miter limit on the paint, used whenever the paint's style is Stroke or + * StrokeAndFill. */ public void setStrokeMiter(float miter) { mArray[mPos] = STROKE_MITER; @@ -787,8 +858,7 @@ public class PaintBundle { /** * Set the paint's Join. * - * @param join set the paint's Join, used whenever the paint's style is - * Stroke or StrokeAndFill. + * @param join set the paint's Join, used whenever the paint's style is Stroke or StrokeAndFill. */ public void setStrokeJoin(int join) { mArray[mPos] = STROKE_JOIN | (join << 16); @@ -801,10 +871,8 @@ public class PaintBundle { } /** - * Set or clear the blend mode. A blend mode defines how source pixels - * (generated by a drawing command) are composited with the - * destination pixels - * (content of the render target). + * Set or clear the blend mode. A blend mode defines how source pixels (generated by a drawing + * command) are composited with the destination pixels (content of the render target). * * @param blendmode The blend mode to be installed in the paint */ @@ -814,15 +882,14 @@ public class PaintBundle { } /** - * Helper for setFlags(), setting or clearing the ANTI_ALIAS_FLAG bit - * AntiAliasing smooths out the edges of what is being drawn, but is has - * no impact on the interior of the shape. See setDither() and - * setFilterBitmap() to affect how colors are treated. + * Helper for setFlags(), setting or clearing the ANTI_ALIAS_FLAG bit AntiAliasing smooths out + * the edges of what is being drawn, but is has no impact on the interior of the shape. See + * setDither() and setFilterBitmap() to affect how colors are treated. * * @param aa true to set the antialias bit in the flags, false to clear it */ public void setAntiAlias(boolean aa) { - mArray[mPos] = ANTI_ALIAS | (((aa) ? 1 : 0) << 16); + mArray[mPos] = ANTI_ALIAS | (aa ? 1 : 0) << 16; mPos++; } @@ -903,6 +970,7 @@ public class PaintBundle { /** * Check all the floats for Nan(id) floats and call listenTo + * * @param context * @param support */ @@ -921,6 +989,7 @@ public class PaintBundle { context.listensTo(Utils.idFromNan(v), support); } break; + case COLOR_FILTER_ID: case COLOR_ID: context.listensTo(mArray[i++], support); break; @@ -940,16 +1009,15 @@ public class PaintBundle { case ANTI_ALIAS: break; - case GRADIENT: { - // TODO gradients should be handled correctly - i = callPrintGradient(cmd, mArray, i, new StringBuilder()); - } + case GRADIENT: + i = callRegisterGradient(cmd, mArray, i, context, support); } } } /** * Update variables if any are float ids + * * @param context */ public void updateVariables(RemoteContext context) { @@ -970,6 +1038,7 @@ public class PaintBundle { mOutArray[i] = fixFloatVar(mArray[i], context); i++; break; + case COLOR_FILTER_ID: case COLOR_ID: mOutArray[i] = fixColor(mArray[i], context); i++; @@ -987,12 +1056,12 @@ public class PaintBundle { case IMAGE_FILTER_QUALITY: case BLEND_MODE: case ANTI_ALIAS: + case CLEAR_COLOR_FILTER: break; - case GRADIENT: { + case GRADIENT: // TODO gradients should be handled correctly i = updateFloatsInGradient(cmd, mOutArray, mArray, i, context); - } } } } @@ -1011,21 +1080,25 @@ public class PaintBundle { return n; } - int updateFloatsInGradient(int cmd, int[] out, int[] array, - int i, - RemoteContext context) { + int updateFloatsInGradient(int cmd, int[] out, int[] array, int i, RemoteContext context) { int ret = i; int type = (cmd >> 16); + int control = array[ret++]; + int len = 0xFF & control; // maximum 256 colors + int register = 0xFFFF & (control >> 16); switch (type) { - case 0: { - int len = array[ret++]; + case LINEAR_GRADIENT: if (len > 0) { + for (int j = 0; j < len; j++) { + int color = array[ret]; + if ((register & (1 << j)) != 0) { + out[ret] = fixColor(color, context); + } ret++; } } len = array[ret++]; - if (len > 0) { for (int j = 0; j < len; j++) { out[ret] = fixFloatVar(array[ret], context); @@ -1044,14 +1117,16 @@ public class PaintBundle { out[ret] = fixFloatVar(array[ret], context); ret++; ret++; // tileMode - } - - break; - case 1: { + break; + case RADIAL_GRADIENT: // RadialGradient - int len = array[ret++]; if (len > 0) { + for (int j = 0; j < len; j++) { + int color = array[ret]; + if ((register & (1 << j)) != 0) { + out[ret] = fixColor(color, context); + } ret++; } } @@ -1063,7 +1138,6 @@ public class PaintBundle { } } - // center out[ret] = fixFloatVar(array[ret], context); ret++; @@ -1073,19 +1147,17 @@ public class PaintBundle { out[ret] = fixFloatVar(array[ret], context); ret++; ret++; // tileMode - - } - - break; - case 2: { + break; + case SWEEP_GRADIENT: // SweepGradient - int len = array[ret++]; - int[] colors = null; if (len > 0) { - colors = new int[len]; - for (int j = 0; j < colors.length; j++) { - colors[j] = array[ret++]; + for (int j = 0; j < len; j++) { + int color = array[ret]; + if ((register & (1 << j)) != 0) { + out[ret] = fixColor(color, context); + } + ret++; } } len = array[ret++]; @@ -1103,14 +1175,12 @@ public class PaintBundle { ret++; out[ret] = fixFloatVar(array[ret], context); ret++; - } - break; - default: { + + break; + default: System.err.println("gradient type unknown"); - } } return ret; } - -}
\ No newline at end of file +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintChangeAdapter.java b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintChangeAdapter.java index 28fe63a03c67..e2402be4e4d4 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintChangeAdapter.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintChangeAdapter.java @@ -18,112 +18,73 @@ package com.android.internal.widget.remotecompose.core.operations.paint; public class PaintChangeAdapter implements PaintChanges { @Override - public void setTextSize(float size) { - - } + public void setTextSize(float size) {} @Override - public void setTypeFace(int fontType, int weight, boolean italic) { - - } + public void setTypeFace(int fontType, int weight, boolean italic) {} @Override - public void setStrokeWidth(float width) { - - } + public void setStrokeWidth(float width) {} @Override - public void setColor(int color) { - - } + public void setColor(int color) {} @Override - public void setStrokeCap(int cap) { - - } + public void setStrokeCap(int cap) {} @Override - public void setStyle(int style) { - - } + public void setStyle(int style) {} @Override - public void setShader(int shader) { - - } + public void setShader(int shader) {} @Override - public void setImageFilterQuality(int quality) { - - } + public void setImageFilterQuality(int quality) {} @Override - public void setAlpha(float a) { - - } + public void setAlpha(float a) {} @Override - public void setStrokeMiter(float miter) { - - } + public void setStrokeMiter(float miter) {} @Override - public void setStrokeJoin(int join) { - - } + public void setStrokeJoin(int join) {} @Override - public void setFilterBitmap(boolean filter) { - - } + public void setFilterBitmap(boolean filter) {} @Override - public void setBlendMode(int blendmode) { - - } + public void setBlendMode(int blendmode) {} @Override - public void setAntiAlias(boolean aa) { - - } + public void setAntiAlias(boolean aa) {} @Override - public void clear(long mask) { - - } + public void clear(long mask) {} @Override - public void setLinearGradient(int[] colorsArray, - float[] stopsArray, - float startX, - float startY, - float endX, - float endY, - int tileMode) { - - } + public void setLinearGradient( + int[] colorsArray, + float[] stopsArray, + float startX, + float startY, + float endX, + float endY, + int tileMode) {} @Override - public void setRadialGradient(int[] colorsArray, - float[] stopsArray, - float centerX, - float centerY, - float radius, - int tileMode) { - - } + public void setRadialGradient( + int[] colorsArray, + float[] stopsArray, + float centerX, + float centerY, + float radius, + int tileMode) {} @Override - public void setSweepGradient(int[] colorsArray, - float[] stopsArray, - float centerX, - float centerY) { - - } + public void setSweepGradient( + int[] colorsArray, float[] stopsArray, float centerX, float centerY) {} @Override - public void setColorFilter(int color, int mode) { - - } - + public void setColorFilter(int color, int mode) {} } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintChanges.java b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintChanges.java index d5dc3889add3..486d763cb6d5 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintChanges.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintChanges.java @@ -15,10 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.paint; -/** - * Interface to a paint object - * For more details see Android Paint - */ +/** Interface to a paint object For more details see Android Paint */ public interface PaintChanges { // MASK to be set/cleared @@ -30,8 +27,7 @@ public interface PaintChanges { int CLEAR_CAP = 1 << (PaintBundle.STROKE_CAP - 1); int CLEAR_STYLE = 1 << (PaintBundle.STYLE - 1); int CLEAR_SHADER = 1 << (PaintBundle.SHADER - 1); - int CLEAR_IMAGE_FILTER_QUALITY = - 1 << (PaintBundle.IMAGE_FILTER_QUALITY - 1); + int CLEAR_IMAGE_FILTER_QUALITY = 1 << (PaintBundle.IMAGE_FILTER_QUALITY - 1); int CLEAR_RADIENT = 1 << (PaintBundle.GRADIENT - 1); int CLEAR_ALPHA = 1 << (PaintBundle.ALPHA - 1); int CLEAR_COLOR_FILTER = 1 << (PaintBundle.COLOR_FILTER - 1); @@ -39,91 +35,105 @@ public interface PaintChanges { /** * Set the size of text + * * @param size */ void setTextSize(float size); /** * Set the width of lines + * * @param width */ void setStrokeWidth(float width); /** * Set the color to use + * * @param color */ void setColor(int color); /** * Set the Stroke Cap + * * @param cap */ void setStrokeCap(int cap); /** * Set the Stroke style FILL and/or STROKE + * * @param style */ void setStyle(int style); /** * Set the id of the shader to use + * * @param shader */ void setShader(int shader); /** * Set the way image is interpolated + * * @param quality */ void setImageFilterQuality(int quality); /** * Set the alpha to draw under + * * @param a */ void setAlpha(float a); /** * Set the Stroke Miter + * * @param miter */ void setStrokeMiter(float miter); /** * Set the Stroke Join + * * @param join */ void setStrokeJoin(int join); /** * Should bitmaps be interpolated + * * @param filter */ void setFilterBitmap(boolean filter); /** * Set the blend mode can be porterduff + others + * * @param mode */ void setBlendMode(int mode); /** - * Set the AntiAlias. Typically true - * Set to off when you need pixilated look (e.g. QR codes) + * Set the AntiAlias. Typically true Set to off when you need pixilated look (e.g. QR codes) + * * @param aa */ void setAntiAlias(boolean aa); /** * Clear some sub set of the settings + * * @param mask */ void clear(long mask); /** * Set a linear gradient fill + * * @param colorsArray * @param stopsArray * @param startX @@ -139,11 +149,11 @@ public interface PaintChanges { float startY, float endX, float endY, - int tileMode - ); + int tileMode); /** * Set a radial gradient fill + * * @param colorsArray * @param stopsArray * @param centerX @@ -157,36 +167,32 @@ public interface PaintChanges { float centerX, float centerY, float radius, - int tileMode - ); + int tileMode); /** * Set a sweep gradient fill + * * @param colorsArray * @param stopsArray * @param centerX * @param centerY */ - void setSweepGradient( - int[] colorsArray, - float[] stopsArray, - float centerX, - float centerY - ); + void setSweepGradient(int[] colorsArray, float[] stopsArray, float centerX, float centerY); /** * Set Color filter mod + * * @param color * @param mode */ void setColorFilter(int color, int mode); /** - * Set TypeFace 0,1,2 - * TODO above should point to a string to be decoded + * Set TypeFace 0,1,2 TODO above should point to a string to be decoded + * * @param fontType * @param weight * @param italic */ void setTypeFace(int fontType, int weight, boolean italic); -}
\ No newline at end of file +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/Painter.java b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/Painter.java index ada3757bd4ca..9a3cd54c3f85 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/Painter.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/Painter.java @@ -15,16 +15,11 @@ */ package com.android.internal.widget.remotecompose.core.operations.paint; - -/** - * Provides a Builder pattern for a PaintBundle - */ +/** Provides a Builder pattern for a PaintBundle */ class Painter { PaintBundle mPaint; - /** - * Write the paint to the buffer - */ + /** Write the paint to the buffer */ public PaintBundle commit() { return mPaint; } @@ -47,8 +42,7 @@ class Painter { /** * Set the paint's Join. * - * @param join set the paint's Join, used whenever the paint's style is - * Stroke or StrokeAndFill. + * @param join set the paint's Join, used whenever the paint's style is Stroke or StrokeAndFill. */ public Painter setStrokeJoin(int join) { mPaint.setStrokeJoin(join); @@ -56,12 +50,11 @@ class Painter { } /** - * Set the width for stroking. Pass 0 to stroke in hairline mode. - * Hairlines always draws a single - * pixel independent of the canvas's matrix. + * Set the width for stroking. Pass 0 to stroke in hairline mode. Hairlines always draws a + * single pixel independent of the canvas's matrix. * - * @param width set the paint's stroke width, used whenever the paint's - * style is Stroke or StrokeAndFill. + * @param width set the paint's stroke width, used whenever the paint's style is Stroke or + * StrokeAndFill. */ public Painter setStrokeWidth(float width) { mPaint.setStrokeWidth(width); @@ -69,8 +62,8 @@ class Painter { } /** - * Set the paint's style, used for controlling how primitives' geometries - * are interpreted (except for drawBitmap, which always assumes Fill). + * Set the paint's style, used for controlling how primitives' geometries are interpreted + * (except for drawBitmap, which always assumes Fill). * * @param style The new style to set in the paint */ @@ -82,8 +75,8 @@ class Painter { /** * Set the paint's Cap. * - * @param cap set the paint's line cap style, used whenever the paint's - * style is Stroke or StrokeAndFill. + * @param cap set the paint's line cap style, used whenever the paint's style is Stroke or + * StrokeAndFill. */ public Painter setStrokeCap(int cap) { mPaint.setStrokeCap(cap); @@ -91,11 +84,11 @@ class Painter { } /** - * Set the paint's stroke miter value. This is used to control the behavior - * of miter joins when the joins angle is sharp. This value must be >= 0. + * Set the paint's stroke miter value. This is used to control the behavior of miter joins when + * the joins angle is sharp. This value must be >= 0. * - * @param miter set the miter limit on the paint, used whenever the paint's - * style is Stroke or StrokeAndFill. + * @param miter set the miter limit on the paint, used whenever the paint's style is Stroke or + * StrokeAndFill. */ public Painter setStrokeMiter(float miter) { mPaint.setStrokeMiter(miter); @@ -103,9 +96,8 @@ class Painter { } /** - * Helper to setColor(), that only assigns the color's alpha value, - * leaving its r,g,b values unchanged. Results are undefined if the alpha - * value is outside of the range [0..1.0] + * Helper to setColor(), that only assigns the color's alpha value, leaving its r,g,b values + * unchanged. Results are undefined if the alpha value is outside of the range [0..1.0] * * @param alpha set the alpha component [0..1.0] of the paint's color. */ @@ -117,9 +109,8 @@ class Painter { /** * Create a color filter that uses the specified color and Porter-Duff mode. * - * @param color The ARGB source color used with the specified Porter-Duff - * mode - * @param mode The porter-duff mode that is applied + * @param color The ARGB source color used with the specified Porter-Duff mode + * @param mode The porter-duff mode that is applied */ public Painter setPorterDuffColorFilter(int color, int mode) { mPaint.setColorFilter(color, mode); @@ -129,17 +120,15 @@ class Painter { /** * sets a shader that draws a linear gradient along a line. * - * @param startX The x-coordinate for the start of the gradient line - * @param startY The y-coordinate for the start of the gradient line - * @param endX The x-coordinate for the end of the gradient line - * @param endY The y-coordinate for the end of the gradient line - * @param colors The sRGB colors to be distributed along the gradient - * line - * @param positions May be null. The relative positions [0..1] of each - * corresponding color in the colors array. If this is null, - * the colors are distributed evenly along the gradient - * line. - * @param tileMode The Shader tiling mode + * @param startX The x-coordinate for the start of the gradient line + * @param startY The y-coordinate for the start of the gradient line + * @param endX The x-coordinate for the end of the gradient line + * @param endY The y-coordinate for the end of the gradient line + * @param colors The sRGB colors to be distributed along the gradient line + * @param positions May be null. The relative positions [0..1] of each corresponding color in + * the colors array. If this is null, the colors are distributed evenly along the gradient + * line. + * @param tileMode The Shader tiling mode */ public Painter setLinearGradient( float startX, @@ -148,29 +137,23 @@ class Painter { float endY, int[] colors, float[] positions, - int tileMode - ) { - mPaint.setLinearGradient(colors, positions, startX, - startY, endX, endY, tileMode); + int tileMode) { + mPaint.setLinearGradient(colors, 0, positions, startX, startY, endX, endY, tileMode); return this; } /** * Sets a shader that draws a radial gradient given the center and radius. * - * @param centerX The x-coordinate of the center of the radius - * @param centerY The y-coordinate of the center of the radius - * @param radius Must be positive. The radius of the circle for this - * gradient. - * @param colors The sRGB colors to be distributed between the center - * and edge of the circle - * @param positions May be <code>null</code>. Valid values are between - * <code>0.0f</code> and - * <code>1.0f</code>. The relative position of each - * corresponding color in the colors array. If - * <code>null</code>, colors are distributed evenly - * between the center and edge of the circle. - * @param tileMode The Shader tiling mode + * @param centerX The x-coordinate of the center of the radius + * @param centerY The y-coordinate of the center of the radius + * @param radius Must be positive. The radius of the circle for this gradient. + * @param colors The sRGB colors to be distributed between the center and edge of the circle + * @param positions May be <code>null</code>. Valid values are between <code>0.0f</code> and + * <code>1.0f</code>. The relative position of each corresponding color in the colors array. + * If <code>null</code>, colors are distributed evenly between the center and edge of the + * circle. + * @param tileMode The Shader tiling mode */ public Painter setRadialGradient( float centerX, @@ -178,33 +161,25 @@ class Painter { float radius, int[] colors, float[] positions, - int tileMode - ) { - mPaint.setRadialGradient(colors, positions, centerX, - centerY, radius, tileMode); + int tileMode) { + mPaint.setRadialGradient(colors, 0, positions, centerX, centerY, radius, tileMode); return this; } /** * Set a shader that draws a sweep gradient around a center point. * - * @param centerX The x-coordinate of the center - * @param centerY The y-coordinate of the center - * @param colors The sRGB colors to be distributed between around the - * center. There must be at least 2 colors in the array. - * @param positions May be NULL. The relative position of each corresponding - * color in the colors array, beginning with 0 and ending - * with 1.0. If the values are not monotonic, the drawing - * may produce unexpected results. If positions is NULL, - * then the colors are automatically spaced evenly. + * @param centerX The x-coordinate of the center + * @param centerY The y-coordinate of the center + * @param colors The sRGB colors to be distributed between around the center. There must be at + * least 2 colors in the array. + * @param positions May be NULL. The relative position of each corresponding color in the colors + * array, beginning with 0 and ending with 1.0. If the values are not monotonic, the drawing + * may produce unexpected results. If positions is NULL, then the colors are automatically + * spaced evenly. */ - public Painter setSweepGradient( - float centerX, - float centerY, - int[] colors, - float[] positions - ) { - mPaint.setSweepGradient(colors, positions, centerX, centerY); + public Painter setSweepGradient(float centerX, float centerY, int[] colors, float[] positions) { + mPaint.setSweepGradient(colors, 0, positions, centerX, centerY); return this; } @@ -219,10 +194,11 @@ class Painter { } /** - * sets a typeface object that best matches the specified existing - * typeface and the specified weight and italic style + * sets a typeface object that best matches the specified existing typeface and the specified + * weight and italic style + * + * <p>Below are numerical values and corresponding common weight names. * - * <p>Below are numerical values and corresponding common weight names.</p> * <table> <thead> * <tr><th>Value</th><th>Common weight name</th></tr> </thead> <tbody> * <tr><td>100</td><td>Thin</td></tr> @@ -236,25 +212,21 @@ class Painter { * <tr><td>900</td><td>Black</td></tr> </tbody> </table> * * @param fontType 0 = default 1 = sans serif 2 = serif 3 = monospace - * @param weight The desired weight to be drawn. - * @param italic {@code true} if italic style is desired to be drawn. - * Otherwise, {@code false} + * @param weight The desired weight to be drawn. + * @param italic {@code true} if italic style is desired to be drawn. Otherwise, {@code false} */ public Painter setTypeface(int fontType, int weight, boolean italic) { mPaint.setTextStyle(fontType, weight, italic); return this; } - public Painter setFilterBitmap(boolean filter) { mPaint.setFilterBitmap(filter); return this; } - public Painter setShader(int id) { mPaint.setShader(id); return this; } - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java index 5b295eb700ec..1d673c4c5ab6 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java @@ -15,9 +15,6 @@ */ package com.android.internal.widget.remotecompose.core.operations.utilities; -import static com.android.internal.widget.remotecompose.core.operations.utilities.NanMap.ID_REGION_ARRAY; -import static com.android.internal.widget.remotecompose.core.operations.utilities.NanMap.ID_REGION_MASK; - /** * high performance floating point expression evaluator used in animation */ @@ -59,7 +56,6 @@ public class AnimatedFloatExpression { public static final float RAD = asNan(OFFSET + 30); public static final float CEIL = asNan(OFFSET + 31); - // Array ops public static final float A_DEREF = asNan(OFFSET + 32); public static final float A_MAX = asNan(OFFSET + 33); @@ -69,14 +65,13 @@ public class AnimatedFloatExpression { public static final float A_LEN = asNan(OFFSET + 37); public static final int LAST_OP = OFFSET + 37; - public static final float VAR1 = asNan(OFFSET + 38); public static final float VAR2 = asNan(OFFSET + 39); // TODO CLAMP, CBRT, DEG, RAD, EXPM1, CEIL, FLOOR - private static final float FP_PI = (float) Math.PI; - private static final float FP_TO_RAD = 57.29577951f; // 180/PI - private static final float FP_TO_DEG = 0.01745329252f; // 180/PI + // private static final float FP_PI = (float) Math.PI; + private static final float FP_TO_RAD = 57.29578f; // 180/PI + private static final float FP_TO_DEG = 0.017453292f; // 180/PI float[] mStack; float[] mLocalStack = new float[128]; @@ -106,20 +101,13 @@ public class AnimatedFloatExpression { int eval(int sp); } - /** - * Evaluate a float expression - * This system works by processing an Array of float (float[]) - * in reverse polish notation (rpn) - * Within that array some floats are commands - * they are encoded within an NaN. - * After processing the array the last item on the array is returned. - * The system supports variables allowing expressions like. - * sin(sqrt(x*x+y*y))/sqrt(x*x+y*y) - * Where x & y are passe as parameters - * Examples: - * (1+2) (1, 2, ADD) adds two numbers returns 3 - * eval(new float[]{ Var1, Var * } + * Evaluate a float expression This system works by processing an Array of float (float[]) in + * reverse polish notation (rpn) Within that array some floats are commands they are encoded + * within an NaN. After processing the array the last item on the array is returned. The system + * supports variables allowing expressions like. sin(sqrt(x*x+y*y))/sqrt(x*x+y*y) Where x & y + * are passe as parameters Examples: (1+2) (1, 2, ADD) adds two numbers returns 3 eval(new + * float[]{ Var1, Var * } * * @param exp * @param var @@ -140,7 +128,6 @@ public class AnimatedFloatExpression { return mStack[sp]; } - /** * Evaluate a float expression * @@ -149,8 +136,9 @@ public class AnimatedFloatExpression { * @param var * @return */ - public float eval(CollectionsAccess ca, float[] exp, float... var) { - mStack = exp; + public float eval(CollectionsAccess ca, float[] exp, int len, float... var) { + System.arraycopy(exp, 0, mLocalStack, 0, len); + mStack = mLocalStack; mVar = var; mCollectionsAccess = ca; int sp = -1; @@ -159,7 +147,7 @@ public class AnimatedFloatExpression { float v = mStack[i]; if (Float.isNaN(v)) { int id = fromNaN(v); - if ((id & ID_REGION_MASK) != ID_REGION_ARRAY) { + if ((id & NanMap.ID_REGION_MASK) != NanMap.ID_REGION_ARRAY) { sp = mOps[id - OFFSET].eval(sp); } else { mStack[++sp] = v; @@ -171,6 +159,34 @@ public class AnimatedFloatExpression { return mStack[sp]; } + /** + * Evaluate a float expression + * + * @param ca + * @param exp + * @return + */ + public float eval(CollectionsAccess ca, float[] exp, int len) { + System.arraycopy(exp, 0, mLocalStack, 0, len); + mStack = mLocalStack; + mCollectionsAccess = ca; + int sp = -1; + + for (int i = 0; i < len; i++) { + float v = mStack[i]; + if (Float.isNaN(v)) { + int id = fromNaN(v); + if ((id & NanMap.ID_REGION_MASK) != NanMap.ID_REGION_ARRAY) { + sp = mOps[id - OFFSET].eval(sp); + } else { + mStack[++sp] = v; + } + } else { + mStack[++sp] = v; + } + } + return mStack[sp]; + } private int dereference(CollectionsAccess ca, int id, int sp) { mStack[sp] = ca.getFloatValue(id, (int) (mStack[sp])); @@ -238,11 +254,11 @@ public class AnimatedFloatExpression { mStack[sp - 1] = mStack[sp - 1] * mStack[sp]; return sp - 1; }, - (sp) -> { // DIV + (sp) -> { // DIV mStack[sp - 1] = mStack[sp - 1] / mStack[sp]; return sp - 1; }, - (sp) -> { // MOD + (sp) -> { // MOD mStack[sp - 1] = mStack[sp - 1] % mStack[sp]; return sp - 1; }, @@ -327,13 +343,11 @@ public class AnimatedFloatExpression { return sp - 2; }, (sp) -> { // Ternary conditional - mStack[sp - 2] = (mStack[sp] > 0) - ? mStack[sp - 1] : mStack[sp - 2]; + mStack[sp - 2] = (mStack[sp] > 0) ? mStack[sp - 1] : mStack[sp - 2]; return sp - 2; }, (sp) -> { // CLAMP(min,max, val) - mStack[sp - 2] = Math.min(Math.max(mStack[sp - 2], mStack[sp]), - mStack[sp - 1]); + mStack[sp - 2] = Math.min(Math.max(mStack[sp - 2], mStack[sp]), mStack[sp - 1]); return sp - 2; }, (sp) -> { // CBRT cuberoot @@ -354,7 +368,7 @@ public class AnimatedFloatExpression { }, (sp) -> { // A_DEREF int id = fromNaN(mStack[sp]); - mStack[sp] = mCollectionsAccess.getFloatValue(id, (int) (mStack[sp - 1])); + mStack[sp] = mCollectionsAccess.getFloatValue(id, (int) mStack[sp - 1]); return sp - 1; }, (sp) -> { // A_MAX @@ -399,11 +413,9 @@ public class AnimatedFloatExpression { }, (sp) -> { // A_LEN int id = fromNaN(mStack[sp]); - mStack[sp] = mCollectionsAccess.getFloatsLength(id); + mStack[sp] = mCollectionsAccess.getListLength(id); return sp; }, - - (sp) -> { // first var = mStack[sp] = mVar[0]; return sp; @@ -492,7 +504,8 @@ public class AnimatedFloatExpression { s.append(toMathName(v)); } else { int id = fromNaN(v); - String idString = (id > ID_REGION_ARRAY) ? ("A_" + (id & 0xFFFFF)) : "" + id; + String idString = + (id > NanMap.ID_REGION_ARRAY) ? ("A_" + (id & 0xFFFFF)) : "" + id; s.append("["); s.append(idString); s.append("]"); @@ -513,7 +526,7 @@ public class AnimatedFloatExpression { } static String toString(float[] exp, int sp) { - String[] str = new String[exp.length]; + // String[] str = new String[exp.length]; if (Float.isNaN(exp[sp])) { int id = fromNaN(exp[sp]) - OFFSET; switch (NO_OF_OPS[id]) { @@ -523,24 +536,38 @@ public class AnimatedFloatExpression { return sNames.get(id) + "(" + toString(exp, sp + 1) + ") "; case 2: if (infix(id)) { - return "(" + toString(exp, sp + 1) - + sNames.get(id) + " " - + toString(exp, sp + 2) + ") "; + return "(" + + toString(exp, sp + 1) + + sNames.get(id) + + " " + + toString(exp, sp + 2) + + ") "; } else { - return sNames.get(id) + "(" - + toString(exp, sp + 1) + ", " - + toString(exp, sp + 2) + ")"; + return sNames.get(id) + + "(" + + toString(exp, sp + 1) + + ", " + + toString(exp, sp + 2) + + ")"; } case 3: if (infix(id)) { - return "((" + toString(exp, sp + 1) + ") ? " - + toString(exp, sp + 2) + ":" - + toString(exp, sp + 3) + ")"; + return "((" + + toString(exp, sp + 1) + + ") ? " + + toString(exp, sp + 2) + + ":" + + toString(exp, sp + 3) + + ")"; } else { return sNames.get(id) - + "(" + toString(exp, sp + 1) - + ", " + toString(exp, sp + 2) - + ", " + toString(exp, sp + 3) + ")"; + + "(" + + toString(exp, sp + 1) + + ", " + + toString(exp, sp + 2) + + ", " + + toString(exp, sp + 3) + + ")"; } } } @@ -549,12 +576,40 @@ public class AnimatedFloatExpression { static final int[] NO_OF_OPS = { -1, // no op - 2, 2, 2, 2, 2, // + - * / % - 2, 2, 2, // min max, power - 1, 1, 1, 1, 1, 1, 1, 1, //sqrt,abs,CopySign,exp,floor,log,ln - 1, 1, 1, 1, 1, 1, 1, 2, // round,sin,cos,tan,asin,acos,atan,atan2 - 3, 3, 3, 1, 1, 1, 1, - 0, 0, 0 // mad, ?:, + 2, + 2, + 2, + 2, + 2, // + - * / % + 2, + 2, + 2, // min max, power + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, // sqrt,abs,CopySign,exp,floor,log,ln + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 2, // round,sin,cos,tan,asin,acos,atan,atan2 + 3, + 3, + 3, + 1, + 1, + 1, + 1, + 0, + 0, + 0 // mad, ?:, // a[0],a[1],a[2] }; diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ArrayAccess.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ArrayAccess.java index 4c7cc3889bcb..eb5e4828f2a0 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ArrayAccess.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ArrayAccess.java @@ -15,10 +15,21 @@ */ package com.android.internal.widget.remotecompose.core.operations.utilities; +/** + * Support a standardized interface to commands that contain arrays All commands that implement + * array access will be collected in a map in the state TODO refactor to DataAccess, + * FloatArrayAccess, ListAccess, MapAccess + */ public interface ArrayAccess { float getFloatValue(int index); + + default int getId(int index) { + return 0; + } + float[] getFloats(); - int getFloatsLength(); + + int getLength(); default int getIntValue(int index) { return (int) getFloatValue(index); diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/CollectionsAccess.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/CollectionsAccess.java index 9e5312676aa4..0128253e1f90 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/CollectionsAccess.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/CollectionsAccess.java @@ -15,12 +15,20 @@ */ package com.android.internal.widget.remotecompose.core.operations.utilities; +/** + * interface to allow expressions to access collections Todo define a convention for when access is + * unavailable + */ public interface CollectionsAccess { float getFloatValue(int id, int index); + float[] getFloats(int id); - int getFloatsLength(int id); - default int getIntValue(int id, int index) { - return (int) getFloatValue(id, index); + int getListLength(int id); + + int getId(int listId, int index); + + default int getIntValue(int listId, int index) { + return (int) getFloatValue(listId, index); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ColorUtils.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ColorUtils.java index fb96ceffa58a..937a25d2cda6 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ColorUtils.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ColorUtils.java @@ -16,21 +16,14 @@ package com.android.internal.widget.remotecompose.core.operations.utilities; /** - * These are tools to use long Color as variables - * long colors are stored a 0xXXXXXXXX XXXXXX?? - * in SRGB the colors are stored 0xAARRGGBB,00000000 - * SRGB color sapce is color space 0 - * Our Color will use color float with a - * Current android supports - * SRGB, LINEAR_SRGB, EXTENDED_SRGB, LINEAR_EXTENDED_SRGB, BT709, BT2020, - * DCI_P3, DISPLAY_P3, NTSC_1953, SMPTE_C, ADOBE_RGB, PRO_PHOTO_RGB, ACES, - * ACESCG, CIE_XYZ, CIE_LAB, BT2020_HLG, BT2020_PQ 0..17 respectively - * - * Our color space will be 62 (MAX_ID-1). (0x3E) - * Storing the default value in SRGB format and having the - * id of the color between the ARGB values and the 62 i.e. - * 0xAARRGGBB 00 00 00 3E + * These are tools to use long Color as variables long colors are stored a 0xXXXXXXXX XXXXXX?? in + * SRGB the colors are stored 0xAARRGGBB,00000000 SRGB color sapce is color space 0 Our Color will + * use color float with a Current android supports SRGB, LINEAR_SRGB, EXTENDED_SRGB, + * LINEAR_EXTENDED_SRGB, BT709, BT2020, DCI_P3, DISPLAY_P3, NTSC_1953, SMPTE_C, ADOBE_RGB, + * PRO_PHOTO_RGB, ACES, ACESCG, CIE_XYZ, CIE_LAB, BT2020_HLG, BT2020_PQ 0..17 respectively * + * <p>Our color space will be 62 (MAX_ID-1). (0x3E) Storing the default value in SRGB format and + * having the id of the color between the ARGB values and the 62 i.e. 0xAARRGGBB 00 00 00 3E */ public class ColorUtils { public static int RC_COLOR = 62; @@ -53,6 +46,7 @@ public class ColorUtils { /** * get default color from long color + * * @param color * @return */ diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/DataMap.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/DataMap.java new file mode 100644 index 000000000000..24f17d7b00c7 --- /dev/null +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/DataMap.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.widget.remotecompose.core.operations.utilities; + +public class DataMap { + public String[] mNames; + public int[] mIds; + public byte[] mTypes; + + public DataMap(String[] names, byte[] types, int[] ids) { + mNames = names; + mTypes = types; + mIds = ids; + } + + public int getPos(String str) { + for (int i = 0; i < mNames.length; i++) { + String name = mNames[i]; + if (str.equals(name)) { + return i; + } + } + return -1; + } + + public byte getType(int pos) { + return mTypes[pos]; + } + + public int getId(int pos) { + return mIds[pos]; + } +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ImageScaling.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ImageScaling.java new file mode 100644 index 000000000000..00c87c1f9c80 --- /dev/null +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ImageScaling.java @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.widget.remotecompose.core.operations.utilities; + +/** Implement the scaling logic for Compose Image or ImageView */ +public class ImageScaling { + + private static final boolean DEBUG = false; + + public static final int SCALE_NONE = 0; + public static final int SCALE_INSIDE = 1; + public static final int SCALE_FILL_WIDTH = 2; + public static final int SCALE_FILL_HEIGHT = 3; + public static final int SCALE_FIT = 4; + public static final int SCALE_CROP = 5; + public static final int SCALE_FILL_BOUNDS = 6; + public static final int SCALE_FIXED_SCALE = 7; + + private float mSrcLeft; + private float mSrcTop; + private float mSrcRight; + private float mSrcBottom; + private float mDstLeft; + private float mDstTop; + private float mDstRight; + private float mDstBottom; + private float mScaleFactor; + private int mScaleType; + + public float mFinalDstLeft; + public float mFinalDstTop; + public float mFinalDstRight; + public float mFinalDstBottom; + + public ImageScaling() {} + + public ImageScaling( + float srcLeft, + float srcTop, + float srcRight, + float srcBottom, + float dstLeft, + float dstTop, + float dstRight, + float dstBottom, + int type, + float scale) { + + mSrcLeft = srcLeft; + mSrcTop = srcTop; + mSrcRight = srcRight; + mSrcBottom = srcBottom; + mDstLeft = dstLeft; + mDstTop = dstTop; + mDstRight = dstRight; + mDstBottom = dstBottom; + mScaleType = type; + mScaleFactor = scale; + adjustDrawToType(); + } + + public void setup( + float srcLeft, + float srcTop, + float srcRight, + float srcBottom, + float dstLeft, + float dstTop, + float dstRight, + float dstBottom, + int type, + float scale) { + + mSrcLeft = srcLeft; + mSrcTop = srcTop; + mSrcRight = srcRight; + mSrcBottom = srcBottom; + mDstLeft = dstLeft; + mDstTop = dstTop; + mDstRight = dstRight; + mDstBottom = dstBottom; + mScaleType = type; + mScaleFactor = scale; + adjustDrawToType(); + } + + static String str(float v) { + String s = " " + (int) v; + return s.substring(s.length() - 3); + } + + void print(String str, float left, float top, float right, float bottom) { + String s = str; + s += str(left) + ", " + str(top) + ", " + str(right) + ", " + str(bottom) + ", "; + s += " [" + str(right - left) + " x " + str(bottom - top) + "]"; + System.out.println(s); + } + + /** This adjust destnation on the DrawBitMapInt to support all contentScale types */ + private void adjustDrawToType() { + int sw = (int) (mSrcRight - mSrcLeft); + int sh = (int) (mSrcBottom - mSrcTop); + float width = mDstRight - mDstLeft; + float height = mDstBottom - mDstTop; + int dw = (int) width; + int dh = (int) height; + int dLeft = 0; + int dRight = dw; + int dTop = 0; + int dBottom = dh; + if (DEBUG) { + print("test rc ", mSrcLeft, mSrcTop, mSrcRight, mSrcBottom); + print("test dst ", mDstLeft, mDstTop, mDstRight, mDstBottom); + } + + switch (mScaleType) { + case SCALE_NONE: + dh = sh; + dw = sw; + dTop = ((int) height - dh) / 2; + dBottom = dh + dTop; + dLeft = ((int) width - dw) / 2; + dRight = dw + dLeft; + break; + case SCALE_INSIDE: + if (dh > sh && dw > sw) { + dh = sh; + dw = sw; + } else if (sw * height > width * sh) { // width dominated + dh = (dw * sh) / sw; + } else { + dw = (dh * sw) / sh; + } + dTop = ((int) height - dh) / 2; + dBottom = dh + dTop; + dLeft = ((int) width - dw) / 2; + dRight = dw + dLeft; + break; + case SCALE_FILL_WIDTH: + dh = (dw * sh) / sw; + + dTop = ((int) height - dh) / 2; + dBottom = dh + dTop; + dLeft = ((int) width - dw) / 2; + dRight = dw + dLeft; + break; + case SCALE_FILL_HEIGHT: + dw = (dh * sw) / sh; + + dTop = ((int) height - dh) / 2; + dBottom = dh + dTop; + dLeft = ((int) width - dw) / 2; + dRight = dw + dLeft; + break; + case SCALE_FIT: + if (sw * height > width * sh) { // width dominated + dh = (dw * sh) / sw; + dTop = ((int) height - dh) / 2; + dBottom = dh + dTop; + } else { + dw = (dh * sw) / sh; + dLeft = ((int) width - dw) / 2; + dRight = dw + dLeft; + } + break; + case SCALE_CROP: + if (sw * height < width * sh) { // width dominated + dh = (dw * sh) / sw; + dTop = ((int) height - dh) / 2; + dBottom = dh + dTop; + } else { + dw = (dh * sw) / sh; + dLeft = ((int) width - dw) / 2; + dRight = dw + dLeft; + } + break; + case SCALE_FILL_BOUNDS: + // do nothing + break; + case SCALE_FIXED_SCALE: + dh = (int) (sh * mScaleFactor); + dw = (int) (sw * mScaleFactor); + dTop = ((int) height - dh) / 2; + dBottom = dh + dTop; + dLeft = ((int) width - dw) / 2; + dRight = dw + dLeft; + break; + } + + mFinalDstRight = dRight + mDstLeft; + mFinalDstLeft = dLeft + mDstLeft; + mFinalDstBottom = dBottom + mDstTop; + mFinalDstTop = dTop + mDstTop; + + if (DEBUG) { + print("test out ", mFinalDstLeft, mFinalDstTop, mFinalDstRight, mFinalDstBottom); + } + } + + public static String typeToString(int type) { + String[] typeString = { + "none", + "inside", + "fill_width", + "fill_height", + "fit", + "crop", + "fill_bounds", + "fixed_scale" + }; + return typeString[type]; + } +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntFloatMap.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntFloatMap.java index b2d714e08a0e..3b4ece937e58 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntFloatMap.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntFloatMap.java @@ -32,9 +32,7 @@ public class IntFloatMap { mValues = new float[DEFAULT_CAPACITY]; } - /** - * clear the map - */ + /** clear the map */ public void clear() { Arrays.fill(mKeys, NOT_PRESENT); Arrays.fill(mValues, Float.NaN); // not strictly necessary but defensive @@ -78,8 +76,7 @@ public class IntFloatMap { int index = findKey(key); if (index == -1) { return 0; - } else - return mValues[index]; + } else return mValues[index]; } /** diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntIntMap.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntIntMap.java index 606dc785eb20..68cd0e655028 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntIntMap.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntIntMap.java @@ -31,9 +31,7 @@ public class IntIntMap { mValues = new int[DEFAULT_CAPACITY]; } - /** - * clear the map - */ + /** clear the map */ public void clear() { Arrays.fill(mKeys, NOT_PRESENT); Arrays.fill(mValues, 0); @@ -77,8 +75,7 @@ public class IntIntMap { int index = findKey(key); if (index == -1) { return 0; - } else - return mValues[index]; + } else return mValues[index]; } /** diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntMap.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntMap.java index 0512fa6be710..84e78431790a 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntMap.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntMap.java @@ -42,7 +42,7 @@ public class IntMap<T> { mSize = 0; } - public T put(int key, T value) { + public T put(int key, T value) { if (key == NOT_PRESENT) throw new IllegalArgumentException("Key cannot be NOT_PRESENT"); if (mSize > mKeys.length * LOAD_FACTOR) { resize(); @@ -50,24 +50,23 @@ public class IntMap<T> { return insert(key, value); } - public T get(int key) { + public T get(int key) { int index = findKey(key); if (index == -1) { - return null; - } else - return mValues.get(index); + return null; + } else return mValues.get(index); } public int size() { return mSize; } - private T insert(int key, T value) { + private T insert(int key, T value) { int index = hash(key) % mKeys.length; while (mKeys[index] != NOT_PRESENT && mKeys[index] != key) { index = (index + 1) % mKeys.length; } - T oldValue = null; + T oldValue = null; if (mKeys[index] == NOT_PRESENT) { mSize++; } else { @@ -78,7 +77,7 @@ public class IntMap<T> { return oldValue; } - private int findKey(int key) { + private int findKey(int key) { int index = hash(key) % mKeys.length; while (mKeys[index] != NOT_PRESENT) { if (mKeys[index] == key) { @@ -89,11 +88,11 @@ public class IntMap<T> { return -1; } - private int hash(int key) { + private int hash(int key) { return key; } - private void resize() { + private void resize() { int[] oldKeys = mKeys; ArrayList<T> oldValues = mValues; mKeys = new int[(oldKeys.length * 2)]; @@ -111,4 +110,46 @@ public class IntMap<T> { } } } + + public T remove(int key) { + int index = hash(key) % mKeys.length; + int initialIndex = index; + + while (mKeys[index] != NOT_PRESENT) { + if (mKeys[index] == key) { + T oldValue = mValues.get(index); + mKeys[index] = NOT_PRESENT; + mValues.set(index, null); + mSize--; + + // Rehash the cluster of keys following the removed key + rehashFrom((index + 1) % mKeys.length); + return oldValue; + } + index = (index + 1) % mKeys.length; + if (index == initialIndex) { + break; // Avoid infinite loop + } + } + return null; // Key not found + } + + private void rehashFrom(int startIndex) { + int index = startIndex; + + while (mKeys[index] != NOT_PRESENT) { + int keyToRehash = mKeys[index]; + T valueToRehash = mValues.get(index); + + // Remove the key-value pair from the current position + mKeys[index] = NOT_PRESENT; + mValues.set(index, null); + mSize--; + + // Re-insert the key-value pair + insert(keyToRehash, valueToRehash); + + index = (index + 1) % mKeys.length; + } + } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java index ae61ec1e5eec..baa144d6b28d 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java @@ -18,8 +18,8 @@ package com.android.internal.widget.remotecompose.core.operations.utilities; /** * High performance Integer expression evaluator * - * The evaluation is based on int opMask, int[]exp - * exp[i] is an operator if (opMask*(1 << i) != 0) + * <p>The evaluation is based on int opMask, int[]exp exp[i] is an operator if (opMask*(1 << i) != + * 0) */ public class IntegerExpressionEvaluator { static IntMap<String> sNames = new IntMap<>(); @@ -51,26 +51,25 @@ public class IntegerExpressionEvaluator { public static final int I_IFELSE = OFFSET + 22; public static final int I_MAD = OFFSET + 23; - public static final float LAST_OP = 24; + public static final float LAST_OP = 25; public static final int I_VAR1 = OFFSET + 24; - public static final int I_VAR2 = OFFSET + 24; - + public static final int I_VAR2 = OFFSET + 25; int[] mStack; int[] mLocalStack = new int[128]; int[] mVar; - interface Op { int eval(int sp); } /** * Evaluate an integer expression + * * @param mask bits that are operators - * @param exp rpn sequence of values and operators - * @param var variables if the expression is a function + * @param exp rpn sequence of values and operators + * @param var variables if the expression is a function * @return return the results of evaluating the expression */ public int eval(int mask, int[] exp, int... var) { @@ -90,10 +89,11 @@ public class IntegerExpressionEvaluator { /** * Evaluate a integer expression + * * @param mask bits that are operators - * @param exp rpn sequence of values and operators - * @param len the number of values in the expression - * @param var variables if the expression is a function + * @param exp rpn sequence of values and operators + * @param len the number of values in the expression + * @param var variables if the expression is a function * @return return the results of evaluating the expression */ public int eval(int mask, int[] exp, int len, int... var) { @@ -114,9 +114,10 @@ public class IntegerExpressionEvaluator { /** * Evaluate a int expression + * * @param opMask bits that are operators - * @param exp rpn sequence of values and operators - * @param var variables if the expression is a function + * @param exp rpn sequence of values and operators + * @param var variables if the expression is a function * @return return the results of evaluating the expression */ public int evalDB(int opMask, int[] exp, int... var) { @@ -150,11 +151,11 @@ public class IntegerExpressionEvaluator { mStack[sp - 1] = mStack[sp - 1] * mStack[sp]; return sp - 1; }, - (sp) -> { // DIV + (sp) -> { // DIV mStack[sp - 1] = mStack[sp - 1] / mStack[sp]; return sp - 1; }, - (sp) -> { // MOD + (sp) -> { // MOD mStack[sp - 1] = mStack[sp - 1] % mStack[sp]; return sp - 1; }, @@ -183,8 +184,7 @@ public class IntegerExpressionEvaluator { return sp - 1; }, (sp) -> { // COPY_SIGN copy the sing of (using bit magic) - mStack[sp - 1] = (mStack[sp - 1] ^ (mStack[sp] >> 31)) - - (mStack[sp] >> 31); + mStack[sp - 1] = (mStack[sp - 1] ^ (mStack[sp] >> 31)) - (mStack[sp] >> 31); return sp - 1; }, (sp) -> { // MIN @@ -219,22 +219,18 @@ public class IntegerExpressionEvaluator { mStack[sp] = (mStack[sp] >> 31) | (-mStack[sp] >>> 31); return sp; }, - (sp) -> { // CLAMP(min,max, val) - mStack[sp - 2] = Math.min(Math.max(mStack[sp - 2], mStack[sp]), - mStack[sp - 1]); + mStack[sp - 2] = Math.min(Math.max(mStack[sp - 2], mStack[sp]), mStack[sp - 1]); return sp - 2; }, (sp) -> { // Ternary conditional - mStack[sp - 2] = (mStack[sp] > 0) - ? mStack[sp - 1] : mStack[sp - 2]; + mStack[sp - 2] = (mStack[sp] > 0) ? mStack[sp - 1] : mStack[sp - 2]; return sp - 2; }, (sp) -> { // MAD mStack[sp - 2] = mStack[sp] + mStack[sp - 1] * mStack[sp - 2]; return sp - 2; }, - (sp) -> { // first var = mStack[sp] = mVar[0]; return sp; @@ -296,7 +292,7 @@ public class IntegerExpressionEvaluator { * Convert an expression encoded as an array of ints int to a string * * @param opMask bits that are operators - * @param exp rpn sequence of values and operators + * @param exp rpn sequence of values and operators * @param labels String that represent the variable names * @return */ @@ -328,7 +324,7 @@ public class IntegerExpressionEvaluator { * Convert an expression encoded as an array of ints int ot a string * * @param opMask bit mask of operators vs commands - * @param exp rpn sequence of values and operators + * @param exp rpn sequence of values and operators * @return string representation of the expression */ public static String toString(int opMask, int[] exp) { @@ -357,8 +353,9 @@ public class IntegerExpressionEvaluator { /** * This creates an infix string expression + * * @param opMask The bits that are operators - * @param exp the array of expressions + * @param exp the array of expressions * @return infix string */ public static String toStringInfix(int opMask, int[] exp) { @@ -375,24 +372,39 @@ public class IntegerExpressionEvaluator { return sNames.get(id) + "(" + toString(mask, exp, sp - 1) + ") "; case 2: if (infix(id)) { - return "(" + toString(mask, exp, sp - 2) - + " " + sNames.get(id) + " " - + toString(mask, exp, sp - 1) + ") "; + return "(" + + toString(mask, exp, sp - 2) + + " " + + sNames.get(id) + + " " + + toString(mask, exp, sp - 1) + + ") "; } else { - return sNames.get(id) + "(" - + toString(mask, exp, sp - 2) + ", " - + toString(mask, exp, sp - 1) + ")"; + return sNames.get(id) + + "(" + + toString(mask, exp, sp - 2) + + ", " + + toString(mask, exp, sp - 1) + + ")"; } case 3: if (infix(id)) { - return "((" + toString(mask, exp, sp + 3) + ") ? " - + toString(mask, exp, sp - 2) + ":" - + toString(mask, exp, sp - 1) + ")"; + return "((" + + toString(mask, exp, sp + 3) + + ") ? " + + toString(mask, exp, sp - 2) + + ":" + + toString(mask, exp, sp - 1) + + ")"; } else { return sNames.get(id) - + "(" + toString(mask, exp, sp - 3) - + ", " + toString(mask, exp, sp - 2) - + ", " + toString(mask, exp, sp - 1) + ")"; + + "(" + + toString(mask, exp, sp - 3) + + ", " + + toString(mask, exp, sp - 2) + + ", " + + toString(mask, exp, sp - 1) + + ")"; } } } @@ -401,11 +413,32 @@ public class IntegerExpressionEvaluator { static final int[] NO_OF_OPS = { -1, // no op - 2, 2, 2, 2, 2, // + - * / % - 2, 2, 2, 2, 2, 2, 2, 2, 2, //<<, >> , >>> , | , &, ^, min max - 1, 1, 1, 1, 1, 1, // neg, abs, ++, -- , not , sign - 3, 3, 3, // clamp, ifElse, mad, - 0, 0, 0 // mad, ?:, + 2, + 2, + 2, + 2, + 2, // + - * / % + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, // <<, >> , >>> , | , &, ^, min max + 1, + 1, + 1, + 1, + 1, + 1, // neg, abs, ++, -- , not , sign + 3, + 3, + 3, // clamp, ifElse, mad, + 0, + 0, + 0 // mad, ?:, // a[0],a[1],a[2] }; @@ -416,13 +449,14 @@ public class IntegerExpressionEvaluator { * @return true if the operator is infix */ static boolean infix(int n) { - return ((n < 12)); + return n < 12; } /** * is it an id or operation + * * @param opMask the bits that mark elements as an operation - * @param i the bit to check + * @param i the bit to check * @return true if the bit is 1 */ public static boolean isOperation(int opMask, int i) { diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/NanMap.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/NanMap.java index 1e669c6b2e35..0616cc7306f5 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/NanMap.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/NanMap.java @@ -18,17 +18,12 @@ package com.android.internal.widget.remotecompose.core.operations.utilities; import com.android.internal.widget.remotecompose.core.operations.Utils; /** - * This defines the major id maps and ranges used by remote compose - * Generally ids ranging from 1 ... 7FFFFF (4095) are for ids - * The data range is divided int to bits - * 0xxxxx are allocated for Predefined Global System Variables - * 1xxxxx are allocated to normal variables - * 2xxxxx are allocated to List&MAPS (Arrays of stuff) - * 3xxxxx are allocated to path & float operations - * 4xxxxx,5xxxxx,7xxxxx are reserved for future use - * 0x1000-0x1100 are used for path operations in PathData - * 0x1100-0x1200 are used for math operations in Animated float - * 0x + * This defines the major id maps and ranges used by remote compose Generally ids ranging from 1 ... + * 7FFFFF (4095) are for ids The data range is divided int to bits 0xxxxx are allocated for + * Predefined Global System Variables 1xxxxx are allocated to normal variables 2xxxxx are allocated + * to List&MAPS (Arrays of stuff) 3xxxxx are allocated to path & float operations + * 4xxxxx,5xxxxx,7xxxxx are reserved for future use 0x1000-0x1100 are used for path operations in + * PathData 0x1100-0x1200 are used for math operations in Animated float 0x */ public class NanMap { public static final int MOVE = 0x300_000; @@ -71,7 +66,6 @@ public class NanMap { public static final int ID_REGION_MASK = 0x700000; public static final int ID_REGION_ARRAY = 0x200000; - /** * Get ID from Nan float * diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringSerializer.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringSerializer.java index fb9078104089..ab7576e12aa6 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringSerializer.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringSerializer.java @@ -15,15 +15,14 @@ */ package com.android.internal.widget.remotecompose.core.operations.utilities; -/** - * Utility serializer maintaining an indent buffer - */ +/** Utility serializer maintaining an indent buffer */ public class StringSerializer { StringBuffer mBuffer = new StringBuffer(); String mIndentBuffer = " "; /** * Append some content to the current buffer + * * @param indent the indentation level to use * @param content content to append */ @@ -35,17 +34,17 @@ public class StringSerializer { mBuffer.append("\n"); } - /** - * Reset the buffer - */ + /** Reset the buffer */ public void reset() { mBuffer = new StringBuffer(); } /** * Return a string representation of the buffer + * * @return string representation */ + @Override public String toString() { return mBuffer.toString(); } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringUtils.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringUtils.java index 8dd5405ddf12..f2ccb401ea8f 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringUtils.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringUtils.java @@ -17,26 +17,21 @@ package com.android.internal.widget.remotecompose.core.operations.utilities; import java.util.Arrays; -/** - * Utilities for string manipulation - */ +/** Utilities for string manipulation */ public class StringUtils { /** - * Converts a float into a string. - * Providing a defined number of characters before and after the + * Converts a float into a string. Providing a defined number of characters before and after the * decimal point. * - * @param value The value to convert to string + * @param value The value to convert to string * @param beforeDecimalPoint digits before the decimal point - * @param afterDecimalPoint digits after the decimal point - * @param pre character to pad width 0 = no pad typically ' ' or '0' - * @param post character to pad width 0 = no pad typically ' ' or '0' + * @param afterDecimalPoint digits after the decimal point + * @param pre character to pad width 0 = no pad typically ' ' or '0' + * @param post character to pad width 0 = no pad typically ' ' or '0' * @return */ - public static String floatToString(float value, - int beforeDecimalPoint, - int afterDecimalPoint, - char pre, char post) { + public static String floatToString( + float value, int beforeDecimalPoint, int afterDecimalPoint, char pre, char post) { int integerPart = (int) value; float fractionalPart = value % 1; @@ -52,7 +47,6 @@ public class StringUtils { integerPartString = new String(pad) + integerPartString; } - } else if (iLen > beforeDecimalPoint) { integerPartString = integerPartString.substring(iLen - beforeDecimalPoint); } @@ -68,7 +62,7 @@ public class StringUtils { fractionalPart = Math.round(fractionalPart); for (int i = 0; i < afterDecimalPoint; i++) { - fractionalPart *= .1; + fractionalPart *= .1F; } String fact = Float.toString(fractionalPart); @@ -92,5 +86,4 @@ public class StringUtils { return integerPartString + "." + fact; } - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/BounceCurve.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/BounceCurve.java index c3cd5ae9c79d..3161aa190895 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/BounceCurve.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/BounceCurve.java @@ -15,9 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.utilities.easing; -/** - * Provide a specific bouncing easing function - */ +/** Provide a specific bouncing easing function */ public class BounceCurve extends Easing { private static final float N1 = 7.5625f; private static final float D1 = 2.75f; @@ -63,5 +61,4 @@ public class BounceCurve extends Easing { } return 0f; } - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/CubicEasing.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/CubicEasing.java index fd1ee036e475..60a59cf464cd 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/CubicEasing.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/CubicEasing.java @@ -16,7 +16,6 @@ package com.android.internal.widget.remotecompose.core.operations.utilities.easing; class CubicEasing extends Easing { - float mType = 0; float mX1 = 0f; float mY1 = 0f; float mX2 = 0f; @@ -92,25 +91,24 @@ class CubicEasing extends Easing { return mY1 * f1 + mY2 * f2 + f3; } - private float getDiffX(float t) { - float t1 = 1 - t; - return 3 * t1 * t1 * mX1 + 6 * t1 * t * (mX2 - mX1) + 3 * t * t * (1 - mX2); - } + // private float getDiffX(float t) { + // float t1 = 1 - t; + // return 3 * t1 * t1 * mX1 + 6 * t1 * t * (mX2 - mX1) + 3 * t * t * (1 - mX2); + // } - private float getDiffY(float t) { - float t1 = 1 - t; - return 3 * t1 * t1 * mY1 + 6 * t1 * t * (mY2 - mY1) + 3 * t * t * (1 - mY2); - } + // private float getDiffY(float t) { + // float t1 = 1 - t; + // return 3 * t1 * t1 * mY1 + 6 * t1 * t * (mY2 - mY1) + 3 * t * t * (1 - mY2); + // } - /** - * binary search for the region and linear interpolate the answer - */ + /** binary search for the region and linear interpolate the answer */ + @Override public float getDiff(float x) { float t = 0.5f; float range = 0.5f; while (range > D_ERROR) { float tx = getX(t); - range *= 0.5; + range *= 0.5f; if (tx < x) { t += range; } else { @@ -124,9 +122,8 @@ class CubicEasing extends Easing { return (y2 - y1) / (x2 - x1); } - /** - * binary search for the region and linear interpolate the answer - */ + /** binary search for the region and linear interpolate the answer */ + @Override public float get(float x) { if (x <= 0.0f) { return 0f; diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/Easing.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/Easing.java index 4ed955069d78..d8bc83eb8a2e 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/Easing.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/Easing.java @@ -15,19 +15,14 @@ */ package com.android.internal.widget.remotecompose.core.operations.utilities.easing; -/** - * The standard interface to Easing functions - */ +/** The standard interface to Easing functions */ public abstract class Easing { int mType; - /** - * get the value at point x - */ + + /** get the value at point x */ public abstract float get(float x); - /** - * get the slope of the easing function at at x - */ + /** get the slope of the easing function at at x */ public abstract float getDiff(float x); public int getType() { @@ -44,5 +39,4 @@ public abstract class Easing { public static final int SPLINE_CUSTOM = 12; public static final int EASE_OUT_BOUNCE = 13; public static final int EASE_OUT_ELASTIC = 14; - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/ElasticOutCurve.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/ElasticOutCurve.java index e26958302e3c..d53cff597f3a 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/ElasticOutCurve.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/ElasticOutCurve.java @@ -15,9 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.utilities.easing; -/** - * Provide a bouncing Easing function - */ +/** Provide a bouncing Easing function */ public class ElasticOutCurve extends Easing { private static final float F_PI = (float) Math.PI; private static final float C4 = 2 * F_PI / 3; @@ -31,9 +29,7 @@ public class ElasticOutCurve extends Easing { } if (x >= 1) { return 1.0f; - } else - return (float) (Math.pow(2.0f, -10 * x) - * Math.sin((x * 10 - 0.75f) * C4) + 1); + } else return (float) (Math.pow(2.0f, -10 * x) * Math.sin((x * 10 - 0.75f) * C4) + 1); } @Override @@ -41,9 +37,11 @@ public class ElasticOutCurve extends Easing { if (x < 0 || x > 1) { return 0.0f; } else - return (float) ((5 * Math.pow(2.0f, (1 - 10 * x)) - * (LOG_8 * Math.cos(TWENTY_PI * x / 3) + 2 - * F_PI * Math.sin(TWENTY_PI * x / 3)) - / 3)); + return (float) + (5 + * Math.pow(2.0f, 1 - 10 * x) + * (LOG_8 * Math.cos(TWENTY_PI * x / 3) + + 2 * F_PI * Math.sin(TWENTY_PI * x / 3)) + / 3); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/FloatAnimation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/FloatAnimation.java index 98dbf0048abd..a29b8af5fbd1 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/FloatAnimation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/FloatAnimation.java @@ -15,9 +15,7 @@ */ package com.android.internal.widget.remotecompose.core.operations.utilities.easing; -/** - * Support Animation of the FloatExpression - */ +/** Support Animation of the FloatExpression */ public class FloatAnimation extends Easing { float[] mSpec; // mSpec[0] = duration @@ -25,12 +23,12 @@ public class FloatAnimation extends Easing { // mSpec[2..1+num_of_param] params // mSpec[2+num_of_param] starting Value Easing mEasingCurve; - private int mType = CUBIC_STANDARD; + private float mDuration = 1; private float mWrap = Float.NaN; private float mInitialValue = Float.NaN; private float mTargetValue = Float.NaN; - private float mScale = 1; + // private float mScale = 1; float mOffset = 0; @Override @@ -51,20 +49,19 @@ public class FloatAnimation extends Easing { } public FloatAnimation() { + mType = CUBIC_STANDARD; mEasingCurve = new CubicEasing(mType); } public FloatAnimation(float... description) { + mType = CUBIC_STANDARD; setAnimationDescription(description); } - public FloatAnimation(int type, - float duration, - float[] description, - float initialValue, - float wrap) { - setAnimationDescription(packToFloatArray(duration, - type, description, initialValue, wrap)); + public FloatAnimation( + int type, float duration, float[] description, float initialValue, float wrap) { + mType = CUBIC_STANDARD; + setAnimationDescription(packToFloatArray(duration, type, description, initialValue, wrap)); } /** @@ -76,11 +73,8 @@ public class FloatAnimation extends Easing { * @param initialValue * @return */ - public static float[] packToFloatArray(float duration, - int type, - float[] spec, - float initialValue, - float wrap) { + public static float[] packToFloatArray( + float duration, int type, float[] spec, float initialValue, float wrap) { int count = 0; if (!Float.isNaN(initialValue)) { @@ -104,7 +98,7 @@ public class FloatAnimation extends Easing { if (duration != 1 || count > 0) { count++; } - if (!Float.isNaN(wrap) || !Float.isNaN(initialValue)) { + if (!Float.isNaN(wrap) || !Float.isNaN(initialValue)) { count++; } float[] ret = new float[count]; @@ -113,11 +107,10 @@ public class FloatAnimation extends Easing { if (ret.length > 0) { ret[pos++] = duration; - } if (ret.length > 1) { - int wrapBit = (Float.isNaN(wrap)) ? 0 : 1; - int initBit = (Float.isNaN(initialValue)) ? 0 : 2; + int wrapBit = Float.isNaN(wrap) ? 0 : 1; + int initBit = Float.isNaN(initialValue) ? 0 : 2; int bits = type | ((wrapBit | initBit) << 8); ret[pos++] = Float.intBitsToFloat(specLen << 16 | bits); } @@ -137,6 +130,7 @@ public class FloatAnimation extends Easing { /** * Create an animation based on a float encoding of the animation + * * @param description */ public void setAnimationDescription(float[] description) { @@ -171,11 +165,12 @@ public class FloatAnimation extends Easing { mEasingCurve = new CubicEasing(type); break; case CUBIC_CUSTOM: - mEasingCurve = new CubicEasing(params[offset + 0], - params[offset + 1], - params[offset + 2], - params[offset + 3] - ); + mEasingCurve = + new CubicEasing( + params[offset + 0], + params[offset + 1], + params[offset + 2], + params[offset + 3]); break; case EASE_OUT_BOUNCE: mEasingCurve = new BounceCurve(type); @@ -191,6 +186,7 @@ public class FloatAnimation extends Easing { /** * Get the duration the interpolate is to take + * * @return duration in seconds */ public float getDuration() { @@ -199,6 +195,7 @@ public class FloatAnimation extends Easing { /** * Set the initial Value + * * @param value */ public void setInitialValue(float value) { @@ -213,6 +210,7 @@ public class FloatAnimation extends Easing { /** * Set the target value to interpolate to + * * @param value */ public void setTargetValue(float value) { @@ -236,25 +234,23 @@ public class FloatAnimation extends Easing { private void setScaleOffset() { if (!Float.isNaN(mInitialValue) && !Float.isNaN(mTargetValue)) { - mScale = (mTargetValue - mInitialValue); + // mScale = (mTargetValue - mInitialValue); // TODO: commented out because + // unused. mOffset = mInitialValue; } else { - mScale = 1; + // mScale = 1; // TODO: commented out because its unused mOffset = 0; } } - /** - * get the value at time t in seconds since start - */ + /** get the value at time t in seconds since start */ + @Override public float get(float t) { - return mEasingCurve.get(t / mDuration) - * (mTargetValue - mInitialValue) + mInitialValue; + return mEasingCurve.get(t / mDuration) * (mTargetValue - mInitialValue) + mInitialValue; } - /** - * get the slope of the easing function at at x - */ + /** get the slope of the easing function at at x */ + @Override public float getDiff(float t) { return mEasingCurve.getDiff(t / mDuration) * (mTargetValue - mInitialValue); } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/GeneralEasing.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/GeneralEasing.java index 50a7d59ed8e0..75a60324aa3c 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/GeneralEasing.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/GeneralEasing.java @@ -15,15 +15,14 @@ */ package com.android.internal.widget.remotecompose.core.operations.utilities.easing; -/** - * Provides and interface to create easing functions - */ -public class GeneralEasing extends Easing{ +/** Provides and interface to create easing functions */ +public class GeneralEasing extends Easing { float[] mEasingData = new float[0]; Easing mEasingCurve = new CubicEasing(CUBIC_STANDARD); /** * Set the curve based on the float encoding of it + * * @param data */ public void setCurveSpecification(float[] data) { @@ -47,11 +46,9 @@ public class GeneralEasing extends Easing{ mEasingCurve = new CubicEasing(type); break; case CUBIC_CUSTOM: - mEasingCurve = new CubicEasing(mEasingData[1], - mEasingData[2], - mEasingData[3], - mEasingData[5] - ); + mEasingCurve = + new CubicEasing( + mEasingData[1], mEasingData[2], mEasingData[3], mEasingData[5]); break; case EASE_OUT_BOUNCE: mEasingCurve = new BounceCurve(type); @@ -59,23 +56,20 @@ public class GeneralEasing extends Easing{ } } - /** - * get the value at point x - */ + /** get the value at point x */ + @Override public float get(float x) { return mEasingCurve.get(x); } - /** - * get the slope of the easing function at at x - */ + /** get the slope of the easing function at at x */ + @Override public float getDiff(float x) { return mEasingCurve.getDiff(x); } + @Override public int getType() { return mEasingCurve.getType(); } - - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/MonotonicCurveFit.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/MonotonicCurveFit.java index 23930b92a282..9355cacde4ad 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/MonotonicCurveFit.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/MonotonicCurveFit.java @@ -17,12 +17,8 @@ package com.android.internal.widget.remotecompose.core.operations.utilities.easi import java.util.Arrays; -/** - * This performs a spline interpolation in multiple dimensions - * - * - */ -public class MonotonicCurveFit { +/** This performs a spline interpolation in multiple dimensions */ +public class MonotonicCurveFit { private static final String TAG = "MonotonicCurveFit"; private double[] mT; private double[][] mY; @@ -32,6 +28,7 @@ public class MonotonicCurveFit { /** * create a collection of curves + * * @param time the point along the curve * @param y the parameter at those points */ @@ -78,6 +75,7 @@ public class MonotonicCurveFit { /** * Get the position of all curves at time t + * * @param t * @param v */ @@ -137,6 +135,7 @@ public class MonotonicCurveFit { /** * Get the position of all curves at time t + * * @param t * @param v */ @@ -196,6 +195,7 @@ public class MonotonicCurveFit { /** * Get the position of the jth curve at time t + * * @param t * @param j * @return @@ -230,7 +230,6 @@ public class MonotonicCurveFit { double t1 = mTangent[i][j]; double t2 = mTangent[i + 1][j]; return interpolate(h, x, y1, y2, t1, t2); - } } return 0; // should never reach here @@ -238,6 +237,7 @@ public class MonotonicCurveFit { /** * Get the slope of all the curves at position t + * * @param t * @param v */ @@ -264,11 +264,11 @@ public class MonotonicCurveFit { break; } } - return; } /** * Get the slope of the j curve at position t + * * @param t * @param j * @return @@ -299,34 +299,38 @@ public class MonotonicCurveFit { return mT; } - /** - * Cubic Hermite spline - */ - private static double interpolate(double h, - double x, - double y1, - double y2, - double t1, - double t2) { + /** Cubic Hermite spline */ + private static double interpolate( + double h, double x, double y1, double y2, double t1, double t2) { double x2 = x * x; double x3 = x2 * x; - return -2 * x3 * y2 + 3 * x2 * y2 + 2 * x3 * y1 - 3 * x2 * y1 + y1 - + h * t2 * x3 + h * t1 * x3 - h * t2 * x2 - 2 * h * t1 * x2 + return -2 * x3 * y2 + + 3 * x2 * y2 + + 2 * x3 * y1 + - 3 * x2 * y1 + + y1 + + h * t2 * x3 + + h * t1 * x3 + - h * t2 * x2 + - 2 * h * t1 * x2 + h * t1 * x; } - /** - * Cubic Hermite spline slope differentiated - */ + /** Cubic Hermite spline slope differentiated */ private static double diff(double h, double x, double y1, double y2, double t1, double t2) { double x2 = x * x; - return -6 * x2 * y2 + 6 * x * y2 + 6 * x2 * y1 - 6 * x * y1 + 3 * h * t2 * x2 - + 3 * h * t1 * x2 - 2 * h * t2 * x - 4 * h * t1 * x + h * t1; + return -6 * x2 * y2 + + 6 * x * y2 + + 6 * x2 * y1 + - 6 * x * y1 + + 3 * h * t2 * x2 + + 3 * h * t1 * x2 + - 2 * h * t2 * x + - 4 * h * t1 * x + + h * t1; } - /** - * This builds a monotonic spline to be used as a wave function - */ + /** This builds a monotonic spline to be used as a wave function */ public static MonotonicCurveFit buildWave(String configString) { // done this way for efficiency String str = configString; diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/StepCurve.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/StepCurve.java index 6ed6548405d2..b4596897a44f 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/StepCurve.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/StepCurve.java @@ -15,14 +15,13 @@ */ package com.android.internal.widget.remotecompose.core.operations.utilities.easing; - /** - * This class translates a series of floating point values into a continuous - * curve for use in an easing function including quantize functions - * it is used with the "spline(0,0.3,0.3,0.5,...0.9,1)" it should start at 0 and end at one 1 + * This class translates a series of floating point values into a continuous curve for use in an + * easing function including quantize functions it is used with the "spline(0,0.3,0.3,0.5,...0.9,1)" + * it should start at 0 and end at one 1 */ public class StepCurve extends Easing { - private static final boolean DEBUG = false; + // private static final boolean DEBUG = false; MonotonicCurveFit mCurveFit; public StepCurve(float[] params, int offset, int len) { @@ -55,12 +54,16 @@ public class StepCurve extends Easing { @Override public float getDiff(float x) { + if (x < 0f) return 0; + if (x > 1f) return 0; return (float) mCurveFit.getSlope(x, 0); } - @Override public float get(float x) { + if (x < 0f) return 0; + if (x > 1f) return 1; + return (float) mCurveFit.getPos(x, 0); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/types/BooleanConstant.java b/core/java/com/android/internal/widget/remotecompose/core/types/BooleanConstant.java index 9045bcbd2e06..57a804284f0d 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/types/BooleanConstant.java +++ b/core/java/com/android/internal/widget/remotecompose/core/types/BooleanConstant.java @@ -15,23 +15,21 @@ */ package com.android.internal.widget.remotecompose.core.types; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.BYTE; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.BYTE; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; -/** - * Used to represent a boolean - */ +/** Used to represent a boolean */ public class BooleanConstant implements Operation { private static final int OP_CODE = Operations.DATA_BOOLEAN; - boolean mValue = false; + private boolean mValue = false; private int mId; public BooleanConstant(int id, boolean value) { @@ -39,15 +37,22 @@ public class BooleanConstant implements Operation { mValue = value; } + /** + * Get the value of the boolean constant + * + * @return the value of the boolean + */ + public boolean getValue() { + return mValue; + } + @Override public void write(WireBuffer buffer) { apply(buffer, mId, mValue); } @Override - public void apply(RemoteContext context) { - - } + public void apply(RemoteContext context) {} @Override public String deepToString(String indent) { @@ -88,14 +93,9 @@ public class BooleanConstant implements Operation { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Expressions Operations", - OP_CODE, - "BooleanConstant") + doc.operation("Expressions Operations", OP_CODE, "BooleanConstant") .description("A boolean and its associated id") - .field(INT, "id", "id of Int") - .field(BYTE, "value", - "8-bit 0 or 1"); - + .field(DocumentedOperation.INT, "id", "id of Int") + .field(BYTE, "value", "8-bit 0 or 1"); } - } diff --git a/core/java/com/android/internal/widget/remotecompose/core/types/IntegerConstant.java b/core/java/com/android/internal/widget/remotecompose/core/types/IntegerConstant.java index 90faf52f2362..3ef9db9de915 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/types/IntegerConstant.java +++ b/core/java/com/android/internal/widget/remotecompose/core/types/IntegerConstant.java @@ -15,20 +15,18 @@ */ package com.android.internal.widget.remotecompose.core.types; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; -/** - * Represents a single integer typically used for states - * or named for input into the system - */ +/** Represents a single integer typically used for states or named for input into the system */ public class IntegerConstant implements Operation { private int mValue = 0; private int mId; @@ -87,13 +85,9 @@ public class IntegerConstant implements Operation { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Expressions Operations", - id(), - "IntegerConstant") + doc.operation("Expressions Operations", id(), "IntegerConstant") .description("A integer and its associated id") - .field(INT, "id", "id of Int") - .field(INT, "value", - "32-bit int value"); - + .field(DocumentedOperation.INT, "id", "id of Int") + .field(INT, "value", "32-bit int value"); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/types/LongConstant.java b/core/java/com/android/internal/widget/remotecompose/core/types/LongConstant.java index 70402cf45eae..6d51d194708f 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/types/LongConstant.java +++ b/core/java/com/android/internal/widget/remotecompose/core/types/LongConstant.java @@ -15,23 +15,21 @@ */ package com.android.internal.widget.remotecompose.core.types; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT; -import static com.android.internal.widget.remotecompose.core.documentation.Operation.LONG; +import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.LONG; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import java.util.List; -/** - * Used to represent a long - */ +/** Used to represent a long */ public class LongConstant implements Operation { private static final int OP_CODE = Operations.DATA_LONG; - long mValue; + private long mValue; private int mId; public LongConstant(int id, long value) { @@ -39,6 +37,15 @@ public class LongConstant implements Operation { mValue = value; } + /** + * Get the value of the long constant + * + * @return the value of the long + */ + public long getValue() { + return mValue; + } + @Override public void write(WireBuffer buffer) { apply(buffer, mId, mValue); @@ -46,6 +53,7 @@ public class LongConstant implements Operation { @Override public void apply(RemoteContext context) { + context.putObject(mId, this); } @Override @@ -79,14 +87,9 @@ public class LongConstant implements Operation { } public static void documentation(DocumentationBuilder doc) { - doc.operation("Expressions Operations", - OP_CODE, - "LongConstant") + doc.operation("Expressions Operations", OP_CODE, "LongConstant") .description("A boolean and its associated id") - .field(INT, "id", "id of Int") - .field(LONG, "value", - "The long Value"); - + .field(DocumentedOperation.INT, "id", "id of Int") + .field(LONG, "value", "The long Value"); } - } diff --git a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java index e32f8239d7ef..906282c1dde3 100644 --- a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java +++ b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java @@ -22,9 +22,7 @@ import com.android.internal.widget.remotecompose.core.operations.layout.Componen import java.io.InputStream; -/** - * Public API to create a new RemoteComposeDocument coming from an input stream - */ +/** Public API to create a new RemoteComposeDocument coming from an input stream */ public class RemoteComposeDocument { CoreDocument mDocument = new CoreDocument(); @@ -48,23 +46,19 @@ public class RemoteComposeDocument { } /** - * Called when an initialization is needed, allowing the document to eg load - * resources / cache them. + * Called when an initialization is needed, allowing the document to eg load resources / cache + * them. */ public void initializeContext(RemoteContext context) { mDocument.initializeContext(context); } - /** - * Returns the width of the document in pixels - */ + /** Returns the width of the document in pixels */ public int getWidth() { return mDocument.getWidth(); } - /** - * Returns the height of the document in pixels - */ + /** Returns the height of the document in pixels */ public int getHeight() { return mDocument.getHeight(); } @@ -77,7 +71,7 @@ public class RemoteComposeDocument { * Paint the document * * @param context the provided PaintContext - * @param theme the theme we want to use for this document. + * @param theme the theme we want to use for this document. */ public void paint(RemoteContext context, int theme) { mDocument.paint(context, theme); @@ -105,8 +99,7 @@ public class RemoteComposeDocument { @Override public String toString() { - return "Document{\n" - + mDocument + '}'; + return "Document{\n" + mDocument + '}'; } /** @@ -120,6 +113,7 @@ public class RemoteComposeDocument { /** * Return a component associated with id + * * @param id the component id * @return the corresponding component or null if not found */ @@ -138,4 +132,3 @@ public class RemoteComposeDocument { return mDocument.getStats(); } } - diff --git a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java index 3d78680bff0a..06bf4cdb0a0d 100644 --- a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java +++ b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java @@ -29,9 +29,7 @@ import android.widget.ScrollView; import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior; import com.android.internal.widget.remotecompose.player.platform.RemoteComposeCanvas; -/** - * A view to to display and play RemoteCompose documents - */ +/** A view to to display and play RemoteCompose documents */ public class RemoteComposePlayer extends FrameLayout { private RemoteComposeCanvas mInner; @@ -73,10 +71,7 @@ public class RemoteComposePlayer extends FrameLayout { public void setDocument(RemoteComposeDocument value) { if (value != null) { if (value.canBeDisplayed( - MAX_SUPPORTED_MAJOR_VERSION, - MAX_SUPPORTED_MINOR_VERSION, 0L - ) - ) { + MAX_SUPPORTED_MAJOR_VERSION, MAX_SUPPORTED_MINOR_VERSION, 0L)) { mInner.setDocument(value); int contentBehavior = value.getDocument().getContentScroll(); applyContentBehavior(contentBehavior); @@ -90,65 +85,58 @@ public class RemoteComposePlayer extends FrameLayout { } /** - * Apply the content behavior (NONE|SCROLL_HORIZONTAL|SCROLL_VERTICAL) to the player, - * adding or removing scrollviews as needed. + * Apply the content behavior (NONE|SCROLL_HORIZONTAL|SCROLL_VERTICAL) to the player, adding or + * removing scrollviews as needed. * * @param contentBehavior document content behavior (NONE|SCROLL_HORIZONTAL|SCROLL_VERTICAL) */ private void applyContentBehavior(int contentBehavior) { switch (contentBehavior) { - case RootContentBehavior.SCROLL_HORIZONTAL: { + case RootContentBehavior.SCROLL_HORIZONTAL: if (!(mInner.getParent() instanceof HorizontalScrollView)) { ((ViewGroup) mInner.getParent()).removeView(mInner); removeAllViews(); - LayoutParams layoutParamsInner = new LayoutParams( - LayoutParams.WRAP_CONTENT, - LayoutParams.MATCH_PARENT); + LayoutParams layoutParamsInner = + new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); HorizontalScrollView horizontalScrollView = new HorizontalScrollView(getContext()); horizontalScrollView.setBackgroundColor(Color.TRANSPARENT); horizontalScrollView.setFillViewport(true); horizontalScrollView.addView(mInner, layoutParamsInner); - LayoutParams layoutParams = new LayoutParams( - LayoutParams.MATCH_PARENT, - LayoutParams.MATCH_PARENT); + LayoutParams layoutParams = + new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); addView(horizontalScrollView, layoutParams); } - } - break; - case RootContentBehavior.SCROLL_VERTICAL: { + break; + case RootContentBehavior.SCROLL_VERTICAL: if (!(mInner.getParent() instanceof ScrollView)) { ((ViewGroup) mInner.getParent()).removeView(mInner); removeAllViews(); - LayoutParams layoutParamsInner = new LayoutParams( - LayoutParams.MATCH_PARENT, - LayoutParams.WRAP_CONTENT); + LayoutParams layoutParamsInner = + new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); ScrollView scrollView = new ScrollView(getContext()); scrollView.setBackgroundColor(Color.TRANSPARENT); scrollView.setFillViewport(true); scrollView.addView(mInner, layoutParamsInner); - LayoutParams layoutParams = new LayoutParams( - LayoutParams.MATCH_PARENT, - LayoutParams.MATCH_PARENT); + LayoutParams layoutParams = + new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); addView(scrollView, layoutParams); } - } - break; + break; default: if (mInner.getParent() != this) { ((ViewGroup) mInner.getParent()).removeView(mInner); removeAllViews(); - LayoutParams layoutParams = new LayoutParams( - LayoutParams.MATCH_PARENT, - LayoutParams.MATCH_PARENT); + LayoutParams layoutParams = + new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); addView(mInner, layoutParams); } } } private void init(Context context, AttributeSet attrs, int defStyleAttr) { - LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, - LayoutParams.MATCH_PARENT); + LayoutParams layoutParams = + new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); setBackgroundColor(Color.TRANSPARENT); mInner = new RemoteComposeCanvas(context, attrs, defStyleAttr); mInner.setBackgroundColor(Color.TRANSPARENT); @@ -241,24 +229,25 @@ public class RemoteComposePlayer extends FrameLayout { * Add a callback for handling click events on the document * * @param callback the callback lambda that will be used when a click is detected - * <p> - * The parameter of the callback are: - * id : the id of the clicked area - * metadata: a client provided unstructured string associated with that area + * <p>The parameter of the callback are: + * <ul> + * <li>id : the id of the clicked area + * <li>metadata: a client provided unstructured string associated with that area + * </ul> */ public void addClickListener(ClickCallbacks callback) { mInner.addClickListener((id, metadata) -> callback.click(id, metadata)); } /** - * Set the playback theme for the document. This allows to filter operations in order - * to have the document adapt to the given theme. This method is intended to be used - * to support night/light themes (system or app level), not custom themes. + * Set the playback theme for the document. This allows to filter operations in order to have + * the document adapt to the given theme. This method is intended to be used to support + * night/light themes (system or app level), not custom themes. * - * @param theme the theme used for playing the document. Possible values for theme are: - * - Theme.UNSPECIFIED -- all instructions in the document will be executed - * - Theme.DARK -- only executed NON Light theme instructions - * - Theme.LIGHT -- only executed NON Dark theme instructions + * @param theme the theme used for playing the document. Possible values for theme are: - + * Theme.UNSPECIFIED -- all instructions in the document will be executed - Theme.DARK -- + * only executed NON Light theme instructions - Theme.LIGHT -- only executed NON Dark theme + * instructions */ public void setTheme(int theme) { if (mInner.getTheme() != theme) { @@ -277,8 +266,7 @@ public class RemoteComposePlayer extends FrameLayout { } /** - * This sets a color based on its name. Overriding the color set in - * the document. + * This sets a color based on its name. Overriding the color set in the document. * * @param colorName Name of the color * @param colorValue The new color value @@ -364,7 +352,7 @@ public class RemoteComposePlayer extends FrameLayout { case "colorFocusedHighlight": setRColor(s, android.R.attr.colorFocusedHighlight); break; - case "colorForeground": // General foreground color for views. + case "colorForeground": // General foreground color for views. setRColor(s, android.R.attr.colorForeground); break; // Foreground color for inverse backgrounds. @@ -483,15 +471,14 @@ public class RemoteComposePlayer extends FrameLayout { } private int getColorFromResource(int id) { + TypedValue typedValue = new TypedValue(); - try (TypedArray arr = getContext() - .getApplicationContext() - .obtainStyledAttributes(typedValue.data, new int[]{id})) { + try (TypedArray arr = + getContext() + .getApplicationContext() + .obtainStyledAttributes(typedValue.data, new int[] {id})) { int color = arr.getColor(0, -1); return color; } } - - } - diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java index 4416cf76295c..f59a0d3fa015 100644 --- a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java +++ b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java @@ -43,8 +43,8 @@ import java.util.ArrayList; import java.util.List; /** - * An implementation of PaintContext for the Android Canvas. - * This is used to play the RemoteCompose operations on Android. + * An implementation of PaintContext for the Android Canvas. This is used to play the RemoteCompose + * operations on Android. */ public class AndroidPaintContext extends PaintContext { Paint mPaint = new Paint(); @@ -83,37 +83,36 @@ public class AndroidPaintContext extends PaintContext { /** * Draw an image onto the canvas * - * @param imageId the id of the image - * @param srcLeft left coordinate of the source area - * @param srcTop top coordinate of the source area - * @param srcRight right coordinate of the source area + * @param imageId the id of the image + * @param srcLeft left coordinate of the source area + * @param srcTop top coordinate of the source area + * @param srcRight right coordinate of the source area * @param srcBottom bottom coordinate of the source area - * @param dstLeft left coordinate of the destination area - * @param dstTop top coordinate of the destination area - * @param dstRight right coordinate of the destination area + * @param dstLeft left coordinate of the destination area + * @param dstTop top coordinate of the destination area + * @param dstRight right coordinate of the destination area * @param dstBottom bottom coordinate of the destination area */ - @Override - public void drawBitmap(int imageId, - int srcLeft, - int srcTop, - int srcRight, - int srcBottom, - int dstLeft, - int dstTop, - int dstRight, - int dstBottom, - int cdId) { + public void drawBitmap( + int imageId, + int srcLeft, + int srcTop, + int srcRight, + int srcBottom, + int dstLeft, + int dstTop, + int dstRight, + int dstBottom, + int cdId) { AndroidRemoteContext androidContext = (AndroidRemoteContext) mContext; if (androidContext.mRemoteComposeState.containsId(imageId)) { - Bitmap bitmap = (Bitmap) androidContext.mRemoteComposeState - .getFromId(imageId); + Bitmap bitmap = (Bitmap) androidContext.mRemoteComposeState.getFromId(imageId); mCanvas.drawBitmap( bitmap, new Rect(srcLeft, srcTop, srcRight, srcBottom), - new Rect(dstLeft, dstTop, dstRight, dstBottom), mPaint - ); + new Rect(dstLeft, dstTop, dstRight, dstBottom), + mPaint); } } @@ -128,28 +127,23 @@ public class AndroidPaintContext extends PaintContext { } @Override - public void drawArc(float left, - float top, - float right, - float bottom, - float startAngle, - float sweepAngle) { - mCanvas.drawArc(left, top, right, bottom, startAngle, - sweepAngle, true, mPaint); + public void drawArc( + float left, float top, float right, float bottom, float startAngle, float sweepAngle) { + mCanvas.drawArc(left, top, right, bottom, startAngle, sweepAngle, false, mPaint); + } + + @Override + public void drawSector( + float left, float top, float right, float bottom, float startAngle, float sweepAngle) { + mCanvas.drawArc(left, top, right, bottom, startAngle, sweepAngle, true, mPaint); } @Override - public void drawBitmap(int id, - float left, - float top, - float right, - float bottom) { + public void drawBitmap(int id, float left, float top, float right, float bottom) { AndroidRemoteContext androidContext = (AndroidRemoteContext) mContext; if (androidContext.mRemoteComposeState.containsId(id)) { - Bitmap bitmap = - (Bitmap) androidContext.mRemoteComposeState.getFromId(id); - Rect src = new Rect(0, 0, - bitmap.getWidth(), bitmap.getHeight()); + Bitmap bitmap = (Bitmap) androidContext.mRemoteComposeState.getFromId(id); + Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); RectF dst = new RectF(left, top, right, bottom); mCanvas.drawBitmap(bitmap, src, dst, mPaint); } @@ -191,21 +185,13 @@ public class AndroidPaintContext extends PaintContext { } @Override - public void drawRoundRect(float left, - float top, - float right, - float bottom, - float radiusX, - float radiusY) { - mCanvas.drawRoundRect(left, top, right, bottom, - radiusX, radiusY, mPaint); + public void drawRoundRect( + float left, float top, float right, float bottom, float radiusX, float radiusY) { + mCanvas.drawRoundRect(left, top, right, bottom, radiusX, radiusY, mPaint); } @Override - public void drawTextOnPath(int textId, - int pathId, - float hOffset, - float vOffset) { + public void drawTextOnPath(int textId, int pathId, float hOffset, float vOffset) { mCanvas.drawTextOnPath(getText(textId), getPath(pathId, 0, 1), hOffset, vOffset, mPaint); } @@ -237,14 +223,15 @@ public class AndroidPaintContext extends PaintContext { } @Override - public void drawTextRun(int textID, - int start, - int end, - int contextStart, - int contextEnd, - float x, - float y, - boolean rtl) { + public void drawTextRun( + int textID, + int start, + int end, + int contextStart, + int contextEnd, + float x, + float y, + boolean rtl) { String textToPaint = getText(textID); if (textToPaint == null) { @@ -262,11 +249,7 @@ public class AndroidPaintContext extends PaintContext { } @Override - public void drawTweenPath(int path1Id, - int path2Id, - float tween, - float start, - float end) { + public void drawTweenPath(int path1Id, int path2Id, float tween, float start, float end) { mCanvas.drawPath(getPath(path1Id, path2Id, tween, start, end), mPaint); } @@ -381,224 +364,219 @@ public class AndroidPaintContext extends PaintContext { /** * This applies paint changes to the current paint * - * @param mPaintData the list change to the paint + * @param paintData the list change to the paint */ @Override - public void applyPaint(PaintBundle mPaintData) { - mPaintData.applyPaintChange((PaintContext) this, new PaintChanges() { - @Override - public void setTextSize(float size) { - mPaint.setTextSize(size); - } - - @Override - public void setTypeFace(int fontType, int weight, boolean italic) { - int[] type = new int[]{Typeface.NORMAL, Typeface.BOLD, - Typeface.ITALIC, Typeface.BOLD_ITALIC}; - - switch (fontType) { - case PaintBundle.FONT_TYPE_DEFAULT: { - if (weight == 400 && !italic) { // for normal case - mPaint.setTypeface(Typeface.DEFAULT); - } else { - mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, - weight, italic)); - } - break; - } - case PaintBundle.FONT_TYPE_SERIF: { - if (weight == 400 && !italic) { // for normal case - mPaint.setTypeface(Typeface.SERIF); - } else { - mPaint.setTypeface(Typeface.create(Typeface.SERIF, - weight, italic)); - } - break; + public void applyPaint(PaintBundle paintData) { + paintData.applyPaintChange( + (PaintContext) this, + new PaintChanges() { + @Override + public void setTextSize(float size) { + mPaint.setTextSize(size); } - case PaintBundle.FONT_TYPE_SANS_SERIF: { - if (weight == 400 && !italic) { // for normal case - mPaint.setTypeface(Typeface.SANS_SERIF); - } else { - mPaint.setTypeface( - Typeface.create(Typeface.SANS_SERIF, - weight, italic)); + + @Override + public void setTypeFace(int fontType, int weight, boolean italic) { + int[] type = + new int[] { + Typeface.NORMAL, + Typeface.BOLD, + Typeface.ITALIC, + Typeface.BOLD_ITALIC + }; + + switch (fontType) { + case PaintBundle.FONT_TYPE_DEFAULT: + if (weight == 400 && !italic) { // for normal case + mPaint.setTypeface(Typeface.DEFAULT); + } else { + mPaint.setTypeface( + Typeface.create(Typeface.DEFAULT, weight, italic)); + } + break; + case PaintBundle.FONT_TYPE_SERIF: + if (weight == 400 && !italic) { // for normal case + mPaint.setTypeface(Typeface.SERIF); + } else { + mPaint.setTypeface( + Typeface.create(Typeface.SERIF, weight, italic)); + } + break; + case PaintBundle.FONT_TYPE_SANS_SERIF: + if (weight == 400 && !italic) { // for normal case + mPaint.setTypeface(Typeface.SANS_SERIF); + } else { + mPaint.setTypeface( + Typeface.create(Typeface.SANS_SERIF, weight, italic)); + } + break; + case PaintBundle.FONT_TYPE_MONOSPACE: + if (weight == 400 && !italic) { // for normal case + mPaint.setTypeface(Typeface.MONOSPACE); + } else { + mPaint.setTypeface( + Typeface.create(Typeface.MONOSPACE, weight, italic)); + } + + break; } - break; } - case PaintBundle.FONT_TYPE_MONOSPACE: { - if (weight == 400 && !italic) { // for normal case - mPaint.setTypeface(Typeface.MONOSPACE); - } else { - mPaint.setTypeface( - Typeface.create(Typeface.MONOSPACE, - weight, italic)); - } - break; + @Override + public void setStrokeWidth(float width) { + mPaint.setStrokeWidth(width); } - } - } - - @Override - public void setStrokeWidth(float width) { - mPaint.setStrokeWidth(width); - } - - @Override - public void setColor(int color) { - mPaint.setColor(color); - } + @Override + public void setColor(int color) { + mPaint.setColor(color); + } - @Override - public void setStrokeCap(int cap) { - mPaint.setStrokeCap(Paint.Cap.values()[cap]); - } + @Override + public void setStrokeCap(int cap) { + mPaint.setStrokeCap(Paint.Cap.values()[cap]); + } - @Override - public void setStyle(int style) { - mPaint.setStyle(Paint.Style.values()[style]); - } + @Override + public void setStyle(int style) { + mPaint.setStyle(Paint.Style.values()[style]); + } - @Override - public void setShader(int shaderId) { - // TODO this stuff should check the shader creation - if (shaderId == 0) { - mPaint.setShader(null); - return; - } - ShaderData data = getShaderData(shaderId); - RuntimeShader shader = new RuntimeShader(getText(data.getShaderTextId())); - String[] names = data.getUniformFloatNames(); - for (int i = 0; i < names.length; i++) { - String name = names[i]; - float[] val = data.getUniformFloats(name); - shader.setFloatUniform(name, val); - } - names = data.getUniformIntegerNames(); - for (int i = 0; i < names.length; i++) { - String name = names[i]; - int[] val = data.getUniformInts(name); - shader.setIntUniform(name, val); - } - names = data.getUniformBitmapNames(); - for (int i = 0; i < names.length; i++) { - String name = names[i]; - int val = data.getUniformBitmapId(name); - } - mPaint.setShader(shader); - } + @Override + public void setShader(int shaderId) { + // TODO this stuff should check the shader creation + if (shaderId == 0) { + mPaint.setShader(null); + return; + } + ShaderData data = getShaderData(shaderId); + RuntimeShader shader = new RuntimeShader(getText(data.getShaderTextId())); + String[] names = data.getUniformFloatNames(); + for (int i = 0; i < names.length; i++) { + String name = names[i]; + float[] val = data.getUniformFloats(name); + shader.setFloatUniform(name, val); + } + names = data.getUniformIntegerNames(); + for (int i = 0; i < names.length; i++) { + String name = names[i]; + int[] val = data.getUniformInts(name); + shader.setIntUniform(name, val); + } + names = data.getUniformBitmapNames(); + for (int i = 0; i < names.length; i++) { + String name = names[i]; + int val = data.getUniformBitmapId(name); + } + mPaint.setShader(shader); + } - @Override - public void setImageFilterQuality(int quality) { - Utils.log(" quality =" + quality); - } + @Override + public void setImageFilterQuality(int quality) { + Utils.log(" quality =" + quality); + } - @Override - public void setBlendMode(int mode) { - mPaint.setBlendMode(origamiToBlendMode(mode)); - } + @Override + public void setBlendMode(int mode) { + mPaint.setBlendMode(origamiToBlendMode(mode)); + } - @Override - public void setAlpha(float a) { - mPaint.setAlpha((int) (255 * a)); - } + @Override + public void setAlpha(float a) { + mPaint.setAlpha((int) (255 * a)); + } - @Override - public void setStrokeMiter(float miter) { - mPaint.setStrokeMiter(miter); - } + @Override + public void setStrokeMiter(float miter) { + mPaint.setStrokeMiter(miter); + } - @Override - public void setStrokeJoin(int join) { - mPaint.setStrokeJoin(Paint.Join.values()[join]); - } + @Override + public void setStrokeJoin(int join) { + mPaint.setStrokeJoin(Paint.Join.values()[join]); + } - @Override - public void setFilterBitmap(boolean filter) { - mPaint.setFilterBitmap(filter); - } + @Override + public void setFilterBitmap(boolean filter) { + mPaint.setFilterBitmap(filter); + } - @Override - public void setAntiAlias(boolean aa) { - mPaint.setAntiAlias(aa); - } + @Override + public void setAntiAlias(boolean aa) { + mPaint.setAntiAlias(aa); + } - @Override - public void clear(long mask) { - if (true) return; - long m = mask; - int k = 1; - while (m > 0) { - if ((m & 1) == 1L) { - switch (k) { - - case PaintBundle.COLOR_FILTER: - mPaint.setColorFilter(null); - break; + @Override + public void clear(long mask) { + if ((mask & (1L << PaintBundle.COLOR_FILTER)) != 0) { + mPaint.setColorFilter(null); } } - k++; - m = m >> 1; - } - } - Shader.TileMode[] mTileModes = new Shader.TileMode[]{ - Shader.TileMode.CLAMP, - Shader.TileMode.REPEAT, - Shader.TileMode.MIRROR}; - - @Override - public void setLinearGradient(int[] colors, - float[] stops, - float startX, - float startY, - float endX, - float endY, - int tileMode) { - mPaint.setShader(new LinearGradient(startX, - startY, - endX, - endY, colors, stops, mTileModes[tileMode])); - - } - - @Override - public void setRadialGradient(int[] colors, - float[] stops, - float centerX, - float centerY, - float radius, - int tileMode) { - mPaint.setShader(new RadialGradient(centerX, centerY, radius, - colors, stops, mTileModes[tileMode])); - } + Shader.TileMode[] mTileModes = + new Shader.TileMode[] { + Shader.TileMode.CLAMP, + Shader.TileMode.REPEAT, + Shader.TileMode.MIRROR + }; + + @Override + public void setLinearGradient( + int[] colors, + float[] stops, + float startX, + float startY, + float endX, + float endY, + int tileMode) { + mPaint.setShader( + new LinearGradient( + startX, + startY, + endX, + endY, + colors, + stops, + mTileModes[tileMode])); + } - @Override - public void setSweepGradient(int[] colors, - float[] stops, - float centerX, - float centerY) { - mPaint.setShader(new SweepGradient(centerX, centerY, colors, stops)); + @Override + public void setRadialGradient( + int[] colors, + float[] stops, + float centerX, + float centerY, + float radius, + int tileMode) { + mPaint.setShader( + new RadialGradient( + centerX, + centerY, + radius, + colors, + stops, + mTileModes[tileMode])); + } - } + @Override + public void setSweepGradient( + int[] colors, float[] stops, float centerX, float centerY) { + mPaint.setShader(new SweepGradient(centerX, centerY, colors, stops)); + } - @Override - public void setColorFilter(int color, int mode) { - PorterDuff.Mode pmode = origamiToPorterDuffMode(mode); - if (pmode != null) { - mPaint.setColorFilter( - new PorterDuffColorFilter(color, pmode)); - } - } - }); + @Override + public void setColorFilter(int color, int mode) { + PorterDuff.Mode pmode = origamiToPorterDuffMode(mode); + if (pmode != null) { + mPaint.setColorFilter(new PorterDuffColorFilter(color, pmode)); + } + } + }); } @Override - public void matrixScale(float scaleX, - float scaleY, - float centerX, - float centerY) { + public void matrixScale(float scaleX, float scaleY, float centerX, float centerY) { if (Float.isNaN(centerX)) { mCanvas.scale(scaleX, scaleY); } else { @@ -622,7 +600,6 @@ public class AndroidPaintContext extends PaintContext { mCanvas.rotate(rotate); } else { mCanvas.rotate(rotate, pivotX, pivotY); - } } @@ -642,15 +619,27 @@ public class AndroidPaintContext extends PaintContext { } @Override - public void roundedClipRect(float width, float height, - float topStart, float topEnd, - float bottomStart, float bottomEnd) { + public void roundedClipRect( + float width, + float height, + float topStart, + float topEnd, + float bottomStart, + float bottomEnd) { Path roundedPath = new Path(); - float[] radii = new float[] { topStart, topStart, - topEnd, topEnd, bottomEnd, bottomEnd, bottomStart, bottomStart}; - - roundedPath.addRoundRect(0f, 0f, width, height, - radii, android.graphics.Path.Direction.CW); + float[] radii = + new float[] { + topStart, + topStart, + topEnd, + topEnd, + bottomEnd, + bottomEnd, + bottomStart, + bottomStart + }; + + roundedPath.addRoundRect(0f, 0f, width, height, radii, android.graphics.Path.Direction.CW); mCanvas.clipPath(roundedPath); } @@ -660,7 +649,7 @@ public class AndroidPaintContext extends PaintContext { if (regionOp == ClipPath.DIFFERENCE) { mCanvas.clipOutPath(path); // DIFFERENCE } else { - mCanvas.clipPath(path); // INTERSECT + mCanvas.clipPath(path); // INTERSECT } } @@ -669,11 +658,7 @@ public class AndroidPaintContext extends PaintContext { mPaint.reset(); } - private Path getPath(int path1Id, - int path2Id, - float tween, - float start, - float end) { + private Path getPath(int path1Id, int path2Id, float tween, float start, float end) { if (tween == 0.0f) { return getPath(path1Id, start, end); } @@ -681,10 +666,8 @@ public class AndroidPaintContext extends PaintContext { return getPath(path2Id, start, end); } AndroidRemoteContext androidContext = (AndroidRemoteContext) mContext; - float[] data1 = - (float[]) androidContext.mRemoteComposeState.getFromId(path1Id); - float[] data2 = - (float[]) androidContext.mRemoteComposeState.getFromId(path2Id); + float[] data1 = (float[]) androidContext.mRemoteComposeState.getFromId(path1Id); + float[] data2 = (float[]) androidContext.mRemoteComposeState.getFromId(path2Id); float[] tmp = new float[data2.length]; for (int i = 0; i < tmp.length; i++) { if (Float.isNaN(data1[i]) || Float.isNaN(data2[i])) { @@ -702,8 +685,7 @@ public class AndroidPaintContext extends PaintContext { AndroidRemoteContext androidContext = (AndroidRemoteContext) mContext; Path path = new Path(); if (androidContext.mRemoteComposeState.containsId(id)) { - float[] data = - (float[]) androidContext.mRemoteComposeState.getFromId(id); + float[] data = (float[]) androidContext.mRemoteComposeState.getFromId(id); FloatsToPath.genPath(path, data, start, end); } return path; @@ -717,4 +699,3 @@ public class AndroidPaintContext extends PaintContext { return (ShaderData) mContext.mRemoteComposeState.getFromId(id); } } - diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPlatformServices.java b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPlatformServices.java new file mode 100644 index 000000000000..f9b22a25ceab --- /dev/null +++ b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPlatformServices.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.widget.remotecompose.player.platform; + +import android.graphics.Bitmap; +import android.graphics.Path; +import android.graphics.PathIterator; + +import com.android.internal.widget.remotecompose.core.Platform; +import com.android.internal.widget.remotecompose.core.operations.PathData; + +import java.io.ByteArrayOutputStream; +import java.util.Arrays; + +/** Services that are needed to be provided by the platform during encoding. */ +public class AndroidPlatformServices implements Platform { + @Override + public byte[] imageToByteArray(Object image) { + if (image instanceof Bitmap) { + // let's create a bitmap + ByteArrayOutputStream byteArrayBitmapStream = new ByteArrayOutputStream(); + ((Bitmap) image).compress(Bitmap.CompressFormat.PNG, 90, byteArrayBitmapStream); + return byteArrayBitmapStream.toByteArray(); + } + return null; + } + + @Override + public int getImageWidth(Object image) { + if (image instanceof Bitmap) { + return ((Bitmap) image).getWidth(); + } + return 0; + } + + @Override + public int getImageHeight(Object image) { + if (image instanceof Bitmap) { + return ((Bitmap) image).getHeight(); + } + return 0; + } + + @Override + public float[] pathToFloatArray(Object path) { + // if (path is RemotePath) { + // return path.createFloatArray() + // } + + if (path instanceof Path) { + return androidPathToFloatArray((Path) path); + } + + return null; + } + + private float[] androidPathToFloatArray(Path path) { + PathIterator i = path.getPathIterator(); + int estimatedSize = 0; + + while (i.hasNext()) { + i.next(); + estimatedSize++; + } + + PathIterator iter = path.getPathIterator(); + float[] pathFloat = new float[estimatedSize * 10]; + + int count = 0; + while (i.hasNext()) { + PathIterator.Segment seg = i.next(); + + switch (seg.getVerb()) { + case PathIterator.VERB_MOVE: + pathFloat[count++] = PathData.MOVE_NAN; + break; + case PathIterator.VERB_LINE: + pathFloat[count++] = PathData.LINE_NAN; + break; + case PathIterator.VERB_QUAD: + pathFloat[count++] = PathData.QUADRATIC_NAN; + break; + case PathIterator.VERB_CONIC: + pathFloat[count++] = PathData.CONIC_NAN; + break; + case PathIterator.VERB_CUBIC: + pathFloat[count++] = PathData.CUBIC_NAN; + break; + case PathIterator.VERB_CLOSE: + pathFloat[count++] = PathData.CLOSE_NAN; + break; + case PathIterator.VERB_DONE: + pathFloat[count++] = PathData.DONE_NAN; + break; + } + for (float p : seg.getPoints()) { + pathFloat[count++] = p; + } + if (seg.getVerb() == PathIterator.VERB_CONIC) { + pathFloat[count++] = seg.getConicWeight(); + } + } + + return Arrays.copyOf(pathFloat, count); + } +} diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java index c98937530897..e7c0cc8a915d 100644 --- a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java +++ b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java @@ -24,13 +24,14 @@ import com.android.internal.widget.remotecompose.core.VariableSupport; import com.android.internal.widget.remotecompose.core.operations.FloatExpression; import com.android.internal.widget.remotecompose.core.operations.ShaderData; import com.android.internal.widget.remotecompose.core.operations.utilities.ArrayAccess; +import com.android.internal.widget.remotecompose.core.operations.utilities.DataMap; import java.util.HashMap; /** * An implementation of Context for Android. - * <p> - * This is used to play the RemoteCompose operations on Android. + * + * <p>This is used to play the RemoteCompose operations on Android. */ class AndroidRemoteContext extends RemoteContext { @@ -127,6 +128,16 @@ class AndroidRemoteContext extends RemoteContext { } @Override + public void putDataMap(int id, DataMap map) { + mRemoteComposeState.putDataMap(id, map); + } + + @Override + public DataMap getDataMap(int id) { + return mRemoteComposeState.getDataMap(id); + } + + @Override public void runAction(int id, String metadata) { mDocument.performClick(id); } @@ -140,7 +151,7 @@ class AndroidRemoteContext extends RemoteContext { /** * Decode a byte array into an image and cache it using the given imageId * - * @param width with of image to be loaded + * @param width with of image to be loaded * @param height height of image to be loaded * @param bitmap a byte array containing the image information * @oaram imageId the id of the image @@ -223,8 +234,18 @@ class AndroidRemoteContext extends RemoteContext { } @Override + public void putObject(int id, Object value) { + mRemoteComposeState.updateObject(id, value); + } + + @Override + public Object getObject(int id) { + return mRemoteComposeState.getObject(id); + } + + @Override public int getInteger(int id) { - return mRemoteComposeState.getInteger(id); + return mRemoteComposeState.getInteger(id); } @Override @@ -252,17 +273,16 @@ class AndroidRemoteContext extends RemoteContext { /////////////////////////////////////////////////////////////////////////////////////////////// @Override - public void addClickArea(int id, - int contentDescriptionId, - float left, - float top, - float right, - float bottom, - int metadataId) { + public void addClickArea( + int id, + int contentDescriptionId, + float left, + float top, + float right, + float bottom, + int metadataId) { String contentDescription = (String) mRemoteComposeState.getFromId(contentDescriptionId); String metadata = (String) mRemoteComposeState.getFromId(metadataId); mDocument.addClickArea(id, contentDescription, left, top, right, bottom, metadata); } - } - diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/ClickAreaView.java b/core/java/com/android/internal/widget/remotecompose/player/platform/ClickAreaView.java index 329178abe8b5..fdd9aad68d47 100644 --- a/core/java/com/android/internal/widget/remotecompose/player/platform/ClickAreaView.java +++ b/core/java/com/android/internal/widget/remotecompose/player/platform/ClickAreaView.java @@ -20,9 +20,7 @@ import android.graphics.Canvas; import android.graphics.Paint; import android.view.View; -/** - * Implementation for the click handling - */ +/** Implementation for the click handling */ class ClickAreaView extends View { private int mId; private String mMetadata; @@ -30,8 +28,8 @@ class ClickAreaView extends View { private boolean mDebug; - ClickAreaView(Context context, boolean debug, int id, - String contentDescription, String metadata) { + ClickAreaView( + Context context, boolean debug, int id, String contentDescription, String metadata) { super(context); this.mId = id; this.mMetadata = metadata; diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/FloatsToPath.java b/core/java/com/android/internal/widget/remotecompose/player/platform/FloatsToPath.java index d75232a6557e..8d3440c33efb 100644 --- a/core/java/com/android/internal/widget/remotecompose/player/platform/FloatsToPath.java +++ b/core/java/com/android/internal/widget/remotecompose/player/platform/FloatsToPath.java @@ -23,72 +23,56 @@ import android.graphics.PathMeasure; import com.android.internal.widget.remotecompose.core.operations.PathData; public class FloatsToPath { - public static void genPath(Path retPath, - float[] floatPath, - float start, - float stop) { + public static void genPath(Path retPath, float[] floatPath, float start, float stop) { int i = 0; Path path = new Path(); // todo this should be cached for performance while (i < floatPath.length) { switch (idFromNan(floatPath[i])) { - case PathData.MOVE: { + case PathData.MOVE: i++; path.moveTo(floatPath[i + 0], floatPath[i + 1]); i += 2; - } - break; - case PathData.LINE: { + break; + case PathData.LINE: i += 3; path.lineTo(floatPath[i + 0], floatPath[i + 1]); i += 2; - } - break; - case PathData.QUADRATIC: { + break; + case PathData.QUADRATIC: i += 3; path.quadTo( + floatPath[i + 0], floatPath[i + 1], floatPath[i + 2], floatPath[i + 3]); + i += 4; + break; + case PathData.CONIC: + i += 3; + + path.conicTo( floatPath[i + 0], floatPath[i + 1], floatPath[i + 2], - floatPath[i + 3] - ); - i += 4; + floatPath[i + 3], + floatPath[i + 4]); - } - break; - case PathData.CONIC: { - i += 3; - path.conicTo( - floatPath[i + 0], floatPath[i + 1], - floatPath[i + 2], floatPath[i + 3], - floatPath[i + 4] - ); i += 5; - } - break; - case PathData.CUBIC: { + break; + case PathData.CUBIC: i += 3; path.cubicTo( floatPath[i + 0], floatPath[i + 1], floatPath[i + 2], floatPath[i + 3], - floatPath[i + 4], floatPath[i + 5] - ); + floatPath[i + 4], floatPath[i + 5]); i += 6; - } - break; - case PathData.CLOSE: { - + break; + case PathData.CLOSE: path.close(); i++; - } - break; - case PathData.DONE: { + break; + case PathData.DONE: i++; - } - break; - default: { - System.err.println(" Odd command " - + idFromNan(floatPath[i])); - } + break; + default: + System.err.println(" Odd command " + idFromNan(floatPath[i])); } } @@ -101,8 +85,7 @@ public class FloatsToPath { float len = measure.getLength(); float scaleStart = Math.max(start, 0f) * len; float scaleStop = Math.min(stop, 1f) * len; - measure.getSegment(scaleStart, scaleStop, retPath, - true); + measure.getSegment(scaleStart, scaleStop, retPath, true); } } else { diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java index f91e15818471..7de6988157b7 100644 --- a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java +++ b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java @@ -31,9 +31,7 @@ import com.android.internal.widget.remotecompose.player.RemoteComposeDocument; import java.util.Set; -/** - * Internal view handling the actual painting / interactions - */ +/** Internal view handling the actual painting / interactions */ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachStateChangeListener { static final boolean USE_VIEW_AREA_CLICK = true; // Use views to represent click areas @@ -102,13 +100,17 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta private void updateClickAreas() { if (USE_VIEW_AREA_CLICK && mDocument != null) { mHasClickAreas = false; - Set<CoreDocument.ClickAreaRepresentation> clickAreas = mDocument - .getDocument().getClickAreas(); + Set<CoreDocument.ClickAreaRepresentation> clickAreas = + mDocument.getDocument().getClickAreas(); removeAllViews(); for (CoreDocument.ClickAreaRepresentation area : clickAreas) { - ClickAreaView viewArea = new ClickAreaView(getContext(), mDebug, - area.getId(), area.getContentDescription(), - area.getMetadata()); + ClickAreaView viewArea = + new ClickAreaView( + getContext(), + mDebug, + area.getId(), + area.getContentDescription(), + area.getMetadata()); int w = (int) area.width(); int h = (int) area.height(); FrameLayout.LayoutParams param = new FrameLayout.LayoutParams(w, h); @@ -116,8 +118,8 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta param.height = h; param.leftMargin = (int) area.getLeft(); param.topMargin = (int) area.getTop(); - viewArea.setOnClickListener(view1 - -> mDocument.getDocument().performClick(area.getId())); + viewArea.setOnClickListener( + view1 -> mDocument.getDocument().performClick(area.getId())); addView(viewArea, param); } if (!clickAreas.isEmpty()) { @@ -201,23 +203,19 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta return super.onTouchEvent(event); } switch (event.getActionMasked()) { - case MotionEvent.ACTION_DOWN: { + case MotionEvent.ACTION_DOWN: mActionDownPoint.x = (int) event.getX(); mActionDownPoint.y = (int) event.getY(); mInActionDown = true; return true; - } - case MotionEvent.ACTION_CANCEL: { + case MotionEvent.ACTION_CANCEL: mInActionDown = false; return true; - } - case MotionEvent.ACTION_UP: { + case MotionEvent.ACTION_UP: mInActionDown = false; performClick(); return true; - } - case MotionEvent.ACTION_MOVE: { - } + case MotionEvent.ACTION_MOVE: } return false; } @@ -227,8 +225,9 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta if (USE_VIEW_AREA_CLICK && mHasClickAreas) { return super.performClick(); } - mDocument.getDocument().onClick(mARContext, - (float) mActionDownPoint.x, (float) mActionDownPoint.y); + mDocument + .getDocument() + .onClick(mARContext, (float) mActionDownPoint.x, (float) mActionDownPoint.y); super.performClick(); invalidate(); return true; @@ -305,6 +304,4 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta invalidate(); } } - } - |