mirror of
https://github.com/openharmony/ability_ability_runtime.git
synced 2026-08-24 22:21:36 -04:00
35bf78b285
Signed-off-by: m00512953 <mingxihua@huawei.com>
195 lines
6.2 KiB
C++
195 lines
6.2 KiB
C++
/*
|
|
* Copyright (c) 2022 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 "js_timer.h"
|
|
|
|
#include <atomic>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "hilog_wrapper.h"
|
|
#include "js_runtime.h"
|
|
#include "js_runtime_utils.h"
|
|
|
|
#ifdef SUPPORT_GRAPHICS
|
|
#include "core/common/container_scope.h"
|
|
#endif
|
|
#ifdef ENABLE_HITRACE
|
|
#include "hitrace/trace.h"
|
|
#endif
|
|
|
|
#ifdef SUPPORT_GRAPHICS
|
|
using OHOS::Ace::ContainerScope;
|
|
#endif
|
|
|
|
namespace OHOS {
|
|
namespace AbilityRuntime {
|
|
namespace {
|
|
std::atomic<uint32_t> g_callbackId(1);
|
|
|
|
class TraceIdScope final {
|
|
public:
|
|
explicit TraceIdScope(const OHOS::HiviewDFX::HiTraceId& traceId) : valid_(traceId.IsValid())
|
|
{
|
|
if (valid_) {
|
|
OHOS::HiviewDFX::HiTrace::SetId(traceId);
|
|
}
|
|
}
|
|
|
|
~TraceIdScope()
|
|
{
|
|
if (valid_) {
|
|
OHOS::HiviewDFX::HiTrace::ClearId();
|
|
}
|
|
}
|
|
|
|
TraceIdScope(const TraceIdScope&) = delete;
|
|
TraceIdScope(TraceIdScope&&) = delete;
|
|
TraceIdScope& operator=(const TraceIdScope&) = delete;
|
|
TraceIdScope& operator=(TraceIdScope&&) = delete;
|
|
|
|
private:
|
|
bool valid_ = false;
|
|
};
|
|
|
|
class JsTimer final {
|
|
public:
|
|
JsTimer(JsRuntime& jsRuntime, const std::shared_ptr<NativeReference>& jsFunction, const std::string &name,
|
|
int64_t interval, bool isInterval)
|
|
: jsRuntime_(jsRuntime), jsFunction_(jsFunction), name_(name), interval_(interval), isInterval_(isInterval)
|
|
{}
|
|
|
|
~JsTimer() = default;
|
|
|
|
void operator()() const
|
|
{
|
|
if (isInterval_) {
|
|
jsRuntime_.PostTask(*this, name_, interval_);
|
|
}
|
|
#ifdef SUPPORT_GRAPHICS
|
|
// call js function
|
|
ContainerScope containerScope(containerScopeId_);
|
|
#endif
|
|
HandleScope handleScope(jsRuntime_);
|
|
|
|
std::vector<NativeValue*> args_;
|
|
args_.reserve(jsArgs_.size());
|
|
for (auto arg : jsArgs_) {
|
|
args_.emplace_back(arg->Get());
|
|
}
|
|
|
|
#ifdef ENABLE_HITRACE
|
|
TraceIdScope traceIdScope(traceId_);
|
|
#endif
|
|
NativeEngine& engine = jsRuntime_.GetNativeEngine();
|
|
engine.CallFunction(engine.CreateUndefined(), jsFunction_->Get(), args_.data(), args_.size());
|
|
}
|
|
|
|
void PushArgs(const std::shared_ptr<NativeReference>& ref)
|
|
{
|
|
jsArgs_.emplace_back(ref);
|
|
}
|
|
|
|
private:
|
|
JsRuntime& jsRuntime_;
|
|
std::shared_ptr<NativeReference> jsFunction_;
|
|
std::vector<std::shared_ptr<NativeReference>> jsArgs_;
|
|
std::string name_;
|
|
int64_t interval_ = 0;
|
|
bool isInterval_ = false;
|
|
#ifdef SUPPORT_GRAPHICS
|
|
int32_t containerScopeId_ = ContainerScope::CurrentId();
|
|
#endif
|
|
#ifdef ENABLE_HITRACE
|
|
OHOS::HiviewDFX::HiTraceId traceId_ = OHOS::HiviewDFX::HiTrace::GetId();
|
|
#endif
|
|
};
|
|
|
|
NativeValue* StartTimeoutOrInterval(NativeEngine* engine, NativeCallbackInfo* info, bool isInterval)
|
|
{
|
|
if (engine == nullptr || info == nullptr) {
|
|
HILOG_ERROR("StartTimeoutOrInterval, engine or callback info is nullptr.");
|
|
return nullptr;
|
|
}
|
|
|
|
// parameter check, must have at least 2 params
|
|
if (info->argc < 2 || info->argv[0]->TypeOf() != NATIVE_FUNCTION || info->argv[1]->TypeOf() != NATIVE_NUMBER) {
|
|
HILOG_ERROR("Set callback timer failed with invalid parameter.");
|
|
return engine->CreateUndefined();
|
|
}
|
|
|
|
// parse parameter
|
|
std::shared_ptr<NativeReference> jsFunction(engine->CreateReference(info->argv[0], 1));
|
|
int64_t delayTime = *ConvertNativeValueTo<NativeNumber>(info->argv[1]);
|
|
uint32_t callbackId = g_callbackId.fetch_add(1, std::memory_order_relaxed);
|
|
std::string name = "JsRuntimeTimer_";
|
|
name.append(std::to_string(callbackId));
|
|
|
|
// create timer task
|
|
JsRuntime& jsRuntime = *reinterpret_cast<JsRuntime*>(engine->GetJsEngine());
|
|
JsTimer task(jsRuntime, jsFunction, name, delayTime, isInterval);
|
|
for (size_t index = 2; index < info->argc; ++index) {
|
|
task.PushArgs(std::shared_ptr<NativeReference>(engine->CreateReference(info->argv[index], 1)));
|
|
}
|
|
|
|
jsRuntime.PostTask(task, name, delayTime);
|
|
return engine->CreateNumber(callbackId);
|
|
}
|
|
|
|
NativeValue* StartTimeout(NativeEngine* engine, NativeCallbackInfo* info)
|
|
{
|
|
return StartTimeoutOrInterval(engine, info, false);
|
|
}
|
|
|
|
NativeValue* StartInterval(NativeEngine* engine, NativeCallbackInfo* info)
|
|
{
|
|
return StartTimeoutOrInterval(engine, info, true);
|
|
}
|
|
|
|
NativeValue* StopTimeoutOrInterval(NativeEngine* engine, NativeCallbackInfo* info)
|
|
{
|
|
if (engine == nullptr || info == nullptr) {
|
|
HILOG_ERROR("Stop timeout or interval failed with engine or callback info is nullptr.");
|
|
return nullptr;
|
|
}
|
|
|
|
// parameter check, must have at least 1 param
|
|
if (info->argc < 1 || info->argv[0]->TypeOf() != NATIVE_NUMBER) {
|
|
HILOG_ERROR("Clear callback timer failed with invalid parameter.");
|
|
return engine->CreateUndefined();
|
|
}
|
|
|
|
uint32_t callbackId = *ConvertNativeValueTo<NativeNumber>(info->argv[0]);
|
|
std::string name = "JsRuntimeTimer_";
|
|
name.append(std::to_string(callbackId));
|
|
|
|
// event should be cancelable before executed
|
|
JsRuntime& jsRuntime = *reinterpret_cast<JsRuntime*>(engine->GetJsEngine());
|
|
jsRuntime.RemoveTask(name);
|
|
return engine->CreateUndefined();
|
|
}
|
|
}
|
|
|
|
void InitTimerModule(NativeEngine& engine, NativeObject& globalObject)
|
|
{
|
|
HILOG_DEBUG("InitTimerModule begin.");
|
|
const char *moduleName = "JsTimer";
|
|
BindNativeFunction(engine, globalObject, "setTimeout", moduleName, StartTimeout);
|
|
BindNativeFunction(engine, globalObject, "setInterval", moduleName, StartInterval);
|
|
BindNativeFunction(engine, globalObject, "clearTimeout", moduleName, StopTimeoutOrInterval);
|
|
BindNativeFunction(engine, globalObject, "clearInterval", moduleName, StopTimeoutOrInterval);
|
|
}
|
|
} // namespace AbilityRuntime
|
|
} // namespace OHOS
|