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 NAPI_ACCESSIBILITY_EXTENSION_H
17 #define NAPI_ACCESSIBILITY_EXTENSION_H
18 
19 #include <uv.h>
20 #include "accessibility_extension.h"
21 #include "accessible_ability_listener.h"
22 #include "ffrt_inner.h"
23 #include "js_runtime.h"
24 #include "napi_accessibility_element.h"
25 #include "native_engine/native_reference.h"
26 
27 namespace OHOS {
28 namespace Accessibility {
29 class NAccessibilityExtension : public AccessibilityExtension {
30 public:
31     NAccessibilityExtension(AbilityRuntime::JsRuntime& jsRuntime);
32     virtual ~NAccessibilityExtension() override;
33 
34     /**
35      * @brief Create NAccessibilityExtension.
36      *
37      * @param runtime The runtime.
38      * @return The NAccessibilityExtension instance.
39      */
40     static NAccessibilityExtension* Create(const std::unique_ptr<AbilityRuntime::Runtime>& runtime);
41 
42     /**
43      * @brief Init the extension.
44      *
45      * @param record the extension record.
46      * @param application the application info.
47      * @param handler the extension handler.
48      * @param token the remote token.
49      */
50     void Init(const std::shared_ptr<AppExecFwk::AbilityLocalRecord> &record,
51         const std::shared_ptr<AppExecFwk::OHOSApplication> &application,
52         std::shared_ptr<AppExecFwk::AbilityHandler> &handler,
53         const sptr<IRemoteObject> &token) override;
54 
55     /**
56      * @brief Called when this Accessibility extension is connected for the first time.
57      *
58      * You can override this function to implement your own processing logic.
59      *
60      * @param want Indicates the {@link Want} structure containing connection information
61      * about the Accessibility extension.
62      * @return Returns a pointer to the <b>sid</b> of the connected Accessibility extension.
63      */
64     sptr<IRemoteObject> OnConnect(const AAFwk::Want &want) override;
65 
66     /**
67      * @brief Called when your accessibility service is successfully connected to the OS.
68      */
69     void OnAbilityConnected();
70 
71     /**
72      * @brief Called when your accessibility service is successfully disconnected to the OS.
73      */
74     void OnAbilityDisconnected();
75 
76     /**
77      * @brief Called when an accessibility event occurs.
78      * @param eventInfo The information of accessible event.
79      */
80     void OnAccessibilityEvent(const AccessibilityEventInfo& eventInfo);
81 
82     /**
83      * @brief Called when a key event occurs.
84      * @param keyEvent Indicates the key event to send.
85      * @return Returns true if the event has been consumed; returns false otherwise.
86      *         The event that has been consumed will not be sent to the application.
87      */
88     bool OnKeyPressEvent(const std::shared_ptr<MMI::KeyEvent> &keyEvent);
89 
90 private:
91     class AbilityListener : public AccessibleAbilityListener {
92     public:
AbilityListener(NAccessibilityExtension & extension)93         AbilityListener(NAccessibilityExtension &extension) : extension_(extension) {}
94         ~AbilityListener() = default;
95         /**
96          * @brief Called when your accessibility service is successfully connected to the OS.
97          */
OnAbilityConnected()98         void OnAbilityConnected() override
99         {
100             extension_.OnAbilityConnected();
101         }
102 
103         /**
104          * @brief Called when an accessibility is disconnected.
105          */
OnAbilityDisconnected()106         void OnAbilityDisconnected() override
107         {
108             extension_.OnAbilityDisconnected();
109         }
110 
111         /**
112          * @brief Called when an accessibility event occurs.
113          * @param eventInfo The information of accessible event.
114          */
OnAccessibilityEvent(const AccessibilityEventInfo & eventInfo)115         void OnAccessibilityEvent(const AccessibilityEventInfo& eventInfo) override
116         {
117             extension_.OnAccessibilityEvent(eventInfo);
118         }
119 
120         /**
121          * @brief Called when a key event occurs.
122          * @param keyEvent Indicates the key event to send.
123          * @return Returns true if the event has been consumed; returns false otherwise.
124          *         The event that has been consumed will not be sent to the application.
125          */
OnKeyPressEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)126         bool OnKeyPressEvent(const std::shared_ptr<MMI::KeyEvent> &keyEvent) override
127         {
128             return extension_.OnKeyPressEvent(keyEvent);
129         }
130 
131     private:
132         NAccessibilityExtension &extension_;
133     };
134 
135     napi_value CallObjectMethod(const char* name,  napi_value* argv = nullptr, size_t argc = 0);
136 
137     std::shared_ptr<AccessibilityElement> GetElement(const AccessibilityEventInfo& eventInfo);
138     void CreateElementInfoByEventInfo(const AccessibilityEventInfo& eventInfo,
139         const std::shared_ptr<AccessibilityElementInfo> &elementInfo);
140 
141     bool GetSrcPathAndModuleName(std::string& srcPath, std::string& moduleName);
142     void OnAccessibilityEventCompleteCallback(uv_work_t* work, int status);
143     int OnAccessibilityEventExec(uv_work_t *work, uv_loop_t *loop);
144     void OnKeyPressEventCompleteCallback(uv_work_t* work, int status);
145     int OnKeyPressEventExec(uv_work_t *work, uv_loop_t *loop);
146 
147     napi_env env_ = nullptr;
148     AbilityRuntime::JsRuntime& jsRuntime_;
149     std::unique_ptr<NativeReference> jsObj_;
150     std::shared_ptr<AbilityListener> listener_ = nullptr;
151 };
152 
153 struct ExtensionCallbackInfo {
154     napi_env env_;
155     NAccessibilityExtension *extension_;
156     ffrt::promise<void> syncPromise_;
157 };
158 
159 struct KeyEventCallbackInfo : public ExtensionCallbackInfo {
160     std::shared_ptr<MMI::KeyEvent> keyEvent_;
161     ffrt::promise<bool> syncPromise_;
162 };
163 
164 struct AccessibilityEventInfoCallbackInfo : public ExtensionCallbackInfo {
165     std::string eventType_ = "";
166     int64_t timeStamp_ = 0;
167     std::shared_ptr<AccessibilityElement> element_ = nullptr;
168     int64_t elementId_ = 0;
169     std::string textAnnouncedForAccessibility_ = "";
170 };
171 
172 napi_handle_scope OpenScope(napi_env env);
173 } // namespace Accessibility
174 } // namespace OHOS
175 
176 #endif  // NAPI_ACCESSIBILITY_EXTENSION_H