summaryrefslogtreecommitdiff
path: root/ServiceManager.h
blob: 38bda57a6f3c2d8e2f5c0a5426e8d3ea5bc02f82 (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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
 * 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 <android/hidl/manager/1.2/IServiceManager.h>
#include <hidl/Status.h>
#include <hidl/MQDescriptor.h>
#include <map>

#include "AccessControl.h"
#include "HidlService.h"

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

using ::android::hardware::hidl_death_recipient;
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_2::IClientCallback;
using ::android::sp;
using ::android::wp;

struct ServiceManager : public V1_2::IServiceManager, hidl_death_recipient {
    // Methods from ::android::hidl::manager::V1_0::IServiceManager follow.
    Return<sp<IBase>> get(const hidl_string& fqName,
                          const hidl_string& name) override;
    Return<bool> add(const hidl_string& name,
                     const sp<IBase>& service) override;

    Return<Transport> getTransport(const hidl_string& fqName,
                                   const hidl_string& name);

    Return<void> list(list_cb _hidl_cb) override;
    Return<void> listByInterface(const hidl_string& fqInstanceName,
                                 listByInterface_cb _hidl_cb) override;

    Return<bool> registerForNotifications(const hidl_string& fqName,
                                          const hidl_string& name,
                                          const sp<IServiceNotification>& callback) override;

    Return<void> debugDump(debugDump_cb _cb) override;
    Return<void> registerPassthroughClient(const hidl_string &fqName,
            const hidl_string &name) override;

    // Methods from ::android::hidl::manager::V1_1::IServiceManager follow.
    Return<bool> unregisterForNotifications(const hidl_string& fqName,
                                            const hidl_string& name,
                                            const sp<IServiceNotification>& callback) override;

    // Methods from ::android::hidl::manager::V1_2::IServiceManager follow.
    Return<bool> registerClientCallback(const hidl_string& fqName,
                                        const hidl_string& name,
                                        const sp<IBase>& server,
                                        const sp<IClientCallback>& cb) override;
    Return<bool> unregisterClientCallback(const sp<IBase>& server,
                                          const sp<IClientCallback>& cb) override;
    Return<bool> addWithChain(const hidl_string& name,
                              const sp<IBase>& service,
                              const hidl_vec<hidl_string>& chain) override;
    Return<void> listManifestByInterface(const hidl_string& fqInstanceName,
                                         listManifestByInterface_cb _hidl_cb) override;
    Return<bool> tryUnregister(const hidl_string& fqName,
                               const hidl_string& name,
                               const sp<IBase>& service) override;

    void handleClientCallbacks();

    virtual void serviceDied(uint64_t cookie, const wp<IBase>& who);
private:
    bool addImpl(const std::string& name,
                 const sp<IBase>& service,
                 const hidl_vec<hidl_string>& interfaceChain,
                 const AccessControl::CallingContext& callingContext);

    // if restrictToInstanceName is nullptr, remove all, otherwise only those services
    // which match this instance name. Returns whether all instances were removed.
    bool removeService(const wp<IBase>& who, const std::string* restrictToInstanceName);
    bool removePackageListener(const wp<IBase>& who);
    bool removeServiceListener(const wp<IBase>& who);
    size_t countExistingService() const;

    // true = continue, false = break
    void forEachExistingService(std::function<bool(const HidlService *)> f) const;
    void forEachExistingService(std::function<bool(HidlService *)> f);
    void forEachServiceEntry(std::function<bool(const HidlService *)> f) const;
    void forEachServiceEntry(std::function<bool(HidlService *)> f);

    HidlService* lookup(const std::string& fqName, const std::string& name);

    using InstanceMap = std::map<
            std::string, // instance name e.x. "manager"
            std::unique_ptr<HidlService>
        >;

    struct PackageInterfaceMap {
        InstanceMap &getInstanceMap();
        const InstanceMap &getInstanceMap() const;

        /**
         * Finds a HidlService with the desired name. If none,
         * returns nullptr. HidlService::getService() might also be nullptr
         * if there are registered IServiceNotification objects for it. Return
         * value should be treated as a temporary reference.
         */
        HidlService *lookup(
            const std::string &name);
        const HidlService *lookup(
            const std::string &name) const;

        void insertService(std::unique_ptr<HidlService> &&service);

        void addPackageListener(sp<IServiceNotification> listener);
        bool removePackageListener(const wp<IBase>& who);
        bool removeServiceListener(const wp<IBase>& who);

        void sendPackageRegistrationNotification(
            const hidl_string &fqName,
            const hidl_string &instanceName);

    private:
        InstanceMap mInstanceMap{};

        std::vector<sp<IServiceNotification>> mPackageListeners{};
    };

    AccessControl mAcl;

    /**
     * Access to this map doesn't need to be locked, since hwservicemanager
     * is single-threaded.
     *
     * e.x.
     * mServiceMap["android.hidl.manager@1.0::IServiceManager"]["manager"]
     *     -> HidlService object
     */
    std::map<
        std::string, // package::interface e.x. "android.hidl.manager@1.0::IServiceManager"
        PackageInterfaceMap
    > mServiceMap;
};

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