1d9f0492fSopenharmony_ci/* 2d9f0492fSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License. 5d9f0492fSopenharmony_ci * You may obtain a copy of the License at 6d9f0492fSopenharmony_ci * 7d9f0492fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d9f0492fSopenharmony_ci * 9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and 13d9f0492fSopenharmony_ci * limitations under the License. 14d9f0492fSopenharmony_ci */ 15d9f0492fSopenharmony_ci#include "device_info_kits.h" 16d9f0492fSopenharmony_ci 17d9f0492fSopenharmony_ci#include "beget_ext.h" 18d9f0492fSopenharmony_ci#include "device_info_proxy.h" 19d9f0492fSopenharmony_ci#include "device_info_load.h" 20d9f0492fSopenharmony_ci#include "idevice_info.h" 21d9f0492fSopenharmony_ci#include "if_system_ability_manager.h" 22d9f0492fSopenharmony_ci#include "iservice_registry.h" 23d9f0492fSopenharmony_ci#include "system_ability_definition.h" 24d9f0492fSopenharmony_ci#include "securec.h" 25d9f0492fSopenharmony_ci#include "sysparam_errno.h" 26d9f0492fSopenharmony_ci 27d9f0492fSopenharmony_cinamespace OHOS { 28d9f0492fSopenharmony_cinamespace device_info { 29d9f0492fSopenharmony_ci 30d9f0492fSopenharmony_cistatic const int DEVINFO_SAID = 3902; 31d9f0492fSopenharmony_cistatic const int DEVICEINFO_LOAD_SA_TIMEOUT_MS = 5000; 32d9f0492fSopenharmony_ci 33d9f0492fSopenharmony_ciDeviceInfoKits::DeviceInfoKits() {} 34d9f0492fSopenharmony_ci 35d9f0492fSopenharmony_ciDeviceInfoKits::~DeviceInfoKits() {} 36d9f0492fSopenharmony_ci 37d9f0492fSopenharmony_ciDeviceInfoKits &DeviceInfoKits::GetInstance() 38d9f0492fSopenharmony_ci{ 39d9f0492fSopenharmony_ci return DelayedRefSingleton<DeviceInfoKits>::GetInstance(); 40d9f0492fSopenharmony_ci} 41d9f0492fSopenharmony_ci 42d9f0492fSopenharmony_civoid DeviceInfoKits::LoadDeviceInfoSa(std::unique_lock<std::mutex> &lock) 43d9f0492fSopenharmony_ci{ 44d9f0492fSopenharmony_ci DINFO_LOGV("deviceInfoService_ is %d", deviceInfoService_ == nullptr); 45d9f0492fSopenharmony_ci if (deviceInfoService_ != nullptr) { 46d9f0492fSopenharmony_ci return; 47d9f0492fSopenharmony_ci } 48d9f0492fSopenharmony_ci auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 49d9f0492fSopenharmony_ci DINFO_CHECK(sam != nullptr, return, "GetSystemAbilityManager return null"); 50d9f0492fSopenharmony_ci 51d9f0492fSopenharmony_ci auto remoteObject = sam->CheckSystemAbility(DEVINFO_SAID); 52d9f0492fSopenharmony_ci if (remoteObject) { 53d9f0492fSopenharmony_ci DINFO_LOGV("deviceinfo sa is already loaded"); 54d9f0492fSopenharmony_ci deviceInfoService_ = iface_cast<IDeviceInfo>(remoteObject); 55d9f0492fSopenharmony_ci return; 56d9f0492fSopenharmony_ci } 57d9f0492fSopenharmony_ci sptr<DeviceInfoLoad> deviceInfoLoad = new (std::nothrow) DeviceInfoLoad(); 58d9f0492fSopenharmony_ci DINFO_CHECK(deviceInfoLoad != nullptr, return, "new deviceInfoLoad fail."); 59d9f0492fSopenharmony_ci 60d9f0492fSopenharmony_ci int32_t ret = sam->LoadSystemAbility(SYSPARAM_DEVICE_SERVICE_ID, deviceInfoLoad); 61d9f0492fSopenharmony_ci DINFO_CHECK(ret == ERR_OK, return, "LoadSystemAbility deviceinfo sa failed"); 62d9f0492fSopenharmony_ci 63d9f0492fSopenharmony_ci if (deathRecipient_ == nullptr) { 64d9f0492fSopenharmony_ci deathRecipient_ = new DeathRecipient(); 65d9f0492fSopenharmony_ci } 66d9f0492fSopenharmony_ci 67d9f0492fSopenharmony_ci // wait_for release lock and block until time out(60s) or match the condition with notice 68d9f0492fSopenharmony_ci auto waitStatus = deviceInfoLoadCon_.wait_for(lock, std::chrono::milliseconds(DEVICEINFO_LOAD_SA_TIMEOUT_MS), 69d9f0492fSopenharmony_ci [this]() { return deviceInfoService_ != nullptr; }); 70d9f0492fSopenharmony_ci if (!waitStatus || deviceInfoService_ == nullptr) { 71d9f0492fSopenharmony_ci // time out or loadcallback fail 72d9f0492fSopenharmony_ci DINFO_LOGE("tokensync load sa timeout"); 73d9f0492fSopenharmony_ci return; 74d9f0492fSopenharmony_ci } 75d9f0492fSopenharmony_ci 76d9f0492fSopenharmony_ci // for dead 77d9f0492fSopenharmony_ci auto object = deviceInfoService_->AsObject(); 78d9f0492fSopenharmony_ci if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient_))) { 79d9f0492fSopenharmony_ci DINFO_LOGE("Failed to add death recipient"); 80d9f0492fSopenharmony_ci } 81d9f0492fSopenharmony_ci} 82d9f0492fSopenharmony_ci 83d9f0492fSopenharmony_cisptr<IDeviceInfo> DeviceInfoKits::GetService(std::unique_lock<std::mutex> &lock) 84d9f0492fSopenharmony_ci{ 85d9f0492fSopenharmony_ci LoadDeviceInfoSa(lock); 86d9f0492fSopenharmony_ci return deviceInfoService_; 87d9f0492fSopenharmony_ci} 88d9f0492fSopenharmony_ci 89d9f0492fSopenharmony_civoid DeviceInfoKits::FinishStartSASuccess(const sptr<IRemoteObject> &remoteObject) 90d9f0492fSopenharmony_ci{ 91d9f0492fSopenharmony_ci DINFO_LOGI("get deviceinfo sa success."); 92d9f0492fSopenharmony_ci // get lock which wait_for release and send a notice so that wait_for can out of block 93d9f0492fSopenharmony_ci std::unique_lock<std::mutex> lock(lock_); 94d9f0492fSopenharmony_ci deviceInfoService_ = iface_cast<IDeviceInfo>(remoteObject); 95d9f0492fSopenharmony_ci deviceInfoLoadCon_.notify_one(); 96d9f0492fSopenharmony_ci} 97d9f0492fSopenharmony_ci 98d9f0492fSopenharmony_civoid DeviceInfoKits::FinishStartSAFailed() 99d9f0492fSopenharmony_ci{ 100d9f0492fSopenharmony_ci DINFO_LOGI("Get deviceinfo sa failed."); 101d9f0492fSopenharmony_ci // get lock which wait_for release and send a notice 102d9f0492fSopenharmony_ci std::unique_lock<std::mutex> lock(lock_); 103d9f0492fSopenharmony_ci deviceInfoService_ = nullptr; 104d9f0492fSopenharmony_ci deviceInfoLoadCon_.notify_one(); 105d9f0492fSopenharmony_ci} 106d9f0492fSopenharmony_ci 107d9f0492fSopenharmony_ciint32_t DeviceInfoKits::GetUdid(std::string& result) 108d9f0492fSopenharmony_ci{ 109d9f0492fSopenharmony_ci std::unique_lock<std::mutex> lock(lock_); 110d9f0492fSopenharmony_ci static std::optional<std::pair<int32_t, std::string>> resultPair; 111d9f0492fSopenharmony_ci if (resultPair.has_value()) { 112d9f0492fSopenharmony_ci int32_t ret = resultPair->first; 113d9f0492fSopenharmony_ci result = resultPair->second; 114d9f0492fSopenharmony_ci DINFO_LOGV("GetUdid from resultPair ret = %d", ret); 115d9f0492fSopenharmony_ci return ret; 116d9f0492fSopenharmony_ci } 117d9f0492fSopenharmony_ci auto deviceService = GetService(lock); 118d9f0492fSopenharmony_ci DINFO_CHECK(deviceService != nullptr, return -1, "Failed to get deviceinfo manager"); 119d9f0492fSopenharmony_ci int ret = deviceService->GetUdid(result); 120d9f0492fSopenharmony_ci DINFO_LOGV("GetSerialID from remote ret = %d", ret); 121d9f0492fSopenharmony_ci if (ret == 0 || ret == SYSPARAM_PERMISSION_DENIED) { 122d9f0492fSopenharmony_ci resultPair = std::make_optional(std::make_pair(ret, result)); 123d9f0492fSopenharmony_ci } 124d9f0492fSopenharmony_ci return ret; 125d9f0492fSopenharmony_ci} 126d9f0492fSopenharmony_ci 127d9f0492fSopenharmony_ciint32_t DeviceInfoKits::GetSerialID(std::string& result) 128d9f0492fSopenharmony_ci{ 129d9f0492fSopenharmony_ci std::unique_lock<std::mutex> lock(lock_); 130d9f0492fSopenharmony_ci static std::optional<std::pair<int32_t, std::string>> resultPair; 131d9f0492fSopenharmony_ci if (resultPair.has_value()) { 132d9f0492fSopenharmony_ci int32_t ret = resultPair->first; 133d9f0492fSopenharmony_ci result = resultPair->second; 134d9f0492fSopenharmony_ci DINFO_LOGV("GetSerialID from resultPair ret = %d", ret); 135d9f0492fSopenharmony_ci return ret; 136d9f0492fSopenharmony_ci } 137d9f0492fSopenharmony_ci auto deviceService = GetService(lock); 138d9f0492fSopenharmony_ci DINFO_CHECK(deviceService != nullptr, return -1, "Failed to get deviceinfo manager"); 139d9f0492fSopenharmony_ci int ret = deviceService->GetSerialID(result); 140d9f0492fSopenharmony_ci DINFO_LOGV("GetSerialID from remote ret = %d", ret); 141d9f0492fSopenharmony_ci if (ret == 0 || ret == SYSPARAM_PERMISSION_DENIED) { 142d9f0492fSopenharmony_ci resultPair = std::make_optional(std::make_pair(ret, result)); 143d9f0492fSopenharmony_ci } 144d9f0492fSopenharmony_ci return ret; 145d9f0492fSopenharmony_ci} 146d9f0492fSopenharmony_ci 147d9f0492fSopenharmony_civoid DeviceInfoKits::DeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote) 148d9f0492fSopenharmony_ci{ 149d9f0492fSopenharmony_ci DelayedRefSingleton<DeviceInfoKits>::GetInstance().ResetService(remote); 150d9f0492fSopenharmony_ci} 151d9f0492fSopenharmony_ci 152d9f0492fSopenharmony_civoid DeviceInfoKits::ResetService(const wptr<IRemoteObject> &remote) 153d9f0492fSopenharmony_ci{ 154d9f0492fSopenharmony_ci DINFO_LOGI("Remote is dead, reset service instance"); 155d9f0492fSopenharmony_ci std::lock_guard<std::mutex> lock(lock_); 156d9f0492fSopenharmony_ci if (deviceInfoService_ != nullptr) { 157d9f0492fSopenharmony_ci sptr<IRemoteObject> object = deviceInfoService_->AsObject(); 158d9f0492fSopenharmony_ci if ((object != nullptr) && (remote == object)) { 159d9f0492fSopenharmony_ci object->RemoveDeathRecipient(deathRecipient_); 160d9f0492fSopenharmony_ci deviceInfoService_ = nullptr; 161d9f0492fSopenharmony_ci } 162d9f0492fSopenharmony_ci } 163d9f0492fSopenharmony_ci} 164d9f0492fSopenharmony_ci} // namespace device_info 165d9f0492fSopenharmony_ci} // namespace OHOS 166