* Copyright (C) 2024 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.
*/
#ifndef OHOS_REQUEST_DOWNLOAD_MANAGER_IMPL_H
#define OHOS_REQUEST_DOWNLOAD_MANAGER_IMPL_H
#include <atomic>
#include <condition_variable>
#include <map>
#include <mutex>
#include <vector>
#include "constant.h"
#include "i_notify_data_listener.h"
#include "i_response_message_handler.h"
#include "iremote_object.h"
#include "iservice_registry.h"
#include "log.h"
#include "refbase.h"
#include "request.h"
#include "request_common.h"
#include "request_service_interface.h"
#include "response_message_receiver.h"
#include "system_ability_status_change_stub.h"
#include "visibility.h"
namespace OHOS::Request {
constexpr int RETRY_TIMES = 5;
class RequestManagerImpl : public IResponseMessageHandler {
public:
static const std::unique_ptr<RequestManagerImpl> &GetInstance();
ExceptionErrorCode CreateTasks(const std::vector<Config> &configs, std::vector<TaskRet> &rets);
ExceptionErrorCode StartTasks(const std::vector<std::string> &tids, std::vector<ExceptionErrorCode> &rets);
ExceptionErrorCode StopTasks(const std::vector<std::string> &tids, std::vector<ExceptionErrorCode> &rets);
ExceptionErrorCode ResumeTasks(const std::vector<std::string> &tids, std::vector<ExceptionErrorCode> &rets);
ExceptionErrorCode RemoveTasks(
const std::vector<std::string> &tids, const Version version, std::vector<ExceptionErrorCode> &rets);
ExceptionErrorCode PauseTasks(
const std::vector<std::string> &tids, const Version version, std::vector<ExceptionErrorCode> &rets);
ExceptionErrorCode QueryTasks(const std::vector<std::string> &tids, std::vector<TaskInfoRet> &rets);
ExceptionErrorCode ShowTasks(const std::vector<std::string> &tids, std::vector<TaskInfoRet> &rets);
ExceptionErrorCode TouchTasks(const std::vector<TaskIdAndToken> &tids, std::vector<TaskInfoRet> &rets);
ExceptionErrorCode SetMaxSpeeds(const std::vector<SpeedConfig> &speedConfig, std::vector<ExceptionErrorCode> &rets);
ExceptionErrorCode SetMode(const std::string &tid, const Mode mode);
ExceptionErrorCode DisableTaskNotification(
const std::vector<std::string> &tids, std::vector<ExceptionErrorCode> &rets);
int32_t Create(const Config &config, int32_t seq, std::string &tid);
int32_t GetTask(const std::string &tid, const std::string &token, Config &config);
int32_t Start(const std::string &tid);
int32_t Stop(const std::string &tid);
int32_t Query(const std::string &tid, TaskInfo &info);
int32_t Touch(const std::string &tid, const std::string &token, TaskInfo &info);
int32_t Search(const Filter &filter, std::vector<std::string> &tids);
int32_t Show(const std::string &tid, TaskInfo &info);
int32_t Pause(const std::string &tid, const Version version);
int32_t QueryMimeType(const std::string &tid, std::string &mimeType);
int32_t Remove(const std::string &tid, const Version version);
int32_t Resume(const std::string &tid);
int32_t SetMaxSpeed(const std::string &tid, const int64_t maxSpeed);
int32_t Subscribe(const std::string &taskId);
int32_t Unsubscribe(const std::string &taskId);
int32_t AddListener(
const std::string &taskId, const SubscribeType &type, const std::shared_ptr<IResponseListener> &listener);
int32_t RemoveListener(
const std::string &taskId, const SubscribeType &type, const std::shared_ptr<IResponseListener> &listener);
int32_t AddListener(
const std::string &taskId, const SubscribeType &type, const std::shared_ptr<INotifyDataListener> &listener);
int32_t RemoveListener(
const std::string &taskId, const SubscribeType &type, const std::shared_ptr<INotifyDataListener> &listener);
void RemoveAllListeners(const std::string &taskId);
int32_t SubRunCount(const sptr<NotifyInterface> &listener);
int32_t UnsubRunCount();
void RestoreListener(void (*callback)());
void RestoreSubRunCount();
void LoadRequestServer();
bool IsSaReady();
void ReopenChannel();
int32_t GetNextSeq();
bool SubscribeSA();
bool UnsubscribeSA();
int32_t CreateGroup(
std::string &gid, const bool gauge, Notification ¬ification);
int32_t AttachGroup(const std::string &gid, const std::vector<std::string> &tids);
int32_t DeleteGroup(const std::string &gid);
private:
RequestManagerImpl() = default;
RequestManagerImpl(const RequestManagerImpl &) = delete;
RequestManagerImpl(RequestManagerImpl &&) = delete;
RequestManagerImpl &operator=(const RequestManagerImpl &) = delete;
sptr<RequestServiceInterface> GetRequestServiceProxy(bool load);
int32_t EnsureChannelOpen();
std::shared_ptr<Request> GetTask(const std::string &taskId);
void OnChannelBroken() override;
void OnResponseReceive(const std::shared_ptr<Response> &response) override;
void OnNotifyDataReceive(const std::shared_ptr<NotifyData> ¬ifyData) override;
void OnFaultsReceive(const std::shared_ptr<int32_t> &tid, const std::shared_ptr<SubscribeType> &type,
const std::shared_ptr<Reason> &reason) override;
void OnWaitReceive(std::int32_t taskId, WaitingReason reason) override;
private:
std::mutex serviceProxyMutex_;
std::mutex saChangeListenerMutex_;
sptr<RequestServiceInterface> requestServiceProxy_;
sptr<ISystemAbilityStatusChange> saChangeListener_;
static constexpr int LOAD_SA_TIMEOUT_MS = 15000;
void (*callback_)() = nullptr;
std::mutex tasksMutex_;
std::map<std::string, std::shared_ptr<Request>> tasks_;
std::recursive_mutex msgReceiverMutex_;
std::shared_ptr<ResponseMessageReceiver> msgReceiver_;
class SystemAbilityStatusChangeListener : public OHOS::SystemAbilityStatusChangeStub {
public:
SystemAbilityStatusChangeListener();
~SystemAbilityStatusChangeListener() = default;
virtual void OnAddSystemAbility(int32_t saId, const std::string &deviceId) override;
virtual void OnRemoveSystemAbility(int32_t asId, const std::string &deviceId) override;
};
template<typename ProxyMethod, typename... Args> int32_t CallProxyMethod(ProxyMethod method, Args &&...args)
{
int32_t ret = E_SERVICE_ERROR;
for (int i = 0; i < RETRY_TIMES; i++) {
auto proxy = this->GetRequestServiceProxy(true);
if (proxy == nullptr) {
REQUEST_HILOGE("Get service proxy failed");
continue;
}
ret = (proxy->*method)(args...);
if (ret == E_SERVICE_ERROR) {
REQUEST_HILOGE("Remote died, retry times: %{public}d", i);
{
std::lock_guard<std::mutex> lock(serviceProxyMutex_);
requestServiceProxy_ = nullptr;
}
continue;
}
break;
}
return ret;
}
};
}
#endif