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