1 /* 2 * Copyright 2018 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 17 package androidx.webkit; 18 19 import androidx.annotation.IntDef; 20 import androidx.annotation.RequiresFeature; 21 import androidx.annotation.RestrictTo; 22 23 import org.jspecify.annotations.NonNull; 24 import org.jspecify.annotations.Nullable; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.util.Objects; 29 30 /** 31 * The Java representation of the HTML5 PostMessage event. See 32 * <a href="https://html.spec.whatwg.org/multipage/comms.html#the-messageevent-interfaces"> 33 * https://html.spec.whatwg.org/multipage/comms.html#the-messageevent-interfaces</a> 34 * for definition of a MessageEvent in HTML5. 35 */ 36 public class WebMessageCompat { 37 38 /** 39 * Indicates the payload of WebMessageCompat is String. 40 */ 41 public static final int TYPE_STRING = 0; 42 /** 43 * Indicates the payload of WebMessageCompat is JavaScript ArrayBuffer. 44 */ 45 public static final int TYPE_ARRAY_BUFFER = 1; 46 private final WebMessagePortCompat @Nullable [] mPorts; 47 private final @Nullable String mString; 48 private final byte @Nullable [] mArrayBuffer; 49 private final @Type int mType; 50 51 /** 52 * Creates a WebMessage with String payload. 53 * 54 * @param data the string of the message. 55 */ WebMessageCompat(@ullable String data)56 public WebMessageCompat(@Nullable String data) { 57 this(data, null); 58 } 59 60 /** 61 * Creates a WebMessage with String payload. 62 * 63 * @param data the string data of the message. 64 * @param ports the ports that are sent with the message. 65 */ WebMessageCompat(@ullable String data, WebMessagePortCompat @Nullable [] ports)66 public WebMessageCompat(@Nullable String data, WebMessagePortCompat @Nullable [] ports) { 67 mString = data; 68 mArrayBuffer = null; 69 mPorts = ports; 70 mType = TYPE_STRING; 71 } 72 73 /** 74 * Creates a WebMessage with JavaScript ArrayBuffer payload. 75 * 76 * @param arrayBuffer the array buffer data of the message. 77 */ 78 @RequiresFeature(name = WebViewFeature.WEB_MESSAGE_ARRAY_BUFFER, 79 enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported") WebMessageCompat(byte @NonNull [] arrayBuffer)80 public WebMessageCompat(byte @NonNull [] arrayBuffer) { 81 this(arrayBuffer, null); 82 } 83 84 /** 85 * Creates a WebMessage with JavaScript ArrayBuffer payload. 86 * 87 * @param arrayBuffer the array buffer data of the message. 88 * @param ports the ports that are sent with the message. 89 */ 90 @RequiresFeature(name = WebViewFeature.WEB_MESSAGE_ARRAY_BUFFER, 91 enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported") WebMessageCompat(byte @NonNull [] arrayBuffer, WebMessagePortCompat @Nullable [] ports)92 public WebMessageCompat(byte @NonNull [] arrayBuffer, 93 WebMessagePortCompat @Nullable [] ports) { 94 Objects.requireNonNull(arrayBuffer); 95 mArrayBuffer = arrayBuffer; 96 mString = null; 97 mPorts = ports; 98 mType = TYPE_ARRAY_BUFFER; 99 } 100 101 /** 102 * Returns the payload type of the message. 103 * 104 * @return the payload type of WebMessageCompat. 105 */ getType()106 public @Type int getType() { 107 return mType; 108 } 109 110 /** 111 * Returns the ArrayBuffer data of message. A ArrayBuffer or Transferable ArrayBuffer can be 112 * received from JavaScript. This should only be called when {@link #getType()} returns 113 * {@link #TYPE_ARRAY_BUFFER}. Example: 114 * <pre class="prettyprint"> 115 * WebMessageCompat message = ... // The WebMessageCompat received or prepared. 116 * if (message.getType() == WebMessageCompat.TYPE_ARRAY_BUFFER) { 117 * byte[] arrayBuffer = message.getArrayBuffer(); 118 * // Access arrayBuffer data here. 119 * } 120 * </pre> 121 * 122 * @return ArrayBuffer payload data. 123 */ getArrayBuffer()124 public byte @NonNull [] getArrayBuffer() { 125 checkType(TYPE_ARRAY_BUFFER); 126 // Required for null check. ArrayBuffer is always non-null when mType == TYPE_ARRAY_BUFFER. 127 Objects.requireNonNull(mArrayBuffer); 128 return mArrayBuffer; 129 } 130 131 /** 132 * Returns the String data of the message. This should only be called when {@link #getType()} 133 * returns {@link #TYPE_STRING}. Example: 134 * <pre class="prettyprint"> 135 * WebMessageCompat message = ... // The WebMessageCompat received or prepared. 136 * if (message.getType() == WebMessageCompat.TYPE_STRING) { 137 * String string = message.getData(); 138 * // Access string data here. 139 * } 140 * </pre> 141 * 142 * @return String payload data. 143 */ getData()144 public @Nullable String getData() { 145 checkType(TYPE_STRING); 146 return mString; 147 } 148 149 /** 150 * Returns the ports that are sent with the message, or {@code null} if no port 151 * is sent. 152 */ getPorts()153 public WebMessagePortCompat @Nullable [] getPorts() { 154 return mPorts; 155 } 156 typeToString(@ype int type)157 private @NonNull String typeToString(@Type int type) { 158 switch (type) { 159 case TYPE_STRING: 160 return "String"; 161 case TYPE_ARRAY_BUFFER: 162 return "ArrayBuffer"; 163 default: 164 return "Unknown"; 165 } 166 } 167 checkType(@ype int typeForGetter)168 private void checkType(@Type int typeForGetter) { 169 if (typeForGetter != mType) { 170 throw new IllegalStateException("Wrong data accessor type detected. " 171 + typeToString(mType) + " expected, but got " + typeToString(typeForGetter)); 172 } 173 } 174 175 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 176 @IntDef({TYPE_STRING, TYPE_ARRAY_BUFFER}) 177 @Retention(RetentionPolicy.SOURCE) 178 public @interface Type { 179 } 180 } 181