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