Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.content.browser; | 5 package org.chromium.content.browser; |
| 6 | 6 |
| 7 import android.util.SparseArray; | |
| 8 | |
| 9 import org.chromium.base.ObserverList; | |
| 10 import org.chromium.base.ThreadUtils; | |
| 11 import org.chromium.base.annotations.CalledByNative; | 7 import org.chromium.base.annotations.CalledByNative; |
| 12 import org.chromium.base.annotations.JNINamespace; | 8 import org.chromium.base.annotations.JNINamespace; |
| 13 import org.chromium.content_public.browser.MessagePortService; | 9 import org.chromium.content_public.browser.MessagePortService; |
| 14 | 10 |
| 15 /** | 11 /** |
| 16 * Provides the Message Channel functionality for Android Apps | 12 * Provides the Message Channel functionality for Android Apps |
| 17 * (including WebView embedders and Chrome Custom Tabs clients). Specifically | 13 * (including WebView embedders and Chrome Custom Tabs clients). Specifically |
| 18 * manages the message ports that are associated with a message channel and | 14 * manages the message ports that are associated with a message channel and |
| 19 * handles posting/receiving messages to/from them. | 15 * handles posting/receiving messages to/from them. |
| 20 * See https://html.spec.whatwg.org/multipage/comms.html#messagechannel for | 16 * See https://html.spec.whatwg.org/multipage/comms.html#messagechannel for |
| 21 * further information on message channels. | 17 * further information on message channels. |
| 22 * | 18 * |
| 23 * The message ports have unique IDs. In Android implementation, | 19 * The message ports have unique IDs. In Android implementation, |
| 24 * the message ports are only known by their IDs at the native side. | 20 * the message ports are only known by their IDs at the native side. |
| 25 * At the java side, the embedder deals with MessagePort objects. The mapping | 21 * At the java side, the embedder deals with MessagePort objects. The mapping |
| 26 * from an ID to an object is in AppWebMessagePortService. AppWebMessagePortServ ice | 22 * from an ID to an object is in AppWebMessagePortService. AppWebMessagePortServ ice |
| 27 * keeps a strong ref to MessagePort objects until they are closed. | 23 * keeps a strong ref to MessagePort objects until they are closed. |
| 28 * | 24 * |
| 29 * Ownership: The Java AppWebMessagePortService has to be owned by Java side glo bal. | 25 * Ownership: The Java AppWebMessagePortService has to be owned by Java side glo bal. |
| 30 * The native AppWebMessagePortService is a singleton. The | 26 * The native AppWebMessagePortService is a singleton. The |
| 31 * native peer maintains a weak ref to the java object and deregisters itself | 27 * native peer maintains a weak ref to the java object and deregisters itself |
| 32 * before being deleted. | 28 * before being deleted. |
| 33 * | 29 * |
| 34 * All methods are called on UI thread except as noted. | 30 * All methods are called on UI thread except as noted. |
| 35 */ | 31 */ |
| 36 @JNINamespace("content") | 32 @JNINamespace("content") |
| 37 public class AppWebMessagePortService implements MessagePortService { | 33 public class AppWebMessagePortService implements MessagePortService { |
| 38 private static final String TAG = "AppWebMessagePortService"; | 34 private static final String TAG = "AppWebMessagePortService"; |
| 39 | 35 |
| 40 /** | |
| 41 * Observer for MessageChannel events. | |
| 42 */ | |
| 43 public static interface MessageChannelObserver { void onMessageChannelCreate d(); } | |
| 44 | |
| 45 // A thread safe storage for Message Ports. | |
| 46 private static class MessagePortStorage { | |
| 47 private SparseArray<AppWebMessagePort> mMessagePorts = new SparseArray<A ppWebMessagePort>(); | |
| 48 private final Object mLock = new Object(); | |
| 49 | |
| 50 public void remove(int portId) { | |
| 51 synchronized (mLock) { | |
| 52 mMessagePorts.remove(portId); | |
| 53 } | |
| 54 } | |
| 55 | |
| 56 public void put(int portId, AppWebMessagePort m) { | |
| 57 synchronized (mLock) { | |
| 58 mMessagePorts.put(portId, m); | |
| 59 } | |
| 60 } | |
| 61 public AppWebMessagePort get(int portId) { | |
| 62 synchronized (mLock) { | |
| 63 return mMessagePorts.get(portId); | |
| 64 } | |
| 65 } | |
| 66 } | |
| 67 | |
| 68 private long mNativeMessagePortService; | 36 private long mNativeMessagePortService; |
| 69 private MessagePortStorage mPortStorage = new MessagePortStorage(); | |
| 70 private ObserverList<MessageChannelObserver> mObserverList = | |
| 71 new ObserverList<MessageChannelObserver>(); | |
| 72 | 37 |
| 73 public AppWebMessagePortService() { | 38 public AppWebMessagePortService() { |
| 74 mNativeMessagePortService = nativeInitAppWebMessagePortService(); | 39 mNativeMessagePortService = nativeInitAppWebMessagePortService(); |
| 75 } | 40 } |
| 76 | 41 |
| 77 public void addObserver(MessageChannelObserver observer) { | |
| 78 mObserverList.addObserver(observer); | |
| 79 } | |
| 80 | |
| 81 public void removeObserver(MessageChannelObserver observer) { | |
| 82 mObserverList.removeObserver(observer); | |
| 83 } | |
| 84 | |
| 85 public void closePort(int messagePortId) { | |
| 86 mPortStorage.remove(messagePortId); | |
| 87 if (mNativeMessagePortService == 0) return; | |
| 88 nativeClosePort(mNativeMessagePortService, messagePortId); | |
| 89 } | |
| 90 | |
| 91 public void postMessage(int senderId, String message, int[] sentPorts) { | |
| 92 // verify that the port is owned by service still (not transferred). | |
| 93 if (mPortStorage.get(senderId) == null) { | |
| 94 throw new IllegalStateException("Cannot post to unknown port " + sen derId); | |
| 95 } | |
| 96 if (mNativeMessagePortService == 0) return; | |
| 97 nativePostAppToWebMessage(mNativeMessagePortService, senderId, message, sentPorts); | |
| 98 } | |
| 99 | |
| 100 public void removeSentPorts(int[] sentPorts) { | |
| 101 // verify that this service still owns all the ports that are transferre d | |
| 102 if (sentPorts != null) { | |
| 103 for (int port : sentPorts) { | |
| 104 AppWebMessagePort p = mPortStorage.get(port); | |
| 105 if (p == null) { | |
| 106 throw new IllegalStateException("Cannot transfer unknown por t " + port); | |
| 107 } | |
| 108 mPortStorage.remove(port); | |
| 109 } | |
| 110 } | |
| 111 } | |
| 112 | |
| 113 @Override | 42 @Override |
| 114 public AppWebMessagePort[] createMessageChannel() { | 43 public AppWebMessagePort[] createMessageChannel() { |
| 115 return new AppWebMessagePort[] {new AppWebMessagePort(this), new AppWebM essagePort(this)}; | 44 return new AppWebMessagePort[] {new AppWebMessagePort(), new AppWebMessa gePort()}; |
|
Yusuf
2017/01/26 22:53:54
does this mean, we maybe don't need this class to
sgurun-gerrit only
2017/01/27 01:16:37
yes, that is what I noticed too.
please get rid o
| |
| 116 } | |
| 117 | |
| 118 // Called on UI thread. | |
| 119 public void releaseMessages(int portId) { | |
| 120 if (mNativeMessagePortService == 0) return; | |
| 121 nativeReleaseMessages(mNativeMessagePortService, portId); | |
| 122 } | |
| 123 | |
| 124 private AppWebMessagePort addPort(AppWebMessagePort m, int portId) { | |
| 125 if (mPortStorage.get(portId) != null) { | |
| 126 throw new IllegalStateException("Port already exists"); | |
| 127 } | |
| 128 m.setPortId(portId); | |
| 129 mPortStorage.put(portId, m); | |
| 130 return m; | |
| 131 } | 45 } |
| 132 | 46 |
| 133 @CalledByNative | 47 @CalledByNative |
| 134 private void onMessageChannelCreated(int portId1, int portId2, AppWebMessage Port[] ports) { | |
| 135 ThreadUtils.assertOnUiThread(); | |
| 136 addPort(ports[0], portId1); | |
| 137 addPort(ports[1], portId2); | |
| 138 for (MessageChannelObserver observer : mObserverList) { | |
| 139 observer.onMessageChannelCreated(); | |
| 140 } | |
| 141 } | |
| 142 | |
| 143 // Called on IO thread. | |
| 144 @CalledByNative | |
| 145 private void onReceivedMessage(int portId, String message, int[] ports) { | |
| 146 AppWebMessagePort[] messagePorts = null; | |
| 147 for (int i = 0; i < ports.length; i++) { | |
| 148 if (messagePorts == null) { | |
| 149 messagePorts = new AppWebMessagePort[ports.length]; | |
| 150 } | |
| 151 messagePorts[i] = addPort(new AppWebMessagePort(this), ports[i]); | |
| 152 } | |
| 153 mPortStorage.get(portId).onReceivedMessage(message, messagePorts); | |
| 154 } | |
| 155 | |
| 156 @CalledByNative | |
| 157 private void unregisterNativeAppWebMessagePortService() { | 48 private void unregisterNativeAppWebMessagePortService() { |
| 158 mNativeMessagePortService = 0; | 49 mNativeMessagePortService = 0; |
| 159 } | 50 } |
| 160 | 51 |
| 161 private native long nativeInitAppWebMessagePortService(); | 52 private native long nativeInitAppWebMessagePortService(); |
| 162 private native void nativePostAppToWebMessage( | |
| 163 long nativeAppWebMessagePortServiceImpl, int senderId, String messag e, int[] portIds); | |
| 164 private native void nativeClosePort(long nativeAppWebMessagePortServiceImpl, int messagePortId); | |
| 165 private native void nativeReleaseMessages( | |
| 166 long nativeAppWebMessagePortServiceImpl, int messagePortId); | |
| 167 } | 53 } |
| OLD | NEW |