• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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