diff options
| author | 2024-06-26 23:32:55 +0000 | |
|---|---|---|
| committer | 2024-06-26 23:32:55 +0000 | |
| commit | 5214899381b19e9476d0ca5479ebff647569a114 (patch) | |
| tree | 05019e6a9ca4a0b06a803a5fe141b536fa7d17de | |
| parent | e0ee0cb78a14d2b7b6d4cdef0b394aed2fa1525d (diff) | |
| parent | eb957409530845548cb2c2dda2013a89ad94313d (diff) | |
Merge "Add support for color theaming" into main
13 files changed, 516 insertions, 13 deletions
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 00262be06623..5c2a1678a556 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java +++ b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java @@ -15,6 +15,7 @@ */ package com.android.internal.widget.remotecompose.core; +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; @@ -308,9 +309,10 @@ public class CoreDocument { /** * Returns true if x,y coordinate is within bounds + * * @param x x-coordinate * @param y y-coordinate - * @return x,y coordinate is within bounds + * @return x, y coordinate is within bounds */ public boolean contains(float x, float y) { return x >= mLeft && x < mRight @@ -483,6 +485,37 @@ public class CoreDocument { return builder.toString(); } + /** + * Gets the names of all named colors. + * + * @return array of named colors or null + */ + public String[] getNamedColors() { + int count = 0; + for (Operation op : mOperations) { + if (op instanceof NamedVariable) { + NamedVariable n = (NamedVariable) op; + if (n.mVarType == NamedVariable.COLOR_TYPE) { + count++; + } + } + } + if (count == 0) { + return null; + } + String[] ret = new String[count]; + int i = 0; + for (Operation op : mOperations) { + if (op instanceof NamedVariable) { + NamedVariable n = (NamedVariable) op; + if (n.mVarType == NamedVariable.COLOR_TYPE) { + ret[i++] = n.mVarName; + } + } + } + return ret; + } + ////////////////////////////////////////////////////////////////////////// // Painting ////////////////////////////////////////////////////////////////////////// @@ -493,6 +526,7 @@ public class CoreDocument { /** * Returns > 0 if it needs to repaint + * * @return */ public int needsRepaint() { @@ -525,7 +559,6 @@ public class CoreDocument { context.loadFloat(RemoteContext.ID_WINDOW_WIDTH, getWidth()); context.loadFloat(RemoteContext.ID_WINDOW_HEIGHT, getHeight()); mRepaintNext = context.updateOps(); - for (Operation op : mOperations) { // operations will only be executed if no theme is set (ie UNSPECIFIED) // or the theme is equal as the one passed in argument to paint. 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 4b45ab691215..fc8668e4c657 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/Operations.java +++ b/core/java/com/android/internal/widget/remotecompose/core/Operations.java @@ -19,6 +19,7 @@ import com.android.internal.widget.remotecompose.core.operations.BitmapData; import com.android.internal.widget.remotecompose.core.operations.ClickArea; import com.android.internal.widget.remotecompose.core.operations.ClipPath; import com.android.internal.widget.remotecompose.core.operations.ClipRect; +import com.android.internal.widget.remotecompose.core.operations.ColorConstant; import com.android.internal.widget.remotecompose.core.operations.ColorExpression; import com.android.internal.widget.remotecompose.core.operations.DrawArc; import com.android.internal.widget.remotecompose.core.operations.DrawBitmap; @@ -42,6 +43,7 @@ import com.android.internal.widget.remotecompose.core.operations.MatrixSave; import com.android.internal.widget.remotecompose.core.operations.MatrixScale; import com.android.internal.widget.remotecompose.core.operations.MatrixSkew; import com.android.internal.widget.remotecompose.core.operations.MatrixTranslate; +import com.android.internal.widget.remotecompose.core.operations.NamedVariable; import com.android.internal.widget.remotecompose.core.operations.PaintData; import com.android.internal.widget.remotecompose.core.operations.PathData; import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior; @@ -105,6 +107,8 @@ public class Operations { public static final int COLOR_EXPRESSIONS = 134; public static final int TEXT_FROM_FLOAT = 135; public static final int TEXT_MERGE = 136; + public static final int NAMED_VARIABLE = 137; + public static final int COLOR_CONSTANT = 138; /////////////////////////////////////////====================== public static IntMap<CompanionOperation> map = new IntMap<>(); @@ -147,7 +151,8 @@ public class Operations { map.put(COLOR_EXPRESSIONS, ColorExpression.COMPANION); map.put(TEXT_FROM_FLOAT, TextFromFloat.COMPANION); map.put(TEXT_MERGE, TextMerge.COMPANION); - + map.put(NAMED_VARIABLE, NamedVariable.COMPANION); + map.put(COLOR_CONSTANT, ColorConstant.COMPANION); } } 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 52fc3143d721..d462c7d64a5a 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java +++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java @@ -19,6 +19,7 @@ import com.android.internal.widget.remotecompose.core.operations.BitmapData; import com.android.internal.widget.remotecompose.core.operations.ClickArea; import com.android.internal.widget.remotecompose.core.operations.ClipPath; import com.android.internal.widget.remotecompose.core.operations.ClipRect; +import com.android.internal.widget.remotecompose.core.operations.ColorConstant; import com.android.internal.widget.remotecompose.core.operations.ColorExpression; import com.android.internal.widget.remotecompose.core.operations.DrawArc; import com.android.internal.widget.remotecompose.core.operations.DrawBitmap; @@ -42,6 +43,7 @@ import com.android.internal.widget.remotecompose.core.operations.MatrixSave; import com.android.internal.widget.remotecompose.core.operations.MatrixScale; import com.android.internal.widget.remotecompose.core.operations.MatrixSkew; import com.android.internal.widget.remotecompose.core.operations.MatrixTranslate; +import com.android.internal.widget.remotecompose.core.operations.NamedVariable; import com.android.internal.widget.remotecompose.core.operations.PaintData; import com.android.internal.widget.remotecompose.core.operations.PathData; import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior; @@ -899,6 +901,20 @@ public class RemoteComposeBuffer { } /** + * Add a simple color + * @param color + * @return id that represents that color + */ + public int addColor(int color) { + ColorConstant c = new ColorConstant(0, color); + short id = (short) mRemoteComposeState.cache(c); + c.mColorId = id; + c.write(mBuffer); + return id; + } + + + /** * Add a color that represents the tween between two colors * @param color1 * @param color2 @@ -1013,5 +1029,14 @@ public class RemoteComposeBuffer { 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.COMPANION.apply(mBuffer, id, + NamedVariable.COLOR_TYPE, name); + } } 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 66a37e677499..bfe67c8e9d19 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java +++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java @@ -33,11 +33,13 @@ import java.util.HashMap; public class RemoteComposeState { public static final int START_ID = 42; private static final int MAX_FLOATS = 500; + private static final int MAX_COLORS = 200; private final IntMap<Object> mIntDataMap = new IntMap<>(); private final IntMap<Boolean> mIntWrittenMap = new IntMap<>(); private final HashMap<Object, Integer> mDataIntMap = new HashMap(); private final float[] mFloatMap = new float[MAX_FLOATS]; // efficient cache - private final int[] mColorMap = new int[MAX_FLOATS]; // efficient cache + private final int[] mColorMap = new int[MAX_COLORS]; // efficient cache + private final boolean[] mColorOverride = new boolean[MAX_COLORS]; private int mNextId = START_ID; { @@ -49,6 +51,7 @@ public class RemoteComposeState { /** * Get Object based on id. The system will cache things like bitmaps * Paths etc. They can be accessed with this command + * * @param id * @return */ @@ -58,6 +61,7 @@ public class RemoteComposeState { /** * true if the cache contain this id + * * @param id * @return */ @@ -150,9 +154,32 @@ public class RemoteComposeState { * @param color */ public void updateColor(int id, int color) { + if (mColorOverride[id]) { + return; + } mColorMap[id] = color; } + /** + * Adds a colorOverride. + * This is a list of ids and there colors optimized for playback; + * + * @param id + * @param color + */ + public void overrideColor(int id, int color) { + mColorOverride[id] = true; + mColorMap[id] = color; + } + + /** + * Clear the color Overrides + */ + public void clearColorOverride() { + for (int i = 0; i < mColorOverride.length; i++) { + mColorOverride[i] = false; + } + } /** * Method to determine if a cached value has been written to the documents WireBuffer based on 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 7e721684be0a..32027d8b535c 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java +++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java @@ -72,6 +72,14 @@ public abstract class RemoteContext { return (System.nanoTime() - mStart) * 1E-9f; } + /** + * Set the value of a named Color. + * This overrides the color in the document + * @param colorName + * @param color + */ + public abstract void setNamedColorOverride(String colorName, int color); + /** * The context can be used in a few different mode, allowing operations to skip being executed: @@ -262,16 +270,45 @@ public abstract class RemoteContext { public static final int ID_COMPONENT_WIDTH = 7; public static final int ID_COMPONENT_HEIGHT = 8; public static final int ID_CALENDAR_MONTH = 9; + public static final int ID_OFFSET_TO_UTC = 10; + 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 + */ public static final float FLOAT_CONTINUOUS_SEC = Utils.asNan(ID_CONTINUOUS_SEC); + /** + * 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 + */ public static final float FLOAT_TIME_IN_MIN = Utils.asNan(ID_TIME_IN_MIN); + /** + * 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 + */ public static final float FLOAT_CALENDAR_MONTH = Utils.asNan(ID_CALENDAR_MONTH); + /** + * 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 + */ + 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); public static final float FLOAT_WINDOW_HEIGHT = Utils.asNan(ID_WINDOW_HEIGHT); public static final float FLOAT_COMPONENT_WIDTH = Utils.asNan(ID_COMPONENT_WIDTH); public static final float FLOAT_COMPONENT_HEIGHT = Utils.asNan(ID_COMPONENT_HEIGHT); + // ID_OFFSET_TO_UTC is the offset from UTC in sec (typically / 3600f) + public static final float FLOAT_OFFSET_TO_UTC = Utils.asNan(ID_OFFSET_TO_UTC); /////////////////////////////////////////////////////////////////////////////////////////////// // Click handling /////////////////////////////////////////////////////////////////////////////////////////////// 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 e9708b75de27..04e04bbb9063 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java +++ b/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java @@ -16,6 +16,9 @@ package com.android.internal.widget.remotecompose.core; import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; /** * This generates the standard system variables for time. @@ -23,6 +26,7 @@ import java.time.LocalDateTime; public class TimeVariables { /** * This class populates all time variables in the system + * * @param context */ public void updateTime(RemoteContext context) { @@ -33,19 +37,29 @@ public class TimeVariables { // hours run from Midnight=0 quantized to Hours 0-23 // CONTINUOUS_SEC is seconds from midnight looping every hour 0-3600 // CONTINUOUS_SEC is accurate to milliseconds due to float precession - int month = dateTime.getDayOfMonth(); + // ID_OFFSET_TO_UTC is the offset from UTC in sec (typically / 3600f) + int month = dateTime.getMonth().getValue(); int hour = dateTime.getHour(); int minute = dateTime.getMinute(); int seconds = dateTime.getSecond(); int currentMinute = hour * 60 + minute; int currentSeconds = minute * 60 + seconds; 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(); + + context.loadFloat(RemoteContext.ID_OFFSET_TO_UTC, offset.getTotalSeconds()); context.loadFloat(RemoteContext.ID_CONTINUOUS_SEC, sec); context.loadFloat(RemoteContext.ID_TIME_IN_SEC, currentSeconds); context.loadFloat(RemoteContext.ID_TIME_IN_MIN, currentMinute); context.loadFloat(RemoteContext.ID_TIME_IN_HR, hour); 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/operations/ColorConstant.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java new file mode 100644 index 000000000000..15c208f2de61 --- /dev/null +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java @@ -0,0 +1,94 @@ +/* + * 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.CompanionOperation; +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 java.util.List; + +/** + * Operation that defines a simple Color based on ID + * Mainly for colors in theming. + */ +public class ColorConstant implements Operation { + public int mColorId; + public int mColor; + public static final Companion COMPANION = new Companion(); + + public ColorConstant(int colorId, int color) { + this.mColorId = colorId; + this.mColor = color; + } + + @Override + public void write(WireBuffer buffer) { + COMPANION.apply(buffer, mColorId, mColor); + } + + @Override + public String toString() { + return "ColorConstant[" + mColorId + "] = " + Utils.colorInt(mColor) + ""; + } + + public static class Companion implements CompanionOperation { + private Companion() { + } + + @Override + public String name() { + return "ColorConstant"; + } + + @Override + public int id() { + return Operations.COLOR_CONSTANT; + } + + /** + * Writes out the operation to the buffer + * + * @param buffer + * @param colorId + * @param color + */ + public void apply(WireBuffer buffer, int colorId, int color) { + buffer.start(Operations.COLOR_CONSTANT); + buffer.writeInt(colorId); + buffer.writeInt(color); + } + + @Override + public void read(WireBuffer buffer, List<Operation> operations) { + int colorId = buffer.readInt(); + int color = buffer.readInt(); + operations.add(new ColorConstant(colorId, color)); + } + } + + @Override + public void apply(RemoteContext context) { + context.loadColor(mColorId, mColor); + } + + @Override + public String deepToString(String indent) { + return indent + toString(); + } +} 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 0c5b286684d4..ae27f5ff450b 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 @@ -32,7 +32,9 @@ public class NamedVariable implements Operation { public int mVarType; public static final Companion COMPANION = new Companion(); public static final int MAX_STRING_SIZE = 4000; - + public static final int COLOR_TYPE = 2; + public static final int FLOAT_TYPE = 1; + public static final int STRING_TYPE = 0; public NamedVariable(int varId, int varType, String name) { this.mVarId = varId; this.mVarType = varType; @@ -72,7 +74,7 @@ public class NamedVariable implements Operation { * @param text */ public void apply(WireBuffer buffer, int varId, int varType, String text) { - buffer.start(Operations.DATA_TEXT); + buffer.start(Operations.NAMED_VARIABLE); buffer.writeInt(varId); buffer.writeInt(varType); buffer.writeUTF8(text); 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 fdc68601bf4d..fcb3bfaca503 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 @@ -78,7 +78,9 @@ public class Utils { */ public static void log(String str) { StackTraceElement s = new Throwable().getStackTrace()[1]; - System.out.println("(" + s.getFileName() + ":" + s.getLineNumber() + ")." + str); + System.out.println("(" + s.getFileName() + + ":" + s.getLineNumber() + "). " + + s.getMethodName() + "() " + str); } /** 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 d1c4d46f2c22..a42c58472164 100644 --- a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java +++ b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java @@ -103,5 +103,15 @@ public class RemoteComposeDocument { return "Document{\n" + mDocument + '}'; } + + /** + * Gets a array of Names of the named colors defined in the loaded doc. + * + * @return + */ + public String[] getNamedColors() { + return mDocument.getNamedColors(); + } + } 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 7423a1679d36..73e94fa6ecf4 100644 --- a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java +++ b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java @@ -16,9 +16,11 @@ package com.android.internal.widget.remotecompose.player; import android.content.Context; +import android.content.res.TypedArray; import android.graphics.Color; import android.util.AttributeSet; import android.util.Log; +import android.util.TypedValue; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.HorizontalScrollView; @@ -53,6 +55,7 @@ public class RemoteComposePlayer extends FrameLayout { /** * Turn on debug information + * * @param debugFlags 1 to set debug on */ public void setDebug(int debugFlags) { @@ -79,6 +82,7 @@ public class RemoteComposePlayer extends FrameLayout { } else { mInner.setDocument(null); } + mapColors(); } /** @@ -106,7 +110,8 @@ public class RemoteComposePlayer extends FrameLayout { LayoutParams.MATCH_PARENT); addView(horizontalScrollView, layoutParams); } - } break; + } + break; case RootContentBehavior.SCROLL_VERTICAL: { if (!(mInner.getParent() instanceof ScrollView)) { ((ViewGroup) mInner.getParent()).removeView(mInner); @@ -123,9 +128,10 @@ public class RemoteComposePlayer extends FrameLayout { LayoutParams.MATCH_PARENT); addView(scrollView, layoutParams); } - } break; + } + break; default: - if (mInner.getParent() != this) { + if (mInner.getParent() != this) { ((ViewGroup) mInner.getParent()).removeView(mInner); removeAllViews(); LayoutParams layoutParams = new LayoutParams( @@ -178,5 +184,230 @@ public class RemoteComposePlayer extends FrameLayout { mInner.invalidate(); } } + + /** + * This returns a list of colors that have names in the Document. + * + * @return + */ + public String[] getNamedColors() { + return mInner.getNamedColors(); + } + + /** + * 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 + */ + public void setColor(String colorName, int colorValue) { + mInner.setColor(colorName, colorValue); + } + + private void mapColors() { + String[] name = getNamedColors(); + + // make every effort to terminate early + if (name == null) { + return; + } + boolean found = false; + for (int i = 0; i < name.length; i++) { + if (name[i].startsWith("android.")) { + found = true; + break; + } + } + if (!found) { + return; + } + + for (int i = 0; i < name.length; i++) { + String s = name[i]; + if (!s.startsWith("android.")) { + continue; + } + String sub = s.substring("android.".length()); + switch (sub) { + case "actionBarItemBackground": + setRColor(s, android.R.attr.actionBarItemBackground); + break; + case "actionModeBackground": + setRColor(s, android.R.attr.actionModeBackground); + break; + case "actionModeSplitBackground": + setRColor(s, android.R.attr.actionModeSplitBackground); + break; + case "activatedBackgroundIndicator": + setRColor(s, android.R.attr.activatedBackgroundIndicator); + break; + case "colorAccent": // Highlight color for interactive elements + setRColor(s, android.R.attr.colorAccent); + break; + case "colorActivatedHighlight": + setRColor(s, android.R.attr.colorActivatedHighlight); + break; + case "colorBackground": // background color for the app’s window + setRColor(s, android.R.attr.colorBackground); + break; + case "colorBackgroundCacheHint": + setRColor(s, android.R.attr.colorBackgroundCacheHint); + break; + // Background color for floating elements + case "colorBackgroundFloating": + setRColor(s, android.R.attr.colorBackgroundFloating); + break; + case "colorButtonNormal": // The default color for buttons + setRColor(s, android.R.attr.colorButtonNormal); + break; + // Color for activated (checked) state of controls. + case "colorControlActivated": + setRColor(s, android.R.attr.colorControlActivated); + break; + case "colorControlHighlight": // Color for highlights on controls + setRColor(s, android.R.attr.colorControlHighlight); + break; + // Default color for controls in their normal state. + case "colorControlNormal": + setRColor(s, android.R.attr.colorControlNormal); + break; + // Color for edge effects (e.g., overscroll glow) + case "colorEdgeEffect": + setRColor(s, android.R.attr.colorEdgeEffect); + break; + case "colorError": + setRColor(s, android.R.attr.colorError); + break; + case "colorFocusedHighlight": + setRColor(s, android.R.attr.colorFocusedHighlight); + break; + case "colorForeground": // General foreground color for views. + setRColor(s, android.R.attr.colorForeground); + break; + // Foreground color for inverse backgrounds. + case "colorForegroundInverse": + setRColor(s, android.R.attr.colorForegroundInverse); + break; + case "colorLongPressedHighlight": + setRColor(s, android.R.attr.colorLongPressedHighlight); + break; + case "colorMultiSelectHighlight": + setRColor(s, android.R.attr.colorMultiSelectHighlight); + break; + case "colorPressedHighlight": + setRColor(s, android.R.attr.colorPressedHighlight); + break; + case "colorPrimary": // The primary branding color for the app. + setRColor(s, android.R.attr.colorPrimary); + break; + case "colorPrimaryDark": // darker variant of the primary color + setRColor(s, android.R.attr.colorPrimaryDark); + break; + case "colorSecondary": + setRColor(s, android.R.attr.colorSecondary); + break; + case "detailsElementBackground": + setRColor(s, android.R.attr.detailsElementBackground); + break; + case "editTextBackground": + setRColor(s, android.R.attr.editTextBackground); + break; + case "galleryItemBackground": + setRColor(s, android.R.attr.galleryItemBackground); + break; + case "headerBackground": + setRColor(s, android.R.attr.headerBackground); + break; + case "itemBackground": + setRColor(s, android.R.attr.itemBackground); + break; + case "numbersBackgroundColor": + setRColor(s, android.R.attr.numbersBackgroundColor); + break; + case "panelBackground": + setRColor(s, android.R.attr.panelBackground); + break; + case "panelColorBackground": + setRColor(s, android.R.attr.panelColorBackground); + break; + case "panelFullBackground": + setRColor(s, android.R.attr.panelFullBackground); + break; + case "popupBackground": + setRColor(s, android.R.attr.popupBackground); + break; + case "queryBackground": + setRColor(s, android.R.attr.queryBackground); + break; + case "selectableItemBackground": + setRColor(s, android.R.attr.selectableItemBackground); + break; + case "submitBackground": + setRColor(s, android.R.attr.submitBackground); + break; + case "textColor": + setRColor(s, android.R.attr.textColor); + break; + case "windowBackground": + setRColor(s, android.R.attr.windowBackground); + break; + case "windowBackgroundFallback": + setRColor(s, android.R.attr.windowBackgroundFallback); + break; + // Primary text color for inverse backgrounds + case "textColorPrimaryInverse": + setRColor(s, android.R.attr.textColorPrimaryInverse); + break; + // Secondary text color for inverse backgrounds + case "textColorSecondaryInverse": + setRColor(s, android.R.attr.textColorSecondaryInverse); + break; + // Tertiary text color for less important text. + case "textColorTertiary": + setRColor(s, android.R.attr.textColorTertiary); + break; + // Tertiary text color for inverse backgrounds + case "textColorTertiaryInverse": + setRColor(s, android.R.attr.textColorTertiaryInverse); + break; + // Text highlight color (e.g., selected text background). + case "textColorHighlight": + setRColor(s, android.R.attr.textColorHighlight); + break; + // Color for hyperlinks. + case "textColorLink": + setRColor(s, android.R.attr.textColorLink); + break; + // Color for hint text. + case "textColorHint": + setRColor(s, android.R.attr.textColorHint); + break; + // text color for inverse backgrounds.. + case "textColorHintInverse": + setRColor(s, android.R.attr.textColorHintInverse); + break; + // Default color for the thumb of switches. + case "colorSwitchThumbNormal": + setRColor(s, android.R.attr.colorControlNormal); + break; + } + } + } + + private void setRColor(String name, int id) { + int color = getColorFromResource(id); + setColor(name, color); + } + + private int getColorFromResource(int id) { + TypedValue typedValue = new TypedValue(); + 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/AndroidRemoteContext.java b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java index 6e4893bc0ee6..dd43bd5d32a6 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 @@ -76,6 +76,16 @@ class AndroidRemoteContext extends RemoteContext { } /** + * Override a color to force it to be the color provided + * + * @param colorName name of color + * @param color + */ + public void setNamedColorOverride(String colorName, int color) { + int id = mVarNameHashMap.get(colorName).mId; + mRemoteComposeState.overrideColor(id, color); + } + /** * Decode a byte array into an image and cache it using the given imageId * * @param width with of image to be loaded 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 97d23c84b5bd..a2f79cc49f2a 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 @@ -42,6 +42,7 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta boolean mInActionDown = false; boolean mDebug = false; Point mActionDownPoint = new Point(0, 0); + AndroidRemoteContext mARContext = new AndroidRemoteContext(); public RemoteComposeCanvas(Context context) { super(context); @@ -88,8 +89,6 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta invalidate(); } - AndroidRemoteContext mARContext = new AndroidRemoteContext(); - @Override public void onViewAttachedToWindow(View view) { if (mDocument == null) { @@ -120,6 +119,20 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta removeAllViews(); } + public String[] getNamedColors() { + return mDocument.getNamedColors(); + } + + /** + * set the color associated with this name. + * + * @param colorName Name of color typically "android.xxx" + * @param colorValue "the argb value" + */ + public void setColor(String colorName, int colorValue) { + mARContext.setNamedColorOverride(colorName, colorValue); + } + public interface ClickCallbacks { void click(int id, String metadata); } |