FileDocCategorySizeDatePackage
FlashlightController.javaAPI DocAndroid 5.1 API13257Thu Mar 12 22:22:42 GMT 2015com.android.systemui.statusbar.policy

FlashlightController

public class FlashlightController extends Object
Manages the flashlight.

Fields Summary
private static final String
TAG
private static final boolean
DEBUG
private static final int
DISPATCH_ERROR
private static final int
DISPATCH_OFF
private static final int
DISPATCH_AVAILABILITY_CHANGED
private final android.hardware.camera2.CameraManager
mCameraManager
private android.os.Handler
mHandler
Call {@link #ensureHandler()} before using
private final ArrayList
mListeners
Lock on mListeners when accessing
private boolean
mFlashlightEnabled
Lock on {@code this} when accessing
private String
mCameraId
private boolean
mCameraAvailable
private android.hardware.camera2.CameraDevice
mCameraDevice
private android.hardware.camera2.CaptureRequest
mFlashlightRequest
private android.hardware.camera2.CameraCaptureSession
mSession
private android.graphics.SurfaceTexture
mSurfaceTexture
private android.view.Surface
mSurface
private final CameraDevice.StateListener
mCameraListener
private final CameraCaptureSession.StateListener
mSessionListener
private final Runnable
mUpdateFlashlightRunnable
private final Runnable
mKillFlashlightRunnable
private final CameraManager.AvailabilityCallback
mAvailabilityCallback
Constructors Summary
public FlashlightController(android.content.Context mContext)


       
        mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
        initialize();
    
Methods Summary
public voidaddListener(com.android.systemui.statusbar.policy.FlashlightController$FlashlightListener l)

        synchronized (mListeners) {
            cleanUpListenersLocked(l);
            mListeners.add(new WeakReference<>(l));
        }
    
private voidcleanUpListenersLocked(com.android.systemui.statusbar.policy.FlashlightController$FlashlightListener listener)

        for (int i = mListeners.size() - 1; i >= 0; i--) {
            FlashlightListener found = mListeners.get(i).get();
            if (found == null || found == listener) {
                mListeners.remove(i);
            }
        }
    
private voiddispatchAvailabilityChanged(boolean available)

        dispatchListeners(DISPATCH_AVAILABILITY_CHANGED, available);
    
private voiddispatchError()

        dispatchListeners(DISPATCH_ERROR, false /* argument (ignored) */);
    
private voiddispatchListeners(int message, boolean argument)

        synchronized (mListeners) {
            final int N = mListeners.size();
            boolean cleanup = false;
            for (int i = 0; i < N; i++) {
                FlashlightListener l = mListeners.get(i).get();
                if (l != null) {
                    if (message == DISPATCH_ERROR) {
                        l.onFlashlightError();
                    } else if (message == DISPATCH_OFF) {
                        l.onFlashlightOff();
                    } else if (message == DISPATCH_AVAILABILITY_CHANGED) {
                        l.onFlashlightAvailabilityChanged(argument);
                    }
                } else {
                    cleanup = true;
                }
            }
            if (cleanup) {
                cleanUpListenersLocked(null);
            }
        }
    
private voiddispatchOff()

        dispatchListeners(DISPATCH_OFF, false /* argument (ignored) */);
    
private synchronized voidensureHandler()

        if (mHandler == null) {
            HandlerThread thread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
            thread.start();
            mHandler = new Handler(thread.getLooper());
        }
    
private java.lang.StringgetCameraId()

        String[] ids = mCameraManager.getCameraIdList();
        for (String id : ids) {
            CameraCharacteristics c = mCameraManager.getCameraCharacteristics(id);
            Boolean flashAvailable = c.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
            Integer lensFacing = c.get(CameraCharacteristics.LENS_FACING);
            if (flashAvailable != null && flashAvailable
                    && lensFacing != null && lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
                return id;
            }
        }
        return null;
    
private android.util.SizegetSmallestSize(java.lang.String cameraId)

        Size[] outputSizes = mCameraManager.getCameraCharacteristics(cameraId)
                .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
                .getOutputSizes(SurfaceTexture.class);
        if (outputSizes == null || outputSizes.length == 0) {
            throw new IllegalStateException(
                    "Camera " + cameraId + "doesn't support any outputSize.");
        }
        Size chosen = outputSizes[0];
        for (Size s : outputSizes) {
            if (chosen.getWidth() >= s.getWidth() && chosen.getHeight() >= s.getHeight()) {
                chosen = s;
            }
        }
        return chosen;
    
private voidhandleError()

        synchronized (this) {
            mFlashlightEnabled = false;
        }
        dispatchError();
        dispatchOff();
        updateFlashlight(true /* forceDisable */);
    
public voidinitialize()

        try {
            mCameraId = getCameraId();
        } catch (Throwable e) {
            Log.e(TAG, "Couldn't initialize.", e);
            return;
        }

        if (mCameraId != null) {
            ensureHandler();
            mCameraManager.registerAvailabilityCallback(mAvailabilityCallback, mHandler);
        }
    
public synchronized booleanisAvailable()

        return mCameraAvailable;
    
public voidkillFlashlight()

        boolean enabled;
        synchronized (this) {
            enabled = mFlashlightEnabled;
        }
        if (enabled) {
            mHandler.post(mKillFlashlightRunnable);
        }
    
private voidpostUpdateFlashlight()

        ensureHandler();
        mHandler.post(mUpdateFlashlightRunnable);
    
public voidremoveListener(com.android.systemui.statusbar.policy.FlashlightController$FlashlightListener l)

        synchronized (mListeners) {
            cleanUpListenersLocked(l);
        }
    
public synchronized voidsetFlashlight(boolean enabled)

        if (mFlashlightEnabled != enabled) {
            mFlashlightEnabled = enabled;
            postUpdateFlashlight();
        }
    
private voidstartDevice()

        mCameraManager.openCamera(getCameraId(), mCameraListener, mHandler);
    
private voidstartSession()

        mSurfaceTexture = new SurfaceTexture(false);
        Size size = getSmallestSize(mCameraDevice.getId());
        mSurfaceTexture.setDefaultBufferSize(size.getWidth(), size.getHeight());
        mSurface = new Surface(mSurfaceTexture);
        ArrayList<Surface> outputs = new ArrayList<>(1);
        outputs.add(mSurface);
        mCameraDevice.createCaptureSession(outputs, mSessionListener, mHandler);
    
private voidteardown()

        mCameraDevice = null;
        mSession = null;
        mFlashlightRequest = null;
        if (mSurface != null) {
            mSurface.release();
            mSurfaceTexture.release();
        }
        mSurface = null;
        mSurfaceTexture = null;
    
private voidupdateFlashlight(boolean forceDisable)

        try {
            boolean enabled;
            synchronized (this) {
                enabled = mFlashlightEnabled && !forceDisable;
            }
            if (enabled) {
                if (mCameraDevice == null) {
                    startDevice();
                    return;
                }
                if (mSession == null) {
                    startSession();
                    return;
                }
                if (mFlashlightRequest == null) {
                    CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest(
                            CameraDevice.TEMPLATE_PREVIEW);
                    builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH);
                    builder.addTarget(mSurface);
                    CaptureRequest request = builder.build();
                    mSession.capture(request, null, mHandler);
                    mFlashlightRequest = request;
                }
            } else {
                if (mCameraDevice != null) {
                    mCameraDevice.close();
                    teardown();
                }
            }

        } catch (CameraAccessException|IllegalStateException|UnsupportedOperationException e) {
            Log.e(TAG, "Error in updateFlashlight", e);
            handleError();
        }