1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18#ifndef ANDROID_VINTF_HAL_MANIFEST_H
19#define ANDROID_VINTF_HAL_MANIFEST_H
20
21#include <utils/Errors.h>
22#include <map>
23#include <string>
24#include <vector>
25
26#include "HalGroup.h"
27#include "Level.h"
28#include "ManifestHal.h"
29#include "ManifestInstance.h"
30#include "MapValueIterator.h"
31#include "SchemaType.h"
32#include "SystemSdk.h"
33#include "VendorNdk.h"
34#include "Version.h"
35#include "Vndk.h"
36#include "XmlFileGroup.h"
37
38namespace android {
39namespace vintf {
40
41struct MatrixHal;
42struct CompatibilityMatrix;
43
44namespace details {
45using InstancesOfVersion =
46    std::map<std::string /* interface */, std::set<std::string /* instance */>>;
47using Instances = std::map<Version, InstancesOfVersion>;
48}  // namespace details
49
50// A HalManifest is reported by the hardware and query-able from
51// framework code. This is the API for the framework.
52struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestXmlFile> {
53   public:
54
55    // Construct a device HAL manifest.
56    HalManifest() : mType(SchemaType::DEVICE) {}
57
58    bool add(ManifestHal&& hal) override;
59
60    // Given a component name (e.g. "android.hardware.camera"),
61    // return getHal(name)->transport if the component exist and v exactly matches
62    // one of the versions in that component, else EMPTY
63    Transport getTransport(const std::string &name, const Version &v,
64            const std::string &interfaceName, const std::string &instanceName) const;
65
66    // Check compatibility against a compatibility matrix. Considered compatible if
67    // - framework manifest vs. device compat-mat
68    //     - checkIncompatibility for HALs returns only optional HALs
69    //     - one of manifest.vndk match compat-mat.vndk
70    // - device manifest vs. framework compat-mat
71    //     - checkIncompatibility for HALs returns only optional HALs
72    //     - manifest.sepolicy.version match one of compat-mat.sepolicy.sepolicy-version
73    bool checkCompatibility(const CompatibilityMatrix &mat, std::string *error = nullptr) const;
74
75    // Generate a compatibility matrix such that checkCompatibility will return true.
76    CompatibilityMatrix generateCompatibleMatrix() const;
77
78    // Returns all component names.
79    std::set<std::string> getHalNames() const;
80
81    // Returns all component names and versions, e.g.
82    // "android.hardware.camera.device@1.0", "android.hardware.camera.device@3.2",
83    // "android.hardware.nfc@1.0"]
84    std::set<std::string> getHalNamesAndVersions() const;
85
86    // Type of the manifest. FRAMEWORK or DEVICE.
87    SchemaType type() const;
88    void setType(SchemaType type);
89
90    // FCM version that it implements.
91    Level level() const;
92
93    // device.mSepolicyVersion. Assume type == device.
94    // Abort if type != device.
95    const Version &sepolicyVersion() const;
96
97    // framework.mVendorNdks. Assume type == framework.
98    // Abort if type != framework.
99    const std::vector<VendorNdk>& vendorNdks() const;
100
101    // If the corresponding <xmlfile> with the given version exists,
102    // - Return the overridden <path> if it is present,
103    // - otherwise the default value: /{system,vendor}/etc/<name>_V<major>_<minor>.xml
104    // Otherwise if the <xmlfile> entry does not exist, "" is returned.
105    std::string getXmlFilePath(const std::string& xmlFileName, const Version& version) const;
106
107    // Get metaversion of this manifest.
108    Version getMetaVersion() const;
109
110    bool forEachInstanceOfVersion(
111        const std::string& package, const Version& expectVersion,
112        const std::function<bool(const ManifestInstance&)>& func) const override;
113
114    // Alternative to forEachInstance if you just need a set of instance names instead.
115    std::set<std::string> getInstances(const std::string& halName, const Version& version,
116                                       const std::string& interfaceName) const;
117
118    // Return whether instance is in getInstances(...).
119    bool hasInstance(const std::string& halName, const Version& version,
120                     const std::string& interfaceName, const std::string& instance) const;
121
122   protected:
123    // Check before add()
124    bool shouldAdd(const ManifestHal& toAdd) const override;
125    bool shouldAddXmlFile(const ManifestXmlFile& toAdd) const override;
126
127   private:
128    friend struct HalManifestConverter;
129    friend class VintfObject;
130    friend class AssembleVintfImpl;
131    friend struct LibVintfTest;
132    friend std::string dump(const HalManifest &vm);
133    friend bool operator==(const HalManifest &lft, const HalManifest &rgt);
134
135    status_t fetchAllInformation(const std::string& path, std::string* error = nullptr);
136
137    details::Instances expandInstances(const std::string& name) const;
138    // Check if all instances in matrixHal is supported in this manifest.
139    bool isCompatible(const details::Instances& instances, const MatrixHal& matrixHal) const;
140
141    // Return a list of error messages (for each <hal> name) that does NOT conform to
142    // the given compatibility matrix. It does not contain components that are optional.
143    // That is, return empty list iff
144    // (instance in matrix) => (instance in manifest).
145    std::vector<std::string> checkIncompatibleHals(const CompatibilityMatrix& mat) const;
146
147    void removeHals(const std::string& name, size_t majorVer);
148
149    // Returns a list of instance names that are in this manifest but
150    // are not specified in the given matrix, whether the HAL is specified as an optional or
151    // required HAL.
152    // That is, return empty list iff
153    // (instance in manifest) => (instance in matrix).
154    std::set<std::string> checkUnusedHals(const CompatibilityMatrix& mat) const;
155
156    SchemaType mType;
157    Level mLevel = Level::UNSPECIFIED;
158    // version attribute. Default is 1.0 for manifests created programatically.
159    Version mMetaVersion{1, 0};
160
161    // entries for device hal manifest only
162    struct {
163        Version mSepolicyVersion;
164    } device;
165
166    // entries for framework hal manifest only
167    struct {
168#pragma clang diagnostic push
169#pragma clang diagnostic ignored "-Wdeprecated-declarations"
170        std::vector<Vndk> mVndks;
171#pragma clang diagnostic pop
172
173        std::vector<VendorNdk> mVendorNdks;
174        SystemSdk mSystemSdk;
175    } framework;
176};
177
178
179} // namespace vintf
180} // namespace android
181
182#endif // ANDROID_VINTF_HAL_MANIFEST_H
183