1/*
2 * Copyright (c) 2021-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#ifndef HISTREAMER_PLUGIN_INTF_PLUGIN_DEFINITION_H
17#define HISTREAMER_PLUGIN_INTF_PLUGIN_DEFINITION_H
18
19#include <functional>
20#include <string>
21#include <memory>
22#include "plugin/common/plugin_types.h"
23
24namespace OHOS {
25namespace Media {
26namespace Plugin {
27/**
28 * @brief Macro definition, creating the version information.
29 *
30 * @details The versioning is the process of assigning a unique version number to a unique state
31 * of plugin interface. Within a given version number category (major, minor), these numbers are
32 * usually assigned in ascending order and correspond to new developments in the plugin.
33 *
34 * Given a version number MAJOR.MINOR:
35 *  - MAJOR: When you make incompatible API changes.
36 *  - MINOR: When you add features in a backwards-compatible manner or do backwards-compatible bug fixes.
37 */
38#define MAKE_VERSION(MAJOR, MINOR) ((((MAJOR)&0xFFFF) << 16) | ((MINOR)&0xFFFF))
39
40/// Plugin interface major number
41#define PLUGIN_INTERFACE_VERSION_MAJOR (1)
42
43/// Plugin interface minor number
44#define PLUGIN_INTERFACE_VERSION_MINOR (0)
45
46/// Plugin interface version
47#define PLUGIN_INTERFACE_VERSION MAKE_VERSION(PLUGIN_INTERFACE_VERSION_MAJOR, PLUGIN_INTERFACE_VERSION_MINOR)
48
49/**
50 * @enum License Type.
51 * an official permission or permit.
52 *
53 * @since 1.0
54 * @version 1.0
55 */
56enum struct LicenseType : uint8_t {
57    APACHE_V2, ///< The Apache License 2.0
58    LGPL,      ///< The GNU Lesser General Public License
59    GPL,       ///< The GNU General Public License
60    CC0,       ///< The Creative Commons Zero v1.0 Universal
61    UNKNOWN,   ///< Unknown License
62};
63
64/**
65 * @brief Definition of plugin packaging information.
66 *
67 * @since 1.0
68 * @version 1.0
69 */
70struct PackageDef {
71    uint32_t pkgVersion;    ///< Package information version, which indicates the latest plug-in interface version
72                            ///< used by the plugin in the package. The default value is PLUGIN_INTERFACE_VERSION.
73
74    std::string name;   ///< Package name. The plugin framework registers the plugin using this name.
75                        ///< If the plugins are packaged as a dynamic library, the name of library
76                        ///< must be in the format of "libplugin_<name>.so".
77
78    LicenseType
79        licenseType;    ///< The License information of the plugin in the package.
80                        ///< The different plugins must be the same.
81                        ///< The plugin framework processing in the plugin running state based on different license.
82};
83
84/// Plugin create function. All plugins must implement this function.
85template <typename T>
86using PluginCreatorFunc = std::function<std::shared_ptr<T>(const std::string& name)>;
87
88/**
89 * @brief Describes the basic information about the plugin.
90 *
91 * @since 1.0
92 * @version 1.0
93 */
94struct PluginDefBase {
95    uint32_t apiVersion; ///< Versions of different plugins. Different types of plugin have their own versions.
96
97    PluginType pluginType = PluginType::INVALID_TYPE; ///< Describe the plugin type, e.g. 'source', 'codec'.
98
99    std::string name;   ///< Indicates the name of a plugin. The name of the same type plugins must be unique.
100                        ///< Plugins with the same name may fail to be registered.
101
102    std::string description; ///< Detailed description of the plugin.
103
104    uint32_t rank;  ///< Plugin score. The plugin with a high score may be preferred. You can evaluate the
105                    ///< plugin score in terms of performance, version support, and license. Range: 0 to 100.
106};
107
108/**
109 * @brief The plugin registration interface.
110 * The plugin framework will provide the implementation.
111 * Developers only need to invoke the API to register the plugin.
112 *
113 * @since 1.0
114 * @version 1.0
115 */
116struct Register {
117    virtual ~Register() = default;
118    /**
119     * @brief Register the plugin.
120     *
121     * @param def   Basic information about the plugin
122     * @return  Registration status return
123     *  @retval OK: The plugin is registered succeed.
124     *  @retval ERROR_PLUGIN_ALREADY_EXISTS: The plugin already exists in plugin registered.
125     *  @retval ERROR_INCOMPATIBLE_VERSION: Incompatible version during plugin registration.
126     */
127    virtual Status AddPlugin(const PluginDefBase& def) = 0;
128};
129
130/**
131 * @brief The package registration interface.
132 * The plugin framework will provide the implementation and auto invoke the API to
133 * finish the package registration when plugin framework first time be initialized.
134 *
135 * @since 1.0
136 * @version 1.0
137 */
138struct PackageRegister : Register {
139    ~PackageRegister() override = default;
140
141    /**
142     * @brief Register the package.
143     * During package registration, all plugins in the package are automatically registered.
144     *
145     * @param def   plugin packaging information.
146     * @return  Registration status return
147     *  @retval OK: The package is registered succeed without any errors.
148     *  @retval ERROR_PLUGIN_ALREADY_EXISTS: The package or plugins already exists.
149     *  @retval ERROR_INCOMPATIBLE_VERSION: Incompatible plugin interface version or api version.
150     */
151    virtual Status AddPackage(const PackageDef& def) = 0;
152};
153
154/// Plugin registration function, all plugins must be implemented.
155using RegisterFunc = Status (*)(std::shared_ptr<Register> reg);
156
157/// Plugin deregister function, all plugins must be implemented.
158using UnregisterFunc = void (*)();
159
160#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
161#define PLUGIN_EXPORT extern "C" __declspec(dllexport)
162#else
163#if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
164#define PLUGIN_EXPORT extern "C" __attribute__((visibility("default")))
165#else
166#define PLUGIN_EXPORT
167#endif
168#endif
169
170/// Macro definition, string concatenation
171#define PLUGIN_PASTE_ARGS(str1, str2) str1##str2
172
173/// Macro definition, string concatenation
174#define PLUGIN_PASTE(str1, str2) PLUGIN_PASTE_ARGS(str1, str2)
175
176/// Macro definition, stringify
177#define PLUGIN_STRINGIFY_ARG(str) #str
178
179/// Macro definition, stringify
180#define PLUGIN_STRINGIFY(str) PLUGIN_STRINGIFY_ARG(str)
181
182/**
183 * @brief Macro definition, Defines basic plugin information.
184 * Which is invoked during plugin package registration. All plugin packages must be implemented.
185 *
186 * @param name              Package name. For details, @see PackageDef::name
187 * @param license           Package License, For details, @see PackageDef::licenseType
188 * @param registerFunc      Plugin registration function, MUST NOT be NULL.
189 * @param unregisterFunc    Plugin deregister function,MUST NOT be NULL.
190 */
191#define PLUGIN_DEFINITION(name, license, registerFunc, unregisterFunc)                                                 \
192    PLUGIN_EXPORT OHOS::Media::Plugin::Status PLUGIN_PASTE(register_, name)(                                           \
193        const std::shared_ptr<OHOS::Media::Plugin::PackageRegister>& pkgReg)                                           \
194    {                                                                                                                  \
195        pkgReg->AddPackage({PLUGIN_INTERFACE_VERSION, PLUGIN_STRINGIFY(name), license});                               \
196        std::shared_ptr<OHOS::Media::Plugin::Register> pluginReg = pkgReg;                                             \
197        return registerFunc(pluginReg);                                                                                \
198    }                                                                                                                  \
199    PLUGIN_EXPORT void PLUGIN_PASTE(unregister_, name)()                                                               \
200    {                                                                                                                  \
201        unregisterFunc();                                                                                              \
202    }
203} // namespace Plugin
204} // namespace Media
205} // namespace OHOS
206#endif // HISTREAMER_PLUGIN_INTF_PLUGIN_DEFINITION_H
207