1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.os;
18 
19 import android.annotation.IntRange;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.SystemApi;
23 import android.annotation.TestApi;
24 
25 import java.io.Closeable;
26 import java.io.IOException;
27 
28 /**
29  * An abstract representation of a memory block, as representing by the HIDL system.
30  *
31  * The block is defined by a {name, size, handle} tuple, where the name is used to determine how to
32  * interpret the handle. The underlying handle is assumed to be owned by this instance and will be
33  * closed as soon as {@link #close()} is called on this instance, or this instance has been
34  * finalized (the latter supports using it in a shared manner without having to worry about who owns
35  * this instance, the former is more efficient resource-wise and is recommended for most use-cases).
36  * Note, however, that ownership of the handle does not necessarily imply ownership of the
37  * underlying file descriptors - the underlying handle may or may not own them. If you want the
38  * underlying handle to outlive this instance, call {@link #releaseHandle()} to obtain the handle
39  * and detach the ownership relationship.
40  *
41  * @hide
42  */
43 @SystemApi
44 @TestApi
45 public class HidlMemory implements Closeable {
46     private final @NonNull String mName;
47     private final long mSize;
48     private @Nullable NativeHandle mHandle;
49     private long mNativeContext;  // For use of native code.
50 
51     /**
52      * Constructor.
53      *
54      * @param name      The name of the IMapper service used to resolve the handle (e.g. "ashmem").
55      * @param size      The (non-negative) size in bytes of the memory block.
56      * @param handle    The handle. May be null. This instance will own the handle and will close it
57      *                  as soon as {@link #close()} is called or the object is destroyed. This, this
58      *                  handle instance should generally not be shared with other clients.
59      */
HidlMemory(@onNull String name, @IntRange(from = 0) long size, @Nullable NativeHandle handle)60     public HidlMemory(@NonNull String name, @IntRange(from = 0) long size,
61             @Nullable NativeHandle handle) {
62         mName = name;
63         mSize = size;
64         mHandle = handle;
65     }
66 
67     /**
68      * Create a copy of this instance, where the underlying handle (and its file descriptors) have
69      * been duplicated.
70      */
71     @NonNull
dup()72     public HidlMemory dup() throws IOException {
73         return new HidlMemory(mName, mSize, mHandle != null ? mHandle.dup() : null);
74     }
75 
76     /**
77      * Close the underlying native handle. No-op if handle is null or has been released using {@link
78      * #releaseHandle()}.
79      */
80     @Override
close()81     public void close() throws IOException {
82         if (mHandle != null) {
83             mHandle.close();
84         }
85     }
86 
87     /**
88      * Disowns the underlying handle and returns it. This object becomes invalid.
89      *
90      * @return The underlying handle.
91      */
92     @NonNull
releaseHandle()93     public NativeHandle releaseHandle() {
94         NativeHandle handle = mHandle;
95         mHandle = null;
96         return handle;
97     }
98 
99     /**
100      * Gets the name, which represents how the handle is to be interpreted.
101      *
102      * @return The name.
103      */
104     @NonNull
getName()105     public String getName() {
106         return mName;
107     }
108 
109     /**
110      * Gets the size of the block, in bytes.
111      *
112      * @return The size.
113      */
getSize()114     public long getSize() {
115         return mSize;
116     }
117 
118     /**
119      * Gets a native handle. The actual interpretation depends on the name and is implementation
120      * defined.
121      *
122      * @return The native handle.
123      */
124     @Nullable
getHandle()125     public NativeHandle getHandle() {
126         return mHandle;
127     }
128 
129     @Override
finalize()130     protected void finalize() {
131         try {
132             close();
133         } catch (IOException e) {
134             throw new RuntimeException(e);
135         } finally {
136             nativeFinalize();
137         }
138     }
139 
nativeFinalize()140     private native void nativeFinalize();
141 }
142