mirror of
https://gitee.com/openharmony/ability_ability_runtime
synced 2024-12-24 18:06:22 +00:00
Signed-off-by: m00512953 <mingxihua@huawei.com>
This commit is contained in:
parent
098f41f70a
commit
15575b77d4
frameworks
js/napi
app
featureAbility
wantagent
native
simulator/ability_simulator/src
interfaces/inner_api
services/abilitymgr/src
@ -960,7 +960,7 @@ NativeValue *JSAbilityDelegator::ParseAbilityMonitorPara(
|
||||
|
||||
if (info.argc > ARGC_ONE) {
|
||||
if (info.argv[INDEX_ONE]->TypeOf() != NativeValueType::NATIVE_FUNCTION) {
|
||||
HILOG_ERROR("Parse callback parameters failed");
|
||||
HILOG_ERROR("ParseAbilityMonitorPara, Parse callback parameters failed");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@ -983,7 +983,7 @@ NativeValue *JSAbilityDelegator::ParseAbilityStageMonitorPara(
|
||||
|
||||
if (info.argc > ARGC_ONE) {
|
||||
if (info.argv[INDEX_ONE]->TypeOf() != NativeValueType::NATIVE_FUNCTION) {
|
||||
HILOG_ERROR("Parse callback parameters failed");
|
||||
HILOG_ERROR("ParseAbilityStageMonitorPara, Parse callback parameters failed");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -12,11 +12,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "native_engine/native_engine.h"
|
||||
|
||||
#ifndef OHOS_ABILITY_RUNTIME_JS_APP_MANAGER_H
|
||||
#define OHOS_ABILITY_RUNTIME_JS_APP_MANAGER_H
|
||||
|
||||
#include "native_engine/native_engine.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
NativeValue* JsAppManagerInit(NativeEngine* engine, NativeValue* exportObj);
|
||||
|
@ -13,13 +13,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_ABILITY_RUNTIME_JS_APP_STATE_OBSERVER_H
|
||||
#define OHOS_ABILITY_RUNTIME_JS_APP_STATE_OBSERVER_H
|
||||
|
||||
#include "application_state_observer_stub.h"
|
||||
#include "native_engine/native_engine.h"
|
||||
#include "event_handler.h"
|
||||
|
||||
#ifndef OHOS_ABILITY_RUNTIME_JS_APP_STATE_OBSERVER_H
|
||||
#define OHOS_ABILITY_RUNTIME_JS_APP_STATE_OBSERVER_H
|
||||
|
||||
namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
using OHOS::AppExecFwk::ApplicationStateObserverStub;
|
||||
|
@ -407,7 +407,7 @@ napi_value SetResultPromise(napi_env env, AsyncCallbackInfo *asyncCallbackInfo)
|
||||
{
|
||||
HILOG_INFO("%{public}s, promise.", __func__);
|
||||
if (asyncCallbackInfo == nullptr) {
|
||||
HILOG_ERROR("%{public}s, param == nullptr.", __func__);
|
||||
HILOG_ERROR("SetResultPromise, param == nullptr.");
|
||||
return nullptr;
|
||||
}
|
||||
napi_value resourceName = 0;
|
||||
@ -575,7 +575,7 @@ napi_value TerminateAbilityPromise(napi_env env, AsyncCallbackInfo *asyncCallbac
|
||||
{
|
||||
HILOG_INFO("%{public}s, promise.", __func__);
|
||||
if (asyncCallbackInfo == nullptr) {
|
||||
HILOG_ERROR("%{public}s, param == nullptr.", __func__);
|
||||
HILOG_ERROR("TerminateAbilityPromise, param == nullptr.");
|
||||
return nullptr;
|
||||
}
|
||||
napi_value resourceName = 0;
|
||||
@ -765,7 +765,7 @@ napi_value HasWindowFocusPromise(napi_env env, AsyncCallbackInfo *asyncCallbackI
|
||||
{
|
||||
HILOG_INFO("%{public}s, promise.", __func__);
|
||||
if (asyncCallbackInfo == nullptr) {
|
||||
HILOG_ERROR("%{public}s, param == nullptr.", __func__);
|
||||
HILOG_ERROR("HasWindowFocusPromise, param == nullptr.");
|
||||
return nullptr;
|
||||
}
|
||||
napi_value resourceName = 0;
|
||||
@ -1090,7 +1090,7 @@ napi_value GetWindowWrapPromise(napi_env env, AsyncCallbackInfo *asyncCallbackIn
|
||||
{
|
||||
HILOG_INFO("%{public}s, promise.", __func__);
|
||||
if (asyncCallbackInfo == nullptr) {
|
||||
HILOG_ERROR("%{public}s, param == nullptr.", __func__);
|
||||
HILOG_ERROR("GetWindowWrapPromise, param == nullptr.");
|
||||
return nullptr;
|
||||
}
|
||||
napi_value resourceName = 0;
|
||||
|
@ -924,7 +924,7 @@ napi_value NAPI_Trigger(napi_env env, napi_callback_info info)
|
||||
size_t argc = NUMBER_OF_PARAMETERS_THREE;
|
||||
napi_value argv[NUMBER_OF_PARAMETERS_THREE] = {};
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
|
||||
HILOG_INFO("argc = [%{public}zu]", argc);
|
||||
HILOG_DEBUG("argc = [%{public}zu]", argc);
|
||||
|
||||
napi_valuetype wantAgentType = napi_valuetype::napi_null;
|
||||
napi_typeof(env, argv[0], &wantAgentType);
|
||||
@ -1075,7 +1075,7 @@ napi_value NAPI_Equal(napi_env env, napi_callback_info info)
|
||||
size_t argc = NUMBER_OF_PARAMETERS_THREE;
|
||||
napi_value argv[NUMBER_OF_PARAMETERS_THREE] = {};
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
|
||||
HILOG_INFO("argc = [%{public}zu]", argc);
|
||||
HILOG_DEBUG("argc = [%{public}zu]", argc);
|
||||
|
||||
napi_valuetype wantAgentFirstType = napi_valuetype::napi_null;
|
||||
napi_typeof(env, argv[0], &wantAgentFirstType);
|
||||
|
@ -156,7 +156,7 @@ void JsAbilityStage::OnCreate(const AAFwk::Want &want) const
|
||||
NativeValue* value = jsAbilityStageObj_->Get();
|
||||
NativeObject* obj = ConvertNativeValueTo<NativeObject>(value);
|
||||
if (obj == nullptr) {
|
||||
HILOG_ERROR("Failed to get AbilityStage object");
|
||||
HILOG_ERROR("OnCreate, Failed to get AbilityStage object");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -248,7 +248,7 @@ void JsAbilityStage::OnMemoryLevel(int32_t level)
|
||||
NativeValue* value = jsAbilityStageObj_->Get();
|
||||
NativeObject* obj = ConvertNativeValueTo<NativeObject>(value);
|
||||
if (obj == nullptr) {
|
||||
HILOG_ERROR("Failed to get AbilityStage object");
|
||||
HILOG_ERROR("OnMemoryLevel, Failed to get AbilityStage object");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "js_data_struct_converter.h"
|
||||
|
||||
#include "configuration_convertor.h"
|
||||
#include "hilog_wrapper.h"
|
||||
#include "js_runtime.h"
|
||||
#include "js_runtime_utils.h"
|
||||
|
||||
@ -222,6 +223,7 @@ NativeValue* CreateJsConfiguration(NativeEngine& engine, const AppExecFwk::Confi
|
||||
|
||||
NativeValue* CreateJsExtensionAbilityInfo(NativeEngine& engine, const AppExecFwk::ExtensionAbilityInfo& info)
|
||||
{
|
||||
HILOG_DEBUG("CreateJsExtensionAbilityInfo begin");
|
||||
NativeValue* objValue = engine.CreateObject();
|
||||
NativeObject* object = ConvertNativeValueTo<NativeObject>(objValue);
|
||||
if (object == nullptr) {
|
||||
@ -249,6 +251,7 @@ NativeValue* CreateJsExtensionAbilityInfo(NativeEngine& engine, const AppExecFwk
|
||||
object->SetProperty("enabled", CreateJsValue(engine, info.enabled));
|
||||
object->SetProperty("readPermission", CreateJsValue(engine, info.readPermission));
|
||||
object->SetProperty("writePermission", CreateJsValue(engine, info.writePermission));
|
||||
HILOG_DEBUG("CreateJsExtensionAbilityInfo end");
|
||||
return objValue;
|
||||
}
|
||||
} // namespace AbilityRuntime
|
||||
|
@ -184,6 +184,7 @@ NativeValue* StopTimeoutOrInterval(NativeEngine* engine, NativeCallbackInfo* inf
|
||||
|
||||
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);
|
||||
|
@ -54,7 +54,7 @@ int32_t PrintVmLog(int32_t, int32_t, const char*, const char*, const char* messa
|
||||
}
|
||||
|
||||
struct DebuggerTask {
|
||||
void OnPostTask(std::function<void()>&& task);
|
||||
void OnPostTask(std::function<void()>&& task) const;
|
||||
|
||||
static void HandleTask(const uv_async_t* req);
|
||||
|
||||
@ -125,7 +125,7 @@ void DebuggerTask::HandleTask(const uv_async_t* req)
|
||||
debuggerTask->func();
|
||||
}
|
||||
|
||||
void DebuggerTask::OnPostTask(std::function<void()>&& task)
|
||||
void DebuggerTask::OnPostTask(std::function<void()>&& task) const
|
||||
{
|
||||
if (uv_is_active((uv_handle_t*)&onPostTaskSignal)) {
|
||||
func = std::move(task);
|
||||
|
@ -59,17 +59,8 @@ struct AbilityTransitionInfo : public Parcelable {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!abilityToken_) {
|
||||
if (!parcel.WriteBool(false)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!parcel.WriteBool(true)) {
|
||||
return false;
|
||||
}
|
||||
if (!parcel.WriteObject(abilityToken_)) {
|
||||
return false;
|
||||
}
|
||||
if (!WriteAbilityToken(parcel)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(parcel.WriteUint64(displayId_) && parcel.WriteBool(isShowWhenLocked_) && parcel.WriteBool(isRecent_))) {
|
||||
@ -102,6 +93,24 @@ struct AbilityTransitionInfo : public Parcelable {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteAbilityToken(Parcel& parcel) const
|
||||
{
|
||||
if (!abilityToken_) {
|
||||
if (!parcel.WriteBool(false)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!parcel.WriteBool(true)) {
|
||||
return false;
|
||||
}
|
||||
if (!parcel.WriteObject(abilityToken_)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteWindowInfo(Parcel& parcel) const
|
||||
{
|
||||
return (parcel.WriteDouble(maxWindowRatio_) && parcel.WriteDouble(minWindowRatio_) &&
|
||||
|
@ -85,17 +85,17 @@ ErrCode WantAgentClient::SendWantSender(const sptr<IWantSender> &target, const S
|
||||
return INNER_ERR;
|
||||
}
|
||||
if (target == nullptr || !data.WriteRemoteObject(target->AsObject())) {
|
||||
HILOG_ERROR("target write failed.");
|
||||
HILOG_ERROR("SendWantSender, target write failed.");
|
||||
return INNER_ERR;
|
||||
}
|
||||
if (!data.WriteParcelable(&senderInfo)) {
|
||||
HILOG_ERROR("senderInfo write failed.");
|
||||
HILOG_ERROR("SendWantSender, senderInfo write failed.");
|
||||
return INNER_ERR;
|
||||
}
|
||||
|
||||
auto error = abms->SendRequest(IAbilityManager::SEND_PENDING_WANT_SENDER, data, reply, option);
|
||||
if (error != NO_ERROR) {
|
||||
HILOG_ERROR("Send request error: %{public}d", error);
|
||||
HILOG_ERROR("SendWantSender, Send request error: %{public}d", error);
|
||||
return error;
|
||||
}
|
||||
return reply.ReadInt32();
|
||||
@ -191,7 +191,7 @@ void WantAgentClient::RegisterCancelListener(const sptr<IWantSender> &sender, co
|
||||
}
|
||||
auto abms = GetAbilityManager();
|
||||
if (!abms) {
|
||||
HILOG_ERROR("ability proxy is nullptr.");
|
||||
HILOG_ERROR("RegisterCancelListener, ability proxy is nullptr.");
|
||||
return;
|
||||
}
|
||||
MessageParcel data;
|
||||
@ -201,16 +201,16 @@ void WantAgentClient::RegisterCancelListener(const sptr<IWantSender> &sender, co
|
||||
return;
|
||||
}
|
||||
if (!data.WriteRemoteObject(sender->AsObject())) {
|
||||
HILOG_ERROR("sender write failed.");
|
||||
HILOG_ERROR("RegisterCancelListener, sender write failed.");
|
||||
return;
|
||||
}
|
||||
if (!data.WriteRemoteObject(receiver->AsObject())) {
|
||||
HILOG_ERROR("receiver write failed.");
|
||||
HILOG_ERROR("RegisterCancelListener, receiver write failed.");
|
||||
return;
|
||||
}
|
||||
auto error = abms->SendRequest(IAbilityManager::REGISTER_CANCEL_LISTENER, data, reply, option);
|
||||
if (error != NO_ERROR) {
|
||||
HILOG_ERROR("Send request error: %{public}d", error);
|
||||
HILOG_ERROR("RegisterCancelListener, Send request error: %{public}d", error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -223,7 +223,7 @@ void WantAgentClient::UnregisterCancelListener(
|
||||
}
|
||||
auto abms = GetAbilityManager();
|
||||
if (!abms) {
|
||||
HILOG_ERROR("ability proxy is nullptr.");
|
||||
HILOG_ERROR("UnregisterCancelListener, ability proxy is nullptr.");
|
||||
return;
|
||||
}
|
||||
MessageParcel data;
|
||||
@ -233,16 +233,16 @@ void WantAgentClient::UnregisterCancelListener(
|
||||
return;
|
||||
}
|
||||
if (!data.WriteRemoteObject(sender->AsObject())) {
|
||||
HILOG_ERROR("sender write failed.");
|
||||
HILOG_ERROR("UnregisterCancelListener, sender write failed.");
|
||||
return;
|
||||
}
|
||||
if (!data.WriteRemoteObject(receiver->AsObject())) {
|
||||
HILOG_ERROR("receiver write failed.");
|
||||
HILOG_ERROR("UnregisterCancelListener, receiver write failed.");
|
||||
return;
|
||||
}
|
||||
auto error = abms->SendRequest(IAbilityManager::UNREGISTER_CANCEL_LISTENER, data, reply, option);
|
||||
if (error != NO_ERROR) {
|
||||
HILOG_ERROR("Send request error: %{public}d", error);
|
||||
HILOG_ERROR("UnregisterCancelListener, Send request error: %{public}d", error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -260,21 +260,21 @@ ErrCode WantAgentClient::GetPendingRequestWant(const sptr<IWantSender> &target,
|
||||
return INNER_ERR;
|
||||
}
|
||||
if (!data.WriteRemoteObject(target->AsObject())) {
|
||||
HILOG_ERROR("target write failed.");
|
||||
HILOG_ERROR("GetPendingRequestWant, target write failed.");
|
||||
return INNER_ERR;
|
||||
}
|
||||
if (!data.WriteParcelable(want.get())) {
|
||||
HILOG_ERROR("want write failed.");
|
||||
HILOG_ERROR("GetPendingRequestWant, want write failed.");
|
||||
return INNER_ERR;
|
||||
}
|
||||
auto error = abms->SendRequest(IAbilityManager::GET_PENDING_REQUEST_WANT, data, reply, option);
|
||||
if (error != NO_ERROR) {
|
||||
HILOG_ERROR("Send request error: %{public}d", error);
|
||||
HILOG_ERROR("GetPendingRequestWant, Send request error: %{public}d", error);
|
||||
return error;
|
||||
}
|
||||
std::unique_ptr<Want> wantInfo(reply.ReadParcelable<Want>());
|
||||
if (!wantInfo) {
|
||||
HILOG_ERROR("readParcelableInfo failed");
|
||||
HILOG_ERROR("GetPendingRequestWant, readParcelableInfo failed");
|
||||
return INNER_ERR;
|
||||
}
|
||||
want = std::move(wantInfo);
|
||||
@ -295,21 +295,21 @@ ErrCode WantAgentClient::GetWantSenderInfo(const sptr<IWantSender> &target, std:
|
||||
return INNER_ERR;
|
||||
}
|
||||
if (!data.WriteRemoteObject(target->AsObject())) {
|
||||
HILOG_ERROR("target write failed.");
|
||||
HILOG_ERROR("GetWantSenderInfo, target write failed.");
|
||||
return INNER_ERR;
|
||||
}
|
||||
if (!data.WriteParcelable(info.get())) {
|
||||
HILOG_ERROR("info write failed.");
|
||||
HILOG_ERROR("GetWantSenderInfo, info write failed.");
|
||||
return INNER_ERR;
|
||||
}
|
||||
auto error = abms->SendRequest(IAbilityManager::GET_PENDING_WANT_SENDER_INFO, data, reply, option);
|
||||
if (error != NO_ERROR) {
|
||||
HILOG_ERROR("Send request error: %{public}d", error);
|
||||
HILOG_ERROR("GetWantSenderInfo, Send request error: %{public}d", error);
|
||||
return error;
|
||||
}
|
||||
std::unique_ptr<WantSenderInfo> wantSenderInfo(reply.ReadParcelable<WantSenderInfo>());
|
||||
if (!wantSenderInfo) {
|
||||
HILOG_ERROR("readParcelable Info failed");
|
||||
HILOG_ERROR("GetWantSenderInfo, readParcelable Info failed");
|
||||
return INNER_ERR;
|
||||
}
|
||||
info = std::move(wantSenderInfo);
|
||||
|
@ -252,19 +252,19 @@ bool ConnectionStateItem::AddConnection(const std::shared_ptr<ConnectionRecord>
|
||||
AbilityRuntime::ConnectionData &data)
|
||||
{
|
||||
if (!record) {
|
||||
HILOG_ERROR("invalid connection record.");
|
||||
HILOG_ERROR("AddConnection, invalid connection record.");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto token = record->GetTargetToken();
|
||||
if (!token) {
|
||||
HILOG_ERROR("invalid token.");
|
||||
HILOG_ERROR("AddConnection, invalid token.");
|
||||
return false;
|
||||
}
|
||||
|
||||
sptr<IRemoteObject> connectionObj = record->GetConnection();
|
||||
if (!connectionObj) {
|
||||
HILOG_ERROR("no connection callback for this connect.");
|
||||
HILOG_ERROR("AddConnection, no connection callback for this connect.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -280,7 +280,7 @@ bool ConnectionStateItem::AddConnection(const std::shared_ptr<ConnectionRecord>
|
||||
}
|
||||
|
||||
if (!connectedExtension) {
|
||||
HILOG_ERROR("connectedExtension is invalid");
|
||||
HILOG_ERROR("AddConnection, connectedExtension is invalid");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -296,31 +296,31 @@ bool ConnectionStateItem::RemoveConnection(const std::shared_ptr<ConnectionRecor
|
||||
AbilityRuntime::ConnectionData &data)
|
||||
{
|
||||
if (!record) {
|
||||
HILOG_ERROR("invalid connection record.");
|
||||
HILOG_ERROR("RemoveConnection, invalid connection record.");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto token = record->GetTargetToken();
|
||||
if (!token) {
|
||||
HILOG_ERROR("invalid token.");
|
||||
HILOG_ERROR("RemoveConnection, invalid token.");
|
||||
return false;
|
||||
}
|
||||
|
||||
sptr<IRemoteObject> connectionObj = record->GetConnection();
|
||||
if (!connectionObj) {
|
||||
HILOG_ERROR("no connection callback for this connect.");
|
||||
HILOG_ERROR("RemoveConnection, no connection callback for this connect.");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto it = connectionMap_.find(token);
|
||||
if (it == connectionMap_.end()) {
|
||||
HILOG_ERROR("no such connectedExtension.");
|
||||
HILOG_ERROR("RemoveConnection, no such connectedExtension.");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto connectedExtension = it->second;
|
||||
if (!connectedExtension) {
|
||||
HILOG_ERROR("can not find such connectedExtension");
|
||||
HILOG_ERROR("RemoveConnection, can not find such connectedExtension");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -375,25 +375,25 @@ bool ConnectionStateItem::RemoveDataAbilityConnection(const DataAbilityCaller &c
|
||||
const std::shared_ptr<DataAbilityRecord> &dataAbility, AbilityRuntime::ConnectionData &data)
|
||||
{
|
||||
if (!dataAbility) {
|
||||
HILOG_ERROR("invalid data ability record.");
|
||||
HILOG_ERROR("RemoveDataAbilityConnection, invalid data ability record.");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto token = dataAbility->GetToken();
|
||||
if (!token) {
|
||||
HILOG_ERROR("invalid data ability token.");
|
||||
HILOG_ERROR("RemoveDataAbilityConnection, invalid data ability token.");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto it = dataAbilityMap_.find(token);
|
||||
if (it == dataAbilityMap_.end()) {
|
||||
HILOG_ERROR("no such connected data ability.");
|
||||
HILOG_ERROR("RemoveDataAbilityConnection, no such connected data ability.");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto connectedDataAbility = it->second;
|
||||
if (!connectedDataAbility) {
|
||||
HILOG_ERROR("can not find such connectedDataAbility");
|
||||
HILOG_ERROR("RemoveDataAbilityConnection, can not find such connectedDataAbility");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -415,13 +415,13 @@ bool ConnectionStateItem::HandleDataAbilityDied(const sptr<IRemoteObject> &token
|
||||
|
||||
auto it = dataAbilityMap_.find(token);
|
||||
if (it == dataAbilityMap_.end()) {
|
||||
HILOG_ERROR("no such connected data ability.");
|
||||
HILOG_ERROR("HandleDataAbilityDied, no such connected data ability.");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto connectedDataAbility = it->second;
|
||||
if (!connectedDataAbility) {
|
||||
HILOG_ERROR("can not find such connectedDataAbility");
|
||||
HILOG_ERROR("HandleDataAbilityDied, can not find such connectedDataAbility");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user