1 #include "dtv_plugin.h"
2 #include <dlfcn.h>
3 #include <libgen.h>
4 #include <utils/Log.h>
5
DtvPlugin(const char * plugin_path)6 DtvPlugin::DtvPlugin(const char* plugin_path) {
7 path_ = plugin_path;
8 basename_ = basename(path_);
9 module_ = NULL;
10 interface_ = NULL;
11 loaded_ = false;
12 }
13
~DtvPlugin()14 DtvPlugin::~DtvPlugin() {
15 if (module_ != NULL) {
16 if (dlclose(module_)) ALOGE("DtvPlugin: Failed to close plugin '%s'", basename_);
17 }
18 }
19
load()20 bool DtvPlugin::load() {
21 ALOGI("Loading plugin '%s' from path '%s'", basename_, path_);
22
23 module_ = dlopen(path_, RTLD_LAZY);
24 if (module_ == NULL) {
25 ALOGE("DtvPlugin::Load::Failed to load plugin '%s'", basename_);
26 ALOGE("dlopen error: %s", dlerror());
27 return false;
28 }
29
30 interface_ = (dtv_plugin*)dlsym(module_, "plugin_entry");
31
32 if (interface_ == NULL) {
33 ALOGE("plugin_entry is NULL.");
34 goto error;
35 }
36
37 if (!interface_->get_transport_types || !interface_->get_streamer_count ||
38 !interface_->validate || !interface_->create_streamer || !interface_->destroy_streamer ||
39 !interface_->open_stream || !interface_->close_stream || !interface_->read_stream) {
40 ALOGW("Plugin: missing one or more callbacks");
41 goto error;
42 }
43
44 loaded_ = true;
45
46 return true;
47
48 error:
49 if (dlclose(module_)) ALOGE("Failed to close plugin '%s'", basename_);
50
51 return false;
52 }
53
getStreamerCount()54 int DtvPlugin::getStreamerCount() {
55 if (!loaded_) {
56 ALOGE("DtvPlugin::GetStreamerCount: Plugin '%s' not loaded!", basename_);
57 return 0;
58 }
59
60 return interface_->get_streamer_count();
61 }
62
isTransportTypeSupported(const char * transport_type)63 bool DtvPlugin::isTransportTypeSupported(const char* transport_type) {
64 const char** transport;
65
66 if (!loaded_) {
67 ALOGE("Plugin '%s' not loaded!", basename_);
68 return false;
69 }
70
71 transport = interface_->get_transport_types();
72 if (transport == NULL) return false;
73
74 while (*transport) {
75 if (strcmp(transport_type, *transport) == 0) return true;
76 transport++;
77 }
78
79 return false;
80 }
81
validate(const char * transport_desc)82 bool DtvPlugin::validate(const char* transport_desc) {
83 if (!loaded_) {
84 ALOGE("Plugin '%s' is not loaded!", basename_);
85 return false;
86 }
87
88 return interface_->validate(transport_desc);
89 }
90
getProperty(const char * key,void * value,int * size)91 bool DtvPlugin::getProperty(const char* key, void* value, int* size) {
92 if (!loaded_) {
93 ALOGE("Plugin '%s' is not loaded!", basename_);
94 return false;
95 }
96
97 if (!interface_->get_property) return false;
98
99 *size = interface_->get_property(NULL, key, value, *size);
100
101 return *size < 0 ? false : true;
102 }
103
setProperty(const char * key,const void * value,int size)104 bool DtvPlugin::setProperty(const char* key, const void* value, int size) {
105 int ret;
106
107 if (!loaded_) {
108 ALOGE("Plugin '%s': not loaded!", basename_);
109 return false;
110 }
111
112 if (!interface_->set_property) return false;
113
114 ret = interface_->set_property(NULL, key, value, size);
115
116 return ret < 0 ? false : true;
117 }
118
interface()119 struct dtv_plugin* DtvPlugin::interface() {
120 if (!loaded_) {
121 ALOGE("Plugin '%s' is not loaded!", basename_);
122 return NULL;
123 }
124
125 return interface_;
126 }
127
pluginBasename()128 const char* DtvPlugin::pluginBasename() {
129 return basename_;
130 }
131