• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      * The underlying router.
18      */
19     private final Router mRouter;
20 
21     /**
22      * The executor to close the underlying router.
23      */
24     private final Executor mExecutor;
25 
26     /**
27      * Exception used to track AutoCloseableRouter's allocation location for debugging puproses when
28      * leaked.
29      */
30     private final Exception mAllocationException;
31 
32     /**
33      * Flags to keep track if this router has been correctly closed.
34      */
35     private boolean mClosed;
36 
37     /**
38      * Constructor.
39      */
AutoCloseableRouter(Core core, Router router)40     public AutoCloseableRouter(Core core, Router router) {
41         mRouter = router;
42         mExecutor = ExecutorFactory.getExecutorForCurrentThread(core);
43         mAllocationException = new Exception("AutocloseableRouter allocated at:");
44     }
45 
46     /**
47      * @see Router#setIncomingMessageReceiver(MessageReceiverWithResponder)
48      */
49     @Override
setIncomingMessageReceiver(MessageReceiverWithResponder incomingMessageReceiver)50     public void setIncomingMessageReceiver(MessageReceiverWithResponder incomingMessageReceiver) {
51         mRouter.setIncomingMessageReceiver(incomingMessageReceiver);
52     }
53 
54     /**
55      * @see HandleOwner#passHandle()
56      */
57     @Override
passHandle()58     public MessagePipeHandle passHandle() {
59         return mRouter.passHandle();
60     }
61 
62     /**
63      * @see MessageReceiver#accept(Message)
64      */
65     @Override
accept(Message message)66     public boolean accept(Message message) {
67         return mRouter.accept(message);
68     }
69 
70     /**
71      * @see MessageReceiverWithResponder#acceptWithResponder(Message, MessageReceiver)
72      */
73     @Override
acceptWithResponder(Message message, MessageReceiver responder)74     public boolean acceptWithResponder(Message message, MessageReceiver responder) {
75         return mRouter.acceptWithResponder(message, responder);
76 
77     }
78 
79     /**
80      * @see Router#start()
81      */
82     @Override
start()83     public void start() {
84         mRouter.start();
85     }
86 
87     /**
88      * @see Router#setErrorHandler(ConnectionErrorHandler)
89      */
90     @Override
setErrorHandler(ConnectionErrorHandler errorHandler)91     public void setErrorHandler(ConnectionErrorHandler errorHandler) {
92         mRouter.setErrorHandler(errorHandler);
93     }
94 
95     /**
96      * @see java.io.Closeable#close()
97      */
98     @Override
close()99     public void close() {
100         mRouter.close();
101         mClosed = true;
102     }
103 
104     /**
105      * @see Object#finalize()
106      */
107     @Override
finalize()108     protected void finalize() throws Throwable {
109         if (!mClosed) {
110             mExecutor.execute(new Runnable() {
111 
112                 @Override
113                 public void run() {
114                     close();
115                 }
116             });
117             throw new IllegalStateException("Warning: Router objects should be explicitly closed "
118                             + "when no longer required otherwise you may leak handles.",
119                     mAllocationException);
120         }
121         super.finalize();
122     }
123 }
124