19596a2c1Sopenharmony_ci/*
29596a2c1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
39596a2c1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
49596a2c1Sopenharmony_ci * you may not use this file except in compliance with the License.
59596a2c1Sopenharmony_ci * You may obtain a copy of the License at
69596a2c1Sopenharmony_ci *
79596a2c1Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
89596a2c1Sopenharmony_ci *
99596a2c1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
109596a2c1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
119596a2c1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129596a2c1Sopenharmony_ci * See the License for the specific language governing permissions and
139596a2c1Sopenharmony_ci * limitations under the License.
149596a2c1Sopenharmony_ci */
159596a2c1Sopenharmony_ci
169596a2c1Sopenharmony_ci#include "accesstoken_kit.h"
179596a2c1Sopenharmony_ci#include "i18n_hilog.h"
189596a2c1Sopenharmony_ci#include "ipc_skeleton.h"
199596a2c1Sopenharmony_ci#include "mem_mgr_client.h"
209596a2c1Sopenharmony_ci#include "mem_mgr_proxy.h"
219596a2c1Sopenharmony_ci#include "system_ability_definition.h"
229596a2c1Sopenharmony_ci#include "tokenid_kit.h"
239596a2c1Sopenharmony_ci#include "i18n_service_ability_stub.h"
249596a2c1Sopenharmony_ci
259596a2c1Sopenharmony_cinamespace OHOS {
269596a2c1Sopenharmony_cinamespace Global {
279596a2c1Sopenharmony_cinamespace I18n {
289596a2c1Sopenharmony_ciI18nServiceAbilityStub::I18nServiceAbilityStub(bool serialInvokeFlag)
299596a2c1Sopenharmony_ci    : IRemoteStub<II18nServiceAbility>(serialInvokeFlag)
309596a2c1Sopenharmony_ci{
319596a2c1Sopenharmony_ci    HILOG_INFO_I18N("I18nServiceAbilityStub object init success.");
329596a2c1Sopenharmony_ci}
339596a2c1Sopenharmony_ci
349596a2c1Sopenharmony_ciI18nServiceAbilityStub::~I18nServiceAbilityStub()
359596a2c1Sopenharmony_ci{
369596a2c1Sopenharmony_ci    HILOG_INFO_I18N("I18nServiceAbilityStub object release.");
379596a2c1Sopenharmony_ci}
389596a2c1Sopenharmony_ci
399596a2c1Sopenharmony_ciint32_t I18nServiceAbilityStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
409596a2c1Sopenharmony_ci    MessageOption &option)
419596a2c1Sopenharmony_ci{
429596a2c1Sopenharmony_ci    HILOG_INFO_I18N("I18nServiceAbilityStub::OnRemoteRequest process request for code=%{public}u", code);
439596a2c1Sopenharmony_ci    // check whether request's descriptor is consistent with sa's descriptor
449596a2c1Sopenharmony_ci    std::u16string descriptor = GetDescriptor();
459596a2c1Sopenharmony_ci    std::u16string remoteDescriptor = data.ReadInterfaceToken();
469596a2c1Sopenharmony_ci    if (descriptor != remoteDescriptor) {
479596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("I18nServiceAbilityStub client and server's descriptor are inconsistent.");
489596a2c1Sopenharmony_ci        reply.WriteInt32(I18nErrorCode::INCONSISTENT_DESCRIPTOR);
499596a2c1Sopenharmony_ci        return 0;
509596a2c1Sopenharmony_ci    }
519596a2c1Sopenharmony_ci    // map request code to corresponding process function.
529596a2c1Sopenharmony_ci    int32_t ret = InvokeInnerFunc(code, data, reply);
539596a2c1Sopenharmony_ci    bool hasMappedInnerFunc = ret > -1;
549596a2c1Sopenharmony_ci    if (!hasMappedInnerFunc) {
559596a2c1Sopenharmony_ci        HILOG_INFO_I18N("I18nServiceAbilityStub::OnRemoteRequest invalid request code=%{public}u", code);
569596a2c1Sopenharmony_ci        ret = IPCObjectStub::OnRemoteRequest(code, data, reply, option);
579596a2c1Sopenharmony_ci    }
589596a2c1Sopenharmony_ci    // trigger release i18n service after one request finished.
599596a2c1Sopenharmony_ci    UnloadI18nServiceAbility();
609596a2c1Sopenharmony_ci    return ret;
619596a2c1Sopenharmony_ci}
629596a2c1Sopenharmony_ci
639596a2c1Sopenharmony_ciint32_t I18nServiceAbilityStub::InvokeInnerFunc(uint32_t code, MessageParcel &data, MessageParcel &reply)
649596a2c1Sopenharmony_ci{
659596a2c1Sopenharmony_ci    switch (code) {
669596a2c1Sopenharmony_ci        case static_cast<uint32_t>(ILocaleConfigAbilityCode::SET_SYSTEM_LANGUAGE): {
679596a2c1Sopenharmony_ci            return I18nServiceAbilityStub::SetSystemLanguageInner(data, reply);
689596a2c1Sopenharmony_ci        }
699596a2c1Sopenharmony_ci        case static_cast<uint32_t>(ILocaleConfigAbilityCode::SET_SYSTEM_REGION): {
709596a2c1Sopenharmony_ci            return I18nServiceAbilityStub::SetSystemRegionInner(data, reply);
719596a2c1Sopenharmony_ci        }
729596a2c1Sopenharmony_ci        case static_cast<uint32_t>(ILocaleConfigAbilityCode::SET_SYSTEM_LOCALE): {
739596a2c1Sopenharmony_ci            return I18nServiceAbilityStub::SetSystemLocaleInner(data, reply);
749596a2c1Sopenharmony_ci        }
759596a2c1Sopenharmony_ci        case static_cast<uint32_t>(ILocaleConfigAbilityCode::SET_24_HOUR_CLOCK): {
769596a2c1Sopenharmony_ci            return I18nServiceAbilityStub::Set24HourClockInner(data, reply);
779596a2c1Sopenharmony_ci        }
789596a2c1Sopenharmony_ci        case static_cast<uint32_t>(ILocaleConfigAbilityCode::SET_USING_LOCAL_DIGIT): {
799596a2c1Sopenharmony_ci            return I18nServiceAbilityStub::SetUsingLocalDigitInner(data, reply);
809596a2c1Sopenharmony_ci        }
819596a2c1Sopenharmony_ci        case static_cast<uint32_t>(ILocaleConfigAbilityCode::ADD_PREFERRED_LANGUAGE): {
829596a2c1Sopenharmony_ci            return I18nServiceAbilityStub::AddPreferredLanguageInner(data, reply);
839596a2c1Sopenharmony_ci        }
849596a2c1Sopenharmony_ci        case static_cast<uint32_t>(ILocaleConfigAbilityCode::REMOVE_PREFERRED_LANGUAGE): {
859596a2c1Sopenharmony_ci            return I18nServiceAbilityStub::RemovePreferredLanguageInner(data, reply);
869596a2c1Sopenharmony_ci        }
879596a2c1Sopenharmony_ci        default:
889596a2c1Sopenharmony_ci            break;
899596a2c1Sopenharmony_ci    }
909596a2c1Sopenharmony_ci    return -1;
919596a2c1Sopenharmony_ci}
929596a2c1Sopenharmony_ci
939596a2c1Sopenharmony_ci/**
949596a2c1Sopenharmony_ci * check whether request process has correct tokenType and permission.
959596a2c1Sopenharmony_ci */
969596a2c1Sopenharmony_ciI18nErrorCode I18nServiceAbilityStub::CheckPermission()
979596a2c1Sopenharmony_ci{
989596a2c1Sopenharmony_ci    uint64_t callerFullToken = IPCSkeleton::GetCallingFullTokenID();
999596a2c1Sopenharmony_ci    uint32_t callerToken = IPCSkeleton::GetCallingTokenID();
1009596a2c1Sopenharmony_ci    bool isSystemApp = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(callerFullToken);
1019596a2c1Sopenharmony_ci    Security::AccessToken::ATokenTypeEnum tokenType =
1029596a2c1Sopenharmony_ci        Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken);
1039596a2c1Sopenharmony_ci    bool isShell = tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL;
1049596a2c1Sopenharmony_ci    bool isNative = tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE;
1059596a2c1Sopenharmony_ci    if (!isSystemApp && !isShell && !isNative) {
1069596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("I18nServiceAbilityStub caller process is not System app, Shell or Native.");
1079596a2c1Sopenharmony_ci        return I18nErrorCode::NO_PERMISSION;
1089596a2c1Sopenharmony_ci    }
1099596a2c1Sopenharmony_ci    int result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken,
1109596a2c1Sopenharmony_ci        "ohos.permission.UPDATE_CONFIGURATION");
1119596a2c1Sopenharmony_ci    if (result != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
1129596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("I18nServiceAbilityStub caller process doesn't have UPDATE_CONFIGURATION permission.");
1139596a2c1Sopenharmony_ci        return I18nErrorCode::NO_PERMISSION;
1149596a2c1Sopenharmony_ci    }
1159596a2c1Sopenharmony_ci    return I18nErrorCode::SUCCESS;
1169596a2c1Sopenharmony_ci}
1179596a2c1Sopenharmony_ci
1189596a2c1Sopenharmony_ciint32_t I18nServiceAbilityStub::SetSystemLanguageInner(MessageParcel &data, MessageParcel &reply)
1199596a2c1Sopenharmony_ci{
1209596a2c1Sopenharmony_ci    int pid = getpid();
1219596a2c1Sopenharmony_ci    Memory::MemMgrClient::GetInstance().SetCritical(pid, true, I18N_SA_ID);
1229596a2c1Sopenharmony_ci    I18nErrorCode err = CheckPermission();
1239596a2c1Sopenharmony_ci    if (err != I18nErrorCode::SUCCESS) {
1249596a2c1Sopenharmony_ci        reply.WriteInt32(static_cast<int32_t>(err));
1259596a2c1Sopenharmony_ci        return 0;
1269596a2c1Sopenharmony_ci    }
1279596a2c1Sopenharmony_ci    std::string language = data.ReadString();
1289596a2c1Sopenharmony_ci    err = SetSystemLanguage(language);
1299596a2c1Sopenharmony_ci    if (err != I18nErrorCode::SUCCESS) {
1309596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("I18nServiceAbilityStub::SetSystemLanguageInner failed with errorCode=%{public}d",
1319596a2c1Sopenharmony_ci            static_cast<int32_t>(err));
1329596a2c1Sopenharmony_ci    }
1339596a2c1Sopenharmony_ci    reply.WriteInt32(static_cast<int32_t>(err));
1349596a2c1Sopenharmony_ci    Memory::MemMgrClient::GetInstance().SetCritical(pid, false, I18N_SA_ID);
1359596a2c1Sopenharmony_ci    return 0;
1369596a2c1Sopenharmony_ci}
1379596a2c1Sopenharmony_ci
1389596a2c1Sopenharmony_ciint32_t I18nServiceAbilityStub::SetSystemRegionInner(MessageParcel &data, MessageParcel &reply)
1399596a2c1Sopenharmony_ci{
1409596a2c1Sopenharmony_ci    int pid = getpid();
1419596a2c1Sopenharmony_ci    Memory::MemMgrClient::GetInstance().SetCritical(pid, true, I18N_SA_ID);
1429596a2c1Sopenharmony_ci    I18nErrorCode err = CheckPermission();
1439596a2c1Sopenharmony_ci    if (err != I18nErrorCode::SUCCESS) {
1449596a2c1Sopenharmony_ci        reply.WriteInt32(static_cast<int32_t>(err));
1459596a2c1Sopenharmony_ci        return 0;
1469596a2c1Sopenharmony_ci    }
1479596a2c1Sopenharmony_ci    std::string region = data.ReadString();
1489596a2c1Sopenharmony_ci    err = SetSystemRegion(region);
1499596a2c1Sopenharmony_ci    if (err != I18nErrorCode::SUCCESS) {
1509596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("I18nServiceAbilityStub::SetSystemRegionInner failed with errorCode=%{public}d",
1519596a2c1Sopenharmony_ci            static_cast<int32_t>(err));
1529596a2c1Sopenharmony_ci    }
1539596a2c1Sopenharmony_ci    reply.WriteInt32(static_cast<int32_t>(err));
1549596a2c1Sopenharmony_ci    Memory::MemMgrClient::GetInstance().SetCritical(pid, false, I18N_SA_ID);
1559596a2c1Sopenharmony_ci    return 0;
1569596a2c1Sopenharmony_ci}
1579596a2c1Sopenharmony_ci
1589596a2c1Sopenharmony_ciint32_t I18nServiceAbilityStub::SetSystemLocaleInner(MessageParcel &data, MessageParcel &reply)
1599596a2c1Sopenharmony_ci{
1609596a2c1Sopenharmony_ci    int pid = getpid();
1619596a2c1Sopenharmony_ci    Memory::MemMgrClient::GetInstance().SetCritical(pid, true, I18N_SA_ID);
1629596a2c1Sopenharmony_ci    I18nErrorCode err = CheckPermission();
1639596a2c1Sopenharmony_ci    if (err != I18nErrorCode::SUCCESS) {
1649596a2c1Sopenharmony_ci        reply.WriteInt32(static_cast<int32_t>(err));
1659596a2c1Sopenharmony_ci        return 0;
1669596a2c1Sopenharmony_ci    }
1679596a2c1Sopenharmony_ci    std::string locale = data.ReadString();
1689596a2c1Sopenharmony_ci    err = SetSystemLocale(locale);
1699596a2c1Sopenharmony_ci    if (err != I18nErrorCode::SUCCESS) {
1709596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("I18nServiceAbilityStub::SetSystemLocaleInner failed with errorCode=%{public}d",
1719596a2c1Sopenharmony_ci            static_cast<int32_t>(err));
1729596a2c1Sopenharmony_ci    }
1739596a2c1Sopenharmony_ci    reply.WriteInt32(static_cast<int32_t>(err));
1749596a2c1Sopenharmony_ci    Memory::MemMgrClient::GetInstance().SetCritical(pid, false, I18N_SA_ID);
1759596a2c1Sopenharmony_ci    return 0;
1769596a2c1Sopenharmony_ci}
1779596a2c1Sopenharmony_ci
1789596a2c1Sopenharmony_ciint32_t I18nServiceAbilityStub::Set24HourClockInner(MessageParcel &data, MessageParcel &reply)
1799596a2c1Sopenharmony_ci{
1809596a2c1Sopenharmony_ci    int pid = getpid();
1819596a2c1Sopenharmony_ci    Memory::MemMgrClient::GetInstance().SetCritical(pid, true, I18N_SA_ID);
1829596a2c1Sopenharmony_ci    I18nErrorCode err = CheckPermission();
1839596a2c1Sopenharmony_ci    if (err != I18nErrorCode::SUCCESS) {
1849596a2c1Sopenharmony_ci        reply.WriteInt32(static_cast<int32_t>(err));
1859596a2c1Sopenharmony_ci        return 0;
1869596a2c1Sopenharmony_ci    }
1879596a2c1Sopenharmony_ci    std::string flag = data.ReadString();
1889596a2c1Sopenharmony_ci    err = Set24HourClock(flag);
1899596a2c1Sopenharmony_ci    if (err != I18nErrorCode::SUCCESS) {
1909596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("I18nServiceAbilityStub::Set24HourClockInner failed with errorCode=%{public}d",
1919596a2c1Sopenharmony_ci            static_cast<int32_t>(err));
1929596a2c1Sopenharmony_ci    }
1939596a2c1Sopenharmony_ci    reply.WriteInt32(static_cast<int32_t>(err));
1949596a2c1Sopenharmony_ci    Memory::MemMgrClient::GetInstance().SetCritical(pid, false, I18N_SA_ID);
1959596a2c1Sopenharmony_ci    return 0;
1969596a2c1Sopenharmony_ci}
1979596a2c1Sopenharmony_ci
1989596a2c1Sopenharmony_ciint32_t I18nServiceAbilityStub::SetUsingLocalDigitInner(MessageParcel &data, MessageParcel &reply)
1999596a2c1Sopenharmony_ci{
2009596a2c1Sopenharmony_ci    int pid = getpid();
2019596a2c1Sopenharmony_ci    Memory::MemMgrClient::GetInstance().SetCritical(pid, true, I18N_SA_ID);
2029596a2c1Sopenharmony_ci    I18nErrorCode err = CheckPermission();
2039596a2c1Sopenharmony_ci    if (err != I18nErrorCode::SUCCESS) {
2049596a2c1Sopenharmony_ci        reply.WriteInt32(static_cast<int32_t>(err));
2059596a2c1Sopenharmony_ci        return 0;
2069596a2c1Sopenharmony_ci    }
2079596a2c1Sopenharmony_ci    bool flag = data.ReadBool();
2089596a2c1Sopenharmony_ci    err = SetUsingLocalDigit(flag);
2099596a2c1Sopenharmony_ci    if (err != I18nErrorCode::SUCCESS) {
2109596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("I18nServiceAbilityStub::SetUsingLocalDigitInner failed with errorCode=%{public}d",
2119596a2c1Sopenharmony_ci            static_cast<int32_t>(err));
2129596a2c1Sopenharmony_ci    }
2139596a2c1Sopenharmony_ci    reply.WriteInt32(static_cast<int32_t>(err));
2149596a2c1Sopenharmony_ci    Memory::MemMgrClient::GetInstance().SetCritical(pid, false, I18N_SA_ID);
2159596a2c1Sopenharmony_ci    return 0;
2169596a2c1Sopenharmony_ci}
2179596a2c1Sopenharmony_ci
2189596a2c1Sopenharmony_ciint32_t I18nServiceAbilityStub::AddPreferredLanguageInner(MessageParcel &data, MessageParcel &reply)
2199596a2c1Sopenharmony_ci{
2209596a2c1Sopenharmony_ci    int pid = getpid();
2219596a2c1Sopenharmony_ci    Memory::MemMgrClient::GetInstance().SetCritical(pid, true, I18N_SA_ID);
2229596a2c1Sopenharmony_ci    I18nErrorCode err = CheckPermission();
2239596a2c1Sopenharmony_ci    if (err != I18nErrorCode::SUCCESS) {
2249596a2c1Sopenharmony_ci        reply.WriteInt32(static_cast<int32_t>(err));
2259596a2c1Sopenharmony_ci        return 0;
2269596a2c1Sopenharmony_ci    }
2279596a2c1Sopenharmony_ci    std::string language = data.ReadString();
2289596a2c1Sopenharmony_ci    int32_t index = data.ReadInt32();
2299596a2c1Sopenharmony_ci    err = AddPreferredLanguage(language, index);
2309596a2c1Sopenharmony_ci    if (err != I18nErrorCode::SUCCESS) {
2319596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("I18nServiceAbilityStub::AddPreferredLanguageInner failed with errorCode=%{public}d",
2329596a2c1Sopenharmony_ci            static_cast<int32_t>(err));
2339596a2c1Sopenharmony_ci    }
2349596a2c1Sopenharmony_ci    reply.WriteInt32(static_cast<int32_t>(err));
2359596a2c1Sopenharmony_ci    Memory::MemMgrClient::GetInstance().SetCritical(pid, false, I18N_SA_ID);
2369596a2c1Sopenharmony_ci    return 0;
2379596a2c1Sopenharmony_ci}
2389596a2c1Sopenharmony_ci
2399596a2c1Sopenharmony_ciint32_t I18nServiceAbilityStub::RemovePreferredLanguageInner(MessageParcel &data, MessageParcel &reply)
2409596a2c1Sopenharmony_ci{
2419596a2c1Sopenharmony_ci    int pid = getpid();
2429596a2c1Sopenharmony_ci    Memory::MemMgrClient::GetInstance().SetCritical(pid, true, I18N_SA_ID);
2439596a2c1Sopenharmony_ci    I18nErrorCode err = CheckPermission();
2449596a2c1Sopenharmony_ci    if (err != I18nErrorCode::SUCCESS) {
2459596a2c1Sopenharmony_ci        reply.WriteInt32(static_cast<int32_t>(err));
2469596a2c1Sopenharmony_ci        return 0;
2479596a2c1Sopenharmony_ci    }
2489596a2c1Sopenharmony_ci    int32_t index = data.ReadInt32();
2499596a2c1Sopenharmony_ci    err = RemovePreferredLanguage(index);
2509596a2c1Sopenharmony_ci    if (err != I18nErrorCode::SUCCESS) {
2519596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("I18nServiceAbilityStub::RemovePreferredLanguageInner failed with errorCode=%{public}d",
2529596a2c1Sopenharmony_ci            static_cast<int32_t>(err));
2539596a2c1Sopenharmony_ci    }
2549596a2c1Sopenharmony_ci    reply.WriteInt32(static_cast<int32_t>(err));
2559596a2c1Sopenharmony_ci    Memory::MemMgrClient::GetInstance().SetCritical(pid, false, I18N_SA_ID);
2569596a2c1Sopenharmony_ci    return 0;
2579596a2c1Sopenharmony_ci}
2589596a2c1Sopenharmony_ci} // namespace I18n
2599596a2c1Sopenharmony_ci} // namespace Global
2609596a2c1Sopenharmony_ci} // namespace OHOS