1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5package org.chromium.mojo.bindings; 6 7import org.chromium.mojo.system.Core; 8import org.chromium.mojo.system.MessagePipeHandle; 9import org.chromium.mojo.system.MojoException; 10import org.chromium.mojo.system.Pair; 11 12import java.io.Closeable; 13 14/** 15 * Base class for mojo generated interfaces. 16 */ 17public interface Interface extends ConnectionErrorHandler, Closeable { 18 19 /** 20 * The close method is called when the connection to the interface is closed. 21 * 22 * @see java.io.Closeable#close() 23 */ 24 @Override 25 public void close(); 26 27 /** 28 * A proxy to a mojo interface. This is base class for all generated proxies. It implements the 29 * Interface and each time a method is called, the parameters are serialized and sent to the 30 * {@link MessageReceiverWithResponder}, along with the response callback if needed. 31 */ 32 public interface Proxy extends Interface { 33 34 /** 35 * Set the {@link ConnectionErrorHandler} that will be notified of errors. 36 */ 37 public void setErrorHandler(ConnectionErrorHandler errorHandler); 38 39 } 40 41 /** 42 * Base implementation of {@link Proxy}. 43 */ 44 abstract class AbstractProxy implements Proxy { 45 46 /** 47 * The {@link Core} implementation to use. 48 */ 49 private final Core mCore; 50 51 /** 52 * The {@link MessageReceiverWithResponder} that will receive a serialized message for each 53 * method call. 54 */ 55 private final MessageReceiverWithResponder mMessageReceiver; 56 57 /** 58 * The {@link ConnectionErrorHandler} that will be notified of errors. 59 */ 60 private ConnectionErrorHandler mErrorHandler = null; 61 62 /** 63 * Constructor. 64 * 65 * @param core the Core implementation used to create pipes and access the async waiter. 66 * @param messageReceiver the message receiver to send message to. 67 */ 68 protected AbstractProxy(Core core, MessageReceiverWithResponder messageReceiver) { 69 this.mCore = core; 70 this.mMessageReceiver = messageReceiver; 71 } 72 73 /** 74 * Returns the message receiver to send message to. 75 */ 76 protected MessageReceiverWithResponder getMessageReceiver() { 77 return mMessageReceiver; 78 } 79 80 /** 81 * Returns the Core implementation. 82 */ 83 protected Core getCore() { 84 return mCore; 85 } 86 87 /** 88 * @see Proxy#setErrorHandler(ConnectionErrorHandler) 89 */ 90 @Override 91 public void setErrorHandler(ConnectionErrorHandler errorHandler) { 92 this.mErrorHandler = errorHandler; 93 } 94 95 /** 96 * @see ConnectionErrorHandler#onConnectionError(MojoException) 97 */ 98 @Override 99 public void onConnectionError(MojoException e) { 100 if (mErrorHandler != null) { 101 mErrorHandler.onConnectionError(e); 102 } 103 } 104 105 /** 106 * @see Closeable#close() 107 */ 108 @Override 109 public void close() { 110 mMessageReceiver.close(); 111 } 112 } 113 114 /** 115 * Base implementation of Stub. Stubs are message receivers that deserialize the payload and 116 * call the appropriate method in the implementation. If the method returns result, the stub 117 * serializes the response and sends it back. 118 * 119 * @param <I> the type of the interface to delegate calls to. 120 */ 121 abstract class Stub<I extends Interface> implements MessageReceiverWithResponder { 122 123 /** 124 * The {@link Core} implementation to use. 125 */ 126 private final Core mCore; 127 128 /** 129 * The implementation to delegate calls to. 130 */ 131 private final I mImpl; 132 133 /** 134 * Constructor. 135 * 136 * @param core the {@link Core} implementation to use. 137 * @param impl the implementation to delegate calls to. 138 */ 139 public Stub(Core core, I impl) { 140 mCore = core; 141 mImpl = impl; 142 } 143 144 /** 145 * Returns the Core implementation. 146 */ 147 protected Core getCore() { 148 return mCore; 149 } 150 151 /** 152 * Returns the implementation to delegate calls to. 153 */ 154 protected I getImpl() { 155 return mImpl; 156 } 157 158 /** 159 * @see org.chromium.mojo.bindings.MessageReceiver#close() 160 */ 161 @Override 162 public void close() { 163 mImpl.close(); 164 } 165 166 } 167 168 /** 169 * The |Manager| object enables building of proxies and stubs for a given interface. 170 * 171 * @param <I> the type of the interface the manager can handle. 172 * @param <P> the type of the proxy the manager can handle. To be noted, P always extends I. 173 */ 174 abstract class Manager<I extends Interface, P extends Proxy> { 175 176 /** 177 * Returns the name of the interface. This is an opaque (but human readable) identifier used 178 * by the service provider to identify services. 179 */ 180 public abstract String getName(); 181 182 /** 183 * Binds the given implementation to the handle. 184 */ 185 public void bind(I impl, MessagePipeHandle handle) { 186 // The router (and by consequence the handle) is intentionally leaked. It will close 187 // itself when the connected handle is closed and the proxy receives the connection 188 // error. 189 Router router = new RouterImpl(handle); 190 bind(handle.getCore(), impl, router); 191 router.start(); 192 } 193 194 /** 195 * Binds the given implementation to the InterfaceRequest. 196 */ 197 public final void bind(I impl, InterfaceRequest<I> request) { 198 bind(impl, request.passHandle()); 199 } 200 201 /** 202 * Returns a Proxy that will send messages to the given |handle|. This implies that the 203 * other end of the handle must be binded to an implementation of the interface. 204 */ 205 public final P attachProxy(MessagePipeHandle handle) { 206 RouterImpl router = new RouterImpl(handle); 207 P proxy = attachProxy(handle.getCore(), router); 208 DelegatingConnectionErrorHandler handlers = new DelegatingConnectionErrorHandler(); 209 handlers.addConnectionErrorHandler(proxy); 210 router.setErrorHandler(handlers); 211 router.start(); 212 return proxy; 213 } 214 215 /** 216 * Constructs a new |InterfaceRequest| for the interface. This method returns a Pair where 217 * the first element is a proxy, and the second element is the request. The proxy can be 218 * used immediately. 219 */ 220 public final Pair<P, InterfaceRequest<I>> getInterfaceRequest(Core core) { 221 Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null); 222 P proxy = attachProxy(handles.first); 223 return Pair.create(proxy, new InterfaceRequest<I>(handles.second)); 224 } 225 226 /** 227 * Binds the implementation to the given |router|. 228 */ 229 final void bind(Core core, I impl, Router router) { 230 router.setErrorHandler(impl); 231 router.setIncomingMessageReceiver(buildStub(core, impl)); 232 } 233 234 /** 235 * Returns a Proxy that will send messages to the given |router|. 236 */ 237 final P attachProxy(Core core, Router router) { 238 return buildProxy(core, new AutoCloseableRouter(core, router)); 239 } 240 241 /** 242 * Creates a new array of the given |size|. 243 */ 244 protected abstract I[] buildArray(int size); 245 246 /** 247 * Constructs a Stub delegating to the given implementation. 248 */ 249 protected abstract Stub<I> buildStub(Core core, I impl); 250 251 /** 252 * Constructs a Proxy forwarding the calls to the given message receiver. 253 */ 254 protected abstract P buildProxy(Core core, MessageReceiverWithResponder messageReceiver); 255 256 } 257} 258