device_info_stub.cpp 5.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "device_info_stub.h"

C
cheng_jinsong 已提交
18
#include <chrono>
C
cheng_jinsong 已提交
19
#include <thread>
C
cheng_jinsong 已提交
20

21 22 23 24 25 26
#include "beget_ext.h"
#include "idevice_info.h"
#include "ipc_skeleton.h"
#include "accesstoken_kit.h"
#include "parcel.h"
#include "string_ex.h"
C
cheng_jinsong 已提交
27 28
#include "if_system_ability_manager.h"
#include "iservice_registry.h"
29 30
#include "system_ability_definition.h"
#include "param_comm.h"
C
cheng_jinsong 已提交
31
#include "parameter.h"
C
chengjinsong2 已提交
32
#include "sysparam_errno.h"
C
cheng_jinsong 已提交
33
#include "init_utils.h"
Z
IPCfix  
zhaohaoran 已提交
34
#include "deviceinfoservice_ipc_interface_code.h"
35 36 37 38 39 40 41 42

namespace OHOS {
using namespace Security;
using namespace Security::AccessToken;

namespace device_info {
REGISTER_SYSTEM_ABILITY_BY_ID(DeviceInfoService, SYSPARAM_DEVICE_SERVICE_ID, true)

C
cheng_jinsong 已提交
43
static std::mutex g_lock;
C
cheng_jinsong 已提交
44
static struct timespec g_lastTime;
C
cheng_jinsong 已提交
45
#ifndef STARTUP_INIT_TEST
C
cheng_jinsong 已提交
46
static const int DEVICE_INFO_EXIT_TIMEOUT_S = 15;
C
cheng_jinsong 已提交
47
#else
C
cheng_jinsong 已提交
48
static const int DEVICE_INFO_EXIT_TIMEOUT_S = 3;
C
cheng_jinsong 已提交
49 50
#endif

C
cheng_jinsong 已提交
51
static int UnloadDeviceInfoSa(void)
C
cheng_jinsong 已提交
52
{
53 54
    {
        std::unique_lock<std::mutex> lock(g_lock);
C
cheng_jinsong 已提交
55
        struct timespec currTimer = {0};
C
cheng_jinsong 已提交
56 57
        (void)clock_gettime(CLOCK_MONOTONIC, &currTimer);
        if (IntervalTime(&g_lastTime, &currTimer) < DEVICE_INFO_EXIT_TIMEOUT_S) {
C
cheng_jinsong 已提交
58
            return 0;
59
        }
C
cheng_jinsong 已提交
60 61 62
    }
    DINFO_LOGI("DeviceInfoService::UnloadDeviceInfoSa");
    auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
C
cheng_jinsong 已提交
63
    DINFO_CHECK(sam != nullptr, return 0, "GetSystemAbilityManager return null");
C
cheng_jinsong 已提交
64 65

    int32_t ret = sam->UnloadSystemAbility(SYSPARAM_DEVICE_SERVICE_ID);
C
cheng_jinsong 已提交
66 67
    DINFO_CHECK(ret == ERR_OK, return 0, "UnLoadSystemAbility deviceinfo sa failed");
    return 1;
C
cheng_jinsong 已提交
68 69
}

70 71 72
int32_t DeviceInfoStub::OnRemoteRequest(uint32_t code,
    MessageParcel &data, MessageParcel &reply, MessageOption &option)
{
C
chengjinsong2 已提交
73 74 75
    std::u16string myDescriptor = IDeviceInfo::GetDescriptor();
    std::u16string remoteDescriptor = data.ReadInterfaceToken();
    DINFO_CHECK(myDescriptor == remoteDescriptor, return ERR_FAIL, "Invalid remoteDescriptor");
76

C
cheng_jinsong 已提交
77 78
    {
        std::unique_lock<std::mutex> lock(g_lock);
C
cheng_jinsong 已提交
79
        (void)clock_gettime(CLOCK_MONOTONIC, &g_lastTime);
C
cheng_jinsong 已提交
80 81
    }

82 83
    int ret = ERR_FAIL;
    switch (code) {
Z
IPCfix  
zhaohaoran 已提交
84
        case static_cast<uint32_t> (DeviceInfoInterfaceCode::COMMAND_GET_UDID): {
C
cheng_jinsong 已提交
85
            if (!CheckPermission(data, "ohos.permission.sec.ACCESS_UDID")) {
C
chengjinsong2 已提交
86
                return SYSPARAM_PERMISSION_DENIED;
87 88 89 90 91 92 93
            }
            char localDeviceInfo[UDID_LEN] = {0};
            ret = GetDevUdid_(localDeviceInfo, UDID_LEN);
            DINFO_CHECK(ret == 0, break, "Failed to get dev udid");
            reply.WriteString16(Str8ToStr16(localDeviceInfo));
            break;
        }
Z
IPCfix  
zhaohaoran 已提交
94
        case static_cast<uint32_t> (DeviceInfoInterfaceCode::COMMAND_GET_SERIAL_ID): {
C
cheng_jinsong 已提交
95
            if (!CheckPermission(data, "ohos.permission.sec.ACCESS_UDID")) {
C
chengjinsong2 已提交
96
                return SYSPARAM_PERMISSION_DENIED;
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
            }
            const char *serialNumber = GetSerial_();
            DINFO_CHECK(serialNumber != nullptr, break, "Failed to get serialNumber");
            reply.WriteString16(Str8ToStr16(serialNumber));
            break;
        }
        default: {
            return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
        }
    }
    return ret;
}

bool DeviceInfoStub::CheckPermission(MessageParcel &data, const std::string &permission)
{
    AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
    int32_t result = TypePermissionState::PERMISSION_GRANTED;
    int32_t tokenType = AccessTokenKit::GetTokenTypeFlag(callerToken);
115
    if (tokenType == TOKEN_INVALID) {
116 117
        DINFO_LOGE("AccessToken type:%d, permission:%d denied!", tokenType, callerToken);
        return false;
118 119
    } else {
        result = AccessTokenKit::VerifyAccessToken(callerToken, permission);
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
    }
    if (result == TypePermissionState::PERMISSION_DENIED) {
        DINFO_LOGE("AccessTokenID:%d, permission:%s denied!", callerToken, permission.c_str());
        return false;
    }
    DINFO_LOGI("tokenType %d dAccessTokenID:%d, permission:%s matched!", tokenType, callerToken, permission.c_str());
    return true;
}

int32_t DeviceInfoService::GetUdid(std::string& result)
{
    return 0;
}
int32_t DeviceInfoService::GetSerialID(std::string& result)
{
    return 0;
}

void DeviceInfoService::OnStart(void)
{
C
cheng_jinsong 已提交
140 141
    int level = GetIntParameter(INIT_DEBUG_LEVEL, (int)INIT_INFO);
    SetInitLogLevel((InitLogLevel)level);
C
cheng_jinsong 已提交
142
    DINFO_LOGI("DeviceInfoService OnStart");
143 144
    bool res = Publish(this);
    if (!res) {
C
cheng_jinsong 已提交
145
        DINFO_LOGE("DeviceInfoService Publish failed");
146
    }
C
cheng_jinsong 已提交
147 148
    threadStarted_ = true;
    std::thread(&DeviceInfoService::ThreadForUnloadSa, this).detach();
149 150
    return;
}
C
cheng_jinsong 已提交
151 152 153

void DeviceInfoService::OnStop(void)
{
C
cheng_jinsong 已提交
154
    threadStarted_ = false;
C
cheng_jinsong 已提交
155
    DINFO_LOGI("DeviceInfoService OnStop");
C
cheng_jinsong 已提交
156 157 158
}

int DeviceInfoService::Dump(int fd, const std::vector<std::u16string>& args)
159
{
C
cheng_jinsong 已提交
160 161 162 163
    (void)args;
    DINFO_LOGI("DeviceInfoService Dump");
    DINFO_CHECK(fd >= 0, return -1, "Invalid fd for dump %d", fd);
    return dprintf(fd, "%s\n", "No information to dump for this service");
164
}
C
cheng_jinsong 已提交
165 166 167 168 169 170 171 172 173 174 175 176 177

void DeviceInfoService::ThreadForUnloadSa(void)
{
    while (1) {
        std::this_thread::sleep_for(std::chrono::seconds(DEVICE_INFO_EXIT_TIMEOUT_S / 3)); // 3 count
        if (!threadStarted_) {
            break;
        }
        if (UnloadDeviceInfoSa() == 1) {
            break;
        }
    }
}
178 179
} // namespace device_info
} // namespace OHOS