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 android.os.Handler; 20 import android.webkit.WebMessagePort; 21 22 import androidx.annotation.NonNull; 23 import androidx.annotation.Nullable; 24 import androidx.annotation.RestrictTo; 25 26 /** 27 * <p>The Java representation of the 28 * <a href="https://html.spec.whatwg.org/multipage/comms.html#messageport"> 29 * HTML5 message ports.</a> 30 * 31 * <p>A Message port represents one endpoint of a Message Channel. In Android 32 * webview, there is no separate Message Channel object. When a message channel 33 * is created, both ports are tangled to each other and started, and then 34 * returned in a MessagePort array, see {@link WebViewCompat#createWebMessageChannel} 35 * for creating a message channel. 36 * 37 * <p>When a message port is first created or received via transfer, it does not 38 * have a WebMessageCallback to receive web messages. The messages are queued until 39 * a WebMessageCallback is set. 40 * 41 * <p>A message port should be closed when it is not used by the embedder application 42 * anymore. A closed port cannot be transferred or cannot be reopened to send 43 * messages. Close can be called multiple times. 44 * 45 * <p>When a port is transferred to JS, it cannot be used to send or receive messages 46 * at the Java side anymore. Different from HTML5 Spec, a port cannot be transferred 47 * if one of these has ever happened: i. a message callback was set, ii. a message was 48 * posted on it. A transferred port cannot be closed by the application, since 49 * the ownership is also transferred. 50 * 51 * <p>It is possible to transfer both ports of a channel to JS, for example for 52 * communication between subframes. 53 */ 54 public abstract class WebMessagePortCompat { 55 /** 56 * The listener for handling MessagePort events. The message callback 57 * methods are called on the main thread. If the embedder application 58 * wants to receive the messages on a different thread, it can do this 59 * by passing a Handler in 60 * {@link WebMessagePortCompat#setWebMessageCallback(Handler, WebMessageCallbackCompat)}. 61 * In the latter case, the application should be extra careful for thread safety 62 * since WebMessagePort methods should be called on main thread. 63 */ 64 public abstract static class WebMessageCallbackCompat { 65 /** 66 * Message callback for receiving onMessage events. 67 * 68 * @param port the WebMessagePort that the message is destined for 69 * @param message the message from the entangled port. 70 */ onMessage(@onNull WebMessagePortCompat port, @Nullable WebMessageCompat message)71 public void onMessage(@NonNull WebMessagePortCompat port, 72 @Nullable WebMessageCompat message) { } 73 } 74 75 /** 76 * @hide disallow app devs to extend this class. 77 */ 78 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) WebMessagePortCompat()79 public WebMessagePortCompat() { } 80 81 /** 82 * Post a WebMessage to the entangled port. 83 * 84 * @param message the message from Java to JS. 85 * 86 * @throws IllegalStateException If message port is already transferred or closed. 87 */ postMessage(@onNull WebMessageCompat message)88 public abstract void postMessage(@NonNull WebMessageCompat message); 89 90 /** 91 * Close the message port and free any resources associated with it. 92 */ close()93 public abstract void close(); 94 95 /** 96 * Sets a callback to receive message events on the main thread. 97 * 98 * @param callback the message callback. 99 */ setWebMessageCallback(@onNull WebMessageCallbackCompat callback)100 public abstract void setWebMessageCallback(@NonNull WebMessageCallbackCompat callback); 101 102 /** 103 * Sets a callback to receive message events on the handler that is provided 104 * by the application. If the handler is null the message events are received on the main 105 * thread. 106 * 107 * @param handler the handler to receive the message events. 108 * @param callback the message callback. 109 */ setWebMessageCallback(@ullable Handler handler, @NonNull WebMessageCallbackCompat callback)110 public abstract void setWebMessageCallback(@Nullable Handler handler, 111 @NonNull WebMessageCallbackCompat callback); 112 113 /** 114 * Internal getter returning the private {@link WebMessagePort} implementing this class. 115 * @hide 116 */ 117 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) getFrameworkPort()118 public abstract WebMessagePort getFrameworkPort(); 119 } 120