1 /* 2 * Copyright (C) 2021 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 <list> 20 #include <map> 21 #include <shared_mutex> 22 23 #include "invoker_rawdata.h" 24 #include "ipc_object_proxy.h" 25 #include "ipc_object_stub.h" 26 #include "ipc_thread_pool.h" 27 #include "iremote_object.h" 28 #include "nocopyable.h" 29 #include "sys_binder.h" 30 31 #ifndef CONFIG_IPC_SINGLE 32 #include "comm_auth_info.h" 33 #include "dbinder_callback_stub.h" 34 #include "dbinder_session_object.h" 35 #include "ISessionService.h" 36 #include "Session.h" 37 #include "stub_refcount_object.h" 38 39 using Communication::SoftBus::ISessionService; 40 using Communication::SoftBus::Session; 41 #endif 42 43 namespace OHOS { 44 #ifdef CONFIG_IPC_SINGLE 45 namespace IPC_SINGLE { 46 #endif 47 #ifndef CONFIG_IPC_SINGLE 48 struct SocketThreadLockInfo { 49 std::mutex mutex; 50 std::condition_variable condition; 51 bool ready = false; 52 }; 53 54 struct ThreadMessageInfo { 55 uint32_t flags; 56 binder_size_t bufferSize; 57 binder_size_t offsetsSize; 58 binder_uintptr_t offsets; 59 uint32_t socketId; 60 void *buffer; 61 std::mutex mutex; 62 std::condition_variable condition; 63 bool ready; 64 }; 65 66 struct ThreadProcessInfo { 67 uint32_t listenFd; 68 uint32_t packageSize; 69 std::shared_ptr<char> buffer; 70 }; 71 #endif 72 73 class IPCProcessSkeleton { 74 public: 75 enum { 76 LISTEN_THREAD_CREATE_OK, // Invoker family. 77 LISTEN_THREAD_CREATE_FAILED, 78 LISTEN_THREAD_CREATED_ALREADY, 79 LISTEN_THREAD_CREATED_TIMEOUT 80 }; 81 ~IPCProcessSkeleton(); 82 83 static IPCProcessSkeleton *GetCurrent(); 84 static std::string ConvertToSecureString(const std::string &str); 85 static std::string ConvertToSecureDesc(const std::string &str); 86 87 #ifndef CONFIG_IPC_SINGLE 88 static uint32_t ConvertChannelID2Int(int64_t databusChannelId); 89 static bool IsHandleMadeByUser(uint32_t handle); 90 #endif 91 bool SetMaxWorkThread(int maxThreadNum); 92 std::u16string MakeHandleDescriptor(int handle); 93 94 bool OnThreadTerminated(const std::string &threadName); 95 bool SpawnThread(int policy = IPCWorkThread::SPAWN_PASSIVE, int proto = IRemoteObject::IF_PROT_DEFAULT); 96 97 sptr<IRemoteObject> FindOrNewObject(int handle); 98 bool IsContainsObject(IRemoteObject *object); 99 sptr<IRemoteObject> QueryObject(const std::u16string &descriptor, bool lockFlag = true); 100 bool AttachObject(IRemoteObject *object, bool lockFlag = true); 101 bool DetachObject(IRemoteObject *object); 102 sptr<IRemoteObject> GetProxyObject(int handle, bool &newFlag); 103 104 sptr<IRemoteObject> GetRegistryObject(); 105 bool SetRegistryObject(sptr<IRemoteObject> &object); 106 void BlockUntilThreadAvailable(); 107 void LockForNumExecuting(); 108 void UnlockForNumExecuting(); 109 110 #ifndef CONFIG_IPC_SINGLE 111 bool AttachRawData(uint32_t fd, std::shared_ptr<InvokerRawData> rawData); 112 bool DetachRawData(uint32_t fd); 113 std::shared_ptr<InvokerRawData> QueryRawData(uint32_t fd); 114 115 sptr<IRemoteObject> GetSAMgrObject(); 116 std::shared_ptr<DBinderSessionObject> ProxyDetachDBinderSession(uint32_t handle, IPCObjectProxy *proxy); 117 bool ProxyAttachDBinderSession(uint32_t handle, std::shared_ptr<DBinderSessionObject> object); 118 std::shared_ptr<DBinderSessionObject> ProxyQueryDBinderSession(uint32_t handle); 119 bool ProxyMoveDBinderSession(uint32_t handle, IPCObjectProxy *proxy); 120 bool QueryProxyBySessionHandle(uint32_t handle, std::vector<uint32_t> &proxyHandle); 121 std::shared_ptr<DBinderSessionObject> QuerySessionByInfo(const std::string &name, const std::string &deviceId); 122 123 bool DetachThreadLockInfo(const std::thread::id &threadId); 124 bool AttachThreadLockInfo(std::shared_ptr<SocketThreadLockInfo> object, const std::thread::id &threadId); 125 std::shared_ptr<SocketThreadLockInfo> QueryThreadLockInfo(const std::thread::id &threadId); 126 void EraseThreadBySeqNumber(uint64_t seqNumber); 127 bool AddThreadBySeqNumber(uint64_t seqNumber, std::shared_ptr<ThreadMessageInfo> messageInfo); 128 std::shared_ptr<ThreadMessageInfo> QueryThreadBySeqNumber(uint64_t seqNumber); 129 bool AddSendThreadInWait(uint64_t seqNumber, std::shared_ptr<ThreadMessageInfo> messageInfo, int userWaitTime); 130 131 int GetSocketIdleThreadNum() const; 132 int GetSocketTotalThreadNum() const; 133 int PopSocketIdFromThread(const std::thread::id &threadId); 134 void WakeUpSocketIOThread(const std::thread::id &threadID); 135 void WakeUpThreadBySeqNumber(uint64_t seqNumber, uint32_t handle); 136 IRemoteObject *QueryStubByIndex(uint64_t stubIndex); 137 uint64_t QueryStubIndex(IRemoteObject *stubObject); 138 uint64_t AddStubByIndex(IRemoteObject *stubObject); 139 uint64_t EraseStubIndex(IRemoteObject *stubObject); 140 uint64_t GetSeqNumber(); 141 uint32_t GetDBinderIdleHandle(std::shared_ptr<DBinderSessionObject> session); 142 std::string GetLocalDeviceID(); 143 144 bool AttachCallbackStub(IPCObjectProxy *ipcProxy, sptr<IPCObjectStub> callbackStub); 145 sptr<IPCObjectStub> QueryCallbackStub(IPCObjectProxy *ipcProxy); 146 sptr<IPCObjectProxy> QueryCallbackProxy(IPCObjectStub *callbackStub); 147 sptr<IPCObjectStub> DetachCallbackStub(IPCObjectProxy *ipcProxy); 148 uint32_t QueryHandleByDatabusSession(const std::string &name, const std::string &deviceId, uint64_t stubIndex); 149 bool StubDetachDBinderSession(uint32_t handle, uint32_t &tokenId); 150 std::shared_ptr<DBinderSessionObject> StubQueryDBinderSession(uint32_t handle); 151 bool StubAttachDBinderSession(uint32_t handle, std::shared_ptr<DBinderSessionObject> object); 152 std::string GetDatabusName(); 153 bool CreateSoftbusServer(const std::string &name); 154 155 bool AttachCommAuthInfo(IRemoteObject *stub, int pid, int uid, uint32_t tokenId, const std::string &deviceId); 156 bool DetachCommAuthInfo(IRemoteObject *stub, int pid, int uid, uint32_t tokenId, const std::string &deviceId); 157 void DetachCommAuthInfoByStub(IRemoteObject *stub); 158 bool QueryCommAuthInfo(int pid, int uid, uint32_t &tokenId, const std::string &deviceId); 159 bool AddDataThreadToIdle(const std::thread::id &threadId); 160 bool DeleteDataThreadFromIdle(const std::thread::id &threadId); 161 std::thread::id GetIdleDataThread(); 162 void AddDataInfoToThread(const std::thread::id &threadId, std::shared_ptr<ThreadProcessInfo> processInfo); 163 std::shared_ptr<ThreadProcessInfo> PopDataInfoFromThread(const std::thread::id &threadId); 164 void WakeUpDataThread(const std::thread::id &threadID); 165 void AddDataThreadInWait(const std::thread::id &threadId); 166 bool IsSameRemoteObject(IRemoteObject *stub, int pid, int uid, uint32_t tokenId, const std::string &deviceId, 167 const std::shared_ptr<CommAuthInfo> &auth); 168 bool IsSameRemoteObject(int pid, int uid, const std::string &deviceId, const std::shared_ptr<CommAuthInfo> &auth); 169 bool DetachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, const std::string &deviceId, 170 uint64_t stubIndex, uint32_t listenFd); 171 std::list<uint64_t> DetachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, 172 const std::string &deviceId, uint32_t listenFd); 173 void DetachAppInfoToStubIndex(uint64_t stubIndex); 174 bool AttachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, const std::string &deviceId, 175 uint64_t stubIndex, uint32_t listenFd); 176 bool AttachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, const std::string &deviceId, 177 uint32_t listenFd); 178 bool QueryAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, const std::string &deviceId, 179 uint64_t stubIndex, uint32_t listenFd); 180 std::string UIntToString(uint32_t input); 181 bool AttachDBinderCallbackStub(sptr<IRemoteObject> rpcProxy, sptr<DBinderCallbackStub> stub); 182 bool DetachDBinderCallbackStubByProxy(sptr<IRemoteObject> rpcProxy); 183 void DetachDBinderCallbackStub(DBinderCallbackStub *stub); 184 sptr<DBinderCallbackStub> QueryDBinderCallbackStub(sptr<IRemoteObject> rpcProxy); 185 sptr<IRemoteObject> QueryDBinderCallbackProxy(sptr<IRemoteObject> stub); 186 #endif 187 188 public: 189 static constexpr int DEFAULT_WORK_THREAD_NUM = 16; 190 static constexpr uint32_t DBINDER_HANDLE_MAGIC = 6872; // 'D'(Binder) 'H'(andle) 191 static constexpr uint32_t DBINDER_HANDLE_BASE = 100000 * DBINDER_HANDLE_MAGIC; 192 static constexpr uint32_t DBINDER_HANDLE_COUNT = 100000; 193 static constexpr uint32_t DBINDER_HANDLE_RANG = 100; 194 static constexpr int32_t FOUNDATION_UID = 5523; 195 static constexpr int ENCRYPT_LENGTH = 4; 196 private: 197 DISALLOW_COPY_AND_MOVE(IPCProcessSkeleton); 198 IPCProcessSkeleton(); 199 #ifndef CONFIG_IPC_SINGLE 200 void ClearDataResource(); 201 #endif 202 203 class DestroyInstance { 204 public: ~DestroyInstance()205 ~DestroyInstance() 206 { 207 if (instance_ != nullptr) { 208 delete instance_; 209 instance_ = nullptr; 210 } 211 } 212 }; 213 214 static IPCProcessSkeleton *instance_; 215 static std::mutex procMutex_; 216 static DestroyInstance destroyInstance_; 217 static std::atomic<bool> exitFlag_; 218 219 // for DFX 220 std::mutex mutex_; 221 std::condition_variable cv_; 222 int numExecuting_ = 0; 223 int numWaitingForThreads_ = 0; 224 225 IPCWorkThreadPool *threadPool_ = nullptr; 226 227 #ifndef CONFIG_IPC_SINGLE 228 std::mutex databusProcMutex_; 229 std::mutex sessionNameMutex_; 230 std::mutex seqNumberMutex_; 231 std::mutex idleDataMutex_; 232 std::mutex dataQueueMutex_; 233 std::mutex findThreadMutex_; 234 235 std::recursive_mutex proxyToSessionMutex_; 236 std::shared_mutex rawDataMutex_; 237 std::shared_mutex databusSessionMutex_; 238 std::shared_mutex threadLockMutex_; 239 std::shared_mutex callbackStubMutex_; 240 std::shared_mutex stubObjectsMutex_; 241 std::shared_mutex appInfoToIndexMutex_; 242 std::shared_mutex commAuthMutex_; 243 std::shared_mutex dbinderSentMutex_; 244 245 std::map<uint32_t, std::shared_ptr<InvokerRawData>> rawData_; 246 std::map<uint64_t, std::shared_ptr<ThreadMessageInfo>> seqNumberToThread_; 247 std::map<uint64_t, IRemoteObject *> stubObjects_; 248 std::map<std::thread::id, std::shared_ptr<SocketThreadLockInfo>> threadLockInfo_; 249 std::map<uint32_t, std::shared_ptr<DBinderSessionObject>> proxyToSession_; 250 std::map<uint32_t, std::shared_ptr<DBinderSessionObject>> dbinderSessionObjects_; 251 std::map<IPCObjectProxy *, sptr<IPCObjectStub>> noticeStub_; 252 std::map<std::thread::id, std::vector<std::shared_ptr<ThreadProcessInfo>>> dataInfoQueue_; // key is threadId 253 std::map<std::string, std::map<uint64_t, uint32_t>> appInfoToStubIndex_; 254 std::map<sptr<IRemoteObject>, wptr<DBinderCallbackStub>> dbinderSentCallback_; 255 256 std::list<std::thread::id> idleDataThreads_; 257 std::list<std::shared_ptr<CommAuthInfo>> commAuth_; 258 259 uint32_t dBinderHandle_ = DBINDER_HANDLE_BASE; /* dbinder handle start at 687200000 */ 260 uint64_t seqNumber_ = 0; 261 std::string sessionName_ = std::string(""); 262 uint64_t randNum_; 263 #endif 264 }; 265 #ifdef CONFIG_IPC_SINGLE 266 } // namespace IPC_SINGLE 267 #endif 268 } // namespace OHOS 269 #endif // OHOS_IPC_IPC_PROCESS_SKELETON_H 270