1 /* 2 * Copyright (C) 2024 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.core.semantics; 17 18 import android.annotation.NonNull; 19 import android.annotation.Nullable; 20 21 import com.android.internal.widget.remotecompose.core.Operation; 22 import com.android.internal.widget.remotecompose.core.Operations; 23 import com.android.internal.widget.remotecompose.core.RemoteContext; 24 import com.android.internal.widget.remotecompose.core.WireBuffer; 25 import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer; 26 import com.android.internal.widget.remotecompose.core.serialize.MapSerializer; 27 import com.android.internal.widget.remotecompose.core.serialize.SerializeTags; 28 29 import java.util.List; 30 31 /** Implementation of the most common semantics used in typical Android apps. */ 32 public class CoreSemantics extends Operation implements AccessibilityModifier { 33 public int mContentDescriptionId = 0; 34 public @Nullable Role mRole = null; 35 public int mTextId = 0; 36 public int mStateDescriptionId = 0; 37 public boolean mEnabled = true; 38 public Mode mMode = Mode.SET; 39 public boolean mClickable = false; 40 41 @Override getOpCode()42 public int getOpCode() { 43 return Operations.ACCESSIBILITY_SEMANTICS; 44 } 45 46 @Nullable 47 @Override getRole()48 public Role getRole() { 49 return mRole; 50 } 51 52 @Override getMode()53 public Mode getMode() { 54 return mMode; 55 } 56 57 @Override write(WireBuffer buffer)58 public void write(WireBuffer buffer) { 59 buffer.writeInt(mContentDescriptionId); 60 buffer.writeByte((mRole != null) ? mRole.ordinal() : -1); 61 buffer.writeInt(mTextId); 62 buffer.writeInt(mStateDescriptionId); 63 buffer.writeByte(mMode.ordinal()); 64 buffer.writeBoolean(mEnabled); 65 buffer.writeBoolean(mClickable); 66 } 67 read(WireBuffer buffer)68 private void read(WireBuffer buffer) { 69 mContentDescriptionId = buffer.readInt(); 70 mRole = Role.fromInt(buffer.readByte()); 71 mTextId = buffer.readInt(); 72 mStateDescriptionId = buffer.readInt(); 73 mMode = Mode.values()[buffer.readByte()]; 74 mEnabled = buffer.readBoolean(); 75 mClickable = buffer.readBoolean(); 76 } 77 78 @Override apply(RemoteContext context)79 public void apply(RemoteContext context) { 80 // Handled via touch helper 81 } 82 83 @NonNull 84 @Override toString()85 public String toString() { 86 StringBuilder builder = new StringBuilder(); 87 builder.append("SEMANTICS"); 88 if (mMode != Mode.SET) { 89 builder.append(" "); 90 builder.append(mMode); 91 } 92 if (mRole != null) { 93 builder.append(" "); 94 builder.append(mRole); 95 } 96 if (mContentDescriptionId > 0) { 97 builder.append(" contentDescription="); 98 builder.append(mContentDescriptionId); 99 } 100 if (mTextId > 0) { 101 builder.append(" text="); 102 builder.append(mTextId); 103 } 104 if (mStateDescriptionId > 0) { 105 builder.append(" stateDescription="); 106 builder.append(mStateDescriptionId); 107 } 108 if (!mEnabled) { 109 builder.append(" disabled"); 110 } 111 if (mClickable) { 112 builder.append(" clickable"); 113 } 114 return builder.toString(); 115 } 116 117 @Nullable 118 @Override deepToString(String indent)119 public String deepToString(String indent) { 120 return indent + this; 121 } 122 123 @Override serializeToString(int indent, @NonNull StringSerializer serializer)124 public void serializeToString(int indent, @NonNull StringSerializer serializer) { 125 serializer.append(indent, "SEMANTICS" + " = " + this); 126 } 127 128 /** 129 * Reads a CoreSemantics object from a WireBuffer and adds it to a list of operations. 130 * 131 * <p>This method reads the data required to construct a CoreSemantics object from the provided 132 * WireBuffer. After reading and constructing the CoreSemantics object, it is added to the 133 * provided list of operations. 134 * 135 * @param buffer The WireBuffer to read data from. 136 * @param operations The list of operations to which the read CoreSemantics object will be 137 * added. 138 */ read(WireBuffer buffer, List<Operation> operations)139 public static void read(WireBuffer buffer, List<Operation> operations) { 140 CoreSemantics semantics = new CoreSemantics(); 141 142 semantics.read(buffer); 143 144 operations.add(semantics); 145 } 146 147 @Override getContentDescriptionId()148 public Integer getContentDescriptionId() { 149 return mContentDescriptionId != 0 ? mContentDescriptionId : null; 150 } 151 getStateDescriptionId()152 public @Nullable Integer getStateDescriptionId() { 153 return mStateDescriptionId != 0 ? mStateDescriptionId : null; 154 } 155 getTextId()156 public @Nullable Integer getTextId() { 157 return mTextId != 0 ? mTextId : null; 158 } 159 160 @Override serialize(MapSerializer serializer)161 public void serialize(MapSerializer serializer) { 162 serializer 163 .addTags(SerializeTags.MODIFIER, SerializeTags.A11Y) 164 .addType("CoreSemantics") 165 .add("contentDescriptionId", mContentDescriptionId) 166 .add("role", mRole) 167 .add("textId", mTextId) 168 .add("stateDescriptionId", mStateDescriptionId) 169 .add("enabled", mEnabled) 170 .add("mode", mMode) 171 .add("clickable", mClickable); 172 } 173 } 174