• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "data_share_manager_impl.h"
17 
18 #include <thread>
19 
20 #include "datashare_log.h"
21 #include "ikvstore_data_service.h"
22 #include "ipc_skeleton.h"
23 #include "iservice_registry.h"
24 #include "system_ability_definition.h"
25 #include "executor_pool.h"
26 #include "rdb_subscriber_manager.h"
27 #include "published_data_subscriber_manager.h"
28 
29 namespace OHOS {
30 namespace DataShare {
GetInstance()31 DataShareManagerImpl& DataShareManagerImpl::GetInstance()
32 {
33     static DataShareManagerImpl manager;
34     return manager;
35 }
36 
GetDistributedDataManager()37 std::shared_ptr<DataShareKvServiceProxy> DataShareManagerImpl::GetDistributedDataManager()
38 {
39     int retry = 0;
40     while (++retry <= GET_SA_RETRY_TIMES) {
41         auto manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
42         if (manager == nullptr) {
43             LOG_ERROR("get system ability manager failed");
44             return nullptr;
45         }
46         LOG_INFO("get distributed data manager %{public}d", retry);
47         auto remoteObject = manager->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID);
48         if (remoteObject == nullptr) {
49             std::this_thread::sleep_for(std::chrono::seconds(RETRY_INTERVAL));
50             continue;
51         }
52         LOG_INFO("get distributed data manager success");
53         return std::make_shared<DataShareKvServiceProxy>(remoteObject);
54     }
55 
56     LOG_ERROR("get distributed data manager failed");
57     return nullptr;
58 }
59 
LinkToDeath(const sptr<IRemoteObject> remote)60 void DataShareManagerImpl::LinkToDeath(const sptr<IRemoteObject> remote)
61 {
62     sptr<DataShareManagerImpl::ServiceDeathRecipient> deathRecipient = new (std::nothrow)
63         DataShareManagerImpl::ServiceDeathRecipient(this);
64     if (deathRecipient == nullptr) {
65         LOG_ERROR("DataShareManagerImpl::LinkToDeath new ServiceDeathRecipient error.");
66         return;
67     }
68     if (!remote->AddDeathRecipient(deathRecipient)) {
69         LOG_ERROR("add death recipient failed");
70     }
71     LOG_ERROR("link to death success");
72 }
73 
GetDataShareServiceProxy()74 sptr<DataShareServiceProxy> DataShareManagerImpl::GetDataShareServiceProxy()
75 {
76     if (dataMgrService_ == nullptr) {
77         dataMgrService_ = GetDistributedDataManager();
78     }
79     if (dataMgrService_ == nullptr) {
80         LOG_ERROR("Get distributed data manager failed!");
81         return nullptr;
82     }
83     auto remote = dataMgrService_->GetFeatureInterface("data_share");
84     if (remote == nullptr) {
85         LOG_ERROR("Get DataShare service failed!");
86         return nullptr;
87     }
88     RegisterClientDeathObserver();
89     return iface_cast<DataShareServiceProxy>(remote);
90 }
91 
RegisterClientDeathObserver()92 void DataShareManagerImpl::RegisterClientDeathObserver()
93 {
94     if (dataMgrService_ == nullptr || bundleName_.empty()) {
95         return;
96     }
97     LOG_INFO("RegisterClientDeathObserver bundleName is %{public}s", bundleName_.c_str());
98     if (clientDeathObserverPtr_ == nullptr) {
99         clientDeathObserverPtr_ = new (std::nothrow) DataShareClientDeathObserverStub();
100     }
101     if (clientDeathObserverPtr_ == nullptr) {
102         LOG_WARN("new KvStoreClientDeathObserver failed");
103         return;
104     }
105     dataMgrService_->RegisterClientDeathObserver(bundleName_, clientDeathObserverPtr_);
106 }
107 
DataShareManagerImpl()108 DataShareManagerImpl::DataShareManagerImpl()
109 {
110     LOG_INFO("construct");
111     pool_ = std::make_shared<ExecutorPool>(MAX_THREADS, MIN_THREADS);
112     SetDeathCallback([](std::shared_ptr<DataShareServiceProxy> proxy) {
113         LOG_INFO("RecoverObs start");
114         RdbSubscriberManager::GetInstance().RecoverObservers(proxy);
115         PublishedDataSubscriberManager::GetInstance().RecoverObservers(proxy);
116     });
117 }
118 
~DataShareManagerImpl()119 DataShareManagerImpl::~DataShareManagerImpl()
120 {
121     LOG_INFO("destroy");
122 }
123 
GetServiceProxy()124 std::shared_ptr<DataShareServiceProxy> DataShareManagerImpl::GetServiceProxy()
125 {
126     if (dataShareService_ != nullptr) {
127         return dataShareService_;
128     }
129 
130     std::lock_guard<std::mutex> lock(mutex_);
131     if (dataShareService_ != nullptr) {
132         return dataShareService_;
133     }
134 
135     auto service = GetDataShareServiceProxy();
136     if (service == nullptr) {
137         return nullptr;
138     }
139     sptr<IDataShareService> serviceBase = service;
140     LinkToDeath(serviceBase->AsObject().GetRefPtr());
141     dataShareService_ = std::shared_ptr<DataShareServiceProxy>(
142             service.GetRefPtr(), [holder = service](const auto *) {});
143     return dataShareService_;
144 }
145 
ResetServiceHandle()146 void DataShareManagerImpl::ResetServiceHandle()
147 {
148     LOG_INFO("enter");
149     std::lock_guard<std::mutex> lock(mutex_);
150     dataMgrService_ = nullptr;
151     dataShareService_ = nullptr;
152 }
153 
SetDeathCallback(std::function<void (std::shared_ptr<DataShareServiceProxy>)> deathCallback)154 void DataShareManagerImpl::SetDeathCallback(std::function<void(std::shared_ptr<DataShareServiceProxy>)> deathCallback)
155 {
156     deathCallback_ = deathCallback;
157 }
158 
SetBundleName(const std::string & bundleName)159 void DataShareManagerImpl::SetBundleName(const std::string &bundleName)
160 {
161     bundleName_ = bundleName;
162 }
163 
OnRemoteDied()164 void DataShareManagerImpl::OnRemoteDied()
165 {
166     LOG_INFO("#######datashare service has dead");
167     ResetServiceHandle();
168     auto taskid = pool_->Schedule(std::chrono::seconds(WAIT_TIME), [this]() {
169         if (GetServiceProxy() != nullptr) {
170             deathCallback_(dataShareService_);
171         }
172     });
173     if (taskid == ExecutorPool::INVALID_TASK_ID) {
174         LOG_ERROR("create scheduler failed, over the max capacity");
175         return;
176     }
177     LOG_DEBUG("create scheduler success");
178 }
179 }
180 }