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