text: /*
   * Copyright (c) 2021 Huawei Device Co., Ltd.
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  #include <thread>
  
  #include "ability.h"
  #include "ability_loader.h"
  #include "app_log_wrapper.h"
  #include "display_type.h"
  #include "form_provider_client.h"
  #include "if_system_ability_manager.h"
  #include "iservice_registry.h"
  #include "system_ability_definition.h"
  #include "task_handler_client.h"
  #include "ohos_application.h"
  #include "continuation_manager.h"
  #include "continuation_register_manager.h"
  #include "continuation_register_manager_proxy.h"
  #include "reverse_continuation_scheduler_primary.h"
  #include "reverse_continuation_scheduler_replica.h"
  #include "reverse_continuation_scheduler_replica_handler_interface.h"
  #include "string_wrapper.h"
  #include "ability_post_event_timeout.h"
  
  #ifdef MMI_COMPILE
  #include "key_events.h"
  #include "touch_events.h"
  #else
  #include "key_event.h"
  #include "touch_event.h"
  #endif
  #include "form_host_client.h"
  #include "form_mgr.h"
  #include "ipc_skeleton.h"
  
  namespace OHOS {
  namespace AppExecFwk {
  REGISTER_AA(Ability)
  const std::string Ability::SYSTEM_UI("com.ohos.systemui");
  const std::string Ability::STATUS_BAR("com.ohos.systemui.statusbar.MainAbility");
  const std::string Ability::NAVIGATION_BAR("com.ohos.systemui.navigationbar.MainAbility");
  const std::string DEVICE_MANAGER_BUNDLE_NAME = "com.ohos.devicemanagerui";
  const std::string DEVICE_MANAGER_NAME = "com.ohos.devicemanagerui.MainAbility";
  const std::string Ability::DMS_SESSION_ID("sessionId");
  const std::string Ability::DMS_ORIGIN_DEVICE_ID("deviceId");
  const int Ability::DEFAULT_DMS_SESSION_ID(0);
  
  static std::mutex formLock;
  
  constexpr int64_t SEC_TO_MILLISEC = 1000;
  constexpr int64_t MILLISEC_TO_NANOSEC = 1000000;
  
  void Ability::Init(const std::shared_ptr<AbilityInfo> &abilityInfo, const std::shared_ptr<OHOSApplication> &application,
      std::shared_ptr<AbilityHandler> &handler, const sptr<IRemoteObject> &token)
  {
      APP_LOGI("%{public}s begin.", __func__);
  
      abilityInfo_ = abilityInfo;
      handler_ = handler;
      AbilityContext::token_ = token;
  
      // page ability only.
      if (abilityInfo_->type == AbilityType::PAGE) {
          abilityWindow_ = std::make_shared<AbilityWindow>();
  
          if (abilityWindow_ != nullptr) {
              APP_LOGI("%{public}s begin abilityWindow_->Init", __func__);
              abilityWindow_->Init(handler_, shared_from_this());
              APP_LOGI("%{public}s end abilityWindow_->Init", __func__);
          }
          continuationManager_ = std::make_shared<ContinuationManager>();
          std::weak_ptr<Ability> ability = shared_from_this();
          std::weak_ptr<ContinuationManager> continuationManager = continuationManager_;
          continuationHandler_ = std::make_shared<ContinuationHandler>(continuationManager, ability);
          if (!continuationManager_->Init(shared_from_this(), GetToken(), GetAbilityInfo(), continuationHandler_)) {
              continuationManager_.reset();
          } else {
              std::weak_ptr<ContinuationHandler> continuationHandler = continuationHandler_;
              sptr<ReverseContinuationSchedulerPrimary> Primary = sptr<ReverseContinuationSchedulerPrimary>(
                  new (std::nothrow) ReverseContinuationSchedulerPrimary(continuationHandler, handler_));
              if (Primary == nullptr) {
                  APP_LOGE("Ability::Init failed,Primary create failed");
              } else {
                  continuationHandler_->SetPrimaryStub(Primary);
                  continuationHandler_->SetAbilityInfo(abilityInfo_);
              }
          }
      }
      lifecycle_ = std::make_shared<LifeCycle>();
      abilityLifecycleExecutor_ = std::make_shared<AbilityLifecycleExecutor>();
      if (abilityLifecycleExecutor_ != nullptr) {
          abilityLifecycleExecutor_->DispatchLifecycleState(AbilityLifecycleExecutor::LifecycleState::INITIAL);
      } else {
          APP_LOGE("%{public}s abilityLifecycleExecutor_ make failed.", __func__);
      }
  
      application_ = application;
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * @brief Obtains a resource manager.
   *
   * @return Returns a ResourceManager object.
   */
  std::shared_ptr<Global::Resource::ResourceManager> Ability::GetResourceManager() const
  {
      return AbilityContext::GetResourceManager();
  }
  
  /**
   * Will be called when ability start. You should override this function
   *
   * @param want ability start information
   */
  void Ability::OnStart(const Want &want)
  {
      APP_LOGI("%{public}s begin.", __func__);
      if (abilityInfo_ == nullptr) {
          APP_LOGE("Ability::OnStart falied abilityInfo_ is nullptr.");
          return;
      }
  
      if (abilityInfo_->type == AppExecFwk::AbilityType::PAGE) {
          sptr<WindowOption> config = WindowOption::Get();
  
          OHOS::WindowType winType = OHOS::WindowType::WINDOW_TYPE_NORMAL;
          if (abilityInfo_->bundleName == SYSTEM_UI) {
              if (abilityInfo_->name == STATUS_BAR) {
                  winType = OHOS::WindowType::WINDOW_TYPE_STATUS_BAR;
              }
              if (abilityInfo_->name == NAVIGATION_BAR) {
                  winType = OHOS::WindowType::WINDOW_TYPE_NAVI_BAR;
              }
          }
          if (abilityInfo_->bundleName == OHOS_REQUEST_PERMISSION_BUNDLENAME &&
              abilityInfo_->name == OHOS_REQUEST_PERMISSION_ABILITY_NAME) {
              winType = OHOS::WindowType::WINDOW_TYPE_ALARM_SCREEN;
          }
  
          if (abilityInfo_->bundleName == DEVICE_MANAGER_BUNDLE_NAME &&
              abilityInfo_->name == DEVICE_MANAGER_NAME) {
              winType = OHOS::WindowType::WINDOW_TYPE_ALARM_SCREEN;
          }
  
          config->SetWindowType(winType);
          APP_LOGI("Ability::OnStart bundleName:%{public}s abilityName:%{public}s: set config.type = %{public}d",
              abilityInfo_->bundleName.c_str(),
              abilityInfo_->name.c_str(),
              winType);
  
          SetUIContent(config);
  
          if (abilityWindow_ != nullptr) {
              APP_LOGI("%{public}s begin abilityWindow_->OnPostAbilityStart.", __func__);
              abilityWindow_->OnPostAbilityStart();
              APP_LOGI("%{public}s end abilityWindow_->OnPostAbilityStart.", __func__);
          }
      }
      // should called in ace ability onStart methord.
  
      SetWant(want);
      if (abilityLifecycleExecutor_ == nullptr) {
          APP_LOGE("Ability::OnStart error. abilityLifecycleExecutor_ == nullptr.");
          return;
      }
      abilityLifecycleExecutor_->DispatchLifecycleState(AbilityLifecycleExecutor::LifecycleState::INACTIVE);
  
      if (lifecycle_ == nullptr) {
          APP_LOGE("Ability::OnStart error. lifecycle_ == nullptr.");
          return;
      }
      lifecycle_->DispatchLifecycle(LifeCycle::Event::ON_START, want);
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * @brief Called when this ability enters the <b>STATE_STOP</b> state.
   *
   * The ability in the <b>STATE_STOP</b> is being destroyed.
   * You can override this function to implement your own processing logic.
   */
  void Ability::OnStop()
  {
      APP_LOGI("%{public}s begin.", __func__);
  
      if (continuationManager_ != nullptr) {
          continuationManager_->UnregisterAbilityTokenIfNeed();
      } else {
          APP_LOGE("%{public}s continuationManager_ is nullptr.", __func__);
      }
  
      if (abilityWindow_ != nullptr && abilityInfo_->type == AppExecFwk::AbilityType::PAGE) {
          APP_LOGI("%{public}s begin abilityWindow_->OnPostAbilityStop.", __func__);
          abilityWindow_->OnPostAbilityStop();
          APP_LOGI("%{public}s end abilityWindow_->OnPostAbilityStop.", __func__);
      }
      if (abilityLifecycleExecutor_ == nullptr) {
          APP_LOGE("Ability::OnStop error. abilityLifecycleExecutor_ == nullptr.");
          return;
      }
      abilityLifecycleExecutor_->DispatchLifecycleState(AbilityLifecycleExecutor::LifecycleState::INITIAL);
  
      if (lifecycle_ == nullptr) {
          APP_LOGE("Ability::OnStop error. lifecycle_ == nullptr.");
          return;
      }
      lifecycle_->DispatchLifecycle(LifeCycle::Event::ON_STOP);
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * @brief Called when this ability enters the <b>STATE_ACTIVE</b> state.
   *
   * The ability in the <b>STATE_ACTIVE</b> state is visible and has focus.
   * You can override this function to implement your own processing logic.
   *
   * @param Want Indicates the {@link Want} structure containing activation information about the ability.
   */
  void Ability::OnActive()
  {
      APP_LOGI("%{public}s begin.", __func__);
  
      if (abilityWindow_ != nullptr) {
          APP_LOGI("%{public}s begin abilityWindow_->OnPostAbilityActive.", __func__);
          abilityWindow_->OnPostAbilityActive();
          APP_LOGI("%{public}s end abilityWindow_->OnPostAbilityActive.", __func__);
      }
      bWindowFocus_ = true;
      if (abilityLifecycleExecutor_ == nullptr) {
          APP_LOGE("Ability::OnActive error. abilityLifecycleExecutor_ == nullptr.");
          return;
      }
      abilityLifecycleExecutor_->DispatchLifecycleState(AbilityLifecycleExecutor::LifecycleState::ACTIVE);
  
      if (lifecycle_ == nullptr) {
          APP_LOGE("Ability::OnActive error. lifecycle_ == nullptr.");
          return;
      }
      lifecycle_->DispatchLifecycle(LifeCycle::Event::ON_ACTIVE);
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * @brief Called when this ability enters the <b>STATE_INACTIVE</b> state.
   *
   * <b>STATE_INACTIVE</b> is an instantaneous state. The ability in this state may be visible but does not have
   * focus.You can override this function to implement your own processing logic.
   */
  void Ability::OnInactive()
  {
      APP_LOGI("%{public}s begin.", __func__);
  
      if (abilityWindow_ != nullptr && abilityInfo_->type == AppExecFwk::AbilityType::PAGE) {
          APP_LOGI("%{public}s begin abilityWindow_->OnPostAbilityInactive.", __func__);
          abilityWindow_->OnPostAbilityInactive();
          APP_LOGI("%{public}s end abilityWindow_->OnPostAbilityInactive.", __func__);
      }
      bWindowFocus_ = false;
      if (abilityLifecycleExecutor_ == nullptr) {
          APP_LOGE("Ability::OnInactive error. abilityLifecycleExecutor_ == nullptr.");
          return;
      }
      abilityLifecycleExecutor_->DispatchLifecycleState(AbilityLifecycleExecutor::LifecycleState::INACTIVE);
  
      if (lifecycle_ == nullptr) {
          APP_LOGE("Ability::OnInactive error. lifecycle_ == nullptr.");
          return;
      }
      lifecycle_->DispatchLifecycle(LifeCycle::Event::ON_INACTIVE);
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * @brief Called when this ability enters the <b>STATE_FOREGROUND</b> state.
   *
   *
   * The ability in the <b>STATE_FOREGROUND</b> state is visible.
   * You can override this function to implement your own processing logic.
   */
  void Ability::OnForeground(const Want &want)
  {
      APP_LOGI("%{public}s begin.", __func__);
  
      if (abilityWindow_ != nullptr) {
          APP_LOGI("%{public}s begin abilityWindow_->OnPostAbilityForeground.", __func__);
          abilityWindow_->OnPostAbilityForeground();
          APP_LOGI("%{public}s end abilityWindow_->OnPostAbilityForeground.", __func__);
      }
  
      if (abilityLifecycleExecutor_ == nullptr) {
          APP_LOGE("Ability::OnForeground error. abilityLifecycleExecutor_ == nullptr.");
          return;
      }
      abilityLifecycleExecutor_->DispatchLifecycleState(AbilityLifecycleExecutor::LifecycleState::INACTIVE);
  
      if (lifecycle_ == nullptr) {
          APP_LOGE("Ability::OnForeground error. lifecycle_ == nullptr.");
          return;
      }
      lifecycle_->DispatchLifecycle(LifeCycle::Event::ON_FOREGROUND, want);
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * @brief Called when this ability enters the <b>STATE_BACKGROUND</b> state.
   *
   *
   * The ability in the <b>STATE_BACKGROUND</b> state is invisible.
   * You can override this function to implement your own processing logic.
   */
  void Ability::OnBackground()
  {
      APP_LOGI("%{public}s begin.", __func__);
  
      if (abilityWindow_ != nullptr && abilityInfo_->type == AppExecFwk::AbilityType::PAGE) {
          APP_LOGI("%{public}s begin abilityWindow_->OnPostAbilityBackground.", __func__);
          abilityWindow_->OnPostAbilityBackground();
          APP_LOGI("%{public}s end abilityWindow_->OnPostAbilityBackground.", __func__);
      }
  
      if (abilityLifecycleExecutor_ == nullptr) {
          APP_LOGE("Ability::OnBackground error. abilityLifecycleExecutor_ == nullptr.");
          return;
      }
      abilityLifecycleExecutor_->DispatchLifecycleState(AbilityLifecycleExecutor::LifecycleState::BACKGROUND);
  
      if (lifecycle_ == nullptr) {
          APP_LOGE("Ability::OnBackground error. lifecycle_ == nullptr.");
          return;
      }
      lifecycle_->DispatchLifecycle(LifeCycle::Event::ON_BACKGROUND);
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * @brief Called when this Service ability is connected for the first time.
   *
   * You can override this function to implement your own processing logic.
   *
   * @param want Indicates the {@link Want} structure containing connection information about the Service ability.
   * @return Returns a pointer to the <b>sid</b> of the connected Service ability.
   */
  sptr<IRemoteObject> Ability::OnConnect(const Want &want)
  {
      APP_LOGI("%{public}s begin.", __func__);
      if (abilityLifecycleExecutor_ == nullptr) {
          APP_LOGE("Ability::OnConnect error. abilityLifecycleExecutor_ == nullptr.");
          return nullptr;
      }
      abilityLifecycleExecutor_->DispatchLifecycleState(AbilityLifecycleExecutor::LifecycleState::ACTIVE);
  
      if (lifecycle_ == nullptr) {
          APP_LOGE("Ability::OnConnect error. lifecycle_ == nullptr.");
          return nullptr;
      }
      lifecycle_->DispatchLifecycle(LifeCycle::Event::ON_ACTIVE);
      APP_LOGI("%{public}s end.", __func__);
      return nullptr;
  }
  
  /**
   * @brief Called when all abilities connected to this Service ability are disconnected.
   *
   * You can override this function to implement your own processing logic.
   *
   */
  void Ability::OnDisconnect(const Want &want)
  {}
  
  /**
   * Start other ability for result.
   *
   * @param want information of other ability
   * @param requestCode request code for abilityMS to return result
   */
  void Ability::StartAbilityForResult(const Want &want, int requestCode)
  {
      APP_LOGI("%{public}s begin.", __func__);
      if (abilityInfo_ == nullptr) {
          APP_LOGE("Ability::StartAbilityForResult abilityInfo_ == nullptr");
          return;
      }
      APP_LOGI("Ability::StartAbilityForResult called type = %{public}d", abilityInfo_->type);
      if (abilityInfo_->type == AppExecFwk::AbilityType::PAGE) {
          AbilityContext::StartAbility(want, requestCode);
      }
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * Starts an ability with specific start settings and returns the execution result when the ability is destroyed.
   * When the ability is destroyed, onAbilityResult(int,int,ohos.aafwk.content.Want) is called and the returned
   * requestCode is transferred to the current method. The given requestCode is customized and cannot be a negative
   * number.
   *
   * @param want Indicates the ability to start.
   * @param requestCode Indicates the request code returned after the ability is started. You can define the request code
   * to identify the results returned by abilities. The value ranges from 0 to 65535.
   * @param abilityStartSetting Indicates the setting ability used to start.
   */
  void Ability::StartAbilityForResult(const Want &want, int requestCode, AbilityStartSetting abilityStartSetting)
  {
      APP_LOGI("%{public}s begin.", __func__);
      if (abilityInfo_ == nullptr) {
          APP_LOGE("Ability::StartAbilityForResult abilityInfo_ == nullptr");
          return;
      }
      APP_LOGI("Ability::StartAbilityForResult called type = %{public}d", abilityInfo_->type);
      if (abilityInfo_->type == AppExecFwk::AbilityType::PAGE) {
          AbilityContext::StartAbility(want, requestCode, abilityStartSetting);
      }
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * Starts a new ability with specific start settings.
   * A Page or Service ability uses this method to start a specific ability.
   * The system locates the target ability from installed abilities based on
   * the value of the intent parameter and then starts it. You can specify the
   * ability to start using the intent parameter.
   *
   * @param want Indicates the ability to start.
   * @param abilityStartSetting Indicates the setting ability used to start.
   */
  void Ability::StartAbility(const Want &want, AbilityStartSetting abilityStartSetting)
  {
      APP_LOGI("%{public}s beign.", __func__);
      if (abilityInfo_ == nullptr) {
          APP_LOGE("Ability::StartAbility abilityInfo_ == nullptr");
          return;
      }
      APP_LOGI("Ability::StartAbility called type = %{public}d", abilityInfo_->type);
      if (abilityInfo_->type == AppExecFwk::AbilityType::PAGE || abilityInfo_->type == AppExecFwk::AbilityType::SERVICE) {
          AbilityContext::StartAbility(want, -1, abilityStartSetting);
      }
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * @brief Called when a key is pressed. When any component in the Ability gains focus, the key-down event for
   * the component will be handled first. This callback will not be invoked if the callback triggered for the
   * key-down event of the component returns true. The default implementation of this callback does nothing
   * and returns false.
   *
   * @param keyCode Indicates the code of the key pressed.
   * @param keyEvent Indicates the key-down event.
   *
   * @return Returns true if this event is handled and will not be passed further; returns false if this event
   * is not handled and should be passed to other handlers.
   */
  bool Ability::OnKeyDown(int keyCode, const KeyEvent &keyEvent)
  {
      APP_LOGI("Ability::OnKeyDown called");
      APP_LOGI("Ability::OnKeyDown keyCode: %{public}d.", keyCode);
      return false;
  }
  
  /**
   * @brief Called when a key is released. When any component in the Ability gains focus, the key-up event for
   * the component will be handled first. This callback will not be invoked if the callback triggered for the
   * key-up event of the component returns true. The default implementation of this callback does nothing and
   * returns false.
   *
   * @param keyCode Indicates the code of the key released.
   * @param keyEvent Indicates the key-up event.
   *
   * @return Returns true if this event is handled and will not be passed further; returns false if this event
   * is not handled and should be passed to other handlers.
   */
  bool Ability::OnKeyUp(int keyCode, const KeyEvent &keyEvent)
  {
      APP_LOGI("Ability::OnKeyUp called");
      APP_LOGI("Ability::OnKeyUp keyCode: %{public}d.", keyCode);
      switch (keyCode) {
  #ifdef MMI_COMPILE
          case OHOS::KeyEventEnum::KEY_BACK:
  #else
          case KeyEvent::CODE_BACK:
  #endif
              APP_LOGI("Ability::OnKey Back key pressed.");
              OnBackPressed();
              return true;
          default:
              break;
      }
      return false;
  }
  
  /**
   * @brief Called when a touch event is dispatched to this ability. The default implementation of this callback
   * does nothing and returns false.
   *
   * @param event  Indicates information about the touch event.
   *
   * @return Returns true if the event is handled; returns false otherwise.
   */
  bool Ability::OnTouchEvent(const TouchEvent &touchEvent)
  {
      APP_LOGI("Ability::OnTouchEvent called");
      APP_LOGI("Ability::OnTouchEvent action: %{public}d phase: %{public}d",
          const_cast<TouchEvent &>(touchEvent).GetAction(),
          const_cast<TouchEvent &>(touchEvent).GetPhase());
      return false;
  }
  
  /**
   * @brief Inflates UI controls by using ComponentContainer.
   * You can create a ComponentContainer instance that contains multiple components.
   *
   * @param componentContainer Indicates a set of customized components.
   */
  void Ability::SetUIContent(const ComponentContainer &componentContainer)
  {}
  
  /**
   * @brief Inflates layout resources by using the layout resource ID.
   *
   * @param layoutRes Indicates the layout resource ID, which cannot be a negative number.
   */
  void Ability::SetUIContent(int layoutRes)
  {}
  
  /**
   * @brief Inflates UI controls by using ComponentContainer.
   * You can create a ComponentContainer instance that contains multiple components.
   *
   * @param componentContainer Indicates the component layout defined by the user.
   * @param context Indicates the context to use.
   * @param typeFlag Indicates the window type.
   */
  void Ability::SetUIContent(
      const ComponentContainer &componentContainer, std::shared_ptr<Context> &context, int typeFlag)
  {}
  
  /**
   * @brief Inflates layout resources by using the layout resource ID.
   *
   * @param layoutRes Indicates the layout resource ID, which cannot be a negative number.
   * @param context Indicates the context to use.
   * @param typeFlag Indicates the window type.
   */
  void Ability::SetUIContent(int layoutRes, std::shared_ptr<Context> &context, int typeFlag)
  {}
  
  /**
   * @brief Inflates UI controls by using WindowConfig.
   *
   * @param config Indicates the window config defined by the user.
   */
  void Ability::SetUIContent(const sptr<WindowOption> &config)
  {
      if (abilityWindow_ == nullptr) {
          APP_LOGE("Ability::SetUIContent abilityWindow_ is nullptr");
          return;
      }
  
      APP_LOGI("%{public}s beign abilityWindow_->SetWindowConfig.", __func__);
      abilityWindow_->SetWindowConfig(config);
      APP_LOGI("%{public}s end abilityWindow_->SetWindowConfig.", __func__);
  }
  
  /**
   * @brief Get the window belong to the ability.
   *
   * @return Returns a IWindowsManager object pointer.
   */
  const sptr<Window> &Ability::GetWindow()
  {
      if (abilityWindow_ != nullptr) {
          return abilityWindow_->GetWindow();
      } else {
          APP_LOGI("%{public}s abilityWindow_ is nullptr.", __func__);
          return nullptr;
      }
  }
  
  /**
   * @brief Obtains the type of audio whose volume is adjusted by the volume button.
   *
   * @return Returns the AudioManager.AudioVolumeType.
   */
  int Ability::GetVolumeTypeAdjustedByKey()
  {
      return 0;
  }
  
  /**
   * @brief Checks whether the main window of this ability has window focus.
   *
   * @return Returns true if this ability currently has window focus; returns false otherwise.
   */
  bool Ability::HasWindowFocus()
  {
      if (abilityInfo_ == nullptr) {
          APP_LOGI("Ability::HasWindowFocus abilityInfo_ == nullptr");
          return false;
      }
  
      if (abilityInfo_->type == AppExecFwk::AbilityType::PAGE) {
          return bWindowFocus_;
      }
  
      return false;
  }
  
  /**
   * @brief Called when a key is lone pressed.
   *
   * @param keyCode Indicates the code of the key long pressed.
   * @param keyEvent Indicates the key-long-press event.
   *
   * @return Returns true if this event is handled and will not be passed further; returns false if this event
   * is not handled and should be passed to other handlers.
   */
  bool Ability::OnKeyPressAndHold(int keyCode, const std::shared_ptr<KeyEvent> &keyEvent)
  {
      return false;
  }
  
  /**
   * @brief Called back after permissions are requested by using
   * AbilityContext.requestPermissionsFromUser(java.lang.String[],int).
   *
   * @param requestCode Indicates the request code passed to this method from
   * AbilityContext.requestPermissionsFromUser(java.lang.String[],int).
   * @param permissions Indicates the list of permissions requested by using
   * AbilityContext.requestPermissionsFromUser(java.lang.String[],int). This parameter cannot be null.
   * @param grantResults Indicates the granting results of the corresponding permissions requested using
   * AbilityContext.requestPermissionsFromUser(java.lang.String[],int). The value 0 indicates that a
   * permission is granted, and the value -1 indicates not.
   *
   */
  void Ability::OnRequestPermissionsFromUserResult(
      int requestCode, const std::vector<std::string> &permissions, const std::vector<int> &grantResults)
  {}
  
  /**
   * @brief Called when this ability is about to leave the foreground and enter the background due to a user operation,
   * for example, when the user touches the Home key.
   *
   */
  void Ability::OnLeaveForeground()
  {}
  
  /**
   * @brief Obtains the MIME type matching the data specified by the URI of the Data ability. This method should be
   * implemented by a Data ability. Data abilities supports general data types, including text, HTML, and JPEG.
   *
   * @param uri Indicates the URI of the data.
   *
   * @return Returns the MIME type that matches the data specified by uri.
   */
  std::string Ability::GetType(const Uri &uri)
  {
      return "";
  }
  
  /**
   * @brief Inserts a data record into the database. This method should be implemented by a Data ability.
   *
   * @param uri Indicates the position where the data is to insert.
   * @param value Indicates the data to insert.
   *
   * @return Returns the index of the newly inserted data record.
   */
  int Ability::Insert(const Uri &uri, const ValuesBucket &value)
  {
      return 0;
  }
  
  /**
   * @brief Called when the system configuration is updated.
   *
   * @param configuration Indicates the updated configuration information.
   */
  void Ability::OnConfigurationUpdated(const Configuration &configuration)
  {}
  
  /**
   * @brief Called when the system configuration is updated.
   *
   * @param level Indicates the memory trim level, which shows the current memory usage status.
   *
   */
  void Ability::OnMemoryLevel(int level)
  {}
  
  /**
   * @brief This is like openFile, open a file that need to be able to return sub-sections of files，often assets
   * inside of their .hap.
   *
   * @param uri Indicates the path of the file to open.
   * @param mode Indicates the file open mode, which can be "r" for read-only access, "w" for write-only access
   * (erasing whatever data is currently in the file), "wt" for write access that truncates any existing file,
   * "wa" for write-only access to append to any existing data, "rw" for read and write access on any existing
   * data, or "rwt" for read and write access that truncates any existing file.
   *
   * @return Returns the RawFileDescriptor object containing file descriptor.
   */
  int Ability::OpenRawFile(const Uri &uri, const std::string &mode)
  {
      return -1;
  }
  
  /**
   * @brief Updates one or more data records in the database. This method should be implemented by a Data ability.
   *
   * @param uri Indicates the database table storing the data to update.
   * @param value Indicates the data to update. This parameter can be null.
   * @param predicates Indicates filter criteria. If this parameter is null, all data records will be updated by default.
   *
   * @return Returns the number of data records updated.
   */
  int Ability::Update(const Uri &uri, const ValuesBucket &value, const DataAbilityPredicates &predicates)
  {
      return 0;
  }
  
  /**
   * @brief get application witch the ability belong
   *
   * @return Returns the application ptr
   */
  std::shared_ptr<OHOSApplication> Ability::GetApplication()
  {
      APP_LOGI("%{public}s begin.", __func__);
  
      if (application_ == nullptr) {
          APP_LOGE("Ability::GetApplication error. application_ == nullptr.");
          return nullptr;
      }
      APP_LOGI("%{public}s end.", __func__);
      return application_;
  }
  
  /**
   * @brief Obtains the class name in this ability name, without the prefixed bundle name.
   *
   * @return Returns the class name of this ability.
   */
  std::string Ability::GetAbilityName()
  {
      if (abilityInfo_ == nullptr) {
          APP_LOGE("Ability::GetAbilityName abilityInfo_ is nullptr");
          return "";
      }
  
      return abilityInfo_->name;
  }
  
  /**
   * @brief OChecks whether the current ability is being destroyed.
   * An ability is being destroyed if you called terminateAbility() on it or someone else requested to destroy it.
   *
   * @return Returns true if the current ability is being destroyed; returns false otherwise.
   */
  bool Ability::IsTerminating()
  {
      return false;
  }
  
  /**
   * @brief Called when startAbilityForResult(ohos.aafwk.content.Want,int) is called to start an ability and the result is
   * returned. This method is called only on Page abilities. You can start a new ability to perform some calculations and
   * use setResult (int,ohos.aafwk.content.Want) to return the calculation result. Then the system calls back the current
   * method to use the returned data to execute its own logic.
   *
   * @param requestCode Indicates the request code returned after the ability is started. You can define the request code
   * to identify the results returned by abilities. The value ranges from 0 to 65535.
   * @param resultCode Indicates the result code returned after the ability is started. You can define the result code to
   * identify an error.
   * @param resultData Indicates the data returned after the ability is started. You can define the data returned. The
   * value can be null.
   *
   */
  void Ability::OnAbilityResult(int requestCode, int resultCode, const Want &want)
  {}
  
  /**
   * @brief Called back when the Back key is pressed.
   * The default implementation destroys the ability. You can override this method.
   *
   */
  void Ability::OnBackPressed()
  {
      APP_LOGI("%{public}s begin.", __func__);
      if (abilityInfo_ == nullptr) {
          APP_LOGE("Ability::OnBackPressed abilityInfo_ is nullptr");
          return;
      }
  
      if (abilityInfo_->isLauncherAbility == false) {
          APP_LOGI("Ability::OnBackPressed the ability is not Launcher");
          TerminateAbility();
      }
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * @brief Called when the launch mode of an ability is set to singleInstance. This happens when you re-launch an
   * ability that has been at the top of the ability stack.
   *
   * @param want Indicates the new Want containing information about the ability.
   */
  void Ability::OnNewWant(const Want &want)
  {
      APP_LOGI("Ability::OnNewWant called");
  }
  
  /**
   * @brief Restores data and states of an ability when it is restored by the system. This method should be implemented by
   * a Page ability. This method is called if an ability was destroyed at a certain time due to resource reclaim or was
   * unexpectedly destroyed and the onSaveAbilityState(ohos.utils.PacMap) method was called to save its user data and
   * states. Generally, this method is called after the onStart(ohos.aafwk.content.Want) method.
   *
   *  @param inState Indicates the PacMap object used for storing data and states. This parameter can not be null.
   *
   */
  void Ability::OnRestoreAbilityState(const PacMap &inState)
  {
      APP_LOGI("Ability::OnRestoreAbilityState called");
  }
  
  /**
   * @brief Saves temporary data and states of this ability. This method should be implemented by a Page ability.
   * This method is called when the system determines that the ability may be destroyed in an unexpected situation, for
   * example, when the screen orientation changes or the user touches the Home key. Generally, this method is used only to
   * save temporary states.
   *
   *  @param outState Indicates the PacMap object used for storing user data and states. This parameter cannot be null.
   *
   */
  void Ability::OnSaveAbilityState(PacMap &outState)
  {
      APP_LOGI("Ability::OnSaveAbilityState called");
  }
  
  /**
   * @brief Called every time a key, touch, or trackball event is dispatched to this ability.
   * You can override this callback method if you want to know that the user has interacted with
   * the device in a certain way while this ability is running. This method, together with onLeaveForeground(),
   * is designed to help abilities intelligently manage status bar notifications. Specifically, they help
   * abilities determine when to cancel a notification.
   *
   */
  void Ability::OnEventDispatch()
  {}
  
  /**
   * @brief Sets the want object that can be obtained by calling getWant().
   * @param Want information of other ability
   */
  void Ability::SetWant(const AAFwk::Want &want)
  {
      setWant_ = std::make_shared<AAFwk::Want>(want);
  }
  
  /**
   * @brief Obtains the Want object that starts this ability.
   *
   * @return Returns the Want object that starts this ability.
   */
  std::shared_ptr<AAFwk::Want> Ability::GetWant()
  {
      return setWant_;
  }
  
  /**
   * @brief Sets the result code and data to be returned by this Page ability to the caller.
   * When a Page ability is destroyed, the caller overrides the AbilitySlice#onAbilityResult(int, int, Want) method to
   * receive the result set in the current method. This method can be called only after the ability has been initialized.
   *
   * @param resultCode Indicates the result code returned after the ability is destroyed. You can define the result code
   * to identify an error.
   * @param resultData Indicates the data returned after the ability is destroyed. You can define the data returned. This
   * parameter can be null.
   */
  void Ability::SetResult(int resultCode, const Want &resultData)
  {
      APP_LOGI("%{public}s begin.", __func__);
      if (abilityInfo_ == nullptr) {
          APP_LOGE("Ability::SetResult abilityInfo_ == nullptr");
          return;
      }
      APP_LOGI("Ability::SetResult called type = %{public}d", abilityInfo_->type);
      if (abilityInfo_->type == AppExecFwk::AbilityType::PAGE) {
          AbilityContext::resultWant_ = resultData;
          AbilityContext::resultCode_ = resultCode;
      }
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * @brief Sets the type of audio whose volume will be adjusted by the volume button.
   *
   * @param volumeType Indicates the AudioManager.AudioVolumeType to set.
   */
  void Ability::SetVolumeTypeAdjustedByKey(int volumeType)
  {}
  
  /**
   * @brief Called back when Service is started.
   * This method can be called only by Service. You can use the StartAbility(ohos.aafwk.content.Want) method to start
   * Service. Then the system calls back the current method to use the transferred want parameter to execute its own
   * logic.
   *
   * @param want Indicates the want of Service to start.
   * @param restart Indicates the startup mode. The value true indicates that Service is restarted after being destroyed,
   * and the value false indicates a normal startup.
   * @param startId Indicates the number of times the Service ability has been started. The startId is incremented by 1
   * every time the ability is started. For example, if the ability has been started for six times, the value of startId
   * is 6.
   */
  void Ability::OnCommand(const AAFwk::Want &want, bool restart, int startId)
  {
      APP_LOGI("%{public}s begin restart=%{public}s,startId=%{public}d.", __func__, restart ? "true" : "false", startId);
      if (abilityLifecycleExecutor_ == nullptr) {
          APP_LOGE("Ability::OnCommand error. abilityLifecycleExecutor_ == nullptr.");
          return;
      }
      abilityLifecycleExecutor_->DispatchLifecycleState(AbilityLifecycleExecutor::LifecycleState::ACTIVE);
  
      if (lifecycle_ == nullptr) {
          APP_LOGE("Ability::OnCommand error. lifecycle_ == nullptr.");
          return;
      }
      lifecycle_->DispatchLifecycle(LifeCycle::Event::ON_ACTIVE);
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * @brief dump ability info
   *
   * @param extra dump ability info
   */
  void Ability::Dump(const std::string &extra)
  {
      APP_LOGI("Ability::Dump called");
      // abilityInfo
      APP_LOGI("==============AbilityInfo==============");
      if (abilityInfo_ != nullptr) {
          APP_LOGI("abilityInfo: package: %{public}s", abilityInfo_->package.c_str());
          APP_LOGI("abilityInfo: name: %{public}s", abilityInfo_->name.c_str());
          APP_LOGI("abilityInfo: label: %{public}s", abilityInfo_->label.c_str());
          APP_LOGI("abilityInfo: description: %{public}s", abilityInfo_->description.c_str());
          APP_LOGI("abilityInfo: iconPath: %{public}s", abilityInfo_->iconPath.c_str());
          APP_LOGI("abilityInfo: visible: %{public}d", abilityInfo_->visible);
          APP_LOGI("abilityInfo: kind: %{public}s", abilityInfo_->kind.c_str());
          APP_LOGI("abilityInfo: type: %{public}d", abilityInfo_->type);
          APP_LOGI("abilityInfo: orientation: %{public}d", abilityInfo_->orientation);
          APP_LOGI("abilityInfo: launchMode: %{public}d", abilityInfo_->launchMode);
          for (auto permission : abilityInfo_->permissions) {
              APP_LOGI("abilityInfo: permission: %{public}s", permission.c_str());
          }
          APP_LOGI("abilityInfo: bundleName: %{public}s", abilityInfo_->bundleName.c_str());
          APP_LOGI("abilityInfo: applicationName: %{public}s", abilityInfo_->applicationName.c_str());
      } else {
          APP_LOGI("abilityInfo is nullptr");
      }
  
      // lifecycle_Event
      APP_LOGI("==============lifecycle_Event==============");
      if (lifecycle_ != nullptr) {
          APP_LOGI("lifecycle_Event: launchMode: %{public}d", lifecycle_->GetLifecycleState());
      } else {
          APP_LOGI("lifecycle is nullptr");
      }
  
      // lifecycle_State
      APP_LOGI("==============lifecycle_State==============");
      if (abilityLifecycleExecutor_ != nullptr) {
          APP_LOGI("lifecycle_State: launchMode: %{public}d", abilityLifecycleExecutor_->GetState());
      } else {
          APP_LOGI("abilityLifecycleExecutor is nullptr");
      }
  
      // applicationInfo
      APP_LOGI("==============applicationInfo==============");
      std::shared_ptr<ApplicationInfo> ApplicationInfoPtr = GetApplicationInfo();
      if (ApplicationInfoPtr != nullptr) {
          APP_LOGI("applicationInfo: name: %{public}s", ApplicationInfoPtr->name.c_str());
          APP_LOGI("applicationInfo: bundleName: %{public}s", ApplicationInfoPtr->bundleName.c_str());
      } else {
          APP_LOGI("ApplicationInfoPtr is nullptr");
      }
  }
  
  /**
   * @brief Keeps this Service ability in the background and displays a notification bar.
   * To use this method, you need to request the ohos.permission.KEEP_BACKGROUND_RUNNING permission from the system.
   * The ohos.permission.KEEP_BACKGROUND_RUNNING permission is of the normal level.
   * This method can be called only by Service abilities after the onStart(ohos.aafwk.content.Want) method is called.
   *
   * @param id Identifies the notification bar information.
   * @param notificationRequest Indicates the NotificationRequest instance containing information for displaying a
   * notification bar.
   */
  void Ability::KeepBackgroundRunning(int id, const NotificationRequest &notificationRequest)
  {}
  
  /**
   * @brief Cancels background running of this ability to free up system memory.
   * This method can be called only by Service abilities when the onStop() method is called.
   *
   */
  void Ability::CancelBackgroundRunning()
  {}
  
  /**
   * @brief Converts the given uri that refer to the Data ability into a normalized URI. A normalized URI can be used
   * across devices, persisted, backed up, and restored. It can refer to the same item in the Data ability even if the
   * context has changed. If you implement URI normalization for a Data ability, you must also implement
   * denormalizeUri(ohos.utils.net.Uri) to enable URI denormalization. After this feature is enabled, URIs passed to any
   * method that is called on the Data ability must require normalization verification and denormalization. The default
   * implementation of this method returns null, indicating that this Data ability does not support URI normalization.
   *
   * @param uri Indicates the Uri object to normalize.
   *
   * @return Returns the normalized Uri object if the Data ability supports URI normalization; returns null otherwise.
   */
  Uri Ability::NormalizeUri(const Uri &uri)
  {
      return uri;
  }
  
  /**
   * @brief Deletes one or more data records. This method should be implemented by a Data ability.
   *
   * @param uri Indicates the database table storing the data to delete.
   * @param predicates Indicates filter criteria. If this parameter is null, all data records will be deleted by default.
   *
   * @return Returns the number of data records deleted.
   */
  int Ability::Delete(const Uri &uri, const DataAbilityPredicates &predicates)
  {
      return 0;
  }
  
  /**
   * @brief Obtains the MIME type of files. This method should be implemented by a Data ability.
   *
   * @param uri Indicates the path of the files to obtain.
   * @param mimeTypeFilter Indicates the MIME type of the files to obtain. This parameter cannot be set to null.
   * 1. * / *: Obtains all types supported by a Data ability.
   * 2. image/ *: Obtains files whose main type is image of any subtype.
   * 3. * /jpg: Obtains files whose subtype is JPG of any main type.
   *
   * @return Returns the MIME type of the matched files; returns null if there is no type that matches the Data ability.
   */
  std::vector<std::string> Ability::GetFileTypes(const Uri &uri, const std::string &mimeTypeFilter)
  {
      return types_;
  }
  
  /**
   * @brief Opens a file. This method should be implemented by a Data ability.
   *
   * @param uri Indicates the path of the file to open.
   * @param mode Indicates the open mode, which can be "r" for read-only access, "w" for write-only access
   * (erasing whatever data is currently in the file), "wt" for write access that truncates any existing file,
   * "wa" for write-only access to append to any existing data, "rw" for read and write access on any existing data,
   * or "rwt" for read and write access that truncates any existing file.
   *
   * @return Returns the FileDescriptor object of the file descriptor.
   */
  int Ability::OpenFile(const Uri &uri, const std::string &mode)
  {
      return -1;
  }
  
  /**
   * @brief Queries one or more data records in the database. This method should be implemented by a Data ability.
   *
   * @param uri Indicates the database table storing the data to query.
   * @param columns Indicates the columns to be queried, in array, for example, {"name","age"}. You should define the
   * processing logic when this parameter is null.
   * @param predicates Indicates filter criteria. If this parameter is null, all data records will be queried by default.
   *
   * @return Returns the queried data.
   */
  std::shared_ptr<ResultSet> Ability::Query(
      const Uri &uri, const std::vector<std::string> &columns, const DataAbilityPredicates &predicates)
  {
      return nullptr;
  }
  
  /**
   * @brief Reloads data in the database.
   * The default implementation of this method returns false. You must implement this method in the child class
   * of your Data Ability if you want to use it.
   *
   * @param uri Indicates the position where the data is to reload.
   * @param extras Indicates the additional parameters contained in the PacMap object to be passed in this call.
   *
   * @return Returns true if the data is successfully reloaded; returns false otherwise.
   */
  bool Ability::Reload(const Uri &uri, const PacMap &extras)
  {
      return false;
  }
  
  /**
   * @brief Inserts multiple data records into the database.
   *
   * @param uri Indicates the path of the data to operate.
   * @param values Indicates the data records to insert.
   *
   * @return Returns the number of data records inserted.
   */
  int Ability::BatchInsert(const Uri &uri, const std::vector<ValuesBucket> &values)
  {
      APP_LOGI("%{public}s begin.", __func__);
      int amount = 0;
      for (auto it = values.begin(); it != values.end(); it++) {
          if (Insert(uri, *it) >= 0) {
              amount++;
          }
      }
      APP_LOGI("%{public}s end, amount=%{public}d", __func__, amount);
      return amount;
  }
  
  /**
   * @brief Migrates this ability to the given device on the same distributed network in a reversible way that allows this
   * ability to be migrated back to the local device through reverseContinueAbility(). The ability to migrate and its
   * ability slices must implement the IAbilityContinuation interface. Otherwise, an exception is thrown, indicating that
   * the ability does not support migration.
   *
   * @param deviceId Indicates the ID of the target device where this ability will be migrated to. If this parameter is
   * null, this method has the same effect as ContinueAbilityReversibly().
   *
   */
  void Ability::ContinueAbilityReversibly(const std::string &deviceId)
  {
      if (!VerifySupportForContinuation()) {
          APP_LOGE("Ability::ContinueAbilityReversibly(deviceId) failed. VerifySupportForContinuation faled");
          return;
      }
      continuationManager_->ContinueAbility(true, deviceId);
  }
  
  /**
   * @brief Migrates this ability to another device on the same distributed network in a reversible way that allows this
   * ability to be migrated back to the local device through reverseContinueAbility(). If there are multiple candidate
   * devices, a pop-up will be displayed for users to choose the desired one. The ability to migrate and its ability
   * slices must implement the IAbilityContinuation interface. Otherwise, an exception is thrown, indicating that the
   * ability does not support migration.
   *
   */
  void Ability::ContinueAbilityReversibly()
  {
      if (!VerifySupportForContinuation()) {
          APP_LOGE("Ability::ContinueAbilityReversibly failed. VerifySupportForContinuation faled");
          return;
      }
      continuationManager_->ContinueAbility(true, "");
  }
  
  /**
   * @brief  public final String getOriginalDeviceId​() throws UnsupportedOperationException
   * Obtains the ID of the source device from which this ability is migrated.
   *
   * @return Returns the source device ID.
   */
  std::string Ability::GetOriginalDeviceId()
  {
      return "";
  }
  
  /**
   * @brief Obtains the migration state of this ability.
   * @return Returns the migration state.
   *
   * @return Returns the source device ID.
   */
  ContinuationState Ability::GetContinuationState()
  {
      if (!VerifySupportForContinuation()) {
          APP_LOGE("Ability::GetContinuationState failed. VerifySupportForContinuation faled");
          return ContinuationState::LOCAL_RUNNING;
      }
      return continuationManager_->GetContinuationState();
  }
  
  /**
   * @brief Obtains the singleton AbilityPackage object to which this ability belongs.
   *
   * @return Returns the singleton AbilityPackage object to which this ability belongs.
   */
  std::shared_ptr<AbilityPackage> Ability::GetAbilityPackage()
  {
      return nullptr;
  }
  
  /**
   * @brief Converts the given normalized uri generated by normalizeUri(ohos.utils.net.Uri) into a denormalized one.
   * The default implementation of this method returns the original URI passed to it.
   *
   * @param uri uri Indicates the Uri object to denormalize.
   *
   * @return Returns the denormalized Uri object if the denormalization is successful; returns the original Uri passed to
   * this method if there is nothing to do; returns null if the data identified by the original Uri cannot be found in the
   * current environment.
   */
  Uri Ability::DenormalizeUri(const Uri &uri)
  {
      return uri;
  }
  
  /**
   * @brief Obtains the Lifecycle object of the current ability.
   *
   * @return Returns the Lifecycle object.
   */
  std::shared_ptr<LifeCycle> Ability::GetLifecycle()
  {
      APP_LOGI("Ability::GetLifecycle called");
      return lifecycle_;
  }
  
  /**
   * @brief Obtains the lifecycle state of this ability.
   *
   * @return Returns the lifecycle state of this ability.
   */
  AbilityLifecycleExecutor::LifecycleState Ability::GetState()
  {
      APP_LOGI("Ability::GetState called");
  
      if (abilityLifecycleExecutor_ == nullptr) {
          APP_LOGE("Ability::GetState error. abilityLifecycleExecutor_ == nullptr.");
          return AbilityLifecycleExecutor::LifecycleState::UNINITIALIZED;
      }
  
      return (AbilityLifecycleExecutor::LifecycleState)abilityLifecycleExecutor_->GetState();
  }
  
  /**
   * @brief A Page or Service ability uses this method to start a specific ability. The system locates the target ability
   * from installed abilities based on the value of the intent parameter and then starts it. You can specify the ability
   * to start using the intent parameter.
   *
   * @param intent Indicates the ability to start.
   */
  void Ability::StartAbility(const Want &want)
  {
      APP_LOGI("%{public}s begin.", __func__);
      AbilityContext::StartAbility(want, -1);
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * @brief Destroys this Page or Service ability.
   * After a Page or Service ability performs all operations, it can use this method to destroy itself
   * to free up memory. This method can be called only after the ability is initialized.
   */
  void Ability::TerminateAbility()
  {
      APP_LOGI("%{public}s begin.", __func__);
      AbilityContext::TerminateAbility();
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * @brief Destroys ability.
   *
   * @param want Indicates the want containing information about TerminateAbility
   *
   * @return Returns the result of TerminateAbility
   */
  int Ability::TerminateAbility(Want &want)
  {
      return -1;
  }
  
  /**
   * @brief Sets the main route for this ability.
   *
   * The main route, also called main entry, refers to the default <b>AbilitySlice</b> to present for this ability.
   * This function should be called only on Feature Abilities. If this function is not called in the
   * {@link OnStart(const Want &want)} function for a Feature Ability, the Feature Ability will fail to start.
   *
   * @param entry Indicates the main entry, which is the class name of the <b>AbilitySlice</b> instance to start.
   *
   * @return Returns the result of SetMainRouter
   */
  void Ability::SetMainRoute(const std::string &entry)
  {}
  
  /**
   * @brief By binding an action, you can set different action parameters in Intent to present different initial pages.
   *         You must register actions in the profile file.
   *
   * @param action Indicates the action to bind.
   *
   * @param entry Indicates the entry, which is the fully qualified name of your AbilitySlice class.
   *
   * @return Returns the result of AddActionRoute
   */
  void Ability::AddActionRoute(const std::string &action, const std::string &entry)
  {}
  
  /**
   * @brief Sets the background color of the window in RGB color mode.
   *
   * @param red The value ranges from 0 to 255.
   *
   * @param green The value ranges from 0 to 255.
   *
   * @param blue The value ranges from 0 to 255.
   *
   * @return Returns the result of SetWindowBackgroundColor
   */
  int Ability::SetWindowBackgroundColor(int red, int green, int blue)
  {
      return -1;
  }
  
  /**
   * @brief Connects the current ability to an ability using the AbilityInfo.AbilityType.SERVICE template.
   *
   * @param want Indicates the want containing information about the ability to connect
   *
   * @param conn Indicates the callback object when the target ability is connected.
   *
   * @return True means success and false means failure
   */
  bool Ability::ConnectAbility(const Want &want, const sptr<AAFwk::IAbilityConnection> &conn)
  {
      return AbilityContext::ConnectAbility(want, conn);
  }
  
  /**
   * @brief Disconnects the current ability from an ability
   *
   * @param conn Indicates the IAbilityConnection callback object passed by connectAbility after the connection
   *              is set up. The IAbilityConnection object uniquely identifies a connection between two abilities.
   */
  void Ability::DisconnectAbility(const sptr<AAFwk::IAbilityConnection> &conn)
  {
      return AbilityContext::DisconnectAbility(conn);
  }
  
  /**
   * @brief Destroys another ability that uses the AbilityInfo.AbilityType.SERVICE template.
   * The current ability using either the AbilityInfo.AbilityType.SERVICE or AbilityInfo.AbilityType.PAGE
   * template can call this method to destroy another ability that uses the AbilityInfo.AbilityType.SERVICE
   * template. The current ability itself can be destroyed by calling the terminateAbility() method.
   *
   * @param want Indicates the Want containing information about the ability to destroy.
   *
   * @return Returns true if the ability is destroyed successfully; returns false otherwise.
   */
  bool Ability::StopAbility(const AAFwk::Want &want)
  {
      return AbilityContext::StopAbility(want);
  }
  
  /**
   * @brief Posts a scheduled Runnable task to a new non-UI thread.
   * The task posted via this method will be executed in a new thread, which allows you to perform certain time-consuming
   * operations. To use this method, you must also override the supportHighPerformanceUI() method.
   *
   * @param task Indicates the Runnable task to post.
   *
   * @param delayTime Indicates the number of milliseconds after which the task will be executed.
   *
   * @return -
   */
  void Ability::PostTask(std::function<void()> task, long delayTime)
  {
      APP_LOGI("%{public}s begin.", __func__);
      TaskHandlerClient::GetInstance()->PostTask(task, delayTime);
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * @brief You can use the IContinuationRegisterManager object to interact with the Device+ control center,
   * including registering and unregistering the ability to migrate, updating the device connection state, and
   * showing the list of devices that can be selected for ability migration.
   *
   * @return Returns true if the migration request is successful; returns false otherwise.
   */
  std::weak_ptr<IContinuationRegisterManager> Ability::GetContinuationRegisterManager()
  {
      if (abilityInfo_ != nullptr) {
          if ((abilityInfo_->type == AbilityType::PAGE) && (continuationRegisterManager_ == nullptr)) {
              std::weak_ptr<Context> context = shared_from_this();
              std::shared_ptr<ContinuationRegisterManagerProxy> continuationRegisterManagerProxy =
                  std::make_shared<ContinuationRegisterManagerProxy>(context);
              continuationRegisterManager_ = std::make_shared<ContinuationRegisterManager>();
              continuationRegisterManager_->Init(continuationRegisterManagerProxy);
          }
      }
      std::weak_ptr<IContinuationRegisterManager> continuationRegisterManager =
          std::weak_ptr<IContinuationRegisterManager>(continuationRegisterManager_);
      return continuationRegisterManager;
  }
  
  /**
   * @brief Migrates this ability to the given device on the same distributed network. The ability to migrate and its
   * ability slices must implement the IAbilityContinuation interface.
   *
   * @param deviceId Indicates the ID of the target device where this ability will be migrated to. If this parameter
   * is null, this method has the same effect as continueAbility().
   *
   */
  void Ability::ContinueAbility(const std::string &deviceId)
  {
      if (deviceId.empty()) {
          APP_LOGE("Ability::ContinueAbility(deviceId) failed. deviceId is empty");
          return;
      }
  
      if (!VerifySupportForContinuation()) {
          APP_LOGE("Ability::ContinueAbility(deviceId) failed. VerifySupportForContinuation faled");
          return;
      }
      continuationManager_->ContinueAbility(false, deviceId);
  }
  
  /**
   * @brief Callback function to ask the user whether to start the migration .
   *
   * @return If the user allows migration, it returns true; otherwise, it returns false.
   */
  bool Ability::OnStartContinuation()
  {
      return false;
  }
  
  /**
   * @brief Save user data of local Ability generated at runtime.
   *
   * @param saveData Indicates the user data to be saved.
   * @return If the data is saved successfully, it returns true; otherwise, it returns false.
   */
  bool Ability::OnSaveData(WantParams &saveData)
  {
      return false;
  }
  
  /**
   * @brief After creating the Ability on the remote device, 
   *      immediately restore the user data saved during the migration of the Ability on the remote device.
   * @param restoreData Indicates the user data to be restored.
   * @return If the data is restored successfully, it returns true; otherwise, it returns false .
   */
  bool Ability::OnRestoreData(WantParams &restoreData)
  {
      return false;
  }
  
  /**
   * @brief This function can be used to implement the processing logic after the migration is completed.
   *
   * @param result Migration result code. 0 means the migration was successful, -1 means the migration failed.
   * @return None.
   */
  void Ability::OnCompleteContinuation(int result)
  {}
  
  /**
   * @brief Used to notify the local Ability that the remote Ability has been destroyed.
   *
   * @return None.
   */
  void Ability::OnRemoteTerminated()
  {}
  bool Ability::VerifySupportForContinuation()
  {
      if (continuationManager_ == nullptr) {
          APP_LOGE("Ability::VerifySupportForContinuation failed. continuationManager_ is nullptr");
          return false;
      }
      return true;
  }
  
  void Ability::HandleCreateAsContinuation(const Want &want)
  {
      if (!IsFlagExists(Want::FLAG_ABILITY_CONTINUATION, want.GetFlags())) {
          APP_LOGI("Ability::HandleCreateAsContinuation return. This not continuated ability");
          return;
      }
  
      // check whether it needs reversible
      bool reversible = false;
      reversible = IsFlagExists(Want::FLAG_ABILITY_CONTINUATION_REVERSIBLE, want.GetFlags());
      if (!VerifySupportForContinuation()) {
          APP_LOGE("Ability::HandleCreateAsContinuation failed. VerifySupportForContinuation failed");
          return;
      }
      bool success = continuationManager_->RestoreData(
          want.GetParams(), reversible, want.GetStringParam(ContinuationHandler::ORIGINAL_DEVICE_ID));
  
      if (success && reversible) {
          // Register this ability to receive reverse continuation callback.
          std::weak_ptr<IReverseContinuationSchedulerReplicaHandler> ReplicaHandler = continuationHandler_;
          reverseContinuationSchedulerReplica_ = sptr<ReverseContinuationSchedulerReplica>(
              new (std::nothrow) ReverseContinuationSchedulerReplica(handler_, ReplicaHandler));
  
          if (reverseContinuationSchedulerReplica_ == nullptr) {
              APP_LOGE("Ability::HandleCreateAsContinuation failed, create reverseContinuationSchedulerReplica failed");
              return;
          }
      }
  
      int sessionId = want.GetIntParam(DMS_SESSION_ID, DEFAULT_DMS_SESSION_ID);
      std::string originDeviceId = want.GetStringParam(DMS_ORIGIN_DEVICE_ID);
      APP_LOGE("Ability::HandleCreateAsContinuationoriginDeviceId: %{public}s", originDeviceId.c_str());
      continuationManager_->NotifyCompleteContinuation(
          originDeviceId, sessionId, success, reverseContinuationSchedulerReplica_);
  }
  bool Ability::IsFlagExists(int flag, int flagSet)
  {
      return (flag & flagSet) == flag;
  }
  
  /**
   * @brief Called when this ability gains or loses window focus.
   *
   * @param hasFocus Specifies whether this ability has focus.
   */
  void Ability::OnWindowFocusChanged(bool hasFocus)
  {}
  
  /**
   * @brief Called when this ability is moved to or removed from the top of the stack.
   *
   * @param topActive Specifies whether this ability is moved to or removed from the top of the stack. The value true
   * indicates that it is moved to the top, and false indicates that it is removed from the top of the stack.
   */
  void Ability::OnTopActiveAbilityChanged(bool topActive)
  {}
  
  /**
   * @brief Called to set caller information for the application. The default implementation returns null.
   *
   * @return Returns the caller information.
   */
  Uri Ability::OnSetCaller()
  {
      return Uri("");
  }
  
  /**
   * @brief Call this when your ability should be closed and the mission should be completely removed as a part of
   * finishing the root ability of the mission.
   */
  void Ability::TerminateAndRemoveMission()
  {
      APP_LOGI("%{public}s begin.", __func__);
      auto state = GetState();
      if (state > AbilityLifecycleExecutor::LifecycleState::INITIAL) {
          APP_LOGI("Ability::TerminateAndRemoveMission the GetState retval is %d", state);
          return;
      }
      AbilityContext::TerminateAndRemoveMission();
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * @brief Create a PostEvent timeout task. The default delay is 5000ms
   *
   * @return Return a smart pointer to a timeout object
   */
  std::shared_ptr<AbilityPostEventTimeout> Ability::CreatePostEventTimeouter(std::string taskstr)
  {
      // std::shared_ptr<EventHandler> eventhandler = handler_;
      return std::make_shared<AbilityPostEventTimeout>(taskstr, handler_);
  }
  
  /**
   * Releases an obtained form by its ID.
   *
   * <p>After this method is called, the form won't be available for use by the application, but the Form Manager
   * Service still keeps the cache information about the form, so that the application can quickly obtain it based on
   * the {@code formId}.</p>
   * <p><b>Permission: </b>{@link ohos.security.SystemPermission#REQUIRE_FORM}</p>
   *
   * @param formId Indicates the form ID.
   * @return Returns {@code true} if the form is successfully released; returns {@code false} otherwise.
   *
   * <ul>
   * <li>The passed {@code formId} is invalid. Its value must be larger than 0.</li>
   * <li>The specified form has not been added by the application.</li>
   * <li>An error occurred when connecting to the Form Manager Service.</li>
   * <li>The application is not granted with the {@link ohos.security.SystemPermission#REQUIRE_FORM} permission.</li>
   * <li>The form has been obtained by another application and cannot be released by the current application.</li>
   * <li>The form is being restored.</li>
   * </ul>
   */
  bool Ability::ReleaseForm(const int64_t formId)
  {
      APP_LOGI("%{public}s called.", __func__);
  
      // release form by formId and do not release cache
      return ReleaseForm(formId, false);
  }
  
  /**
   * Releases an obtained form by its ID.
   *
   * <p>After this method is called, the form won't be available for use by the application, if isReleaseCache is
   * false, this method is same as {@link #releaseForm(int)}, otherwise the Form Manager Service still store this
   * form in the cache.</p>
   * <p><b>Permission: </b>{@link ohos.security.SystemPermission#REQUIRE_FORM}</p>
   *
   * @param formId Indicates the form ID.
   * @param isReleaseCache Indicates whether to clear cache in service.
   * @return Returns {@code true} if the form is successfully released; returns {@code false} otherwise.
   *
   * <ul>
   * <li>The passed {@code formId} is invalid. Its value must be larger than 0.</li>
   * <li>The specified form has not been added by the application.</li>
   * <li>An error occurred when connecting to the Form Manager Service.</li>
   * <li>The application is not granted with the {@link ohos.security.SystemPermission#REQUIRE_FORM} permission.</li>
   * <li>The form has been obtained by another application and cannot be released by the current application.</li>
   * <li>The form is being restored.</li>
   * </ul>
   */
  bool Ability::ReleaseForm(const int64_t formId, const bool isReleaseCache)
  {
      APP_LOGI("%{public}s called.", __func__);
  
      // release form with formId and specifies whether to release the cache
      return DeleteForm(formId, isReleaseCache ? RELEASE_CACHED_FORM : RELEASE_FORM);  
  }
  
  /**
   * Deletes an obtained form by its ID.
   *
   * <p>After this method is called, the form won't be available for use by the application and the Form Manager
   * Service no longer keeps the cache information about the form.</p>
   * <p><b>Permission: </b>{@link ohos.security.SystemPermission#REQUIRE_FORM}</p>
   *
   * @param formId Indicates the form ID.
   * @return Returns {@code true} if the form is successfully deleted; returns {@code false} otherwise.
   *
   * <ul>
   * <li>The passed {@code formId} is invalid. Its value must be larger than 0.</li>
   * <li>The specified form has not been added by the application.</li>
   * <li>An error occurred when connecting to the Form Manager Service.</li>
   * <li>The application is not granted with the {@link ohos.security.SystemPermission#REQUIRE_FORM} permission.</li>
   * <li>The form has been obtained by another application and cannot be deleted by the current application.</li>
   * <li>The form is being restored.</li>
   * </ul>
   */
  bool Ability::DeleteForm(const int64_t formId)
  {
      APP_LOGI("%{public}s called.", __func__);
  
      // delete form with formId
      return DeleteForm(formId, DELETE_FORM);
  }
  
  /**
   * @brief Cast temp form with formId.
   *
   * @param formId Indicates the form's ID.
   * 
   * @return Returns {@code true} if the form is successfully casted; returns {@code false} otherwise.
   */
  bool Ability::CastTempForm(const int64_t formId)
  {
      APP_LOGI("%{public}s start",__func__);
      if (formId <= 0) {
          APP_LOGE("%{public}s error, passing in form id can't be negative.", __func__);
          return false;
      }
  
      //APP_LOGI("%{public}s, castTempForm begin of temp form %{public}lld", __func__, formId);
  
      bool result = FormMgr::GetInstance().CastTempForm(formId, FormHostClient::GetInstance());
  
      if (!result) {
          APP_LOGE("%{public}s error, some internal server occurs, error code is %{public}d.", __func__, result);
          return false;
      }
  
      userReqParams_[formId].SetParam(Constants::PARAM_FORM_TEMPORARY_KEY, false);
  
      APP_LOGI("%{public}s end",__func__);
      return true;
  }
  
  /**
   * @brief Obtains a specified form that matches the application bundle name, module name, form name, and
   * other related information specified in the passed {@code Want}.
   *
   * <p>This method is asynchronous. After the {@link FormJsInfo} instance is obtained.
   *
   * @param formId Indicates the form ID.
   * @param want Indicates the detailed information about the form to be obtained, including the bundle name,
   *        module name, ability name, form name, form id, tempForm flag, form dimension, and form customize data.
   * @param callback Indicates the callback to be invoked whenever the {@link FormJsInfo} instance is obtained.
   * @return Returns {@code true} if the request is successfully initiated; returns {@code false} otherwise.
   */
  bool Ability::AcquireForm(const int64_t formId, const Want &want, const std::shared_ptr<FormCallback> callback)
  {
      APP_LOGI("%{public}s called.", __func__);
  
      struct timespec ts;
      clock_gettime(CLOCK_REALTIME, &ts);
      long currentTime = ts.tv_sec * SEC_TO_MILLISEC + ts.tv_nsec / MILLISEC_TO_NANOSEC;
      APP_LOGI("%{public}s begin, current time: %{public}ld", __func__, currentTime);
  
      // check fms recover status
      if (FormMgr::GetRecoverStatus() == Constants::IN_RECOVERING) {
          APP_LOGE("%{public}s error, form is in recover status, can't do action on form.", __func__);
          return false;
      }
  
      // check form id
      //APP_LOGD("%{public}s, param of formId %{public}lld.", __func__, formId);
      if (formId < 0) {
          APP_LOGE("%{public}s error, form id should not be negative.", __func__);
          return false;
      }
  
      // check param of want
      if (!CheckWantValid(formId, want)) {
          APP_LOGE("%{public}s error, failed to check param of want.", __func__);
          return false;
      };
  
      ElementName elementName = want.GetElement();
      std::string bundleName = elementName.GetBundleName();
      std::string abilityName = elementName.GetAbilityName();
      //APP_LOGI("%{public}s, begin to acquire form, bundleName is %{public}s, abilityName is %{public}s, formId is %{public}lld.",__func__, bundleName.c_str(), abilityName.c_str(), formId);
  
      // hostClient init
      sptr<FormHostClient> formHostClient = FormHostClient::GetInstance();
      if (formHostClient == nullptr) {
          APP_LOGE("%{public}s error, formHostClient == nullptr.", __func__);
          return false;
      }
  
      // acquire form request to fms
      FormJsInfo formJsInfo;
      if (FormMgr::GetInstance().AddForm(formId, want, formHostClient, formJsInfo) != ERR_OK) {
          APP_LOGE("%{public}s error, acquire form for fms failed.", __func__);
          return false;
      }
      // APP_LOGI("%{public}s, end to acquire form, the formId returned from the fms is %{public}lld.",
      //  __func__, formJsInfo.formId);
  
      // check for form presence in hostForms
      if (formHostClient->ContainsForm(formJsInfo.formId)) {
          APP_LOGE("%{public}s error, form has already acquired, do not support acquire twice.", __func__);
          return false;
      }
  
      // add ability of form to hostForms
      std::shared_ptr<Ability> thisAbility = this->shared_from_this();
      formHostClient->AddForm(thisAbility, formJsInfo.formId);
  
      // post the async task of handleAcquireResult
      PostTask([this, want, formJsInfo, callback]() {HandleAcquireResult(want, formJsInfo, callback);}, 0L);
  
      // the acquire form is successfully
      return true;
  }
  
  /**
   * @brief Updates the content of a specified JS form.
   *
   * <p>This method is called by a form provider to update JS form data as needed.
   *
   * @param formId Indicates the form ID.
   * @param formProviderData The data used to update the JS form displayed on the client.
   * @return Returns {@code true} if the request is successfully initiated; returns {@code false} otherwise.
   */
  bool Ability::UpdateForm(const int64_t formId, const FormProviderData &formProviderData)
  {
      APP_LOGI("%{public}s called.", __func__);
  
      // check fms recover status
      if (FormMgr::GetRecoverStatus() == Constants::IN_RECOVERING) {
          APP_LOGE("%{public}s error, form is in recover status, can't do action on form.", __func__);
          return false;
      }
  
      // check formId
      if (formId <= 0) {
          APP_LOGE("%{public}s error, the passed in formId can't be negative or zero.", __func__);
          return false;
      }
  
      // check formProviderData
      if (formProviderData.GetDataString().empty()) {
          APP_LOGE("%{public}s error, the formProviderData is null.", __func__);
          return false;
      }
  
      // update form request to fms
      if (FormMgr::GetInstance().UpdateForm(formId, abilityInfo_->bundleName, formProviderData) != ERR_OK) {
          APP_LOGE("%{public}s error, update form for fms failed.", __func__);
          return false;
      }
  
      // the update form is successfully
      return true;
  }
  
  /**
   * @brief Sends a notification to the form framework to make the specified forms visible.
   *
   * <p>After this method is successfully called, {@link Ability#OnVisibilityChanged(std::map<int64_t, int>)}
   * will be called to notify the form provider of the form visibility change event.</p>
   *
   * @param formIds Indicates the IDs of the forms to be made visible.
   * @return Returns {@code true} if the request is successfully initiated; returns {@code false} otherwise.
   */
  bool Ability::NotifyVisibleForms(const std::vector<int64_t> &formIds)
  {
      APP_LOGI("%{public}s called.", __func__);
  
      return NotifyWhetherVisibleForms(formIds, Constants::FORM_VISIBLE);
  }
  
  /**
   * @brief Sends a notification to the form framework to make the specified forms invisible.
   *
   * <p>After this method is successfully called, {@link Ability#OnVisibilityChanged(std::map<int64_t, int>)}
   * will be called to notify the form provider of the form visibility change event.</p>
   *
   * @param formIds Indicates the IDs of the forms to be made invisible.
   * @return Returns {@code true} if the request is successfully initiated; returns {@code false} otherwise.
   */
  bool Ability::NotifyInvisibleForms(const std::vector<int64_t> &formIds)
  {
      APP_LOGI("%{public}s called.", __func__);
  
      return NotifyWhetherVisibleForms(formIds, Constants::FORM_INVISIBLE);
  }
  
  /**
  * @brief Set form next refresh time.
  *
  * <p>This method is called by a form provider to set refresh time.
  *
  * @param formId Indicates the ID of the form to set refresh time.
  * @param nextTime Indicates the next time gap now in seconds, can not be litter than 300 seconds.
  * @return Returns {@code true} if seting succeed; returns {@code false} otherwise.
  */
  bool Ability::SetFormNextRefreshTime(const int64_t formId, const int64_t nextTime)
  {
      APP_LOGI("%{public}s called.", __func__);
  
      if (nextTime < MIN_NEXT_TIME) {
          APP_LOGE("next time litte than 300 seconds.");
          return false;
      }
  
      if (FormMgr::GetInstance().GetRecoverStatus() == Constants::IN_RECOVERING) {
          APP_LOGE("%{public}s, formManager is in recovering", __func__);
          return false;
      }
  
      int result = FormMgr::GetInstance().SetNextRefreshTime(formId, nextTime);
      if (result != ERR_OK) {
          APP_LOGE("%{public}s, internal error:[%{public}d]", __func__, result);
          return false;
      }
  
      return true;
  }
  /**
   * @brief Requests for form data update.
   *
   * This method must be called when the application has detected that a system setting item (such as the language,
   * resolution, or screen orientation) being listened for has changed. Upon receiving the update request, the form
   * provider automatically updates the form data (if there is any update) through the form framework, with the update
   * process being unperceivable by the application.
   *
   * @param formId Indicates the ID of the form to update.
   * @return Returns true if the update request is successfully initiated, returns false otherwise.
   */
  bool Ability::RequestForm(const int64_t formId)
  {
      APP_LOGI("%{public}s called.", __func__);
      Want want;
      return RequestForm(formId, want);
  }
  
  /**
   * @brief Update form.
   *
   * @param formJsInfo Indicates the obtained {@code FormJsInfo} instance.
   */
  void Ability::ProcessFormUpdate(const FormJsInfo &formJsInfo)
  {
      APP_LOGI("%{public}s called.", __func__);
  
      // post the async task of handleFormMessage
      int32_t msgCode = OHOS_FORM_UPDATE_FORM;
      PostTask([this, msgCode, formJsInfo]() {HandleFormMessage(msgCode, formJsInfo);}, 0L);
  }
  /**
   * @brief Uninstall form.
   *
   * @param formId Indicates the ID of the form to uninstall.
   */
  void Ability::ProcessFormUninstall(const int64_t formId) {
      APP_LOGI("%{public}s start.", __func__);
      std::shared_ptr<FormCallback> formCallback = nullptr;
      {
          std::lock_guard<std::mutex> lock(formLock);
          // get callback iterator by formId
          std::map<int64_t, std::shared_ptr<FormCallback>>::iterator appCallbackIterator = 
              appCallbacks_.find(formId);
  
  
          // call the callback function when you need to be notified
          if (appCallbackIterator == appCallbacks_.end()) {
              //APP_LOGE("%{public}s failed, callback not find, formId: %{public}lld.", __func__, formId);
              return;
          }
          formCallback = appCallbackIterator->second;
          CleanFormResource(formId);
      }
      if ( formCallback == nullptr) {
          APP_LOGE("%{public}s failed, callback is nullptr.", __func__);
          return;
      }
  
      formCallback->OnFormUninstall(formId);
  
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * @brief Called to return a FormProviderInfo object.
   *
   * <p>You must override this method if your ability will serve as a form provider to provide a form for clients.
   * The default implementation returns nullptr. </p>
   *
   * @param want   Indicates the detailed information for creating a FormProviderInfo.
   *               The Want object must include the form ID, form name of the form,
   *               which can be obtained from Ability#PARAM_FORM_IDENTITY_KEY,
   *               Ability#PARAM_FORM_NAME_KEY, and Ability#PARAM_FORM_DIMENSION_KEY,
   *               respectively. Such form information must be managed as persistent data for further form
   *               acquisition, update, and deletion.
   * 
   * @return Returns the created FormProviderInfo object.
   */
  FormProviderInfo Ability::OnCreate(const Want &want)
  {
      APP_LOGI("%{public}s called.", __func__);
      FormProviderInfo formProviderInfo;
      return formProviderInfo;
  }
  
  /**
   * @brief Called to notify the form provider that a specified form has been deleted. Override this method if
   * you want your application, as the form provider, to be notified of form deletion.
   *
   * @param formId Indicates the ID of the deleted form.
   * @return None.
   */
  void Ability::OnDelete(const int64_t formId)
  {}
  
  /**
   * @brief Called to notify the form provider to update a specified form.
   *
   * @param formId Indicates the ID of the form to update.
   * @return none.
   */
  void Ability::OnUpdate(const int64_t formId)
  {
  }
  
  /**
   * @brief Called when the form provider is notified that a temporary form is successfully converted to a normal form.
   *
   * @param formId Indicates the ID of the form.
   * @return None.
   */
  void Ability::OnCastTemptoNormal(const int64_t formId)
  {}
  
  /**
   * @brief Called when the form provider receives form events from the fms.
   *
   * @param formEventsMap Indicates the form events occurred. The key in the Map object indicates the form ID,
   *                      and the value indicates the event type, which can be either FORM_VISIBLE
   *                      or FORM_INVISIBLE. FORM_VISIBLE means that the form becomes visible,
   *                      and FORM_INVISIBLE means that the form becomes invisible.
   * @return none.
   */
  void Ability::OnVisibilityChanged(const std::map<int64_t, int32_t> &formEventsMap)
  {
  }
  /**
   * @brief Called to notify the form provider to update a specified form.
   *
   * @param formId Indicates the ID of the form to update.
   * @param message Form event message.
   */
  void Ability::OnTriggerEvent(const int64_t formId, const std::string &message)
  {
  }
  /**
   * @brief Delete or release form with formId.
   *
   * @param formId Indicates the form's ID.
   * @param deleteType Indicates the type of delete or release.
   * @return Returns {@code true} if the form is successfully deleted; returns {@code false} otherwise.
   */
  bool Ability::DeleteForm(const int64_t formId, const int32_t deleteType)
  {
      APP_LOGI("%{public}s called.", __func__);
      // check fms recover status
      if (FormMgr::GetRecoverStatus() == Constants::IN_RECOVERING) {
          APP_LOGE("%{public}s error, form is in recover status, can't do action on form.", __func__);
          return false;
      }
      // check formId 
      if (formId <= 0) {
          APP_LOGE("%{public}s error, the passed in formId can't be negative or zero.", __func__);
          return false;
      }
  
      // APP_LOGI("%{public}s, delete form begin, formId is %{public}lld and deleteType is %{public}d.",
      //  __func__, formId, deleteType);
      {
          // form lock
          std::lock_guard<std::mutex> lock(formLock);
          // clean form resource when form is temp form
          if (std::find(
              lostedByReconnectTempForms_.begin(), 
              lostedByReconnectTempForms_.end(), 
              formId) != lostedByReconnectTempForms_.end()) {
              CleanFormResource(formId);
              // the delete temp form is successfully
              return true;
          }
      }
  
      // hostClient init
      sptr<FormHostClient> formHostClient = FormHostClient::GetInstance();
      // delete or release request to fms
      int result;
      if (deleteType == DELETE_FORM) {
          result = FormMgr::GetInstance().DeleteForm(formId, formHostClient);
      } else {
          result = FormMgr::GetInstance().ReleaseForm(
              formId, 
              formHostClient, 
              (deleteType == RELEASE_CACHED_FORM) ? true : false);
      }
      if (result != ERR_OK) {
          APP_LOGE("%{public}s error, some internal server occurs, error code is %{public}d.", __func__, result);
          return false;
      }
      {
          // form lock
          std::lock_guard<std::mutex> lock(formLock);
          // clean form resource
          CleanFormResource(formId);
      }
      // the delete form is successfully
      return true;
  }
  
  /**
   * @brief Clean form resource with formId.
   *
   * @param formId Indicates the form's ID.
   */
  void Ability::CleanFormResource(const int64_t formId) 
  {
      APP_LOGI("%{public}s called.", __func__);
      // compatible with int form id
      int64_t cleanId {-1L};
      for (auto param : userReqParams_) {
          if ((param.first & 0x00000000ffffffffL) == (formId & 0x00000000ffffffffL)) {
              cleanId = param.first;
              break;
          }
      }
      if (cleanId == -1L) {
          return;
      }
  
      //APP_LOGD("%{public}s. clean id is %{public}lld.", __func__, cleanId);
      // remove wantParam, callback and lostedByReconnectTempForms
      appCallbacks_.erase(cleanId);
      userReqParams_.erase(cleanId);
      auto tempForm = std::find(lostedByReconnectTempForms_.begin(), lostedByReconnectTempForms_.end(), cleanId);
      if (tempForm != lostedByReconnectTempForms_.end()) {
          lostedByReconnectTempForms_.erase(tempForm);
      }
  
      // remove ability
      std::shared_ptr<Ability> thisAbility = this->shared_from_this();
      FormHostClient::GetInstance()->RemoveForm(thisAbility, cleanId);
  
  
      // unregister death callback when appCallbacks is empty
      if (appCallbacks_.empty()) {
          std::shared_ptr<Ability> thisAbility = this->shared_from_this();
          FormMgr::GetInstance().UnRegisterDeathCallback(thisAbility);
      }
      APP_LOGI("%{public}s end.", __func__);
  }
  
  /**
   * @brief Handle acquire result of the obtained form instance.
   *
   * @param want Indicates the detailed information about the form to be obtained, including the bundle name,
   *        module name, ability name, form name, form id, tempForm flag, form dimension, and form customize data.
   * @param formJsInfo Indicates the obtained {@code FormJsInfo} instance.
   * @param callback Indicates the callback to be invoked whenever the {@link FormJsInfo} instance is obtained.
   */
  void Ability::HandleAcquireResult(
      const Want &want, 
      const FormJsInfo &formJsInfo, 
      const std::shared_ptr<FormCallback> callback)
  {
      APP_LOGI("%{public}s called.", __func__);
      {
          // form lock
          std::lock_guard<std::mutex> lock(formLock);
  
          // register death when userReqParams is empty
          if (userReqParams_.empty()) {
              std::shared_ptr<Ability> thisAbility = this->shared_from_this();
              FormMgr::GetInstance().RegisterDeathCallback(thisAbility);
          }
  
          // save wantParam and callback
          userReqParams_.insert(std::make_pair(formJsInfo.formId, want));
          appCallbacks_.insert(std::make_pair(formJsInfo.formId, callback));
      }
  
      struct timespec ts;
      clock_gettime(CLOCK_REALTIME, &ts);
      long currentTime = ts.tv_sec * SEC_TO_MILLISEC + ts.tv_nsec / MILLISEC_TO_NANOSEC;
      APP_LOGI("%{public}s, AcquireForm end, current time: %{public}ld", __func__, currentTime);
  
      // handle acquire message of the obtained form instance
      callback->OnAcquired(FormCallback::OHOS_FORM_ACQUIRE_SUCCESS, formJsInfo);
  }
  
  /**
   * @brief Handle acquire message of the obtained form instance.
   *
   * @param msgCode Indicates the code of message type.
   * @param formJsInfo Indicates the obtained {@code FormJsInfo} instance.
   */
  void Ability::HandleFormMessage(const int32_t msgCode, const FormJsInfo &formJsInfo)
  {
      APP_LOGI("%{public}s called.", __func__);
      std::shared_ptr<FormCallback> formCallback = nullptr;
      {
          std::lock_guard<std::mutex> lock(formLock);
          // get callback iterator by formId
          std::map<int64_t, std::shared_ptr<FormCallback>>::iterator appCallbackIterator = 
              appCallbacks_.find(formJsInfo.formId);
  
  
          // call the callback function when you need to be notified
          if (appCallbackIterator == appCallbacks_.end()) {
             // APP_LOGE("%{public}s failed, callback not find, formId: %{public}lld.", __func__, formJsInfo.formId);
              return;
          }
          formCallback = appCallbackIterator->second;
      }
      if ( formCallback == nullptr) {
          APP_LOGE("%{public}s failed, callback is nullptr.", __func__);
          return;
      }
  
      //APP_LOGI("%{public}s, call user implement of form %{public}lld.", __func__, formJsInfo.formId);
  
      if (msgCode == OHOS_FORM_ACQUIRE_FORM) {
          formCallback->OnAcquired(FormCallback::OHOS_FORM_ACQUIRE_SUCCESS, formJsInfo);
      } else {
          formCallback->OnUpdate(FormCallback::OHOS_FORM_UPDATE_SUCCESS, formJsInfo);
      }
  }
  
  /**
   * @brief Notify the forms visibility change event.
   * 
   * @param formIds Indicates the IDs of the forms to be made visible or invisible.
   * @param eventType Indicates the form events occurred. FORM_VISIBLE means that the form becomes visible,
   *                  and FORM_INVISIBLE means that the form becomes invisible.
   * @return Returns {@code true} if the request is successfully initiated; returns {@code false} otherwise.
   */
  bool Ability::NotifyWhetherVisibleForms(const std::vector<int64_t> &formIds, int32_t eventType)
  {
      APP_LOGI("%{public}s called.", __func__);
  
      if (formIds.empty() || formIds.size() > Constants::MAX_VISIBLE_NOTIFY_LIST) {
          APP_LOGE("%{public}s, formIds is empty or exceed 32.", __func__);
          return false;
      }
  
      if (FormMgr::GetRecoverStatus() == Constants::IN_RECOVERING) {
          APP_LOGE("%{public}s error, form is in recover status, can't do action on form.", __func__);
          return false;
      }
  
      int resultCode = FormMgr::GetInstance().NotifyWhetherVisibleForms(formIds, FormHostClient::GetInstance(), eventType);
      if (resultCode != ERR_OK) {
          APP_LOGE("%{public}s error, internal error occurs, error code:%{public}d.",  __func__, resultCode);
          return false;
      }
      return true;
  }
  
  /**
   * @brief Check the param of want.
   * 
   * @param formId Indicates the form's ID.
   * @param want Indicates the detailed information about the form to be obtained, including the bundle name,
   *        module name, ability name, form name, form id, tempForm flag, form dimension, and form customize data.
   * @return Returns {@code true} if the check result is ok; returns {@code false} ng.
   */
  bool Ability::CheckWantValid(const int64_t formId, const Want &want)
  {
      APP_LOGI("%{public}s called.", __func__);
  
      // get want parameters
      int32_t formDimension = want.GetIntParam(Constants::PARAM_FORM_DIMENSION_KEY, 1);
      std::string moduleName = want.GetStringParam(Constants::PARAM_MODULE_NAME_KEY);
  
      ElementName elementName = want.GetElement();
      std::string bundleName = elementName.GetBundleName();
      std::string abilityName = elementName.GetAbilityName();
  
      bool tempFormFlg = want.GetBoolParam(Constants::PARAM_FORM_TEMPORARY_KEY, false);
  
      APP_LOGD("%{public}s, param of formDimension %{public}d in want.", __func__, formDimension);
      APP_LOGD("%{public}s, param of moduleName %{public}s in want.", __func__, moduleName.c_str());
      APP_LOGD("%{public}s, param of bundleName %{public}s in want.", __func__, bundleName.c_str());
      APP_LOGD("%{public}s, param of abilityName %{public}s in want.", __func__, abilityName.c_str());
      APP_LOGD("%{public}s, param of tempFormFlg %{public}d in want.", __func__, tempFormFlg);
  
      // check want parameters
      if (bundleName.empty() || abilityName.empty() || moduleName.empty()) {
          APP_LOGE("%{public}s error, bundleName or abilityName or moduleName is not set in want.", __func__);
          return false;
      }
      if (FormHostClient::GetInstance()->ContainsForm(formId)) {
          APP_LOGE("%{public}s error, form has already acquired, do not support acquire twice.", __func__);
          return false;
      }
      if (formDimension <= 0) {
          APP_LOGE("%{public}s error, dimension should not be zero or negative in want.", __func__);
          return false;
      }
      if (tempFormFlg && formId != 0) {
          APP_LOGE("%{public}s error, can not select form id when acquire temporary form.", __func__);
          return false;
      }
  
      // the check is successfully
      return true;
  }
  
  /**
   * @brief Enable form update.
   *
   * @param formIds FormIds of hostclient.
   */
  bool Ability::EnableUpdateForm(const std::vector<int64_t> &formIds)
  {
      APP_LOGI("%{public}s called.", __func__);
      return LifecycleUpdate(formIds, ENABLE_FORM_UPDATE);
  }
  
  /**
   * @brief Disable form update.
   *
   * @param formIds FormIds of hostclient.
   */
  bool Ability::DisableUpdateForm(const std::vector<int64_t> &formIds)
  {
      APP_LOGI("%{public}s called.", __func__);
      return LifecycleUpdate(formIds, DISABLE_FORM_UPDATE);
  }
  
  bool Ability::LifecycleUpdate(std::vector<int64_t> formIds, int32_t updateType) 
  {
      if (FormMgr::GetRecoverStatus() == Constants::IN_RECOVERING) {
          APP_LOGE("%{public}s error, form is in recover status, can't do action on form.", __func__);
          return false;
      }
  
      // hostClient init
      sptr<FormHostClient> formHostClient = FormHostClient::GetInstance();
      if (formHostClient == nullptr) {
          APP_LOGE("%{public}s error, formHostClient == nullptr.", __func__);
          return false;
      }
  
      int result = FormMgr::GetInstance().LifecycleUpdate(formIds, formHostClient, updateType);
      if (result != ERR_OK) {
          APP_LOGE("%{public}s error, internal error.", __func__);
          return false;
      }
  
      return true;
  }
  
  /**
   * @brief Requests for form data update, by passing a set of parameters (using Want) to the form provider.
   *
   * This method must be called when the application has detected that a system setting item (such as the language,
   * resolution, or screen orientation) being listened for has changed. Upon receiving the update request, the form
   * provider automatically updates the form data (if there is any update) through the form framework, with the update
   * process being unperceivable by the application.
   *
   * @param formId Indicates the ID of the form to update.
   * @param want Indicates a set of parameters to be transparently passed to the form provider.
   * @return Returns true if the update request is successfully initiated, returns false otherwise.
   */
  bool Ability::RequestForm(const int64_t formId, const Want &want)
  {
      APP_LOGI("%{public}s called.", __func__);
  
      if (formId <= 0) {
          APP_LOGE("%{public}s error, The passed formid is invalid. Its value must be larger than 0.", __func__);
          return false;
      }
  
      if (FormMgr::GetRecoverStatus() == Constants::IN_RECOVERING) {
          APP_LOGE("%{public}s error, form is in recover status, can't do action on form.", __func__);
          return false;
      }
  
      // requestForm request to fms
      int resultCode = FormMgr::GetInstance().RequestForm(formId, FormHostClient::GetInstance(), want);
      if (resultCode != ERR_OK) {
          APP_LOGE("%{public}s error, failed to notify the form service that the form user's lifecycle is updated, error code is %{public}d.", __func__, resultCode);
          return false;
      }
  
      return true;
  }
  
  /**
   * @brief Called to reacquire form and update the form host after the death callback is received.
   *
   */
  void Ability::OnDeathReceived()
  {
      APP_LOGI("%{public}s called.", __func__);
  
      int64_t formId;
      std::map<int64_t, Want> &userReqParams = userReqParams_;
      std::vector<int64_t> &lostedTempForms = lostedByReconnectTempForms_;
      for (const auto &userReqRaram : userReqParams) {
          formId = userReqRaram.first;
          Want want;
          {
              std::lock_guard<std::mutex> lock(formLock);
              want = userReqRaram.second;
              if (want.GetBoolParam(Constants::PARAM_FORM_TEMPORARY_KEY, false)
                  && std::find(lostedTempForms.begin(), lostedTempForms.end(),
                      formId) == lostedTempForms.end()) {
                  lostedTempForms.emplace_back(formId);
                  continue;
              }
          }
  
          bool result = ReAcquireForm(formId, want);
          if (!result) {
             // APP_LOGI("%{public}s error, reacquire form failed, formId:%{public}lld.", __func__, formId);
              std::shared_ptr<FormCallback> formCallback = nullptr;
              {
                  std::lock_guard<std::mutex> lock(formLock);
                  // get callback iterator by formId
                  std::map<int64_t, std::shared_ptr<FormCallback>>::iterator appCallbackIterator = appCallbacks_.find(formId);
                  
                  if (appCallbackIterator == appCallbacks_.end()) {
                      //APP_LOGW("%{public}s error, lack of form callback for form, formId:%{public}lld.", __func__, formId);
                      continue;
                  }
                  formCallback = appCallbackIterator->second;
              }
              if(formCallback == nullptr) {
                  APP_LOGW("%{public}s failed, callback is nullptr.", __func__);
                  continue;
              }           
  
              FormJsInfo formJsInfo;
              formJsInfo.formId = formId;
              formCallback->OnAcquired(FormCallback::OHOS_FORM_RESTORE_FAILURE, formJsInfo);
          }
      }
  }
  
  /**
   * @brief Reacquire a specified form when the death callback is received.
   * 
   * @param formId Indicates the form ID.
   * @param want Indicates the detailed information about the form to be obtained.
   * @return Returns true if the request is successfully initiated; returns false otherwise.
   */
  bool Ability::ReAcquireForm(const int64_t formId, const Want &want)
  {
      APP_LOGI("%{public}s called.", __func__);
  
      // get the form host client
      sptr<FormHostClient> formHostClient = FormHostClient::GetInstance();
      if (formHostClient == nullptr) {
          //APP_LOGE("%{public}s error, formHostClient is nullptr, formId:%{public}lld.", __func__, formId);
          return false;
      }
  
      // reacquire form
      FormJsInfo formJsInfo;
      if (FormMgr::GetInstance().AddForm(formId, want, formHostClient, formJsInfo) != ERR_OK
          || formJsInfo.formId <= 0 || formJsInfo.formId != formId) {
          //APP_LOGE("%{public}s error, fms reacquire form failed, formId:%{public}lld.", __func__, formId);
          return false;
      }
  
      // handle update message of the obtained form instance.
      ProcessFormUpdate(formJsInfo);
  
      return true;
  }
  
  /**
   * @brief Check form manager service ready.
   *
   * @return Returns true if form manager service ready; returns false otherwise.
   */
  bool Ability::CheckFMSReady()
  {
      APP_LOGI("%{public}s called.", __func__);
  
      sptr<ISystemAbilityManager> systemAbilityManager =
       SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
      auto remoteObject = systemAbilityManager->GetSystemAbility(FORM_MGR_SERVICE_ID);
      if (remoteObject == nullptr) {
          APP_LOGI("%{public}s, form manager service is not ready.", __func__);
          return false;
      }
      
      return true;
  }
  
  /**
   * @brief Get All FormsInfo.
   *
   * @param formInfos Returns the forms' information of all forms provided.
   * @return Returns true if the request is successfully initiated; returns false otherwise.
   */
  bool Ability::GetAllFormsInfo(std::vector<FormInfo> &formInfos)
  {
      APP_LOGI("%{public}s called.", __func__);
  
      sptr<IBundleMgr> iBundleMgr = GetBundleMgr();
      if (iBundleMgr == nullptr) {
          APP_LOGE("%{public}s error, failed to get IBundleMgr.", __func__);
          return false;
      }
      
      if (!CheckPermission()) {
          return false;
      }
  
      return iBundleMgr->GetAllFormsInfo(formInfos);
  }
  
  /**
   * @brief Get forms info by application name.
   *
   * @param bundleName Application name.
   * @param formInfos Returns the forms' information of the specify application name.
   * @return Returns true if the request is successfully initiated; returns false otherwise.
   */
  bool Ability::GetFormsInfoByApp(std::string &bundleName, std::vector<FormInfo> &formInfos)
  {
      APP_LOGI("%{public}s called.", __func__);
      bool IsGetFormsInfoByApp = false;
      if (bundleName.empty()) {
          APP_LOGW("save info fail, empty bundle name");
          return IsGetFormsInfoByApp;
      }
  
      sptr<IBundleMgr> iBundleMgr = GetBundleMgr();
      if (iBundleMgr == nullptr) {
          APP_LOGE("%{public}s error, failed to get IBundleMgr.", __func__);
          return IsGetFormsInfoByApp;
      }
      
      if (!CheckPermission()) {
          return IsGetFormsInfoByApp;
      }
      
      IsGetFormsInfoByApp = iBundleMgr->GetFormsInfoByApp(bundleName, formInfos);
      if (formInfos.size() == 0){
          return IsGetFormsInfoByApp;
      }
      
      return IsGetFormsInfoByApp;
  }
  
  
   /**
   * @brief Get forms info by application name and module name.
   *
   * @param bundleName Application name.
   * @param moduleName Module name of hap.
   * @param formInfos Returns the forms' information of the specify application name and module name.
   * @return Returns true if the request is successfully initiated; returns false otherwise.
   */
  bool Ability::GetFormsInfoByModule(std::string &bundleName, std::string &moduleName, std::vector<FormInfo> &formInfos)
  {
      APP_LOGI("%{public}s called.", __func__);
  
      bool IsGetFormsInfoByModule = false;
      if (bundleName.empty() || moduleName.empty()) {
          APP_LOGW("save info fail, empty bundle name");
          return IsGetFormsInfoByModule;
      }
  
      sptr<IBundleMgr> iBundleMgr = GetBundleMgr();
      if (iBundleMgr == nullptr) {
          APP_LOGE("%{public}s error, failed to get IBundleMgr.", __func__);
          return IsGetFormsInfoByModule;
      }
  
      if (!CheckPermission()) {
          return IsGetFormsInfoByModule;
      }
      
      IsGetFormsInfoByModule = iBundleMgr->GetFormsInfoByModule(bundleName, moduleName, formInfos);
      
      return IsGetFormsInfoByModule;
  }
  
  /**
   * @brief Acquire a bundle manager, if it not existed.
   * @return returns the bundle manager ipc object, or nullptr for failed.
   */
  sptr<IBundleMgr> Ability::GetBundleMgr()
  {
      APP_LOGI("%{public}s called.", __func__);
  
      if (iBundleMgr_ == nullptr) {
          sptr<ISystemAbilityManager> systemAbilityManager =
           SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
          auto remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
          if (remoteObject == nullptr) {
              APP_LOGE("%{public}s error, failed to get bundle manager service.", __func__);
              return nullptr;
          }
  
          iBundleMgr_ = iface_cast<IBundleMgr>(remoteObject);
          if (iBundleMgr_ == nullptr) {        
              APP_LOGE("%{public}s error, failed to get bundle manager service", __func__);
              return nullptr;  
          }
      }
      
      return iBundleMgr_;
  }
  
  /**
   * @brief check permission of bundle, if it not existed.
   * @return returns the permission is vaild, or false for failed.
   */
  bool Ability::CheckPermission() {
      APP_LOGI("%{public}s called.", __func__);
  
      int32_t uid = IPCSkeleton::GetCallingUid();
      if (!iBundleMgr_->CheckIsSystemAppByUid(uid)) {
          APP_LOGE("%{public}s fail, form is not system app. uid:%{public}d", __func__, uid);
          return false;
      }
  
      std::string bundleName;
      bool result = iBundleMgr_->GetBundleNameForUid(uid, bundleName);
      if (!result || bundleName.empty()) {
          APP_LOGE("%{public}s failed, cannot get bundle name by uid:%{public}d", __func__, uid);
          return false;
      }
  
      return true;
  }
  
  /**
   * @brief Add the bundle manager instance for debug.
   * @param bundleManager the bundle manager ipc object.
   */
  void Ability::SetBundleManager(const sptr<IBundleMgr> &bundleManager)
  {
      APP_LOGI("%{public}s called.", __func__);
  
      iBundleMgr_ = bundleManager;
  }
  
  /**
   * @brief Acquire a form provider remote object.
   * @return Returns form provider remote object.
   */
  sptr<IRemoteObject> Ability::GetFormRemoteObject()
  {
      APP_LOGI("%{public}s start", __func__);
      if(providerRemoteObject_ == nullptr) {
          sptr<FormProviderClient> providerClient = new (std::nothrow) FormProviderClient();
          std::shared_ptr<Ability> thisAbility = this->shared_from_this();
          if(thisAbility == nullptr) {
              APP_LOGE("%{public}s failed, thisAbility is nullptr", __func__);
          }
          providerClient->SetOwner(thisAbility);
          providerRemoteObject_ = providerClient->AsObject();
      }
      APP_LOGI("%{public}s end", __func__);
      return providerRemoteObject_;
  }
  
  }  // namespace AppExecFwk
  }  // namespace OHOS
  