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 #ifndef BASE_SERVICE_KITS_IMPL_H
17 #define BASE_SERVICE_KITS_IMPL_H
18 
19 #include <mutex>
20 
21 #include "iremote_object.h"
22 
23 #include "common_death_recipient.h"
24 #include "load_sa_service.h"
25 #include "update_define.h"
26 
27 namespace OHOS::UpdateEngine {
28 #define RETURN_FAIL_WHEN_SERVICE_NULL(service) \
29     if ((service) == nullptr) {                \
30         ENGINE_LOGE("Service is null");        \
31         return INT_CALL_IPC_ERR;               \
32     }
33 
34 template <typename SERVICE> class BaseServiceKitsImpl {
35 public:
36     explicit BaseServiceKitsImpl(int32_t systemAbilityId, bool isNeedAddDeathRecipient = true)
37         : systemAbilityId_(systemAbilityId), isNeedAddDeathRecipient_(isNeedAddDeathRecipient) {}
38     virtual ~BaseServiceKitsImpl();
39 
40 protected:
41     sptr<SERVICE> GetService();
42     void ResetRemoteService();
RegisterCallback()43     virtual void RegisterCallback(){};
44     virtual void ResetService(const wptr<IRemoteObject> &remote);
45 
46 protected:
47     std::recursive_mutex remoteServerLock_;
48     sptr<SERVICE> remoteServer_ = nullptr;
49     sptr<IRemoteObject::DeathRecipient> deathRecipient_ = nullptr;
50     int32_t systemAbilityId_;
51 
52 private:
53     void AddDeathRecipient(const sptr<IRemoteObject> &object);
54 
55 private:
56     bool isNeedAddDeathRecipient_ = true;
57 };
58 
~BaseServiceKitsImpl()59 template <typename SERVICE> BaseServiceKitsImpl<SERVICE>::~BaseServiceKitsImpl()
60 {
61     ENGINE_LOGI("BaseServiceKitsImpl desConstructor");
62     std::lock_guard<std::recursive_mutex> lock(remoteServerLock_);
63     if (isNeedAddDeathRecipient_ && remoteServer_ != nullptr && deathRecipient_ != nullptr) {
64         sptr<IRemoteObject> object = remoteServer_->AsObject();
65         if (object != nullptr) {
66             bool removeResult = object->RemoveDeathRecipient(deathRecipient_);
67             ENGINE_LOGI("RemoveDeathRecipient result is %{public}s", removeResult ? "success" : "error");
68         }
69     }
70     deathRecipient_ = nullptr;
71     remoteServer_ = nullptr;
72 }
73 
GetService()74 template <typename SERVICE> sptr<SERVICE> BaseServiceKitsImpl<SERVICE>::GetService()
75 {
76     std::lock_guard<std::recursive_mutex> lock(remoteServerLock_);
77     if (remoteServer_ != nullptr) {
78         return remoteServer_;
79     }
80     ENGINE_LOGI("GetService recreate service instance");
81     sptr<ISystemAbilityManager> manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
82     ENGINE_CHECK(manager != nullptr, return nullptr, "manager is nullptr");
83     sptr<IRemoteObject> object = manager->CheckSystemAbility(systemAbilityId_);
84     if (object == nullptr) {
85         ENGINE_CHECK(LoadSaService::GetInstance()->TryLoadSa(systemAbilityId_), return nullptr, "TryLoadSa fail");
86         object = manager->GetSystemAbility(systemAbilityId_);
87         ENGINE_CHECK(object != nullptr, return nullptr, "Get  remote object from samgr failed");
88     }
89     AddDeathRecipient(object);
90     remoteServer_ = iface_cast<SERVICE>(object);
91     ENGINE_CHECK(remoteServer_ != nullptr, return nullptr, "service iface_cast failed");
92     RegisterCallback();
93     return remoteServer_;
94 }
95 
AddDeathRecipient(const sptr<IRemoteObject> & object)96 template <typename SERVICE> void BaseServiceKitsImpl<SERVICE>::AddDeathRecipient(const sptr<IRemoteObject> &object)
97 {
98     if (isNeedAddDeathRecipient_ && object != nullptr) {
99         if (deathRecipient_ == nullptr) {
100             auto resetCallback = [this](const wptr<IRemoteObject> &remote) { this->ResetService(remote); };
101             deathRecipient_ = new CommonDeathRecipient(resetCallback);
102         }
103         if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient_))) {
104             ENGINE_LOGE("Failed to add death recipient");
105         }
106     }
107 }
108 
ResetRemoteService()109 template <typename SERVICE> void BaseServiceKitsImpl<SERVICE>::ResetRemoteService()
110 {
111     ENGINE_LOGI("ResetRemoteService, do ResetService");
112     std::lock_guard<std::recursive_mutex> lock(remoteServerLock_);
113     if (remoteServer_ != nullptr) {
114         remoteServer_ = nullptr;
115     }
116 }
117 
ResetService(const wptr<IRemoteObject> & remote)118 template <typename SERVICE> void BaseServiceKitsImpl<SERVICE>::ResetService(const wptr<IRemoteObject> &remote)
119 {
120     ENGINE_LOGI("Remote is dead, do ResetService");
121     std::lock_guard<std::recursive_mutex> lock(remoteServerLock_);
122     if (deathRecipient_ != nullptr && remote != nullptr) {
123         remote->RemoveDeathRecipient(deathRecipient_);
124     }
125     remoteServer_ = nullptr;
126     deathRecipient_ = nullptr;
127 }
128 }
129 #endif // BASE_SERVICE_KITS_IMPL_H
130