Minor changes from code inspection results
[zxing.git] / android / src / com / google / zxing / client / android / camera / FlashlightManager.java
1 /*
2  * Copyright (C) 2010 ZXing authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.google.zxing.client.android.camera;
18
19 import android.os.IBinder;
20 import android.util.Log;
21
22 import java.lang.reflect.InvocationTargetException;
23 import java.lang.reflect.Method;
24
25 /**
26  * This class is used to activate the weak light on some camera phones (not flash)
27  * in order to illuminate surfaces for scanning. There is no official way to do this,
28  * but, classes which allow access to this function still exist on some devices.
29  * This therefore proceeds through a great deal of reflection.
30  *
31  * See <a href="http://almondmendoza.com/2009/01/05/changing-the-screen-brightness-programatically/">
32  * http://almondmendoza.com/2009/01/05/changing-the-screen-brightness-programatically/</a> and
33  * <a href="http://code.google.com/p/droidled/source/browse/trunk/src/com/droidled/demo/DroidLED.java">
34  * http://code.google.com/p/droidled/source/browse/trunk/src/com/droidled/demo/DroidLED.java</a>.
35  * Thanks to Ryan Alford for pointing out the availability of this class.
36  */
37 final class FlashlightManager {
38
39   private static final String TAG = FlashlightManager.class.getSimpleName();
40
41   private static final Object iHardwareService;
42   private static final Method setFlashEnabledMethod;
43   static {
44     iHardwareService = getHardwareService();
45     setFlashEnabledMethod = getSetFlashEnabledMethod(iHardwareService);
46     if (iHardwareService == null) {
47       Log.v(TAG, "This device does supports control of a flashlight");
48     } else {
49       Log.v(TAG, "This device does not support control of a flashlight");
50     }
51   }
52
53   private FlashlightManager() {
54   }
55
56   private static Object getHardwareService() {
57     Class<?> serviceManagerClass = maybeForName("android.os.ServiceManager");
58     if (serviceManagerClass == null) {
59       return null;
60     }
61
62     Method getServiceMethod = maybeGetMethod(serviceManagerClass, "getService", String.class);
63     if (getServiceMethod == null) {
64       return null;
65     }
66
67     Object hardwareService = invoke(getServiceMethod, null, "hardware");
68     if (hardwareService == null) {
69       return null;
70     }
71
72     Class<?> iHardwareServiceStubClass = maybeForName("android.os.IHardwareService$Stub");
73     if (iHardwareServiceStubClass == null) {
74       return null;
75     }
76
77     Method asInterfaceMethod = maybeGetMethod(iHardwareServiceStubClass, "asInterface", IBinder.class);
78     if (asInterfaceMethod == null) {
79       return null;
80     }
81
82     return invoke(asInterfaceMethod, null, hardwareService);
83   }
84
85   private static Method getSetFlashEnabledMethod(Object iHardwareService) {
86     if (iHardwareService == null) {
87       return null;
88     }
89     Class<?> proxyClass = iHardwareService.getClass();
90     return maybeGetMethod(proxyClass, "setFlashlightEnabled", boolean.class);
91   }
92
93   private static Class<?> maybeForName(String name) {
94     try {
95       return Class.forName(name);
96     } catch (ClassNotFoundException cnfe) {
97       // OK
98       return null;
99     } catch (RuntimeException re) {
100       Log.w(TAG, "Unexpected error while finding class " + name, re);
101       return null;
102     }
103   }
104
105   private static Method maybeGetMethod(Class<?> clazz, String name, Class<?>... argClasses) {
106     try {
107       return clazz.getMethod(name, argClasses);
108     } catch (NoSuchMethodException nsme) {
109       // OK
110       return null;
111     } catch (RuntimeException re) {
112       Log.w(TAG, "Unexpected error while finding method " + name, re);
113       return null;
114     }
115   }
116
117   private static Object invoke(Method method, Object instance, Object... args) {
118     try {
119       return method.invoke(instance, args);
120     } catch (IllegalAccessException e) {
121       Log.w(TAG, "Unexpected error while invoking " + method, e);
122       return null;
123     } catch (InvocationTargetException e) {
124       Log.w(TAG, "Unexpected error while invoking " + method, e.getCause());
125       return null;
126     } catch (RuntimeException re) {
127       Log.w(TAG, "Unexpected error while invoking " + method, re);
128       return null;
129     }
130   }
131
132   static void enableFlashlight() {
133     setFlashlight(true);
134   }
135
136   static void disableFlashlight() {
137     setFlashlight(false);
138   }
139
140   private static void setFlashlight(boolean active) {
141     if (iHardwareService != null) {
142       invoke(setFlashEnabledMethod, iHardwareService, active);
143     }
144   }
145
146 }