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.system.impl;
6 
7 import org.chromium.base.Log;
8 import org.chromium.mojo.system.Core;
9 import org.chromium.mojo.system.Core.HandleSignalsState;
10 import org.chromium.mojo.system.Handle;
11 import org.chromium.mojo.system.UntypedHandle;
12 
13 /**
14  * Implementation of {@link Handle}.
15  */
16 abstract class HandleBase implements Handle {
17     private static final String TAG = "HandleImpl";
18 
19     /**
20      * The pointer to the scoped handle owned by this object.
21      */
22     private int mMojoHandle;
23 
24     /**
25      * The core implementation. Will be used to delegate all behavior.
26      */
27     protected CoreImpl mCore;
28 
29     /**
30      * Base constructor. Takes ownership of the passed handle.
31      */
HandleBase(CoreImpl core, int mojoHandle)32     HandleBase(CoreImpl core, int mojoHandle) {
33         mCore = core;
34         mMojoHandle = mojoHandle;
35     }
36 
37     /**
38      * Constructor for transforming {@link HandleBase} into a specific one. It is used to transform
39      * an {@link UntypedHandle} into a typed one, or any handle into an {@link UntypedHandle}.
40      */
HandleBase(HandleBase other)41     protected HandleBase(HandleBase other) {
42         mCore = other.mCore;
43         HandleBase otherAsHandleImpl = other;
44         int mojoHandle = otherAsHandleImpl.mMojoHandle;
45         otherAsHandleImpl.mMojoHandle = CoreImpl.INVALID_HANDLE;
46         mMojoHandle = mojoHandle;
47     }
48 
49     /**
50      * @see org.chromium.mojo.system.Handle#close()
51      */
52     @Override
close()53     public void close() {
54         if (mMojoHandle != CoreImpl.INVALID_HANDLE) {
55             // After a close, the handle is invalid whether the close succeed or not.
56             int handle = mMojoHandle;
57             mMojoHandle = CoreImpl.INVALID_HANDLE;
58             mCore.close(handle);
59         }
60     }
61 
62     /**
63      * @see org.chromium.mojo.system.Handle#querySignalsState()
64      */
65     @Override
querySignalsState()66     public HandleSignalsState querySignalsState() {
67         return mCore.queryHandleSignalsState(mMojoHandle);
68     }
69 
70     /**
71      * @see org.chromium.mojo.system.Handle#isValid()
72      */
73     @Override
isValid()74     public boolean isValid() {
75         return mMojoHandle != CoreImpl.INVALID_HANDLE;
76     }
77 
78     /**
79      * @see org.chromium.mojo.system.Handle#toUntypedHandle()
80      */
81     @Override
toUntypedHandle()82     public UntypedHandle toUntypedHandle() {
83         return new UntypedHandleImpl(this);
84     }
85 
86     /**
87      * @see org.chromium.mojo.system.Handle#getCore()
88      */
89     @Override
getCore()90     public Core getCore() {
91         return mCore;
92     }
93 
94     /**
95      * @see Handle#releaseNativeHandle()
96      */
97     @Override
releaseNativeHandle()98     public int releaseNativeHandle() {
99         int result = mMojoHandle;
100         mMojoHandle = CoreImpl.INVALID_HANDLE;
101         return result;
102     }
103 
104     /**
105      * Getter for the native scoped handle.
106      *
107      * @return the native scoped handle.
108      */
getMojoHandle()109     int getMojoHandle() {
110         return mMojoHandle;
111     }
112 
113     /**
114      * invalidate the handle. The caller must ensures that the handle does not leak.
115      */
invalidateHandle()116     void invalidateHandle() {
117         mMojoHandle = CoreImpl.INVALID_HANDLE;
118     }
119 
120     /**
121      * Close the handle if it is valid. Necessary because we cannot let handle leak, and we cannot
122      * ensure that every handle will be manually closed.
123      *
124      * @see java.lang.Object#finalize()
125      */
126     @Override
finalize()127     protected final void finalize() throws Throwable {
128         if (isValid()) {
129             // This should not happen, as the user of this class should close the handle. Adding a
130             // warning.
131             Log.w(TAG, "Handle was not closed.");
132             // Ignore result at this point.
133             mCore.closeWithResult(mMojoHandle);
134         }
135         super.finalize();
136     }
137 }
138