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