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.internal; 18 19 import android.annotation.SuppressLint; 20 import android.os.Build; 21 import android.os.Handler; 22 import android.webkit.WebMessage; 23 import android.webkit.WebMessagePort; 24 25 import androidx.annotation.RequiresApi; 26 import androidx.webkit.WebMessageCompat; 27 import androidx.webkit.WebMessagePortCompat; 28 29 /** 30 * Implementation of {@link WebMessagePortCompat}. 31 * This class uses either the framework, the WebView APK, or both, to implement 32 * {@link WebMessagePortCompat} functionality. 33 */ 34 public class WebMessagePortImpl extends WebMessagePortCompat { 35 private final WebMessagePort mFrameworksImpl; 36 // TODO(gsennton) add WebMessagePortBoundaryInterface variable 37 38 public WebMessagePortImpl(WebMessagePort frameworksImpl) { 39 mFrameworksImpl = frameworksImpl; 40 } 41 42 @SuppressLint("NewApi") 43 @Override 44 public void postMessage(WebMessageCompat message) { 45 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 46 mFrameworksImpl.postMessage(compatToFrameworkMessage(message)); 47 } else { // TODO(gsennton) add reflection-based implementation 48 throw WebViewFeatureInternal.getUnsupportedOperationException(); 49 } 50 } 51 52 @SuppressLint("NewApi") 53 @Override 54 public void close() { 55 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 56 mFrameworksImpl.close(); 57 } else { // TODO(gsennton) add reflection-based implementation 58 throw WebViewFeatureInternal.getUnsupportedOperationException(); 59 } 60 } 61 62 @Override 63 public void setWebMessageCallback(final WebMessageCallbackCompat callback) { 64 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 65 mFrameworksImpl.setWebMessageCallback(new WebMessagePort.WebMessageCallback() { 66 @Override 67 @SuppressWarnings("NewApi") 68 public void onMessage(WebMessagePort port, WebMessage message) { 69 callback.onMessage(new WebMessagePortImpl(port), 70 frameworkMessageToCompat(message)); 71 } 72 }); 73 } else { // TODO(gsennton) add reflection-based implementation 74 throw WebViewFeatureInternal.getUnsupportedOperationException(); 75 } 76 } 77 78 @Override 79 public void setWebMessageCallback(Handler handler, final WebMessageCallbackCompat callback) { 80 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 81 mFrameworksImpl.setWebMessageCallback(new WebMessagePort.WebMessageCallback() { 82 @Override 83 @SuppressWarnings("NewApi") 84 public void onMessage(WebMessagePort port, WebMessage message) { 85 callback.onMessage(new WebMessagePortImpl(port), 86 frameworkMessageToCompat(message)); 87 } 88 }, handler); 89 } else { // TODO(gsennton) add reflection-based implementation 90 throw WebViewFeatureInternal.getUnsupportedOperationException(); 91 } 92 } 93 94 @Override 95 public WebMessagePort getFrameworkPort() { 96 return mFrameworksImpl; 97 } 98 99 /** 100 * Convert an array of {@link WebMessagePort} objects into an array containing objects of the 101 * corresponding support library class {@link WebMessagePortCompat}. 102 */ 103 public static WebMessagePortCompat[] portsToCompat(WebMessagePort[] ports) { 104 if (ports == null) return null; 105 WebMessagePortCompat[] compatPorts = new WebMessagePortCompat[ports.length]; 106 for (int n = 0; n < ports.length; n++) { 107 compatPorts[n] = new WebMessagePortImpl(ports[n]); 108 } 109 return compatPorts; 110 } 111 112 /** 113 * Convert an array of {@link WebMessagePortCompat} objects into an array containing objects of 114 * the corresponding framework class {@link WebMessagePort}. 115 */ 116 public static WebMessagePort[] compatToPorts(WebMessagePortCompat[] compatPorts) { 117 if (compatPorts == null) return null; 118 WebMessagePort[] ports = new WebMessagePort[compatPorts.length]; 119 for (int n = 0; n < ports.length; n++) { 120 ports[n] = compatPorts[n].getFrameworkPort(); 121 } 122 return ports; 123 } 124 125 /** 126 * Convert a {@link WebMessageCompat} into the corresponding framework class {@link WebMessage}. 127 */ 128 @RequiresApi(23) 129 public static WebMessage compatToFrameworkMessage(WebMessageCompat message) { 130 return new WebMessage( 131 message.getData(), 132 compatToPorts(message.getPorts())); 133 } 134 135 /** 136 * Convert a {@link WebMessage} into the corresponding support library class 137 * {@link WebMessageCompat}. 138 */ 139 @RequiresApi(23) 140 public static WebMessageCompat frameworkMessageToCompat(WebMessage message) { 141 return new WebMessageCompat( 142 message.getData(), 143 portsToCompat(message.getPorts())); 144 } 145 } 146