1 package org.rpi.os;
2
3 import java.io.File;
4 import java.lang.reflect.Field;
5 import java.net.URL;
6 import java.security.AccessController;
7 import java.security.PrivilegedAction;
8 import java.util.ArrayList;
9 import java.util.Arrays;
10 import java.util.List;
11
12 import org.apache.log4j.Logger;
13 import org.rpi.utils.Utils;
14 import com.pi4j.io.gpio.GpioController;
15 import net.xeoh.plugins.base.impl.PluginManagerFactory;
16 import net.xeoh.plugins.base.PluginManager;
17
18 public class OSManager {
19
20 private static Logger log = Logger.getLogger(OSManager.class);
21 private boolean bRaspi = false;
22 private PluginManager pm = null;
23 private boolean bUsedPi4J = false;
24 private static OSManager instance = null;
25
26 private static final String OHNET_LIB_DIR = "/mediaplayer_lib/ohNet";
27
28 public static OSManager getInstance() {
29 if (instance == null) {
30 instance = new OSManager();
31 }
32 return instance;
33 }
34
35 protected OSManager() {
36 log.debug("Initializing OSManager");
37 setJavaPath();
38 if (isRaspi()) {
39 log.debug("This is a Raspi so Attempt to initialize Pi4J");
40
41 }
42 }
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 public void addLibraryPath(String pathToAdd) throws Exception {
70 log.debug("Adding Path: " + pathToAdd);
71 Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths");
72 usrPathsField.setAccessible(true);
73
74 String[] paths = (String[]) usrPathsField.get(null);
75
76 for (String path : paths)
77 if (path.equals(pathToAdd))
78 return;
79
80 String[] newPaths = Arrays.copyOf(paths, paths.length + 1);
81 newPaths[newPaths.length - 1] = pathToAdd;
82 usrPathsField.set(null, newPaths);
83 }
84
85
86
87
88 private void setJavaPath() {
89 String fullPath = constructLibraryPath();
90 if (!Utils.isEmpty(fullPath)) {
91 try {
92 addLibraryPath(fullPath);
93 } catch (Exception e) {
94 log.error("Cannot add library path", e);
95 }
96 }
97 }
98
99
100
101
102
103
104
105
106 public String constructLibraryPath() {
107 String fullPath = null;
108
109 String class_name = this.getClass().getName();
110 log.debug("Find Class, ClassName: " + class_name);
111 String path = getFilePath(this.getClass(), true);
112
113 if (path.endsWith("/")) {
114 path = path.substring(0, (path.length() - 1));
115 log.debug("Path ended with '/'. Updated Path to be: " + path);
116 } else {
117 log.debug("Path did not end with '/': " + path);
118 }
119
120 fullPath = path + getOhnetLibDir();
121
122 log.warn("Using fullPath " + fullPath);
123
124 return fullPath;
125 }
126
127
128
129
130
131
132
133
134
135
136
137
138 public String getOhnetLibDir() {
139
140 String path_suffix = OHNET_LIB_DIR + "/default";
141 log.debug("Path of this File is: " + path_suffix);
142
143 String os = System.getProperty("os.name").toUpperCase();
144 log.debug("OS Name: " + os);
145
146 if (os.startsWith("WINDOWS")) {
147 log.debug("Windows OS");
148 String osPathName = "windows";
149 String osArch = System.getProperty("os.arch");
150
151 String architecture = "x86";
152 if (osArch.endsWith("64")) {
153 architecture = "x64";
154 }
155
156 path_suffix = OHNET_LIB_DIR + "/" + osPathName + "/" + architecture;
157 } else if (os.startsWith("LINUX")) {
158 String osPathName = "linux";
159
160 String arch = System.getProperty("os.arch").toUpperCase();
161 if (arch.startsWith("ARM")) {
162 String osArch = "arm";
163
164 log.debug("Its an ARM device, now check, which revision");
165 try {
166 String armVersion = getReadElfTag("Tag_CPU_arch");
167
168 if (armVersion == null) {
169 log.error("Cannot determine ARM version...");
170 osArch = "UNKNOWN";
171 } else if (armVersion.equals("v5")) {
172 osArch = osArch + "v5sf";
173 } else if (armVersion.equals("v6")) {
174
175
176 log.debug("We think this is a Raspi");
177 setRaspi(true);
178 if (isHardFloat()) {
179 osArch = osArch + "v6hf";
180 } else {
181 osArch = osArch + "v6sf";
182 }
183 } else if (armVersion.equals("v7")) {
184 osArch = osArch + "v7";
185 } else {
186 log.error("Unknown ARM version...(" + armVersion + ")");
187 osArch = "UNKNOWN";
188 }
189
190 if (!osArch.equals("UNKNOWN")) {
191 path_suffix = OHNET_LIB_DIR + "/" + osPathName + "/" + osArch;
192 }
193 } catch (Exception e) {
194 log.debug("Error Determining ARM OS Type: ", e);
195 }
196 } else if (arch.startsWith("I386")) {
197 String version = System.getProperty("os.version");
198 log.debug("OS is Linux, and arch is " + arch + ". Version is: " + version);
199 path_suffix = OHNET_LIB_DIR + "/" + osPathName + "/x86";
200 } else if (arch.startsWith("AMD64")) {
201 String version = System.getProperty("os.version");
202 log.debug("OS is Linux, and arch is " + arch + ". Version is: " + version);
203 path_suffix = OHNET_LIB_DIR + "/" + osPathName + "/amd64";
204 }
205 }
206
207 return path_suffix;
208 }
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230 public synchronized String getFilePath(Class mClass, boolean bUseFullNamePath) {
231
232 String home = (String)System.getProperties().get("mediaplayer.core.home");
233 if (!Utils.isEmpty(home)) {
234 return home;
235 }
236
237 String className = mClass.getName();
238 if (!className.startsWith("/")) {
239 className = "/" + className;
240 }
241 className = className.replace('.', '/');
242 className = className + ".class";
243 log.debug("Find Class, Full ClassName: " + className);
244 String[] splits = className.split("/");
245 String properName = splits[splits.length - 1];
246 log.debug("Find Class, Proper ClassName: " + properName);
247 URL classUrl = mClass.getResource(className);
248 if (classUrl != null) {
249 String temp = classUrl.getFile();
250 log.debug("Find Class, ClassURL: " + temp);
251 if (temp.startsWith("file:")) {
252 temp = temp.substring(5);
253 }
254
255 if (temp.toUpperCase().contains(".JAR!")) {
256 log.debug("Find Class, This is a JarFile: " + temp);
257 String[] parts = temp.split("/");
258 String jar_path = "";
259 for (String part : parts) {
260 if (!part.toUpperCase().endsWith(".JAR!")) {
261 jar_path += part + "/";
262 } else {
263 log.debug("Find File: Returning JarPath: " + jar_path);
264 return jar_path;
265 }
266 }
267 } else {
268 log.debug("Find Class, This is NOT a Jar File: " + temp);
269 if (temp.endsWith(className)) {
270 if (bUseFullNamePath) {
271 temp = temp.substring(0, (temp.length() - className.length()));
272 } else {
273 temp = temp.substring(0, (temp.length() - properName.length()));
274 }
275 }
276 }
277 log.debug("Find File: Returning FilePath: " + temp);
278 return temp;
279 } else {
280 log.debug("Find Class, URL Not Found");
281 return "\nClass '" + className + "' not found in \n'" + System.getProperty("java.class.path") + "'";
282 }
283 }
284
285
286
287
288 public void loadPlugins() {
289 try {
290 log.info("Start of LoadPlugins");
291 pm = PluginManagerFactory.createPluginManager();
292 List<File> files = listFiles("plugins");
293 if (files == null)
294 return;
295 for (File file : files) {
296 try {
297 if (file.getName().toUpperCase().endsWith(".JAR")) {
298 log.debug("Attempt to Load Plugin: " + file.getName() + " " + file.toURI());
299 pm.addPluginsFrom(file.toURI());
300 }
301 } catch (Exception e) {
302 log.error("Unable to load Plugins", e);
303 }
304 }
305 log.info("End of LoadPlugins");
306 } catch (Exception e) {
307 log.error("Error Loading Plugins");
308 }
309 }
310
311
312
313
314
315
316
317 private List<File> listFiles(String directoryName) {
318 File directory = new File(directoryName);
319 List<File> resultList = new ArrayList<File>();
320 File[] fList = directory.listFiles();
321 if (fList == null)
322 return resultList;
323 resultList.addAll(Arrays.asList(fList));
324 for (File file : fList) {
325 if (file.isFile()) {
326 } else if (file.isDirectory()) {
327 resultList.addAll(listFiles(file.getAbsolutePath()));
328 }
329 }
330 return resultList;
331 }
332
333
334
335
336
337
338 public boolean isRaspi() {
339 return bRaspi;
340 }
341
342 private void setRaspi(boolean bRaspi) {
343 this.bRaspi = bRaspi;
344 }
345
346
347
348
349
350
351 public boolean isSoftFloat() {
352 return !isHardFloat();
353 }
354
355
356
357
358 public void dispose() {
359 try {
360 if (pm != null) {
361 pm.shutdown();
362 }
363 } catch (Exception e) {
364 log.error("Error closing PluginManager", e);
365 }
366 try {
367 if (bUsedPi4J)
368 Pi4JManager.getInstance().dispose();
369 } catch (Exception e) {
370 log.error("Error closing pi4j", e);
371 }
372 }
373
374 public GpioController getGpio() {
375 bUsedPi4J = true;
376 return Pi4JManager.getInstance().getGpio();
377 }
378
379
380
381
382
383
384
385
386
387
388 public boolean isHardFloat() {
389
390 return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
391 ArrayList<String> gnueabihf = new ArrayList<String>();
392 public Boolean run() {
393 gnueabihf.add("gnueabihf");
394 gnueabihf.add("armhf");
395 if (Utils.containsString(System.getProperty("sun.boot.library.path"), gnueabihf) ||
396 Utils.containsString(System.getProperty("java.library.path"), gnueabihf) ||
397 Utils.containsString(System.getProperty("java.home"), gnueabihf) ||
398 getBashVersionInfo().contains("gnueabihf") ||
399 hasReadElfTag("Tag_ABI_HardFP_use")) {
400 log.debug("This is a HardFloat");
401 return true;
402 }
403 log.debug("This is a HardFloat");
404 return false;
405 }
406 });
407 }
408
409
410
411
412
413
414
415
416
417 private static String getBashVersionInfo() {
418 String versionInfo = "";
419 try {
420 String result[] = Utils.execute("bash --version");
421 for(String line : result) {
422 if(!line.isEmpty()) {
423 versionInfo = line;
424 break;
425 }
426 }
427 }
428 catch(Exception e)
429 {
430 log.error("Error Executing bash --version", e);
431 }
432
433
434 return versionInfo;
435 }
436
437
438
439
440
441 private static boolean hasReadElfTag(String tag) {
442 String tagValue = getReadElfTag(tag);
443 if(tagValue != null && !tagValue.isEmpty())
444 return true;
445 return false;
446 }
447
448
449
450
451
452 private static String getReadElfTag(String tag) {
453 String tagValue = null;
454 try {
455 String result[] = Utils.execute("/usr/bin/readelf -A /proc/self/exe");
456 if(result != null){
457 for(String line : result) {
458 line = line.trim();
459 if (line.startsWith(tag) && line.contains(":")) {
460 String lineParts[] = line.split(":", 2);
461 if(lineParts.length > 1)
462 tagValue = lineParts[1].trim();
463 break;
464 }
465 }
466 }
467 }
468 catch(Exception e)
469 {
470 log.error("IOException during readelf operation", e);
471 }
472
473
474
475
476
477
478
479 return tagValue;
480 }
481
482
483 }