• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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_UI_ABILITY_H
17 #define OHOS_ABILITY_RUNTIME_UI_ABILITY_H
18 
19 #include "ability_context.h"
20 #include "ability_continuation_interface.h"
21 #include "ability_lifecycle_executor.h"
22 #include "ability_lifecycle_interface.h"
23 #include "ability_local_record.h"
24 #include "ability_transaction_callback_info.h"
25 #include "configuration.h"
26 #include "context.h"
27 #include "continuation_handler_stage.h"
28 #include "foundation/ability/ability_runtime/interfaces/kits/native/ability/ability_runtime/ability_context.h"
29 #include "resource_config_helper.h"
30 #include "iability_callback.h"
31 #include "want.h"
32 #ifdef SUPPORT_GRAPHICS
33 #include "display_manager.h"
34 #include "session_info.h"
35 #include "window_scene.h"
36 #include "window_manager.h"
37 #endif
38 
39 namespace OHOS {
40 namespace AppExecFwk {
41 class AbilityHandler;
42 class AbilityRecovery;
43 class OHOSApplication;
44 class LifeCycle;
45 class ContinuationHandlerStage;
46 class ContinuationManagerStage;
47 class InsightIntentExecuteParam;
48 struct InsightIntentExecuteResult;
49 using InsightIntentExecutorAsyncCallback = AbilityTransactionCallbackInfo<InsightIntentExecuteResult>;
50 } // namespace AppExecFwk
51 namespace AbilityRuntime {
52 class Runtime;
53 using InsightIntentExecuteResult = AppExecFwk::InsightIntentExecuteResult;
54 using InsightIntentExecuteParam = AppExecFwk::InsightIntentExecuteParam;
55 using InsightIntentExecutorAsyncCallback = AppExecFwk::InsightIntentExecutorAsyncCallback;
56 class UIAbility : public AppExecFwk::AbilityContext,
57                   public AppExecFwk::ILifeCycle,
58                   public AppExecFwk::IAbilityCallback,
59                   public AppExecFwk::IAbilityContinuation,
60                   public std::enable_shared_from_this<UIAbility> {
61 public:
62     UIAbility() = default;
63     virtual ~UIAbility() = default;
64 
65     /**
66      * @brief Create a UIAbility instance through the singleton pattern
67      * @param runtime the runtime pointer
68      * @return Returns the UIAbility object of the ability
69      */
70     static UIAbility *Create(const std::unique_ptr<Runtime> &runtime);
71 
72     /**
73      * @brief Obtains the Lifecycle object of the current ability
74      * @return Returns the Lifecycle object.
75      */
76     std::shared_ptr<AppExecFwk::LifeCycle> GetLifecycle() override final;
77 
78     /**
79      * Register lifecycle observer on UIAbility.
80      *
81      * @param observer the lifecycle observer to be registered on UIAbility.
82      */
83     void RegisterAbilityLifecycleObserver(
84         const std::shared_ptr<AppExecFwk::ILifecycleObserver> &observer) override final;
85 
86     /**
87      * Unregister lifecycle observer on UIAbility.
88      *
89      * @param observer the lifecycle observer to be unregistered on UIAbility.
90      */
91     void UnregisterAbilityLifecycleObserver(
92         const std::shared_ptr<AppExecFwk::ILifecycleObserver> &observer) override final;
93 
94     /**
95      * @brief Obtains the AbilityContext object of the ability.
96      * @return Returns the AbilityContext object of the ability.
97      */
98     std::shared_ptr<AbilityRuntime::AbilityContext> GetAbilityContext();
99 
100     /**
101      * @brief Obtains the Want object that starts this ability.
102      * @return Returns the Want object that starts this ability.
103      */
104     std::shared_ptr<AAFwk::Want> GetWant() override;
105 
106     /**
107      * @brief Init the UIability
108      * @param abilityInfo Indicate the Ability information
109      * @param application Indicates the main process
110      * @param handler the UIability EventHandler object
111      * @param token the remote token
112      */
113     virtual void Init(std::shared_ptr<AppExecFwk::AbilityLocalRecord> record,
114         const std::shared_ptr<AppExecFwk::OHOSApplication> application,
115         std::shared_ptr<AppExecFwk::AbilityHandler> &handler, const sptr<IRemoteObject> &token);
116 
117     /**
118      * @brief Attach Ability Context
119      * @param abilityContext Indicate the AbilityContext
120      */
121     void AttachAbilityContext(const std::shared_ptr<AbilityRuntime::AbilityContext> &abilityContext);
122 
123     /**
124      * @brief Called when this ability is started. You must override this function if you want to perform some
125      * initialization operations during ability startup.
126      * This function can be called only once in the entire lifecycle of an ability.
127      * @param Want Indicates the {@link Want} structure containing startup information about the ability.
128      * @param sessionInfo Indicates the sessionInfo.
129      */
130     virtual void OnStart(const AAFwk::Want &want, sptr<AAFwk::SessionInfo> sessionInfo = nullptr);
131 
132     /**
133      * @brief Called when this ability enters the <b>STATE_STOP</b> state.
134      * The ability in the <b>STATE_STOP</b> is being destroyed.
135      * You can override this function to implement your own processing logic.
136      */
137     virtual void OnStop();
138 
139     /**
140      * @brief Called when this ability enters the <b>STATE_STOP</b> state.
141      * The ability in the <b>STATE_STOP</b> is being destroyed.
142      * You can override this function to implement your own processing logic.
143      * @param callbackInfo Indicates the lifecycle transaction callback information
144      * @param isAsyncCallback Indicates whether it is an asynchronous lifecycle callback
145      */
146     virtual void OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo, bool &isAsyncCallback);
147 
148     /**
149      * @brief The callback of OnStop.
150      */
151     virtual void OnStopCallback();
152 
153     /**
154      * @brief request a remote object of callee from this ability.
155      * @return Returns the remote object of callee.
156      */
157     virtual sptr<IRemoteObject> CallRequest();
158 
159     /**
160      * @brief Called when the system configuration is updated.
161      * @param configuration Indicates the updated configuration information.
162      */
163     void OnConfigurationUpdatedNotify(const AppExecFwk::Configuration &configuration);
164 
165     /**
166      * @brief Update context.config when configuration is updated.
167      */
UpdateContextConfiguration()168     virtual void UpdateContextConfiguration() {}
169 
170     /**
171      * @brief Called when the system configuration is updated.
172      * @param level Indicates the memory trim level, which shows the current memory usage status.
173      */
174     virtual void OnMemoryLevel(int level);
175 
176     /**
177      * @brief Obtains the class name in this ability name, without the prefixed bundle name.
178      * @return Returns the class name of this ability.
179      */
180     std::string GetAbilityName();
181 
182     /**
183      * @brief Obtains the module name in this ability name, without the prefixed bundle name.
184      * @return Returns the module name of this ability.
185      */
186     std::string GetModuleName();
187 
188     /**
189      * @brief Called when startAbilityForResult(ohos.aafwk.content.Want,int) is called to start an ability and the
190      * result is returned. This method is called only on Page abilities. You can start a new ability to perform some
191      * calculations and use setResult (int,ohos.aafwk.content.Want) to return the calculation result. Then the system
192      * calls back the current method to use the returned data to execute its own logic.
193      * @param requestCode Indicates the request code returned after the ability is started. You can define the request
194      * code to identify the results returned by abilities. The value ranges from 0 to 65535.
195      * @param resultCode Indicates the result code returned after the ability is started. You can define the result code
196      * to identify an error.
197      * @param want Indicates the data returned after the ability is started. You can define the data returned. The
198      * value can be null.
199      */
200     virtual void OnAbilityResult(int requestCode, int resultCode, const AAFwk::Want &want);
201 
202     /**
203      * @brief Called when the launch mode of an ability is set to singleInstance. This happens when you re-launch an
204      * ability that has been at the top of the ability stack.
205      * @param want Indicates the new Want containing information about the ability.
206      */
207     virtual void OnNewWant(const AAFwk::Want &want);
208 
209     /**
210      * @brief Restores data and states of an ability when it is restored by the system. This method should be
211      * implemented by a Page ability. This method is called if an ability was destroyed at a certain time due to
212      * resource reclaim or was unexpectedly destroyed and the onSaveAbilityState(ohos.utils.PacMap) method was called to
213      * save its user data and states. Generally, this method is called after the onStart(ohos.aafwk.content.Want)
214      * method.
215      * @param inState Indicates the PacMap object used for storing data and states. This parameter can not be null.
216      */
217     virtual void OnRestoreAbilityState(const AppExecFwk::PacMap &inState);
218 
219     /**
220      * @brief Sets the want object that can be obtained by calling getWant().
221      * @param Want information of other ability
222      */
223     void SetWant(const AAFwk::Want &want);
224 
225     /**
226      * @brief dump ability info
227      * @param params dump params that indicate different dump targets
228      * @param info dump ability info
229      */
230     virtual void Dump(const std::vector<std::string> &params, std::vector<std::string> &info);
231 
232     /**
233      * @brief Save user data of local Ability generated at runtime.
234      * @param saveData Indicates the user data to be saved.
235      * @return If the data is saved successfully, it returns true; otherwise, it returns false.
236      */
237     bool OnSaveData(AAFwk::WantParams &saveData) override;
238 
239     /**
240      * @brief After creating the Ability on the remote device,
241      * immediately restore the user data saved during the migration of the Ability on the remote device.
242      * @param restoreData Indicates the user data to be restored.
243      * @return If the data is restored successfully, it returns true; otherwise, it returns false .
244      */
245     bool OnRestoreData(AAFwk::WantParams &restoreData) override;
246 
247     /**
248      * @brief Obtains the lifecycle state of this ability.
249      * @return Returns the lifecycle state of this ability.
250      */
251     virtual AppExecFwk::AbilityLifecycleExecutor::LifecycleState GetState() final;
252 
253     /**
254      * @brief Release the ability instance.
255      */
256     void DestroyInstance();
257 
258     /**
259      * @brief Update configuration
260      * @param configuration Indicates the updated configuration information.
261      */
262     virtual void OnConfigurationUpdated(const AppExecFwk::Configuration &configuration);
263 
264     /**
265      * @brief Prepare user data of local Ability.
266      * @param wantParams Indicates the user data to be saved.
267      * @return If the ability is willing to continue and data saved successfully, it returns 0;
268      * otherwise, it returns errcode.
269      */
270     virtual int32_t OnContinue(AAFwk::WantParams &wantParams);
271 
272     /**
273      * @brief Migrates this ability to the given device on the same distributed network. The ability to migrate and its
274      * ability slices must implement the IAbilityContinuation interface.
275      * @param deviceId Indicates the ID of the target device where this ability will be migrated to.
276      * @param versionCode Target bundle version.
277      */
278     virtual void ContinueAbilityWithStack(const std::string &deviceId, uint32_t versionCode) final;
279 
280     /**
281      * @brief Callback function to ask the user whether to start the migration .
282      * @return If the user allows migration, it returns true; otherwise, it returns false.
283      */
284     bool OnStartContinuation() override;
285 
286     /**
287      * @brief This function can be used to implement the processing logic after the migration is completed.
288      * @param result Migration result code. 0 means the migration was successful, -1 means the migration failed.
289      * @return None.
290      */
291     void OnCompleteContinuation(int result) override;
292 
293     /**
294      * @brief Used to notify the local Ability that the remote Ability has been destroyed.
295      * @return None.
296      */
297     void OnRemoteTerminated() override;
298 
299     /**
300      * @brief Prepare user data of local Ability.
301      * @param reason the reason why framework invoke this function
302      * @param wantParams Indicates the user data to be saved.
303      * @return result code defined in abilityConstants
304      */
305     virtual int32_t OnSaveState(int32_t reason, AAFwk::WantParams &wantParams);
306 
307     /**
308      * @brief enable ability recovery.
309      * @param abilityRecovery shared_ptr of abilityRecovery
310      */
311     void EnableAbilityRecovery(const std::shared_ptr<AppExecFwk::AbilityRecovery> &abilityRecovery);
312 
313     /**
314      * @brief Callback when the ability is shared.You can override this function to implement your own sharing logic.
315      * @param wantParams Indicates the user data to be saved.
316      * @return the result of OnShare
317      */
318     virtual int32_t OnShare(AAFwk::WantParams &wantParams);
319 
320     bool CheckIsSilentForeground() const;
321 
322     void SetIsSilentForeground(bool isSilentForeground);
323 
324 protected:
325     const AAFwk::LaunchParam &GetLaunchParam() const;
326     bool IsRestoredInContinuation() const;
327     void NotifyContinuationResult(const AAFwk::Want &want, bool success);
328     bool ShouldRecoverState(const AAFwk::Want &want);
329     bool IsUseNewStartUpRule();
330 
331     std::shared_ptr<AbilityRuntime::AbilityContext> abilityContext_ = nullptr;
332     std::shared_ptr<AppExecFwk::AbilityStartSetting> setting_ = nullptr;
333     std::shared_ptr<AppExecFwk::AbilityRecovery> abilityRecovery_ = nullptr;
334     std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo_ = nullptr;
335     AAFwk::LaunchParam launchParam_;
336     bool securityFlag_ = false;
337 
338 private:
339     friend class UIAbilityImpl;
340     void DispatchLifecycleOnForeground(const AAFwk::Want &want);
341     void HandleCreateAsRecovery(const AAFwk::Want &want);
342     void SetStartAbilitySetting(std::shared_ptr<AppExecFwk::AbilityStartSetting> setting);
343     void SetLaunchParam(const AAFwk::LaunchParam &launchParam);
344     void InitConfigurationProperties(const AppExecFwk::Configuration &changeConfiguration,
345         ResourceConfigHelper &resourceConfig);
346 
347     std::shared_ptr<AppExecFwk::ContinuationHandlerStage> continuationHandler_ = nullptr;
348     std::shared_ptr<AppExecFwk::ContinuationManagerStage> continuationManager_ = nullptr;
349     std::shared_ptr<AppExecFwk::AbilityHandler> handler_ = nullptr;
350     std::shared_ptr<AppExecFwk::LifeCycle> lifecycle_ = nullptr;
351     std::shared_ptr<AppExecFwk::AbilityLifecycleExecutor> abilityLifecycleExecutor_ = nullptr;
352     std::shared_ptr<AppExecFwk::OHOSApplication> application_ = nullptr;
353     std::shared_ptr<AAFwk::Want> setWant_ = nullptr;
354     sptr<IRemoteObject> reverseContinuationSchedulerReplica_ = nullptr;
355     bool isNewRuleFlagSetted_ = false;
356     bool startUpNewRule_ = false;
357     bool isSilentForeground_ = false;
358 
359 #ifdef SUPPORT_GRAPHICS
360 public:
361     uint32_t sceneFlag_ = 0;
362 
363     /**
364      * @brief Called after instantiating WindowScene.
365      * You can override this function to implement your own processing logic.
366      */
367     virtual void OnSceneCreated();
368 
369     /**
370      * @brief Called after ability stoped.
371      * You can override this function to implement your own processing logic.
372      */
373     virtual void OnSceneWillDestroy();
374 
375     /**
376      * @brief Called after ability stoped.
377      * You can override this function to implement your own processing logic.
378      */
379     virtual void onSceneDestroyed();
380 
381     /**
382      * @brief Called after ability restored.
383      * You can override this function to implement your own processing logic.
384      */
385     virtual void OnSceneRestored();
386 
387     /**
388      * @brief Called when this ability enters the <b>STATE_FOREGROUND</b> state.
389      * The ability in the <b>STATE_FOREGROUND</b> state is visible.
390      * You can override this function to implement your own processing logic.
391      */
392     virtual void OnForeground(const AAFwk::Want &want);
393 
394     /**
395      * @brief Called when this ability enters the <b>STATE_BACKGROUND</b> state.
396      * The ability in the <b>STATE_BACKGROUND</b> state is invisible.
397      * You can override this function to implement your own processing logic.
398      */
399     virtual void OnBackground();
400 
401     /**
402      * @brief Called when ability prepare terminate.
403      * @return Return true if ability need to stop terminating; return false if ability need to terminate.
404      */
405     virtual bool OnPrepareTerminate();
406 
407     /**
408      * @brief Inflates UI controls by using windowOption.
409      * @param windowOption Indicates the window option defined by the user.
410      */
411     virtual void InitWindow(int32_t displayId, sptr<Rosen::WindowOption> option);
412 
413     /**
414      * @brief Get the window belong to the ability.
415      * @return Returns a Window object pointer.
416      */
417     virtual const sptr<Rosen::Window> GetWindow();
418 
419     /**
420      * @brief get the scene belong to the ability.
421      * @return Returns a WindowScene object pointer.
422      */
423     std::shared_ptr<Rosen::WindowScene> GetScene();
424 
425     /**
426      * @brief Called when this ability is about to leave the foreground and enter the background due to a user
427      * operation, for example, when the user touches the Home key.
428      */
429     virtual void OnLeaveForeground();
430 
431     /**
432      * @brief Get page ability stack info.
433      * @return A string represents page ability stack info, empty if failed;
434      */
435     virtual std::string GetContentInfo();
436 
437     /**
438      * @brief Set WindowScene listener
439      * @param listener WindowScene listener
440      * @return None.
441      */
442     void SetSceneListener(const sptr<Rosen::IWindowLifeCycle> &listener);
443 
444     /**
445      * @brief Called back at ability context.
446      * @return current window mode of the ability.
447      */
448     int GetCurrentWindowMode() override;
449 
450     /**
451      * @brief Set mission label of this ability.
452      * @param label the label of this ability.
453      * @return Returns ERR_OK if success.
454      */
455     ErrCode SetMissionLabel(const std::string &label) override;
456 
457     /**
458      * @brief Set mission icon of this ability.
459      * @param icon the icon of this ability.
460      * @return Returns ERR_OK if success.
461      */
462     ErrCode SetMissionIcon(const std::shared_ptr<OHOS::Media::PixelMap> &icon) override;
463 
464     /**
465      * @brief Get window rectangle of this ability.
466      * @param left the left position of window rectangle.
467      * @param top the top position of window rectangle.
468      * @param width the width position of window rectangle.
469      * @param height the height position of window rectangle.
470      */
471     void GetWindowRect(int32_t &left, int32_t &top, int32_t &width, int32_t &height) override;
472 
473     /**
474      * @brief Get ui content object.
475      * @return UIContent object of ACE.
476      */
477     Ace::UIContent *GetUIContent() override;
478 
479     /**
480      * @brief Call "onForeground" js function barely.
481      *
482      * @param want Want
483      */
484     virtual void CallOnForegroundFunc(const AAFwk::Want &want);
485 
486     /**
487      * @brief Request focus for current window, can be override.
488      *
489      * @param want Want
490      */
491     virtual void RequestFocus(const AAFwk::Want &want);
492 
493     /**
494      * @brief Execute insight intent when an ability is in foreground, schedule it to foreground repeatly.
495      *
496      * @param want Want.
497      * @param executeParam insight intent execute param.
498      * @param callback insight intent async callback.
499      */
500     virtual void ExecuteInsightIntentRepeateForeground(const AAFwk::Want &want,
501         const std::shared_ptr<InsightIntentExecuteParam> &executeParam,
502         std::unique_ptr<InsightIntentExecutorAsyncCallback> callback);
503 
504     /**
505      * @brief Execute insight intent when an ability didn't started or in background, schedule it to foreground.
506      *
507      * @param want Want.
508      * @param executeParam insight intent execute param.
509      * @param callback insight intent async callback.
510      */
511     virtual void ExecuteInsightIntentMoveToForeground(const AAFwk::Want &want,
512         const std::shared_ptr<InsightIntentExecuteParam> &executeParam,
513         std::unique_ptr<InsightIntentExecutorAsyncCallback> callback);
514 
515     /**
516      * @brief Execute insight intent when an ability didn't started, schedule it to background.
517      *
518      * @param want Want.
519      * @param executeParam insight intent execute param.
520      * @param callback insight intent async callback.
521      */
522     virtual void ExecuteInsightIntentBackground(const AAFwk::Want &want,
523         const std::shared_ptr<InsightIntentExecuteParam> &executeParam,
524         std::unique_ptr<InsightIntentExecutorAsyncCallback> callback);
525 
526     /**
527      * @brief create modal UIExtension.
528      * @param want Create modal UIExtension with want object.
529      */
530     int CreateModalUIExtension(const AAFwk::Want &want);
531 
532     /**
533      * @brief Update sessionToken.
534      * @param sessionToken The token of session.
535      */
536     void UpdateSessionToken(sptr<IRemoteObject> sessionToken);
537 
538     void EraseUIExtension(int32_t sessionId) override;
539 
540     void SetIdentityToken(const std::string &identityToken);
541     std::string GetIdentityToken() const;
542 
543 protected:
544     class UIAbilityDisplayListener : public OHOS::Rosen::IDisplayInfoChangedListener {
545     public:
UIAbilityDisplayListener(const std::weak_ptr<UIAbility> & ability)546         explicit UIAbilityDisplayListener(const std::weak_ptr<UIAbility> &ability)
547         {
548             ability_ = ability;
549         }
550 
OnDisplayInfoChange(const sptr<IRemoteObject> & token,Rosen::DisplayId displayId,float density,Rosen::DisplayOrientation orientation)551         void OnDisplayInfoChange(const sptr<IRemoteObject>& token, Rosen::DisplayId displayId, float density,
552             Rosen::DisplayOrientation orientation) override
553             {
554                 auto sptr = ability_.lock();
555                 if (sptr != nullptr) {
556                     sptr->OnDisplayInfoChange(token, displayId, density, orientation);
557                 }
558             }
559 
560     private:
561         std::weak_ptr<UIAbility> ability_;
562     };
563 
564     void OnCreate(Rosen::DisplayId displayId);
565     void OnDestroy(Rosen::DisplayId displayId);
566     void OnChange(Rosen::DisplayId displayId);
567     void OnDisplayInfoChange(const sptr<IRemoteObject>& token, Rosen::DisplayId displayId, float density,
568         Rosen::DisplayOrientation orientation);
569 
570     class AbilityDisplayMoveListener : public OHOS::Rosen::IDisplayMoveListener {
571     public:
AbilityDisplayMoveListener(std::weak_ptr<UIAbility> && ability)572         explicit AbilityDisplayMoveListener(std::weak_ptr<UIAbility> &&ability) : ability_(ability) {}
573 
OnDisplayMove(Rosen::DisplayId from,Rosen::DisplayId to)574         void OnDisplayMove(Rosen::DisplayId from, Rosen::DisplayId to) override
575         {
576             auto sptr = ability_.lock();
577             if (sptr != nullptr) {
578                 sptr->OnDisplayMove(from, to);
579             }
580         }
581 
582     private:
583         std::weak_ptr<UIAbility> ability_;
584     };
585 
586     void OnDisplayMove(Rosen::DisplayId from, Rosen::DisplayId to);
587     void UpdateConfiguration(Rosen::DisplayId to, float density, int32_t width, int32_t height);
588     virtual void DoOnForeground(const AAFwk::Want &want);
589     sptr<Rosen::WindowOption> GetWindowOption(const AAFwk::Want &want);
590     virtual void ContinuationRestore(const AAFwk::Want &want);
591 
592     std::shared_ptr<Rosen::WindowScene> scene_ = nullptr;
593     sptr<Rosen::IWindowLifeCycle> sceneListener_ = nullptr;
594     sptr<UIAbilityDisplayListener> abilityDisplayListener_ = nullptr;
595     sptr<Rosen::IDisplayMoveListener> abilityDisplayMoveListener_ = nullptr;
596 private:
597     void OnStartForSupportGraphics(const AAFwk::Want &want);
598     void OnChangeForUpdateConfiguration(const AppExecFwk::Configuration &newConfig);
599     void SetSessionToken(sptr<IRemoteObject> sessionToken);
600 
601     std::string identityToken_;
602     bool showOnLockScreen_ = false;
603     std::mutex wantMutexlock_;
604 #endif
605 };
606 } // namespace AbilityRuntime
607 } // namespace OHOS
608 #endif // OHOS_ABILITY_RUNTIME_UI_ABILITY_H
609