1 /*
2  * Copyright (c) 2023 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_client.h"
17 
18 #include <cstdint>
19 #include <mutex>
20 
21 #include "access_token.h"
22 #include "accesstoken_kit.h"
23 #include "if_system_ability_manager.h"
24 #include "iremote_broker.h"
25 #include "iremote_object.h"
26 #include "iservice_registry.h"
27 #include "nocopyable.h"
28 #include "refbase.h"
29 #include "system_ability_definition.h"
30 #include "token_setproc.h"
31 #include "tokenid_kit.h"
32 
33 #include "iam_logger.h"
34 
35 #include "face_auth_defines.h"
36 #include "iface_auth.h"
37 
38 #define LOG_TAG "FACE_AUTH_SDK"
39 
40 namespace OHOS {
41 namespace UserIam {
42 namespace FaceAuth {
43 class FaceAuthClientImpl : public FaceAuthClient, public NoCopyable {
44 public:
45     int32_t SetBufferProducer(sptr<IBufferProducer> &producer) override;
46 
47 private:
48     friend class FaceAuthClient;
49     FaceAuthClientImpl() = default;
50     ~FaceAuthClientImpl() override = default;
51     static FaceAuthClientImpl &Instance();
52     class FaceAuthClientImplDeathRecipient : public IRemoteObject::DeathRecipient, public NoCopyable {
53     public:
54         FaceAuthClientImplDeathRecipient() = default;
55         ~FaceAuthClientImplDeathRecipient() override = default;
56         void OnRemoteDied(const wptr<IRemoteObject> &remote) override;
57     };
58     bool CheckSystemPermission();
59     void ResetProxy(const wptr<IRemoteObject> &remote);
60     sptr<IFaceAuth> GetProxy();
61     sptr<IFaceAuth> proxy_ { nullptr };
62     sptr<IRemoteObject::DeathRecipient> deathRecipient_ { nullptr };
63     std::mutex mutex_;
64     uint64_t tokenIdLowMask_ = 0xffffffff;
65 };
66 
CheckSystemPermission()67 bool FaceAuthClientImpl::CheckSystemPermission()
68 {
69     using namespace Security::AccessToken;
70     uint64_t fullTokenId = GetSelfTokenID();
71     bool checkRet = TokenIdKit::IsSystemAppByFullTokenID(fullTokenId);
72     AccessTokenID tokenId = fullTokenId & tokenIdLowMask_;
73     if (AccessTokenKit::GetTokenType(tokenId) == TOKEN_HAP && !checkRet) {
74         return false;
75     }
76     return true;
77 }
78 
SetBufferProducer(sptr<IBufferProducer> & producer)79 int32_t FaceAuthClientImpl::SetBufferProducer(sptr<IBufferProducer> &producer)
80 {
81     IAM_LOGI("start");
82     if (!CheckSystemPermission()) {
83         IAM_LOGE("the caller is not a system application");
84         return FACE_AUTH_CHECK_SYSTEM_PERMISSION_FAILED;
85     }
86     sptr<IFaceAuth> proxy = GetProxy();
87     if (proxy == nullptr) {
88         IAM_LOGE("get faceAuthProxy fail");
89         return FACE_AUTH_ERROR;
90     }
91     return proxy->SetBufferProducer(producer);
92 }
93 
GetProxy()94 sptr<IFaceAuth> FaceAuthClientImpl::GetProxy()
95 {
96     IAM_LOGI("start");
97     std::lock_guard<std::mutex> lock(mutex_);
98     if (proxy_ != nullptr) {
99         return proxy_;
100     }
101 
102     sptr<ISystemAbilityManager> systemAbilityManager =
103         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
104     if (systemAbilityManager == nullptr) {
105         IAM_LOGE("failed to get systemAbilityManager.");
106         return nullptr;
107     }
108 
109     sptr<IRemoteObject> obj = systemAbilityManager->CheckSystemAbility(SUBSYS_USERIAM_SYS_ABILITY_FACEAUTH);
110     if (obj == nullptr) {
111         IAM_LOGE("failed to get remoteObject.");
112         return nullptr;
113     }
114 
115     sptr<IRemoteObject::DeathRecipient> dr(new (std::nothrow) FaceAuthClientImplDeathRecipient());
116     if ((dr == nullptr) || (obj->IsProxyObject() && !obj->AddDeathRecipient(dr))) {
117         IAM_LOGE("add death recipient fail");
118         return nullptr;
119     }
120 
121     proxy_ = iface_cast<IFaceAuth>(obj);
122     deathRecipient_ = dr;
123     return proxy_;
124 }
125 
ResetProxy(const wptr<IRemoteObject> & remote)126 void FaceAuthClientImpl::ResetProxy(const wptr<IRemoteObject> &remote)
127 {
128     IAM_LOGI("start");
129     std::lock_guard<std::mutex> lock(mutex_);
130     if (proxy_ == nullptr) {
131         IAM_LOGE("proxy_ is null");
132         return;
133     }
134     auto serviceRemote = proxy_->AsObject();
135     if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
136         IAM_LOGI("need reset");
137         serviceRemote->RemoveDeathRecipient(deathRecipient_);
138         proxy_ = nullptr;
139         deathRecipient_ = nullptr;
140     }
141     IAM_LOGI("end reset proxy");
142 }
143 
OnRemoteDied(const wptr<IRemoteObject> & remote)144 void FaceAuthClientImpl::FaceAuthClientImplDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
145 {
146     IAM_LOGI("start");
147     if (remote == nullptr) {
148         IAM_LOGE("remote is nullptr");
149         return;
150     }
151     FaceAuthClientImpl::Instance().ResetProxy(remote);
152 }
153 
Instance()154 FaceAuthClientImpl &FaceAuthClientImpl::Instance()
155 {
156     static FaceAuthClientImpl impl;
157     return impl;
158 }
159 
GetInstance()160 FaceAuthClient &FaceAuthClient::GetInstance()
161 {
162     return FaceAuthClientImpl::Instance();
163 }
164 } // namespace FaceAuth
165 } // namespace UserIam
166 } // namespace OHOS
167