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 
24 namespace OHOS {
25 namespace Media {
26 namespace 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  */
56 enum 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  */
70 struct 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.
85 template <typename T>
86 using 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  */
94 struct 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  */
116 struct 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  */
138 struct 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.
155 using RegisterFunc = Status (*)(std::shared_ptr<Register> reg);
156 
157 /// Plugin deregister function, all plugins must be implemented.
158 using 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