* 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 REQUEST_PRE_DOWNLOAD_MODULE_H
#define REQUEST_PRE_DOWNLOAD_MODULE_H
#include <list>
#include <map>
#include "napi/native_api.h"
#include "napi/native_common.h"
#include "napi/native_node_api.h"
namespace OHOS::Request {
enum class ErrorCode: uint32_t {
OTHERS = 0xFF,
DNS = 0x00,
TCP = 0x10,
SSL = 0x20,
HTTP = 0x30,
};
struct DownloadError {
const ErrorCode errorCode;
const std::string message;
DownloadError(ErrorCode code, const std::string& msg) : errorCode(code), message(msg) {}
};
enum class CallbackType {
SUCCESS,
ERROR
};
* @brief Registry of JS callbacks registered for one URL and one callback
* type (success or error).
*
* Holds strong references (napi_ref) to every registered JS function. Removals
* requested while an invocation is in flight are deferred: the entry is marked
* inactive and physically removed once the invocation finishes.
*/
class CallbackInfo {
friend class CallbackManager;
public:
CallbackInfo(napi_env env, const std::string &url)
: env_(env), url_(url)
{
}
napi_status RemoveCallback(napi_value cb);
napi_status RegisterCallback(napi_value cb);
void InvokeSuccessCallbacks(napi_value values[]);
void InvokeErrorCallbacks(napi_value values[]);
protected:
const napi_env env_;
const std::string url_;
std::list<std::pair<bool, napi_ref>> allCb_;
std::recursive_mutex allCbMutex_;
std::atomic<uint32_t> validCbNum{ 0 };
bool isInvoked_{ false };
size_t toDeleteCount_{ 0 };
void CleanupCallbacks();
};
class Data;
* @brief Process-wide registry of cache download callbacks, keyed by URL.
*
* Keeps two maps (success and error) of per-URL CallbackInfo. Native download
* completion arrives on non-JS threads, so invocation is scheduled onto the JS
* thread with napi_send_event before any JS function is called.
*/
class CallbackManager {
public:
static CallbackManager &GetInstance();
napi_status RegisterCallback(const std::string& url, CallbackType type, napi_env env, napi_value callback);
napi_status RemoveCallback(const std::string& url, CallbackType type, napi_env env, napi_value callback);
void InvokeSuccessCallbacks(const std::string& url,
std::shared_ptr<Data> data, napi_env env, const std::string& taskId);
void InvokeErrorCallbacks(const std::string& url,
std::shared_ptr<DownloadError> error, napi_env env, const std::string& taskId);
private:
CallbackManager() = default;
CallbackManager(const CallbackManager&) = delete;
CallbackManager& operator=(const CallbackManager&) = delete;
std::recursive_mutex mgrMutex_;
std::map<std::string, std::shared_ptr<CallbackInfo>> successCallbacks_;
std::map<std::string, std::shared_ptr<CallbackInfo>> errorCallbacks_;
};
}
#endif