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 UPDATE_SESSION_H 17 #define UPDATE_SESSION_H 18 19 #include <functional> 20 #include <iostream> 21 #include <memory> 22 #include <mutex> 23 #include <string> 24 #include <thread> 25 #include <vector> 26 27 #include "iupdate_service.h" 28 #include "napi/native_api.h" 29 #include "napi/native_node_api.h" 30 #include "node_api.h" 31 #include "node_api_types.h" 32 #include "update_client.h" 33 #include "update_helper.h" 34 35 namespace updateClient { 36 class UpdateSession { 37 public: 38 UpdateSession() = default; 39 40 UpdateSession(UpdateClient *client, int32_t type, size_t argc, size_t callbackNumber); 41 ~UpdateSession()42 virtual ~UpdateSession() {}; 43 44 napi_value StartWork(napi_env env, size_t startIndex, 45 const napi_value *args, UpdateClient::DoWorkFunction worker, void *context); 46 GetUpdateClient()47 UpdateClient* GetUpdateClient() const 48 { 49 return client_; 50 } 51 GetType()52 int32_t GetType() const 53 { 54 return type_; 55 } 56 GetSessionId()57 uint32_t GetSessionId() const 58 { 59 return sessionId; 60 } 61 CompleteWork(napi_env env,napi_status status)62 virtual void CompleteWork(napi_env env, napi_status status) {} 63 virtual void ExecuteWork(napi_env env); 64 virtual napi_value StartWork(napi_env env, size_t startIndex, const napi_value *args) = 0; NotifyJS(napi_env env,napi_value thisVar,int32_t retcode,const UpdateResult & result)65 virtual void NotifyJS(napi_env env, napi_value thisVar, int32_t retcode, const UpdateResult &result) 66 { 67 return; 68 } 69 70 // JS thread, which is used to notify the JS page upon completion of the operation. CompleteWork(napi_env env,napi_status status,void * data)71 static void CompleteWork(napi_env env, napi_status status, void *data) 72 { 73 auto sess = reinterpret_cast<UpdateSession*>(data); 74 CLIENT_CHECK(sess != nullptr && sess->GetUpdateClient() != nullptr, return, "Session is null pointer"); 75 sess->CompleteWork(env, status); 76 // If the share ptr is used, you can directly remove the share ptr. 77 UpdateClient *client = sess->GetUpdateClient(); 78 if (client != nullptr) { 79 client->RemoveSession(sess->GetSessionId()); 80 } 81 } 82 83 // The C++ thread executes the synchronization operation. After the synchronization is complete, 84 // the CompleteWork is called to notify the JS page of the completion of the operation. ExecuteWork(napi_env env,void * data)85 static void ExecuteWork(napi_env env, void* data) 86 { 87 auto sess = reinterpret_cast<UpdateSession*>(data); 88 CLIENT_CHECK(sess != nullptr, return, "sess is null"); 89 sess->ExecuteWork(env); 90 } 91 protected: 92 napi_value CreateWorkerName(napi_env env) const; 93 int32_t CreateReference(napi_env env, napi_value arg, uint32_t refcount, napi_ref &reference) const; 94 95 protected: 96 uint32_t sessionId {0}; 97 UpdateClient *client_ = nullptr; 98 int32_t type_ {}; 99 size_t totalArgc_ = 0; 100 size_t callbackNumber_ = 0; 101 void* context_ {}; 102 UpdateClient::DoWorkFunction doWorker_ {}; 103 }; 104 105 class UpdateAsyncession : public UpdateSession { 106 public: UpdateAsyncession(UpdateClient * client,int32_t type,size_t argc,size_t callbackNumber)107 UpdateAsyncession(UpdateClient *client, int32_t type, size_t argc, size_t callbackNumber) : 108 UpdateSession(client, type, argc, callbackNumber) 109 { 110 callbackRef_.resize(callbackNumber); 111 } 112 ~UpdateAsyncession()113 ~UpdateAsyncession() override 114 { 115 callbackRef_.clear(); 116 } 117 118 void CompleteWork(napi_env env, napi_status status) override; 119 napi_value StartWork(napi_env env, size_t startIndex, const napi_value *args) override; 120 private: 121 napi_async_work worker_ = nullptr; 122 std::vector<napi_ref> callbackRef_ = {0}; 123 }; 124 125 class UpdateAsyncessionNoCallback : public UpdateAsyncession { 126 public: UpdateAsyncessionNoCallback(UpdateClient * client,int32_t type,size_t argc,size_t callbackNumber)127 UpdateAsyncessionNoCallback(UpdateClient *client, int32_t type, size_t argc, size_t callbackNumber) : 128 UpdateAsyncession(client, type, argc, callbackNumber) {} 129 ~UpdateAsyncessionNoCallback()130 ~UpdateAsyncessionNoCallback() override { } 131 132 void CompleteWork(napi_env env, napi_status status) override; 133 }; 134 135 class UpdatePromiseSession : public UpdateSession { 136 public: UpdatePromiseSession(UpdateClient * client,int32_t type,size_t argc,size_t callbackNumber)137 UpdatePromiseSession(UpdateClient *client, int32_t type, size_t argc, size_t callbackNumber) : 138 UpdateSession(client, type, argc, callbackNumber) {} 139 ~UpdatePromiseSession()140 ~UpdatePromiseSession() override {} 141 142 void CompleteWork(napi_env env, napi_status status) override; 143 napi_value StartWork(napi_env env, size_t startIndex, const napi_value *args) override; 144 private: 145 napi_async_work worker_ = nullptr; 146 napi_deferred deferred_ = nullptr; 147 }; 148 149 class UpdateListener : public UpdateSession { 150 public: UpdateListener(UpdateClient * client,int32_t type,size_t argc,size_t callbackNumber,bool isOnce)151 UpdateListener(UpdateClient *client, int32_t type, size_t argc, size_t callbackNumber, bool isOnce) : 152 UpdateSession(client, type, argc, callbackNumber), isOnce_(isOnce) {} 153 ~UpdateListener()154 ~UpdateListener() override {} 155 156 napi_value StartWork(napi_env env, size_t startIndex, const napi_value *args) override; 157 158 void NotifyJS(napi_env env, napi_value thisVar, int32_t retcode, const UpdateResult &result) override; 159 IsOnce()160 bool IsOnce() const 161 { 162 return isOnce_; 163 } 164 GetEventType()165 std::string GetEventType() const 166 { 167 return eventType_; 168 } 169 170 bool CheckEqual(napi_env env, napi_value handler, const std::string &type); 171 172 void RemoveHandlerRef(napi_env env); 173 private: 174 bool isOnce_ = false; 175 std::string eventType_; 176 napi_ref handlerRef_ = nullptr; 177 std::mutex mutex_; 178 }; 179 } // namespace updateClient 180 #endif // UPDATE_SESSION_H 181