• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "distributed_screen_status_manager.h"
17 
18 #include "ans_inner_errors.h"
19 #include "ans_log_wrapper.h"
20 #include "device_manager.h"
21 #include "distributed_preferences.h"
22 
23 namespace OHOS {
24 namespace Notification {
25 namespace {
26 const std::string APP_ID = "notification_service";
27 const std::string STORE_ID = "distributed_screen_status";
28 const std::string DELIMITER = "|";
29 const std::string SCREEN_STATUS_LABEL = "screen_status";
30 const std::string SCREEN_STATUS_VALUE_ON = "on";
31 const std::string SCREEN_STATUS_VALUE_OFF = "off";
32 constexpr char KV_STORE_PATH[] = "/data/service/el1/public/database/notification_service";
33 } // namespace
34 
DistributedScreenStatusManager()35 DistributedScreenStatusManager::DistributedScreenStatusManager() : DistributedFlowControl()
36 {
37     DistributedDeviceCallback::IDeviceChange callback = {
38         .OnConnected = std::bind(&DistributedScreenStatusManager::OnDeviceConnected, this, std::placeholders::_1),
39         .OnDisconnected = std::bind(&DistributedScreenStatusManager::OnDeviceDisconnected, this, std::placeholders::_1),
40     };
41     deviceCb_ = std::make_shared<DistributedDeviceCallback>(callback);
42     GetKvDataManager();
43 }
44 
~DistributedScreenStatusManager()45 DistributedScreenStatusManager::~DistributedScreenStatusManager()
46 {}
47 
OnDeviceConnected(const std::string & deviceId)48 void DistributedScreenStatusManager::OnDeviceConnected(const std::string &deviceId)
49 {
50     ANS_LOGD("deviceId:%{public}s", deviceId.c_str());
51     std::lock_guard<std::recursive_mutex> lock(mutex_);
52     CheckKvStore();
53 }
54 
OnDeviceDisconnected(const std::string & deviceId)55 void DistributedScreenStatusManager::OnDeviceDisconnected(const std::string &deviceId)
56 {
57     std::lock_guard<std::recursive_mutex> lock(mutex_);
58     if (!CheckKvDataManager()) {
59         return;
60     }
61 
62     std::vector<DistributedHardware::DmDeviceInfo> devInfoList;
63     int32_t ret = DistributedHardware::DeviceManager::GetInstance().GetTrustedDeviceList(APP_ID, "", devInfoList);
64     if (ret != ERR_OK) {
65         ANS_LOGE("Get trust device list failed ret = %{public}d", ret);
66         kvDataManager_.reset();
67         return;
68     }
69 
70     if (!devInfoList.empty()) {
71         return;
72     }
73 
74     kvStore_.reset();
75 
76     DistributedKv::AppId appId = {.appId = APP_ID};
77     DistributedKv::StoreId storeId = {.storeId = STORE_ID};
78     kvDataManager_->DeleteKvStore(appId, storeId, KV_STORE_PATH);
79 
80     if (!CheckKvStore()) {
81         return;
82     }
83 
84     SetLocalScreenStatus(localScreenOn_);
85 }
86 
GetKvDataManager()87 void DistributedScreenStatusManager::GetKvDataManager()
88 {
89 #ifdef DISABLE_DISTRIBUTED_NOTIFICATION_SUPPORTED
90     initCallback_ = std::make_shared<DeviceInitCallBack>();
91     int32_t ret = DistributedHardware::DeviceManager::GetInstance().InitDeviceManager(APP_ID + STORE_ID, initCallback_);
92     if (ret != 0) {
93         ANS_LOGE("init device manager failed, ret:%{public}d", ret);
94         return;
95     }
96 #else
97     int32_t ret = 0;
98 #endif
99     ret = DistributedHardware::DeviceManager::GetInstance().RegisterDevStateCallback(APP_ID + STORE_ID, "", deviceCb_);
100     if (ret != 0) {
101         ANS_LOGD("register devStateCallback failed, ret:%{public}d", ret);
102         return;
103     }
104 
105     kvDataManager_ = std::make_unique<DistributedKv::DistributedKvDataManager>();
106     KvManagerFlowControlClear();
107 }
108 
OnRemoteDied()109 void DistributedScreenStatusManager::DeviceInitCallBack::OnRemoteDied()
110 {
111     ANS_LOGW("DeviceInitCallBack OnRemoteDied");
112 }
113 
CheckKvDataManager()114 bool DistributedScreenStatusManager::CheckKvDataManager()
115 {
116     if (kvDataManager_ == nullptr) {
117         GetKvDataManager();
118     }
119     if (kvDataManager_ == nullptr) {
120         ANS_LOGE("kvDataManager is nullptr.");
121         return false;
122     }
123     return true;
124 }
125 
GetKvStore()126 void DistributedScreenStatusManager::GetKvStore()
127 {
128     bool enable = false;
129     DistributedPreferences::GetInstance()->GetDistributedEnable(enable);
130     if (!enable) {
131         ANS_LOGI("DistributedEnable is false, no need to create db.");
132         return;
133     }
134 
135     if (!CheckKvDataManager()) {
136         return;
137     }
138     DistributedKv::Options options = {
139         .createIfMissing = true,
140         .autoSync = false,
141         .securityLevel = DistributedKv::SecurityLevel::S1,
142         .area = DistributedKv::EL1,
143         .kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION,
144         .baseDir = KV_STORE_PATH
145     };
146     DistributedKv::AppId appId = {.appId = APP_ID};
147     DistributedKv::StoreId storeId = {.storeId = STORE_ID};
148     DistributedKv::Status status = kvDataManager_->GetSingleKvStore(options, appId, storeId, kvStore_);
149     if (status != DistributedKv::Status::SUCCESS) {
150         ANS_LOGE("kvDataManager GetSingleKvStore failed ret = 0x%{public}x", status);
151         kvStore_.reset();
152         DistributedHardware::DeviceManager::GetInstance().UnRegisterDevStateCallback(APP_ID + STORE_ID);
153         kvDataManager_.reset();
154         return;
155     }
156 
157     KvStoreFlowControlClear();
158 }
159 
CheckKvStore()160 bool DistributedScreenStatusManager::CheckKvStore()
161 {
162     if (kvStore_ == nullptr) {
163         GetKvStore();
164     }
165     if (kvStore_ == nullptr) {
166         ANS_LOGE("kvStore is nullptr.");
167         return false;
168     }
169     return true;
170 }
171 
GenerateDistributedKey(const std::string & deviceId)172 std::string DistributedScreenStatusManager::GenerateDistributedKey(const std::string &deviceId)
173 {
174     return deviceId + DELIMITER + SCREEN_STATUS_LABEL;
175 }
176 
CheckRemoteDevicesIsUsing(bool & isUsing)177 ErrCode DistributedScreenStatusManager::CheckRemoteDevicesIsUsing(bool &isUsing)
178 {
179     std::lock_guard<std::recursive_mutex> lock(mutex_);
180     if (!CheckKvDataManager() || kvStore_ == nullptr) {
181         return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
182     }
183 
184     if (!KvManagerFlowControl() || !KvStoreFlowControl()) {
185         ANS_LOGE("flow control.");
186         return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
187     }
188 
189     std::vector<DistributedHardware::DmDeviceInfo> devInfoList;
190     int32_t ret = DistributedHardware::DeviceManager::GetInstance().GetTrustedDeviceList(APP_ID, "", devInfoList);
191     if (ret != ERR_OK) {
192         ANS_LOGE("Get trust device list failed ret = %{public}d", ret);
193         kvDataManager_.reset();
194         return ERR_ANS_DISTRIBUTED_GET_INFO_FAILED;
195     }
196 
197     DistributedKv::Key prefixKey("");
198     std::vector<DistributedKv::Entry> entries;
199     DistributedKv::Status status = kvStore_->GetEntries(prefixKey, entries);
200     if (status != DistributedKv::Status::SUCCESS) {
201         ANS_LOGE("kvStore GetEntries() failed ret = 0x%{public}x", status);
202         kvStore_.reset();
203         return ERR_ANS_DISTRIBUTED_GET_INFO_FAILED;
204     }
205 
206     for (auto entry : entries) {
207         std::string key = entry.key.ToString();
208         std::string deviceId = key.substr(0, key.find_first_of(DELIMITER));
209         ANS_LOGD("value:%{public}s", entry.value.ToString().c_str());
210         for (auto devInfo : devInfoList) {
211             if (strcmp(devInfo.deviceId, deviceId.c_str()) == 0) {
212                 isUsing = isUsing || (entry.value.ToString() == SCREEN_STATUS_VALUE_ON);
213                 break;
214             }
215         }
216         if (isUsing) {
217             break;
218         }
219     }
220 
221     ANS_LOGI("%{public}s, isUsing:%{public}s", __FUNCTION__, isUsing ? "true" : "false");
222     return ERR_OK;
223 }
224 
SetLocalScreenStatus(bool screenOn)225 ErrCode DistributedScreenStatusManager::SetLocalScreenStatus(bool screenOn)
226 {
227     std::lock_guard<std::recursive_mutex> lock(mutex_);
228     ANS_LOGI("%{public}s, screenOn:%{public}s", __FUNCTION__, screenOn ? "true" : "false");
229     localScreenOn_ = screenOn;
230     if (kvStore_ == nullptr) {
231         return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
232     }
233 
234     if (!KvManagerFlowControl() || !KvStoreFlowControl()) {
235         ANS_LOGE("flow control.");
236         return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
237     }
238 
239     DistributedHardware::DmDeviceInfo localDevice;
240     int32_t ret = DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceInfo(APP_ID, localDevice);
241     if (ret != ERR_OK) {
242         ANS_LOGE("Get trust local device info failed ret = %{public}d", ret);
243         return ERR_ANS_DISTRIBUTED_GET_INFO_FAILED;
244     }
245 
246     DistributedKv::Key kvStoreKey = GenerateDistributedKey(localDevice.deviceId);
247     DistributedKv::Value kvStoreValue = screenOn ? SCREEN_STATUS_VALUE_ON : SCREEN_STATUS_VALUE_OFF;
248     DistributedKv::Status status = kvStore_->Put(kvStoreKey, kvStoreValue);
249     if (status != DistributedKv::Status::SUCCESS) {
250         ANS_LOGE("kvStore Put() failed ret = 0x%{public}x", status);
251         return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
252     }
253 
254     return ERR_OK;
255 }
256 }  // namespace Notification
257 }  // namespace OHOS
258