1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.internal.widget.remotecompose.player.platform; 17 18 import android.graphics.Bitmap; 19 import android.graphics.BitmapFactory; 20 import android.graphics.Canvas; 21 22 import com.android.internal.widget.remotecompose.core.RemoteContext; 23 import com.android.internal.widget.remotecompose.core.VariableSupport; 24 import com.android.internal.widget.remotecompose.core.operations.FloatExpression; 25 import com.android.internal.widget.remotecompose.core.operations.ShaderData; 26 27 import java.util.HashMap; 28 29 /** 30 * An implementation of Context for Android. 31 * <p> 32 * This is used to play the RemoteCompose operations on Android. 33 */ 34 class AndroidRemoteContext extends RemoteContext { 35 useCanvas(Canvas canvas)36 public void useCanvas(Canvas canvas) { 37 if (mPaintContext == null) { 38 mPaintContext = new AndroidPaintContext(this, canvas); 39 } else { 40 // need to make sure to update the canvas for the current one 41 mPaintContext.reset(); 42 ((AndroidPaintContext) mPaintContext).setCanvas(canvas); 43 } 44 mWidth = canvas.getWidth(); 45 mHeight = canvas.getHeight(); 46 } 47 48 /////////////////////////////////////////////////////////////////////////////////////////////// 49 // Data handling 50 /////////////////////////////////////////////////////////////////////////////////////////////// 51 52 @Override loadPathData(int instanceId, float[] floatPath)53 public void loadPathData(int instanceId, float[] floatPath) { 54 if (!mRemoteComposeState.containsId(instanceId)) { 55 mRemoteComposeState.cache(instanceId, floatPath); 56 } 57 } 58 59 static class VarName { 60 String mName; 61 int mId; 62 int mType; 63 VarName(String name, int id, int type)64 VarName(String name, int id, int type) { 65 mName = name; 66 mId = id; 67 mType = type; 68 } 69 } 70 71 HashMap<String, VarName> mVarNameHashMap = new HashMap<>(); 72 73 @Override loadVariableName(String varName, int varId, int varType)74 public void loadVariableName(String varName, int varId, int varType) { 75 mVarNameHashMap.put(varName, new VarName(varName, varId, varType)); 76 } 77 78 /** 79 * Decode a byte array into an image and cache it using the given imageId 80 * 81 * @param width with of image to be loaded 82 * @param height height of image to be loaded 83 * @param bitmap a byte array containing the image information 84 * @oaram imageId the id of the image 85 */ 86 @Override loadBitmap(int imageId, int width, int height, byte[] bitmap)87 public void loadBitmap(int imageId, int width, int height, byte[] bitmap) { 88 if (!mRemoteComposeState.containsId(imageId)) { 89 Bitmap image = BitmapFactory.decodeByteArray(bitmap, 0, bitmap.length); 90 mRemoteComposeState.cache(imageId, image); 91 } 92 } 93 94 @Override loadText(int id, String text)95 public void loadText(int id, String text) { 96 if (!mRemoteComposeState.containsId(id)) { 97 mRemoteComposeState.cache(id, text); 98 } else { 99 mRemoteComposeState.update(id, text); 100 } 101 } 102 103 @Override getText(int id)104 public String getText(int id) { 105 return (String) mRemoteComposeState.getFromId(id); 106 } 107 108 @Override loadFloat(int id, float value)109 public void loadFloat(int id, float value) { 110 mRemoteComposeState.updateFloat(id, value); 111 } 112 113 114 @Override loadColor(int id, int color)115 public void loadColor(int id, int color) { 116 mRemoteComposeState.updateColor(id, color); 117 } 118 119 @Override loadAnimatedFloat(int id, FloatExpression animatedFloat)120 public void loadAnimatedFloat(int id, FloatExpression animatedFloat) { 121 mRemoteComposeState.cache(id, animatedFloat); 122 } 123 124 @Override loadShader(int id, ShaderData value)125 public void loadShader(int id, ShaderData value) { 126 mRemoteComposeState.cache(id, value); 127 } 128 129 @Override getFloat(int id)130 public float getFloat(int id) { 131 return (float) mRemoteComposeState.getFloat(id); 132 } 133 134 @Override getColor(int id)135 public int getColor(int id) { 136 return mRemoteComposeState.getColor(id); 137 } 138 139 @Override listensTo(int id, VariableSupport variableSupport)140 public void listensTo(int id, VariableSupport variableSupport) { 141 mRemoteComposeState.listenToVar(id, variableSupport); 142 } 143 144 @Override updateOps()145 public int updateOps() { 146 return mRemoteComposeState.getOpsToUpdate(this); 147 } 148 149 @Override getShader(int id)150 public ShaderData getShader(int id) { 151 return (ShaderData) mRemoteComposeState.getFromId(id); 152 } 153 154 /////////////////////////////////////////////////////////////////////////////////////////////// 155 // Click handling 156 /////////////////////////////////////////////////////////////////////////////////////////////// 157 158 @Override addClickArea(int id, int contentDescriptionId, float left, float top, float right, float bottom, int metadataId)159 public void addClickArea(int id, 160 int contentDescriptionId, 161 float left, 162 float top, 163 float right, 164 float bottom, 165 int metadataId) { 166 String contentDescription = (String) mRemoteComposeState.getFromId(contentDescriptionId); 167 String metadata = (String) mRemoteComposeState.getFromId(metadataId); 168 mDocument.addClickArea(id, contentDescription, left, top, right, bottom, metadata); 169 } 170 } 171 172