1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "face_auth_service.h"
17
18#include <cstdint>
19#include <functional>
20#include <map>
21#include <memory>
22#include <mutex>
23#include <string>
24#include <vector>
25
26#include "accesstoken_kit.h"
27#include "iam_executor_idriver_manager.h"
28#include "ibuffer_producer.h"
29#include "ipc_skeleton.h"
30#include "iremote_object.h"
31#include "iservice_registry.h"
32#include "refbase.h"
33#include "system_ability.h"
34#include "system_ability_definition.h"
35#include "tokenid_kit.h"
36
37#include "iam_check.h"
38#include "iam_logger.h"
39#include "iam_para2str.h"
40#include "iam_ptr.h"
41
42#include "face_auth_defines.h"
43#include "face_auth_driver_hdi.h"
44#include "face_auth_interface_adapter.h"
45#include "screen_brightness_manager.h"
46
47#define LOG_TAG "FACE_AUTH_SA"
48
49namespace OHOS {
50namespace UserIam {
51namespace FaceAuth {
52namespace UserAuth = OHOS::UserIam::UserAuth;
53using namespace OHOS::UserIam;
54namespace {
55const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(FaceAuthService::GetInstance().get());
56const uint16_t FACE_AUTH_DEFAULT_HDI_ID = 1;
57const auto FACE_AUTH_DEFAULT_HDI_ADAPTER = Common::MakeShared<FaceAuthInterfaceAdapter>();
58auto FACE_AUTH_DEFAULT_HDI = Common::MakeShared<FaceAuthDriverHdi>(FACE_AUTH_DEFAULT_HDI_ADAPTER);
59// serviceName and HdiConfig.id must be globally unique
60const std::map<std::string, UserAuth::HdiConfig> HDI_NAME_2_CONFIG = {
61    { "face_auth_interface_service", { FACE_AUTH_DEFAULT_HDI_ID, FACE_AUTH_DEFAULT_HDI } },
62};
63const std::vector<std::shared_ptr<FaceAuthDriverHdi>> FACE_AUTH_DRIVER_HDIS = { FACE_AUTH_DEFAULT_HDI };
64// setup brightness manager
65const auto screenBrightnessManager = ScreenBrightnessManager::GetInstance();
66} // namespace
67std::mutex FaceAuthService::mutex_;
68std::shared_ptr<FaceAuthService> FaceAuthService::instance_ = nullptr;
69
70FaceAuthService::FaceAuthService() : SystemAbility(SUBSYS_USERIAM_SYS_ABILITY_FACEAUTH, true)
71{
72}
73
74std::shared_ptr<FaceAuthService> FaceAuthService::GetInstance()
75{
76    if (instance_ == nullptr) {
77        std::lock_guard<std::mutex> guard(mutex_);
78        if (instance_ == nullptr) {
79            instance_ = Common::MakeShared<FaceAuthService>();
80            if (instance_ == nullptr) {
81                IAM_LOGE("make share failed");
82            }
83        }
84    }
85    return instance_;
86}
87
88void FaceAuthService::OnStart()
89{
90    IAM_LOGI("start");
91    StartDriverManager();
92    Publish(this);
93    IAM_LOGI("success");
94}
95
96void FaceAuthService::OnStop()
97{
98    IAM_LOGE("service is persistent, OnStop is not implemented");
99}
100
101bool FaceAuthService::IsPermissionGranted(const std::string &permission)
102{
103    IAM_LOGI("start");
104    uint32_t tokenId = this->GetCallingTokenID();
105    int ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permission);
106    if (ret != Security::AccessToken::RET_SUCCESS) {
107        IAM_LOGE("failed to verify access token, code = %{public}d", ret);
108        return false;
109    }
110    return true;
111}
112
113int32_t FaceAuthService::SetBufferProducer(sptr<IBufferProducer> &producer)
114{
115    const std::string MANAGE_USER_IDM_PERMISSION = "ohos.permission.MANAGE_USER_IDM";
116    std::lock_guard<std::mutex> guard(mutex_);
117    IAM_LOGI("set buffer producer %{public}s", Common::GetPointerNullStateString(producer).c_str());
118    using namespace Security::AccessToken;
119    uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
120    bool checkRet = TokenIdKit::IsSystemAppByFullTokenID(fullTokenId);
121    uint32_t tokenId = this->GetCallingTokenID();
122    ATokenTypeEnum callingType = AccessTokenKit::GetTokenTypeFlag(tokenId);
123    if (callingType == TOKEN_HAP && !checkRet) {
124        IAM_LOGE("the caller is not a system application");
125        return FACE_AUTH_CHECK_SYSTEM_PERMISSION_FAILED;
126    }
127    if (!IsPermissionGranted(MANAGE_USER_IDM_PERMISSION)) {
128        IAM_LOGE("failed to check permission");
129        return FACE_AUTH_CHECK_PERMISSION_FAILED;
130    }
131    for (auto hdi : FACE_AUTH_DRIVER_HDIS) {
132        IF_FALSE_LOGE_AND_RETURN_VAL(hdi != nullptr, FACE_AUTH_ERROR);
133        int ret = hdi->SetBufferProducer(producer);
134        if (ret != FACE_AUTH_SUCCESS) {
135            IAM_LOGE("SetBufferProducer fail");
136            return FACE_AUTH_ERROR;
137        }
138    }
139    return FACE_AUTH_SUCCESS;
140}
141
142void FaceAuthService::StartDriverManager()
143{
144    IAM_LOGI("start");
145    int32_t ret = UserAuth::IDriverManager::Start(HDI_NAME_2_CONFIG);
146    if (ret != FACE_AUTH_SUCCESS) {
147        IAM_LOGE("start driver manager failed");
148    }
149}
150} // namespace FaceAuth
151} // namespace UserIam
152} // namespace OHOS
153