summaryrefslogtreecommitdiff
path: root/HidlService.h
blob: 76d1c381462e86f24856ecfa30a6db67c0a96dd8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * 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.
 */

#pragma once

#include <set>

#include <android/hidl/manager/1.2/IServiceManager.h>
#include <hidl/Status.h>
#include <hidl/MQDescriptor.h>

namespace android {
namespace hidl {
namespace manager {
namespace implementation {

using ::android::hardware::hidl_vec;
using ::android::hardware::hidl_string;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hidl::base::V1_0::IBase;
using ::android::hidl::manager::V1_0::IServiceNotification;
using ::android::hidl::manager::V1_1::IServiceManager;
using ::android::hidl::manager::V1_2::IClientCallback;
using ::android::sp;

struct HidlService {
    HidlService(const std::string &interfaceName,
                const std::string &instanceName,
                const sp<IBase> &service,
                const pid_t pid);
    HidlService(const std::string &interfaceName,
                const std::string &instanceName)
    : HidlService(
        interfaceName,
        instanceName,
        nullptr,
        static_cast<pid_t>(IServiceManager::PidConstant::NO_PID))
    {}
    virtual ~HidlService() {}

    /**
     * Note, getService() can be nullptr. This is because you can have a HidlService
     * with registered IServiceNotification objects but no service registered yet.
     */
    sp<IBase> getService() const;
    void setService(sp<IBase> service, pid_t pid);
    pid_t getDebugPid() const;
    const std::string &getInterfaceName() const;
    const std::string &getInstanceName() const;

    void addListener(const sp<IServiceNotification> &listener);
    bool removeListener(const wp<IBase> &listener);
    void registerPassthroughClient(pid_t pid);

    // also sends onClients(true) if we have clients
    // knownClientCount, see forceHandleClientCallbacks
    void addClientCallback(const sp<IClientCallback>& callback, size_t knownClientCount);
    bool removeClientCallback(const sp<IClientCallback>& callback);

    // return is if we are guaranteed to have a client
    // knownClientCount, see forceHandleClientCallbacks
    bool handleClientCallbacks(bool isCalledOnInterval, size_t knownClientCount);

    // Updates client callbacks (even if mClientCallbacks is emtpy)
    // see handleClientCallbacks
    //
    // knownClientCount - this is the number of clients that is currently
    // expected to be in use by known actors. This number of clients must be
    // exceeded in order to consider the service to have clients.
    //
    // returns whether or not this service has clients
    bool forceHandleClientCallbacks(bool isCalledOnInterval, size_t knownClientCount);

    // when giving out a handle to a client, but the kernel might not know this yet
    void guaranteeClient();

    std::string string() const; // e.x. "android.hidl.manager@1.0::IServiceManager/manager"
    const std::set<pid_t> &getPassthroughClients() const;

protected:
    // mockable number of clients including hwservicemanager. -1 if not implemented or unavailable.
    virtual ssize_t getNodeStrongRefCount();

private:
    void sendRegistrationNotifications();

    // Also updates mHasClients (of what the last callback was)
    void sendClientCallbackNotifications(bool hasClients);

    // Only sends notification
    void sendClientCallbackNotification(const sp<IClientCallback>& callback, bool hasClients);

    const std::string                     mInterfaceName; // e.x. "android.hidl.manager@1.0::IServiceManager"
    const std::string                     mInstanceName;  // e.x. "manager"
    sp<IBase>                             mService;

    std::vector<sp<IServiceNotification>> mListeners{};
    std::set<pid_t>                       mPassthroughClients{};
    pid_t                                 mPid = static_cast<pid_t>(IServiceManager::PidConstant::NO_PID);

    std::vector<sp<IClientCallback>>      mClientCallbacks{};
    bool                                  mHasClients = false; // notifications sent on true -> false.
    bool                                  mGuaranteeClient = false; // whenever a client is handed out
    size_t                                mNoClientsCounter = 0;
};

}  // namespace implementation
}  // namespace manager
}  // namespace hidl
}  // namespace android