FlashlightManager.java 3.15 KB
package com.ectrip.cyt.zxing.camera;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import android.os.IBinder;

import com.ectrip.cyt.utils.LogUtil;

final class FlashlightManager {
	private final String TAG = FlashlightManager.class.getSimpleName();

	private Object iHardwareService;
	private Method setFlashEnabledMethod;

	public FlashlightManager() {
		iHardwareService = getHardwareService();
		setFlashEnabledMethod = getSetFlashEnabledMethod(iHardwareService);
		if (iHardwareService == null) {
			LogUtil.i(TAG, "This device does supports control of a flashlight");
		} else {
			LogUtil.i(TAG, "This device does not support control of a flashlight");
		}
	}

	/**
	 * 控制相机闪光灯开关
	 */
	// FIXME
	public void enableFlashlight() {
		setFlashlight(false);
	}

	public void disableFlashlight() {
		setFlashlight(false);
	}

	private Object getHardwareService() {
		Class<?> serviceManagerClass = maybeForName("android.os.ServiceManager");
		if (serviceManagerClass == null) {
			return null;
		}

		Method getServiceMethod = maybeGetMethod(serviceManagerClass,
				"getService", String.class);
		if (getServiceMethod == null) {
			return null;
		}

		Object hardwareService = invoke(getServiceMethod, null, "hardware");
		if (hardwareService == null) {
			return null;
		}

		Class<?> iHardwareServiceStubClass = maybeForName("android.os.IHardwareService$Stub");
		if (iHardwareServiceStubClass == null) {
			return null;
		}

		Method asInterfaceMethod = maybeGetMethod(iHardwareServiceStubClass,
				"asInterface", IBinder.class);
		if (asInterfaceMethod == null) {
			return null;
		}

		return invoke(asInterfaceMethod, null, hardwareService);
	}

	private Method getSetFlashEnabledMethod(Object iHardwareService) {
		if (iHardwareService == null) {
			return null;
		}
		Class<?> proxyClass = iHardwareService.getClass();
		return maybeGetMethod(proxyClass, "setFlashlightEnabled", boolean.class);
	}

	private Class<?> maybeForName(String name) {
		try {
			return Class.forName(name);
		} catch (ClassNotFoundException cnfe) {
			// OK
			return null;
		} catch (RuntimeException re) {
			LogUtil.w(TAG, "Unexpected error while finding class " + name);
			return null;
		}
	}

	private Method maybeGetMethod(Class<?> clazz, String name,
								  Class<?>... argClasses) {
		try {
			return clazz.getMethod(name, argClasses);
		} catch (NoSuchMethodException nsme) {
			// OK
			return null;
		} catch (RuntimeException re) {
			LogUtil.w(TAG, "Unexpected error while finding method " + name);
			return null;
		}
	}

	private Object invoke(Method method, Object instance, Object... args) {
		try {
			return method.invoke(instance, args);
		} catch (IllegalAccessException e) {
			LogUtil.w(TAG, "Unexpected error while invoking " + method);
			return null;
		} catch (InvocationTargetException e) {
			LogUtil.w(TAG, "Unexpected error while invoking " + method);
			return null;
		} catch (RuntimeException re) {
			LogUtil.w(TAG, "Unexpected error while invoking " + method);
			return null;
		}
	}

	private void setFlashlight(boolean active) {
		if (iHardwareService != null) {
			invoke(setFlashEnabledMethod, iHardwareService, active);
		}
	}

}