1 /*
2  * Copyright (c) 2022 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_ABILITY_RUNTIME_JS_NAPI_COMMON_ABILITY_H
17 #define OHOS_ABILITY_RUNTIME_JS_NAPI_COMMON_ABILITY_H
18 
19 #include "ability_connect_callback_stub.h"
20 #include "ability_info.h"
21 #include "ability_manager_errors.h"
22 #include "application_info.h"
23 #include "feature_ability_common.h"
24 #include "js_free_install_observer.h"
25 #include "js_runtime_utils.h"
26 
27 namespace OHOS {
28 namespace AppExecFwk {
29 class JsNapiCommon {
30 public:
31     JsNapiCommon();
32     virtual ~JsNapiCommon();
33 
34     struct JsPermissionOptions {
35         bool uidFlag = false;
36         bool pidFlag = false;
37         int32_t uid = 0;
38         int32_t pid = 0;
39     };
40 
41     struct JsApplicationInfo {
42         ApplicationInfo appInfo;
43     };
44 
45     struct JsBundleName {
46         std::string name = "";
47     };
48     typedef JsBundleName JsProcessName;
49     typedef JsBundleName JsCallingBundleName;
50     typedef JsBundleName JsOrCreateLocalDir;
51     typedef JsBundleName JsFilesDir;
52     typedef JsBundleName JsCacheDir;
53     typedef JsBundleName JsCtxAppType;
54     typedef JsBundleName JsOrCreateDistributedDir;
55     typedef JsBundleName JsAppType;
56 
57     struct JsElementName {
58         std::string deviceId = "";
59         std::string bundleName = "";
60         std::string abilityName = "";
61         std::string uri = "";
62         std::string shortName = "";
63     };
64 
65     struct JsProcessInfo {
66         std::string processName = "";
67         pid_t pid = 0;
68     };
69 
70     struct JsConfigurations {
71         bool status;
72     };
73     typedef JsConfigurations JsDrawnCompleted;
74 
75     struct JsHapModuleInfo {
76         HapModuleInfo hapModInfo;
77     };
78 
79     struct JsAbilityInfoInfo {
80         AbilityInfo abilityInfo;
81     };
82 
83     struct JsWant {
84         Want want;
85     };
86 
87     bool CheckAbilityType(const AbilityType typeWant);
88     std::string ConvertErrorCode(int32_t errCode);
89     sptr<NAPIAbilityConnection> FindConnectionLocked(const Want &want, int64_t &id);
90     void RemoveAllCallbacksLocked();
91     bool CreateConnectionAndConnectAbilityLocked(
92         std::shared_ptr<ConnectionCallback> callback, const Want &want, int64_t &id);
93     void RemoveConnectionLocked(const Want &want);
94     napi_value HandleJsConnectAbilityError(napi_env env, std::shared_ptr<ConnectionCallback> &connectionCallback,
95         const Want &want, int32_t errorVal);
96 
97     napi_value OnFindAbilityConnection(napi_env env, sptr<NAPIAbilityConnection> &abilityConnection,
98         std::shared_ptr<ConnectionCallback> &connectionCallback, const Want &want, int64_t id);
99     napi_value JsConnectAbility(napi_env env, napi_callback_info info, const AbilityType abilityType);
100 
101     void SetJsDisConnectAbilityCallback(std::shared_ptr<int32_t> &errorVal, const AbilityType &abilityType,
102         sptr<NAPIAbilityConnection> &abilityConnection, AbilityRuntime::NapiAsyncTask::ExecuteCallback &execute,
103         AbilityRuntime::NapiAsyncTask::CompleteCallback &complete);
104     napi_value JsDisConnectAbility(napi_env env, napi_callback_info info, const AbilityType abilityType);
105     napi_value JsGetContext(napi_env env, const napi_callback_info info, const AbilityType abilityType);
106     napi_value JsGetFilesDir(napi_env env, napi_callback_info info, const AbilityType abilityType);
107     napi_value JsIsUpdatingConfigurations(napi_env env, napi_callback_info info, const AbilityType abilityType);
108     napi_value JsPrintDrawnCompleted(napi_env env, napi_callback_info info, const AbilityType abilityType);
109     napi_value JsGetCacheDir(napi_env env, napi_callback_info info, const AbilityType abilityType);
110     napi_value JsGetCtxAppType(napi_env env, napi_callback_info info, const AbilityType abilityType);
111     napi_value JsGetCtxHapModuleInfo(napi_env env, napi_callback_info info, const AbilityType abilityType);
112     napi_value JsGetAppVersionInfo(napi_env env, napi_callback_info info, const AbilityType abilityType);
113     napi_value JsGetApplicationContext(
114         napi_env env, napi_callback_info info, const AbilityType abilityType);
115     napi_value JsGetCtxAbilityInfo(napi_env env, napi_callback_info info, const AbilityType abilityType);
116     napi_value JsGetOrCreateDistributedDir(
117         napi_env env, napi_callback_info info, const AbilityType abilityType);
118 #ifdef SUPPORT_GRAPHICS
119     napi_value JsGetDisplayOrientation(
120         napi_env env, napi_callback_info info, const AbilityType abilityType);
121 #endif
122     napi_value JsGetWant(napi_env env, napi_callback_info info, const AbilityType abilityType);
123     napi_value JsTerminateAbility(napi_env env, AbilityRuntime::NapiCallbackInfo& info);
124     void SetJsStartAbilityExecuteCallback(std::shared_ptr<int32_t> &errorVal, AbilityType &abilityType,
125         std::shared_ptr<CallAbilityParam> &param, AbilityRuntime::NapiAsyncTask::ExecuteCallback &execute);
126     napi_value JsStartAbility(napi_env env, napi_callback_info info, AbilityType abilityType);
127     napi_value JsGetExternalCacheDir(napi_env env, napi_callback_info info, AbilityType abilityType);
128 
129     napi_value CreateProcessInfo(napi_env env, const std::shared_ptr<JsProcessInfo> &processInfo);
130     napi_value CreateElementName(napi_env env, const std::shared_ptr<JsElementName> &elementName);
131     napi_value CreateHapModuleInfo(napi_env env, const std::shared_ptr<JsHapModuleInfo> &hapModInfo);
132     napi_value CreateModuleInfo(napi_env env, const ModuleInfo &modInfo);
133     napi_value CreateModuleInfos(napi_env env, const std::vector<ModuleInfo> &moduleInfos);
134     napi_value CreateAppInfo(napi_env env, const ApplicationInfo &appInfo);
135     napi_value CreateAppInfo(napi_env env, const std::shared_ptr<JsApplicationInfo> &appInfo);
136     napi_value CreateAbilityInfo(napi_env env, const AbilityInfo &abilityInfo);
137     napi_value CreateAbilityInfo(napi_env env, const std::shared_ptr<JsAbilityInfoInfo> &abilityInfo);
138     napi_value CreateAbilityInfos(napi_env env, const std::vector<AbilityInfo> &abilityInfos);
139     napi_value CreateAppVersionInfo(napi_env env, const std::shared_ptr<JsApplicationInfo> &appInfo);
140     napi_value CreateWant(napi_env env, const std::shared_ptr<JsWant> &want);
141     bool UnwarpVerifyPermissionParams(napi_env env, napi_callback_info info, JsPermissionOptions &options);
142     bool GetStringsValue(napi_env env, napi_value object, std::vector<std::string> &strList);
143     bool GetPermissionOptions(napi_env env, napi_value object, JsPermissionOptions &options);
144     void AddFreeInstallObserver(napi_env env, const AAFwk::Want &want, napi_value callback, napi_value* result);
145     Ability *ability_;
146     sptr<AbilityRuntime::JsFreeInstallObserver> freeInstallObserver_ = nullptr;
147 };
148 
149 enum {
150     CONNECTION_STATE_DISCONNECTED = -1,
151 
152     CONNECTION_STATE_CONNECTED = 0,
153 
154     CONNECTION_STATE_CONNECTING = 1
155 };
156 
157 using ConnectRemoveKeyType = JsNapiCommon*;
158 struct ConnectionCallback {
ConnectionCallbackConnectionCallback159     ConnectionCallback(napi_env env, napi_value cbInfo, ConnectRemoveKeyType key)
160     {
161         this->env = env;
162         napi_value jsMethod = nullptr;
163         napi_get_named_property(env, cbInfo, "onConnect", &jsMethod);
164         napi_create_reference(env, jsMethod, 1, &connectCallbackRef);
165         napi_get_named_property(env, cbInfo, "onDisconnect", &jsMethod);
166         napi_create_reference(env, jsMethod, 1, &disconnectCallbackRef);
167         napi_get_named_property(env, cbInfo, "onFailed", &jsMethod);
168         napi_create_reference(env, jsMethod, 1, &failedCallbackRef);
169         removeKey = key;
170     }
171     ConnectionCallback(ConnectionCallback &) = delete;
ConnectionCallbackConnectionCallback172     ConnectionCallback(ConnectionCallback &&other)
173         : env(other.env), connectCallbackRef(other.connectCallbackRef),
174         disconnectCallbackRef(other.disconnectCallbackRef), failedCallbackRef(other.failedCallbackRef),
175         removeKey(other.removeKey)
176     {
177         other.env = nullptr;
178         other.connectCallbackRef = nullptr;
179         other.disconnectCallbackRef = nullptr;
180         other.failedCallbackRef = nullptr;
181         other.removeKey = nullptr;
182     }
183     const ConnectionCallback &operator=(ConnectionCallback &) = delete;
184     const ConnectionCallback &operator=(ConnectionCallback &&other)
185     {
186         Reset();
187         env = other.env;
188         connectCallbackRef = other.connectCallbackRef;
189         disconnectCallbackRef = other.disconnectCallbackRef;
190         failedCallbackRef = other.failedCallbackRef;
191         other.env = nullptr;
192         other.connectCallbackRef = nullptr;
193         other.disconnectCallbackRef = nullptr;
194         other.failedCallbackRef = nullptr;
195         other.removeKey = nullptr;
196         return *this;
197     }
~ConnectionCallbackConnectionCallback198     ~ConnectionCallback()
199     {
200         Reset();
201     }
202     void Reset();
203 
204     napi_env env = nullptr;
205     napi_ref connectCallbackRef = nullptr;
206     napi_ref disconnectCallbackRef = nullptr;
207     napi_ref failedCallbackRef = nullptr;
208     ConnectRemoveKeyType removeKey = nullptr;
209 };
210 
211 class NAPIAbilityConnection : public AAFwk::AbilityConnectionStub {
212 public:
213     void OnAbilityConnectDone(
214         const AppExecFwk::ElementName &element, const sptr<IRemoteObject> &remoteObject, int resultCode) override;
215     void OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode) override;
216     void AddConnectionCallback(std::shared_ptr<ConnectionCallback> callback);
217     void HandleOnAbilityConnectDone(ConnectionCallback &callback, int resultCode);
218     void HandleOnAbilityDisconnectDone(ConnectionCallback &callback, int resultCode);
219     int GetConnectionState() const;
220     void SetConnectionState(int connectionState);
221     size_t GetCallbackSize();
222     size_t RemoveAllCallbacks(ConnectRemoveKeyType key);
223 
224 private:
225     std::list<std::shared_ptr<ConnectionCallback>> callbacks_;
226     AppExecFwk::ElementName element_;
227     sptr<IRemoteObject> serviceRemoteObject_ = nullptr;
228     int connectionState_ = CONNECTION_STATE_DISCONNECTED;
229     mutable std::mutex lock_;
230 };
231 
232 struct ConnectionKey {
233     Want want;
234     int64_t id;
235 };
236 
237 struct key_compare {
operatorkey_compare238     bool operator()(const ConnectionKey &key1, const ConnectionKey &key2) const
239     {
240         if (key1.id < key2.id) {
241             return true;
242         }
243         return false;
244     }
245 };
246 }  // namespace AppExecFwk
247 }  // namespace OHOS
248 #endif  // OHOS_ABILITY_RUNTIME_JS_NAPI_COMMON_ABILITY_H
249