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 5 package org.chromium.mojo.bindings; 6 7 import org.chromium.mojo.system.Core; 8 import org.chromium.mojo.system.MessagePipeHandle; 9 10 import java.util.concurrent.Executor; 11 12 /** 13 * Wrapper around {@link Router} that will close the connection when not referenced anymore. 14 */ 15 class AutoCloseableRouter implements Router { 16 17 /** 18 * The underlying router. 19 */ 20 private final Router mRouter; 21 22 /** 23 * The executor to close the underlying router. 24 */ 25 private final Executor mExecutor; 26 27 /** 28 * Flags to keep track if this router has been correctly closed. 29 */ 30 private boolean mClosed; 31 32 /** 33 * Constructor. 34 */ AutoCloseableRouter(Core core, Router router)35 public AutoCloseableRouter(Core core, Router router) { 36 mRouter = router; 37 mExecutor = ExecutorFactory.getExecutorForCurrentThread(core); 38 } 39 40 /** 41 * @see Router#setIncomingMessageReceiver(MessageReceiverWithResponder) 42 */ 43 @Override setIncomingMessageReceiver(MessageReceiverWithResponder incomingMessageReceiver)44 public void setIncomingMessageReceiver(MessageReceiverWithResponder incomingMessageReceiver) { 45 mRouter.setIncomingMessageReceiver(incomingMessageReceiver); 46 } 47 48 /** 49 * @see HandleOwner#passHandle() 50 */ 51 @Override passHandle()52 public MessagePipeHandle passHandle() { 53 return mRouter.passHandle(); 54 } 55 56 /** 57 * @see MessageReceiver#accept(Message) 58 */ 59 @Override accept(Message message)60 public boolean accept(Message message) { 61 return mRouter.accept(message); 62 } 63 64 /** 65 * @see MessageReceiverWithResponder#acceptWithResponder(Message, MessageReceiver) 66 */ 67 @Override acceptWithResponder(Message message, MessageReceiver responder)68 public boolean acceptWithResponder(Message message, MessageReceiver responder) { 69 return mRouter.acceptWithResponder(message, responder); 70 71 } 72 73 /** 74 * @see Router#start() 75 */ 76 @Override start()77 public void start() { 78 mRouter.start(); 79 } 80 81 /** 82 * @see Router#setErrorHandler(ConnectionErrorHandler) 83 */ 84 @Override setErrorHandler(ConnectionErrorHandler errorHandler)85 public void setErrorHandler(ConnectionErrorHandler errorHandler) { 86 mRouter.setErrorHandler(errorHandler); 87 } 88 89 /** 90 * @see java.io.Closeable#close() 91 */ 92 @Override close()93 public void close() { 94 mRouter.close(); 95 mClosed = true; 96 } 97 98 /** 99 * @see Object#finalize() 100 */ 101 @Override finalize()102 protected void finalize() throws Throwable { 103 if (!mClosed) { 104 mExecutor.execute(new Runnable() { 105 106 @Override 107 public void run() { 108 close(); 109 } 110 }); 111 throw new IllegalStateException("Warning: Router objects should be explicitly closed " + 112 "when no longer required otherwise you may leak handles."); 113 } 114 super.finalize(); 115 } 116 } 117