1/* 2 * Copyright (c) 2021 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 "device_info_stub.h" 17 18#include <chrono> 19#include <thread> 20 21#include "beget_ext.h" 22#include "idevice_info.h" 23#include "ipc_skeleton.h" 24#include "accesstoken_kit.h" 25#include "parcel.h" 26#include "string_ex.h" 27#include "if_system_ability_manager.h" 28#include "iservice_registry.h" 29#include "system_ability_definition.h" 30#include "param_comm.h" 31#include "parameter.h" 32#include "sysparam_errno.h" 33#include "init_utils.h" 34#include "deviceinfoservice_ipc_interface_code.h" 35 36namespace OHOS { 37using namespace Security; 38using namespace Security::AccessToken; 39 40namespace device_info { 41REGISTER_SYSTEM_ABILITY_BY_ID(DeviceInfoService, SYSPARAM_DEVICE_SERVICE_ID, true) 42 43static std::mutex g_lock; 44static struct timespec g_lastTime; 45#ifndef STARTUP_INIT_TEST 46static const int DEVICE_INFO_EXIT_TIMEOUT_S = 60; 47#else 48static const int DEVICE_INFO_EXIT_TIMEOUT_S = 3; 49#endif 50static const int DEVICE_INFO_EXIT_WAITTIMES = 12; 51 52 53static int UnloadDeviceInfoSa(void) 54{ 55 { 56 std::unique_lock<std::mutex> lock(g_lock); 57 struct timespec currTimer = {0}; 58 (void)clock_gettime(CLOCK_MONOTONIC, &currTimer); 59 if (IntervalTime(&g_lastTime, &currTimer) < DEVICE_INFO_EXIT_TIMEOUT_S) { 60 return 0; 61 } 62 } 63 DINFO_LOGI("DeviceInfoService::UnloadDeviceInfoSa"); 64 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 65 DINFO_CHECK(sam != nullptr, return 0, "GetSystemAbilityManager return null"); 66 67 int32_t ret = sam->UnloadSystemAbility(SYSPARAM_DEVICE_SERVICE_ID); 68 DINFO_CHECK(ret == ERR_OK, return 0, "UnLoadSystemAbility deviceinfo sa failed"); 69 return 1; 70} 71 72int32_t DeviceInfoStub::OnRemoteRequest(uint32_t code, 73 MessageParcel &data, MessageParcel &reply, MessageOption &option) 74{ 75 std::u16string myDescriptor = IDeviceInfo::GetDescriptor(); 76 std::u16string remoteDescriptor = data.ReadInterfaceToken(); 77 DINFO_CHECK(myDescriptor == remoteDescriptor, return ERR_FAIL, "Invalid remoteDescriptor"); 78 79 { 80 std::unique_lock<std::mutex> lock(g_lock); 81 (void)clock_gettime(CLOCK_MONOTONIC, &g_lastTime); 82 } 83 84 int ret = ERR_FAIL; 85 switch (code) { 86 case static_cast<uint32_t> (DeviceInfoInterfaceCode::COMMAND_GET_UDID): { 87 if (!CheckPermission(data, "ohos.permission.sec.ACCESS_UDID")) { 88 return SYSPARAM_PERMISSION_DENIED; 89 } 90 char localDeviceInfo[UDID_LEN] = {0}; 91 ret = GetDevUdid_(localDeviceInfo, UDID_LEN); 92 DINFO_CHECK(ret == 0, break, "Failed to get dev udid"); 93 reply.WriteString16(Str8ToStr16(localDeviceInfo)); 94 break; 95 } 96 case static_cast<uint32_t> (DeviceInfoInterfaceCode::COMMAND_GET_SERIAL_ID): { 97 if (!CheckPermission(data, "ohos.permission.sec.ACCESS_UDID")) { 98 return SYSPARAM_PERMISSION_DENIED; 99 } 100 const char *serialNumber = GetSerial_(); 101 DINFO_CHECK(serialNumber != nullptr, break, "Failed to get serialNumber"); 102 reply.WriteString16(Str8ToStr16(serialNumber)); 103 ret = ERR_NONE; 104 break; 105 } 106 default: { 107 return IPCObjectStub::OnRemoteRequest(code, data, reply, option); 108 } 109 } 110 return ret; 111} 112 113bool DeviceInfoStub::CheckPermission(MessageParcel &data, const std::string &permission) 114{ 115 AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID(); 116 int32_t result = TypePermissionState::PERMISSION_GRANTED; 117 int32_t tokenType = AccessTokenKit::GetTokenTypeFlag(callerToken); 118 if (tokenType == TOKEN_INVALID) { 119 DINFO_LOGE("AccessToken type:%d, permission:%d denied!", tokenType, callerToken); 120 return false; 121 } else { 122 result = AccessTokenKit::VerifyAccessToken(callerToken, permission); 123 } 124 if (result == TypePermissionState::PERMISSION_DENIED) { 125 DINFO_LOGE("permission:%s denied!", permission.c_str()); 126 return false; 127 } 128 return true; 129} 130 131int32_t DeviceInfoService::GetUdid(std::string& result) 132{ 133 return 0; 134} 135int32_t DeviceInfoService::GetSerialID(std::string& result) 136{ 137 return 0; 138} 139 140void DeviceInfoService::OnStart(void) 141{ 142 int level = GetIntParameter(INIT_DEBUG_LEVEL, (int)INIT_INFO); 143 SetInitLogLevel((InitLogLevel)level); 144 DINFO_LOGI("DeviceInfoService OnStart"); 145 bool res = Publish(this); 146 if (!res) { 147 DINFO_LOGE("DeviceInfoService Publish failed"); 148 } 149 threadStarted_ = true; 150 std::thread([this] {this->ThreadForUnloadSa();}).detach(); 151 return; 152} 153 154void DeviceInfoService::OnStop(void) 155{ 156 threadStarted_ = false; 157 DINFO_LOGI("DeviceInfoService OnStop"); 158} 159 160int DeviceInfoService::Dump(int fd, const std::vector<std::u16string>& args) 161{ 162 (void)args; 163 DINFO_LOGI("DeviceInfoService Dump"); 164 DINFO_CHECK(fd >= 0, return -1, "Invalid fd for dump %d", fd); 165 return dprintf(fd, "%s\n", "No information to dump for this service"); 166} 167 168void DeviceInfoService::ThreadForUnloadSa(void) 169{ 170 while (1) { 171 std::this_thread::sleep_for(std::chrono::seconds(DEVICE_INFO_EXIT_TIMEOUT_S / DEVICE_INFO_EXIT_WAITTIMES)); 172 if (!threadStarted_) { 173 break; 174 } 175 if (UnloadDeviceInfoSa() == 1) { 176 break; 177 } 178 } 179} 180} // namespace device_info 181} // namespace OHOS 182