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 #pragma once
18 
19 #include <IVhalClient.h>
20 #include <aidl/android/hardware/automotive/remoteaccess/ApState.h>
21 #include <aidl/android/hardware/automotive/remoteaccess/BnRemoteAccess.h>
22 #include <aidl/android/hardware/automotive/remoteaccess/BnRemoteTaskCallback.h>
23 #include <aidl/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.h>
24 #include <aidl/android/hardware/automotive/remoteaccess/ScheduleInfo.h>
25 #include <android-base/thread_annotations.h>
26 #include <android/binder_auto_utils.h>
27 #include <utils/SystemClock.h>
28 #include <wakeup_client.grpc.pb.h>
29 
30 #include <string>
31 #include <thread>
32 
33 namespace android {
34 namespace hardware {
35 namespace automotive {
36 namespace remoteaccess {
37 
38 // A IRemoteTaskCallback implementation for debug purpose.
39 class DebugRemoteTaskCallback final
40     : public aidl::android::hardware::automotive::remoteaccess::BnRemoteTaskCallback {
41   public:
DebugRemoteTaskCallback()42     DebugRemoteTaskCallback() { mStartTimeMillis = android::uptimeMillis(); };
43 
44     ndk::ScopedAStatus onRemoteTaskRequested(const std::string& clientId,
45                                              const std::vector<uint8_t>& data) override;
46     std::string printTasks();
47 
48   private:
49     struct TaskData {
50         std::string clientId;
51         std::vector<uint8_t> data;
52     };
53 
54     std::mutex mLock;
55     int64_t mStartTimeMillis;
56     std::vector<TaskData> mTasks;
57 };
58 
59 class RemoteAccessService
60     : public aidl::android::hardware::automotive::remoteaccess::BnRemoteAccess {
61   public:
62     explicit RemoteAccessService(WakeupClient::StubInterface* grpcStub);
63 
64     ~RemoteAccessService();
65 
66     ndk::ScopedAStatus getVehicleId(std::string* vehicleId) override;
67 
68     ndk::ScopedAStatus getProcessorId(std::string* processorId) override;
69 
70     ndk::ScopedAStatus getWakeupServiceName(std::string* wakeupServiceName) override;
71 
72     ndk::ScopedAStatus setRemoteTaskCallback(
73             const std::shared_ptr<
74                     aidl::android::hardware::automotive::remoteaccess::IRemoteTaskCallback>&
75                     callback) override;
76 
77     ndk::ScopedAStatus clearRemoteTaskCallback() override;
78 
79     ndk::ScopedAStatus notifyApStateChange(
80             const aidl::android::hardware::automotive::remoteaccess::ApState& newState) override;
81 
82     ndk::ScopedAStatus isTaskScheduleSupported(bool* out) override;
83 
84     ndk::ScopedAStatus getSupportedTaskTypesForScheduling(
85             std::vector<aidl::android::hardware::automotive::remoteaccess::TaskType>* out) override;
86 
87     ndk::ScopedAStatus scheduleTask(
88             const aidl::android::hardware::automotive::remoteaccess::ScheduleInfo& scheduleInfo)
89             override;
90 
91     ndk::ScopedAStatus unscheduleTask(const std::string& clientId,
92                                       const std::string& scheduleId) override;
93 
94     ndk::ScopedAStatus unscheduleAllTasks(const std::string& clientId) override;
95 
96     ndk::ScopedAStatus isTaskScheduled(const std::string& clientId, const std::string& scheduleId,
97                                        bool* out) override;
98 
99     ndk::ScopedAStatus getAllPendingScheduledTasks(
100             const std::string& clientId,
101             std::vector<aidl::android::hardware::automotive::remoteaccess::ScheduleInfo>* out)
102             override;
103 
104     binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
105 
106   private:
107     // For testing.
108     friend class RemoteAccessServiceUnitTest;
109 
110     static bool checkDumpPermission();
111 
112     WakeupClient::StubInterface* mGrpcStub;
113     std::thread mThread;
114     // Whether the GRPC server exists. Only checked and set during init.
115     bool mGrpcServerExist = false;
116     std::mutex mLock;
117     std::condition_variable mCv;
118     std::shared_ptr<aidl::android::hardware::automotive::remoteaccess::IRemoteTaskCallback>
119             mRemoteTaskCallback GUARDED_BY(mLock);
120     std::unique_ptr<grpc::ClientContext> mGetRemoteTasksContext GUARDED_BY(mLock);
121     // Associated with mCv to notify the task loop to stop waiting and exit.
122     bool mTaskWaitStopped GUARDED_BY(mLock);
123     // A mutex to make sure startTaskLoop does not overlap with stopTaskLoop.
124     std::mutex mStartStopTaskLoopLock;
125     bool mTaskLoopRunning GUARDED_BY(mStartStopTaskLoopLock) = false;
126     bool mGrpcReadChannelOpen GUARDED_BY(mLock) = false;
127     std::unordered_map<std::string, size_t> mClientIdToTaskCount GUARDED_BY(mLock);
128 
129     // Default wait time before retry connecting to remote access client is 10s.
130     size_t mRetryWaitInMs = 10'000;
131     std::shared_ptr<DebugRemoteTaskCallback> mDebugCallback;
132 
133     std::thread mInjectDebugTaskThread;
134 
135     void runTaskLoop();
136     void maybeStartTaskLoop();
137     void maybeStopTaskLoop();
138     ndk::ScopedAStatus getVehicleIdWithClient(
139             android::frameworks::automotive::vhal::IVhalClient& client, std::string* vehicleId);
140 
setRetryWaitInMs(size_t retryWaitInMs)141     void setRetryWaitInMs(size_t retryWaitInMs) { mRetryWaitInMs = retryWaitInMs; }
142     void dumpHelp(int fd);
143     void printCurrentStatus(int fd);
144     std::string clientIdToTaskCountToStringLocked() REQUIRES(mLock);
145     void debugInjectTask(int fd, std::string_view clientId, std::string_view taskData);
146     void debugInjectTaskNextReboot(int fd, std::string_view clientId, std::string_view taskData,
147                                    const char* latencyInSecStr);
148     void updateGrpcReadChannelOpen(bool grpcReadChannelOpen);
149     android::base::Result<void> deliverRemoteTaskThroughCallback(const std::string& clientId,
150                                                                  std::string_view taskData);
151     bool isTaskScheduleSupported();
152 };
153 
154 }  // namespace remoteaccess
155 }  // namespace automotive
156 }  // namespace hardware
157 }  // namespace android
158