1 /* 2 * Copyright (C) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef OHOS_IPC_IPC_PROCESS_SKELETON_H 17 #define OHOS_IPC_IPC_PROCESS_SKELETON_H 18 19 #include <atomic> 20 #include <list> 21 #include <map> 22 #include <shared_mutex> 23 24 #include "invoker_rawdata.h" 25 #include "ipc_object_proxy.h" 26 #include "ipc_object_stub.h" 27 #include "ipc_thread_pool.h" 28 #include "iremote_object.h" 29 #include "nocopyable.h" 30 #include "sys_binder.h" 31 32 #ifndef CONFIG_IPC_SINGLE 33 #include "comm_auth_info.h" 34 #include "dbinder_callback_stub.h" 35 #include "dbinder_session_object.h" 36 #include "dbinder_softbus_client.h" 37 #include "stub_refcount_object.h" 38 #endif 39 40 namespace OHOS { 41 #ifdef CONFIG_IPC_SINGLE 42 namespace IPC_SINGLE { 43 #endif 44 #ifndef CONFIG_IPC_SINGLE 45 struct SocketThreadLockInfo { 46 std::mutex mutex; 47 std::condition_variable condition; 48 bool ready = false; 49 }; 50 51 struct ThreadMessageInfo { 52 uint32_t flags; 53 binder_size_t bufferSize; 54 binder_size_t offsetsSize; 55 binder_uintptr_t offsets; 56 uint32_t socketId; 57 void *buffer; 58 std::mutex mutex; 59 std::condition_variable condition; 60 bool ready; 61 }; 62 63 struct ThreadProcessInfo { 64 int32_t listenFd; 65 uint32_t packageSize; 66 std::shared_ptr<char> buffer; 67 }; 68 69 struct AppAuthInfo { 70 uint32_t pid; 71 uint32_t uid; 72 uint32_t tokenId; 73 int32_t socketId; 74 uint64_t stubIndex; 75 IRemoteObject *stub; 76 std::string deviceId; 77 }; 78 #endif 79 80 class IPCProcessSkeleton { 81 public: 82 enum { 83 LISTEN_THREAD_CREATE_OK, // Invoker family. 84 LISTEN_THREAD_CREATE_FAILED, 85 LISTEN_THREAD_CREATED_ALREADY, 86 LISTEN_THREAD_CREATED_TIMEOUT 87 }; 88 ~IPCProcessSkeleton(); 89 90 static IPCProcessSkeleton *GetCurrent(); 91 static std::string ConvertToSecureString(const std::string &str); GetIPCRuntimeInfo()92 static inline const char *GetIPCRuntimeInfo() 93 { 94 #ifndef CONFIG_IPC_SINGLE 95 return "ipc_core"; 96 #else 97 return "ipc_single"; 98 #endif 99 }; 100 101 #ifndef CONFIG_IPC_SINGLE 102 static uint32_t ConvertChannelID2Int(int64_t databusChannelId); 103 static bool IsHandleMadeByUser(uint32_t handle); 104 #endif 105 bool SetIPCProxyLimit(uint64_t num, std::function<void(uint64_t num)> callback); 106 bool SetMaxWorkThread(int maxThreadNum); 107 std::u16string MakeHandleDescriptor(int handle); 108 109 bool OnThreadTerminated(const std::string &threadName); 110 bool SpawnThread(int policy = IPCWorkThread::SPAWN_PASSIVE, int proto = IRemoteObject::IF_PROT_DEFAULT); 111 112 sptr<IRemoteObject> FindOrNewObject(int handle, const dbinder_negotiation_data *dbinderData = nullptr); 113 bool IsContainsObject(IRemoteObject *object); 114 sptr<IRemoteObject> QueryObject(const std::u16string &descriptor, bool lockFlag = true); 115 bool AttachObject(IRemoteObject *object, bool lockFlag = true); 116 bool DetachObject(IRemoteObject *object); 117 sptr<IRemoteObject> GetProxyObject(int handle, bool &newFlag); 118 119 sptr<IRemoteObject> GetRegistryObject(); 120 bool SetRegistryObject(sptr<IRemoteObject> &object); 121 void BlockUntilThreadAvailable(); 122 void LockForNumExecuting(); 123 void UnlockForNumExecuting(); 124 125 #ifndef CONFIG_IPC_SINGLE 126 bool AttachRawData(int32_t socketId, uint64_t seqNumber, std::shared_ptr<InvokerRawData> rawData); 127 bool DetachRawData(int32_t socketId, uint64_t seqNumber); 128 std::shared_ptr<InvokerRawData> QueryRawData(int32_t socketId, uint64_t seqNumber); 129 130 sptr<IRemoteObject> GetSAMgrObject(); 131 std::shared_ptr<DBinderSessionObject> ProxyDetachDBinderSession(uint32_t handle, IPCObjectProxy *proxy); 132 bool ProxyAttachDBinderSession(uint32_t handle, std::shared_ptr<DBinderSessionObject> object); 133 std::shared_ptr<DBinderSessionObject> ProxyQueryDBinderSession(uint32_t handle); 134 bool ProxyMoveDBinderSession(uint32_t handle, IPCObjectProxy *proxy); 135 bool QueryProxyBySocketId(int32_t socketId, std::vector<uint32_t> &proxyHandle); 136 std::shared_ptr<DBinderSessionObject> QuerySessionByInfo(const std::string &name, const std::string &deviceId); 137 138 bool DetachThreadLockInfo(const std::thread::id &threadId); 139 bool AttachThreadLockInfo(std::shared_ptr<SocketThreadLockInfo> object, const std::thread::id &threadId); 140 std::shared_ptr<SocketThreadLockInfo> QueryThreadLockInfo(const std::thread::id &threadId); 141 void EraseThreadBySeqNumber(uint64_t seqNumber); 142 bool AddThreadBySeqNumber(uint64_t seqNumber, std::shared_ptr<ThreadMessageInfo> messageInfo); 143 std::shared_ptr<ThreadMessageInfo> QueryThreadBySeqNumber(uint64_t seqNumber); 144 bool AddSendThreadInWait(uint64_t seqNumber, std::shared_ptr<ThreadMessageInfo> messageInfo, int userWaitTime); 145 146 int GetSocketIdleThreadNum() const; 147 int GetSocketTotalThreadNum() const; 148 int PopSocketIdFromThread(const std::thread::id &threadId); 149 void WakeUpSocketIOThread(const std::thread::id &threadID); 150 void WakeUpThreadBySeqNumber(uint64_t seqNumber, uint32_t handle); 151 IRemoteObject *QueryStubByIndex(uint64_t stubIndex); 152 uint64_t QueryStubIndex(IRemoteObject *stubObject); 153 uint64_t AddStubByIndex(IRemoteObject *stubObject); 154 uint64_t EraseStubIndex(IRemoteObject *stubObject); 155 uint64_t GetSeqNumber(); 156 uint32_t GetDBinderIdleHandle(std::shared_ptr<DBinderSessionObject> session); 157 std::string GetLocalDeviceID(); 158 159 bool AttachCallbackStub(IPCObjectProxy *ipcProxy, sptr<IPCObjectStub> callbackStub); 160 sptr<IPCObjectStub> QueryCallbackStub(IPCObjectProxy *ipcProxy); 161 sptr<IPCObjectProxy> QueryCallbackProxy(IPCObjectStub *callbackStub); 162 sptr<IPCObjectStub> DetachCallbackStub(IPCObjectProxy *ipcProxy); 163 uint32_t QueryHandleByDatabusSession(const std::string &name, const std::string &deviceId, uint64_t stubIndex); 164 bool StubDetachDBinderSession(uint32_t handle, uint32_t &tokenId); 165 std::shared_ptr<DBinderSessionObject> StubQueryDBinderSession(uint32_t handle); 166 bool StubAttachDBinderSession(uint32_t handle, std::shared_ptr<DBinderSessionObject> object); 167 std::string GetDatabusName(); 168 bool CreateSoftbusServer(const std::string &name); 169 bool RemoveSoftbusServer(); 170 171 bool AttachCommAuthInfo(IRemoteObject *stub, int pid, int uid, uint32_t tokenId, const std::string &deviceId); 172 bool DetachCommAuthInfo(IRemoteObject *stub, int pid, int uid, uint32_t tokenId, const std::string &deviceId); 173 void DetachCommAuthInfoByStub(IRemoteObject *stub); 174 void DetachCommAuthInfoBySocketId(int32_t socketId); 175 bool QueryCommAuthInfo(int pid, int uid, uint32_t &tokenId, const std::string &deviceId); 176 void UpdateCommAuthSocketInfo(int pid, int uid, uint32_t &tokenId, const std::string &deviceId, 177 const int32_t socketId); 178 bool AttachOrUpdateAppAuthInfo(const AppAuthInfo &appAuthInfo); 179 bool DetachAppAuthInfo(const AppAuthInfo &appAuthInfo); 180 void DetachAppAuthInfoByStub(IRemoteObject *stub, uint64_t stubIndex); 181 std::list<uint64_t> DetachAppAuthInfoBySocketId(int32_t socketId); 182 bool QueryCommAuthInfo(AppAuthInfo &appAuthInfo); 183 bool QueryAppInfoToStubIndex(const AppAuthInfo &appAuthInfo); 184 bool AddDataThreadToIdle(const std::thread::id &threadId); 185 bool DeleteDataThreadFromIdle(const std::thread::id &threadId); 186 std::thread::id GetIdleDataThread(); 187 void AddDataInfoToThread(const std::thread::id &threadId, std::shared_ptr<ThreadProcessInfo> processInfo); 188 std::shared_ptr<ThreadProcessInfo> PopDataInfoFromThread(const std::thread::id &threadId); 189 void WakeUpDataThread(const std::thread::id &threadID); 190 void AddDataThreadInWait(const std::thread::id &threadId); 191 bool IsSameRemoteObject(IRemoteObject *stub, int pid, int uid, uint32_t tokenId, const std::string &deviceId, 192 const std::shared_ptr<CommAuthInfo> &auth); 193 bool IsSameRemoteObject(int pid, int uid, const std::string &deviceId, const std::shared_ptr<CommAuthInfo> &auth); 194 bool DetachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, const std::string &deviceId, 195 uint64_t stubIndex, int32_t listenFd); 196 std::list<uint64_t> DetachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, 197 const std::string &deviceId, int32_t listenFd); 198 void DetachAppInfoToStubIndex(uint64_t stubIndex); 199 std::list<uint64_t> DetachAppInfoToStubIndex(int32_t listenFd); 200 bool AttachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, const std::string &deviceId, 201 uint64_t stubIndex, int32_t listenFd); 202 bool AttachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, const std::string &deviceId, 203 int32_t listenFd); 204 bool QueryAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, const std::string &deviceId, 205 uint64_t stubIndex, int32_t listenFd); 206 std::string UIntToString(uint32_t input); 207 bool AttachDBinderCallbackStub(sptr<IRemoteObject> rpcProxy, sptr<DBinderCallbackStub> stub); 208 bool DetachDBinderCallbackStubByProxy(sptr<IRemoteObject> rpcProxy); 209 void DetachDBinderCallbackStub(DBinderCallbackStub *stub); 210 sptr<DBinderCallbackStub> QueryDBinderCallbackStub(sptr<IRemoteObject> rpcProxy); 211 sptr<IRemoteObject> QueryDBinderCallbackProxy(sptr<IRemoteObject> stub); 212 #endif 213 214 public: 215 static constexpr int DEFAULT_WORK_THREAD_NUM = 16; 216 static constexpr uint32_t DBINDER_HANDLE_MAGIC = 6872; // 'D'(Binder) 'H'(andle) 217 static constexpr uint32_t DBINDER_HANDLE_BASE = 100000 * DBINDER_HANDLE_MAGIC; 218 static constexpr uint32_t DBINDER_HANDLE_COUNT = 100000; 219 static constexpr uint32_t DBINDER_HANDLE_RANG = 100; 220 static constexpr int ENCRYPT_LENGTH = 4; 221 static constexpr uint32_t INVALID_HANDLE_VALUE = 0xFFFFFFFF; 222 static constexpr uint32_t THREADS_FULL_TIME_THRESHOLD = 500; // 500ms 223 224 private: 225 DISALLOW_COPY_AND_MOVE(IPCProcessSkeleton); 226 IPCProcessSkeleton(); 227 #ifndef CONFIG_IPC_SINGLE 228 void ClearDataResource(); 229 #endif 230 231 class DestroyInstance { 232 public: 233 ~DestroyInstance(); 234 }; 235 236 static IPCProcessSkeleton *instance_; 237 static std::mutex procMutex_; 238 static DestroyInstance destroyInstance_; 239 static std::atomic<bool> exitFlag_; 240 std::atomic<int> lastErrHandle_ = -1; 241 std::atomic<int> lastErrCnt_ = 0; 242 243 // for DFX 244 std::mutex mutex_; 245 std::condition_variable cv_; 246 int numExecuting_ = 0; 247 int numWaitingForThreads_ = 0; 248 uint64_t numExecutingFullLastTime_ = 0; 249 250 IPCWorkThreadPool *threadPool_ = nullptr; 251 252 #ifndef CONFIG_IPC_SINGLE 253 std::mutex databusProcMutex_; 254 255 std::mutex idleDataMutex_; 256 std::list<std::thread::id> idleDataThreads_; 257 258 std::mutex dataQueueMutex_; 259 std::map<std::thread::id, std::vector<std::shared_ptr<ThreadProcessInfo>>> dataInfoQueue_; // key is threadId 260 261 std::mutex findThreadMutex_; 262 std::map<uint64_t, std::shared_ptr<ThreadMessageInfo>> seqNumberToThread_; 263 264 std::shared_mutex proxyToSessionMutex_; 265 std::map<uint32_t, std::shared_ptr<DBinderSessionObject>> proxyToSession_; 266 267 std::shared_mutex rawDataMutex_; 268 std::map<std::string, std::shared_ptr<InvokerRawData>> rawData_; 269 270 std::shared_mutex databusSessionMutex_; 271 std::map<uint32_t, std::shared_ptr<DBinderSessionObject>> dbinderSessionObjects_; 272 273 std::shared_mutex threadLockMutex_; 274 std::map<std::thread::id, std::shared_ptr<SocketThreadLockInfo>> threadLockInfo_; 275 276 std::shared_mutex callbackStubMutex_; 277 std::map<IPCObjectProxy *, sptr<IPCObjectStub>> noticeStub_; 278 279 std::shared_mutex stubObjectsMutex_; 280 std::unordered_map<uint64_t, IRemoteObject *> stubObjects_; 281 282 std::shared_mutex appAuthMutex_; 283 std::shared_mutex appInfoToIndexMutex_; 284 std::map<std::string, std::map<uint64_t, int32_t>> appInfoToStubIndex_; 285 286 std::shared_mutex commAuthMutex_; 287 std::list<std::shared_ptr<CommAuthInfo>> commAuth_; 288 289 std::shared_mutex dbinderSentMutex_; 290 std::map<sptr<IRemoteObject>, wptr<DBinderCallbackStub>> dbinderSentCallback_; 291 292 std::mutex seqNumberMutex_; 293 uint64_t seqNumber_ = 0; 294 295 std::shared_mutex sessionNameMutex_; 296 std::string sessionName_; 297 std::atomic<int32_t> listenSocketId_ = 0; 298 299 uint32_t dBinderHandle_ = DBINDER_HANDLE_BASE; /* dbinder handle start at 687200000 */ 300 uint64_t randNum_; 301 #endif 302 }; 303 #ifdef CONFIG_IPC_SINGLE 304 } // namespace IPC_SINGLE 305 #endif 306 } // namespace OHOS 307 #endif // OHOS_IPC_IPC_PROCESS_SKELETON_H 308