1 /*
2  * Copyright (C) 2022 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 HARDWARE_GOOGLE_PIXEL_USB_MONITORFFS_H_
18 #define HARDWARE_GOOGLE_PIXEL_USB_MONITORFFS_H_
19 
20 #include <android-base/unique_fd.h>
21 #include <pixelusb/CommonUtils.h>
22 
23 #include <mutex>
24 #include <string>
25 #include <thread>
26 #include <vector>
27 
28 namespace android {
29 namespace hardware {
30 namespace google {
31 namespace pixel {
32 namespace usb {
33 
34 using ::android::base::unique_fd;
35 
36 // MonitorFfs automously manages gadget pullup by monitoring
37 // the ep file status. Restarts the usb gadget when the ep
38 // owner restarts.
39 class MonitorFfs {
40   private:
41     // Monitors the endpoints Inotify events.
42     unique_fd mInotifyFd;
43     // Control pipe for shutting down the mMonitor thread.
44     // mMonitor exits when SHUTDOWN_MONITOR is written into
45     // mEventFd/
46     unique_fd mEventFd;
47     // Pools on mInotifyFd and mEventFd.
48     unique_fd mEpollFd;
49     std::vector<int> mWatchFd;
50 
51     // Maintains the list of Endpoints.
52     std::vector<std::string> mEndpointList;
53     // protects the CV.
54     std::mutex mLock;
55     std::condition_variable mCv;
56     // protects mInotifyFd, mEpollFd.
57     std::mutex mLockFd;
58 
59     // Flag to maintain the current status of gadget pullup.
60     bool mCurrentUsbFunctionsApplied;
61 
62     // Thread object that executes the ep monitoring logic.
63     std::unique_ptr<std::thread> mMonitor;
64     // Callback to be invoked when gadget is pulled up.
65     void (*mCallback)(bool functionsApplied, void *payload);
66     void *mPayload;
67     // Name of the USB gadget. Used for pullup.
68     const char *const mGadgetName;
69     // Monitor State
70     bool mMonitorRunning;
71 
72   public:
73     MonitorFfs(const char *const gadget);
74     // Inits all the UniqueFds.
75     void reset();
76     // Starts monitoring endpoints and pullup the gadget when
77     // the descriptors are written.
78     bool startMonitor();
79     // Waits for timeout_ms for gadget pull up to happen.
80     // Returns immediately if the gadget is already pulled up.
81     bool waitForPullUp(int timeout_ms);
82     // Adds the given fd to the watch list.
83     bool addInotifyFd(std::string fd);
84     // Adds the given endpoint to the watch list.
85     void addEndPoint(std::string ep);
86     // Registers the async callback from the caller to notify the caller
87     // when the gadget pull up happens.
88     void registerFunctionsAppliedCallback(void (*callback)(bool functionsApplied, void *(payload)),
89                                           void *payload);
90     bool isMonitorRunning();
91     // Ep monitoring and the gadget pull up logic.
92     static void *startMonitorFd(void *param);
93 };
94 
95 }  // namespace usb
96 }  // namespace pixel
97 }  // namespace google
98 }  // namespace hardware
99 }  // namespace android
100 
101 #endif  // HARDWARE_GOOGLE_PIXEL_USB_MONITORFFS_H_
102