1 //
2 // Copyright 2018 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 #ifndef __VTS_RESOURCE_VTSHIDLHANDLEDRIVER_H
18 #define __VTS_RESOURCE_VTSHIDLHANDLEDRIVER_H
19 
20 #include <mutex>
21 #include <unordered_map>
22 
23 #include <android-base/logging.h>
24 #include <cutils/native_handle.h>
25 #include <hidl/HidlSupport.h>
26 
27 using android::hardware::hidl_handle;
28 
29 using namespace std;
30 using HandleId = int;
31 
32 namespace android {
33 namespace vts {
34 
35 // A hidl_handle driver that manages all hidl_handle objects created
36 // on the target side. Users can create handle objects to manage their
37 // File I/O.
38 // TODO: Currently, this class only supports opening a single file in
39 //       one handle object. In the future, we need to support opening
40 //       a list of various file types, such as socket, pipe.
41 //
42 // Example:
43 //   VtsHidlHandleDriver handle_driver;
44 //
45 //   // Create a new file handler.
46 //   int writer_id = handle_driver.CreateFileHandle(
47 //        "test.txt", O_RDWR | O_CREAT | O_TRUNC, S_IRWXG, vector<int>());
48 //
49 //   string write_data = "Hello World!";
50 //   // Writer writes to test.txt.
51 //   handle_driver.WriteFile(writer_id,
52 //                           static_cast<const void*>(write_data.c_str())),
53 //                           write_data.length());
54 class VtsHidlHandleDriver {
55  public:
56   // Constructor to initialize a hidl_handle manager.
57   VtsHidlHandleDriver();
58 
59   // Destructor to clean up the class.
60   ~VtsHidlHandleDriver();
61 
62   // Creates a hidl_handle object by providing a single file path to the file
63   // to be opened with the flag and mode, and a list of integers needed in
64   // native_handle_t struct.
65   //
66   // @param filepath path to the file to be opened.
67   // @param flag     file status flag, details in Linux man page.
68   // @param mode     file access mode, details in Linux man page.
69   // @param data     vector of integers useful in native_handle_t struct.
70   //
71   // @return new handle ID registered on the target side.
72   HandleId CreateFileHandle(string filepath, int flag, int mode,
73                             vector<int> data);
74 
75   // Closes all file descriptors in the handle object associated with input ID.
76   //
77   // @param handle_id identifies the handle object.
78   //
79   // @return true if the handle object is found, false otherwise.
80   bool UnregisterHidlHandle(HandleId handle_id);
81 
82   // Reads a file in the handle object.
83   // Caller specifies the handle_id and number of bytes to read.
84   // This function assumes caller only wants to read from a single file,
85   // so it will access the first file descriptor in the native_handle_t struct,
86   // and the first descriptor must be a file.
87   //
88   // @param handle_id identifies the handle object.
89   // @param read_data data read back from file.
90   // @param num_bytes number of bytes to read.
91   //
92   // @return number of bytes read, -1 to signal failure.
93   ssize_t ReadFile(HandleId handle_id, void* read_data, size_t num_bytes);
94 
95   // Writes to a file in the handle object.
96   // Caller specifies the handle_id and number of bytes to write.
97   // This function assumes caller only wants to write to a single file,
98   // so it will access the first file descriptor in the native_handle_t struct,
99   // and the first descriptor must be a file.
100   //
101   // @param handle_id  identifies the handle object.
102   // @param write_data data to be written into to file.
103   // @param num_bytes  number of bytes to write.
104   //
105   // @return number of bytes written, -1 to signal failure.
106   ssize_t WriteFile(HandleId handle_id, const void* write_data,
107                     size_t num_bytes);
108 
109   // Registers a handle object in the driver using an existing
110   // hidl_handle address created by vtsc.
111   //
112   // @param handle_address address of hidl_handle pointer.
113   //
114   // @return id to be used to hidl_handle later.
115   //         -1 if registration fails.
116   HandleId RegisterHidlHandle(size_t hidl_handle_address);
117 
118   // Get hidl_handle address of handle object with handle_id.
119   //
120   // @param handle_id identifies the handle object.
121   // @param result    stores the hidl_handle address.
122   //
123   // @return true if handle object is found, false otherwise.
124   bool GetHidlHandleAddress(HandleId handle_id, size_t* result);
125 
126  private:
127   // Finds the handle object with ID handle_id.
128   // Logs error if handle_id is not found.
129   //
130   // @param handle_id identifies the handle object.
131   // @param release   whether to release the handle object managed unique_ptr.
132   //        This parameter is only true if UnregisterHidlHandle() is called.
133   //
134   // @return hidl_handle pointer.
135   hidl_handle* FindHandle(HandleId handle_id, bool release = false);
136 
137   // A map to keep track of each hidl_handle information.
138   // Store hidl_handle smart pointers.
139   unordered_map<HandleId, unique_ptr<hidl_handle>> hidl_handle_map_;
140 
141   // A mutex to ensure insert and lookup on hidl_handle_map_ are thread-safe.
142   mutex map_mutex_;
143 };
144 
145 }  // namespace vts
146 }  // namespace android
147 #endif  //__VTS_RESOURCE_VTSHIDLHANDLEDRIVER_H