package com.easygbs.device; import android.app.Service; import android.arch.lifecycle.BuildConfig; import android.arch.lifecycle.LiveData; import android.content.Intent; import android.hardware.usb.UsbDevice; import android.os.Binder; import android.os.IBinder; import android.util.Log; import android.util.SparseArray; import android.widget.Toast; import com.serenegiant.usb.DeviceFilter; import com.serenegiant.usb.IButtonCallback; import com.serenegiant.usb.IStatusCallback; import com.serenegiant.usb.USBMonitor; import com.serenegiant.usb.UVCCamera; import java.nio.ByteBuffer; public class UVCCameraService extends Service { public static class UVCCameraLivaData extends LiveData { @Override protected void postValue(UVCCamera value) { super.postValue(value); } } public static final UVCCameraLivaData liveData = new UVCCameraLivaData(); public static class MyUVCCamera extends UVCCamera { boolean prev = false; @Override public synchronized void startPreview() { if (prev) return; super.startPreview(); prev = true; } @Override public synchronized void stopPreview() { if (!prev) return; super.stopPreview(); prev = false; } @Override public synchronized void destroy() { prev = false; super.destroy(); } } private static final String TAG = UVCCameraService.class.getSimpleName(); private USBMonitor mUSBMonitor; private UVCCamera mUVCCamera; private SparseArray cameras = new SparseArray<>(); public class MyBinder extends Binder { public UVCCameraService getService() { return UVCCameraService.this; } } MyBinder binder = new MyBinder(); @Override public IBinder onBind(Intent intent) { return binder; } public UVCCamera getCamera() { return mUVCCamera; } private void releaseCamera() { if (mUVCCamera != null) { try { mUVCCamera.close(); mUVCCamera.destroy(); mUVCCamera = null; } catch (final Exception e) { // } } } @Override public void onCreate() { super.onCreate(); mUSBMonitor = new USBMonitor(this, new USBMonitor.OnDeviceConnectListener() { @Override public void onAttach(final UsbDevice device) { Log.v(TAG, "onAttach:" + device); mUSBMonitor.requestPermission(device); } @Override public void onConnect(final UsbDevice device, final USBMonitor.UsbControlBlock ctrlBlock, final boolean createNew) { releaseCamera(); if (BuildConfig.DEBUG) Log.v(TAG, "onConnect:"); try { final UVCCamera camera = new MyUVCCamera(); camera.open(ctrlBlock); camera.setStatusCallback(new IStatusCallback() { @Override public void onStatus(final int statusClass, final int event, final int selector, final int statusAttribute, final ByteBuffer data) { Log.i(TAG, "onStatus(statusClass=" + statusClass + "; " + "event=" + event + "; " + "selector=" + selector + "; " + "statusAttribute=" + statusAttribute + "; " + "data=...)"); } }); camera.setButtonCallback(new IButtonCallback() { @Override public void onButton(final int button, final int state) { Log.i(TAG, "onButton(button=" + button + "; " + "state=" + state + ")"); } }); // camera.setPreviewTexture(camera.getSurfaceTexture()); mUVCCamera = camera; liveData.postValue(camera); Toast.makeText(UVCCameraService.this, "UVCCamera connected!", Toast.LENGTH_SHORT).show(); if (device != null) cameras.append(device.getDeviceId(), camera); } catch (Exception ex) { ex.printStackTrace(); } } @Override public void onDisconnect(final UsbDevice device, final USBMonitor.UsbControlBlock ctrlBlock) { Log.v(TAG, "onDisconnect:"); // Toast.makeText(MainActivity.this, R.string.usb_camera_disconnected, Toast.LENGTH_SHORT).show(); // releaseCamera(); if (device != null) { UVCCamera camera = cameras.get(device.getDeviceId()); if (mUVCCamera == camera) { mUVCCamera = null; Toast.makeText(UVCCameraService.this, "UVCCamera disconnected!", Toast.LENGTH_SHORT).show(); liveData.postValue(null); } cameras.remove(device.getDeviceId()); } else { Toast.makeText(UVCCameraService.this, "UVCCamera disconnected!", Toast.LENGTH_SHORT).show(); mUVCCamera = null; liveData.postValue(null); } // if (mUSBMonitor != null) { // mUSBMonitor.destroy(); // } // // mUSBMonitor = new USBMonitor(OutterCameraService.this, this); // mUSBMonitor.setDeviceFilter(DeviceFilter.getDeviceFilters(OutterCameraService.this, R.xml.device_filter)); // mUSBMonitor.register(); } @Override public void onCancel(UsbDevice usbDevice) { releaseCamera(); } @Override public void onDettach(final UsbDevice device) { Log.v(TAG, "onDettach:"); releaseCamera(); // AppContext.getInstance().bus.post(new UVCCameraDisconnect()); } }); mUSBMonitor.setDeviceFilter(DeviceFilter.getDeviceFilters(this, R.xml.device_filter)); mUSBMonitor.register(); } @Override public void onDestroy() { releaseCamera(); if (mUSBMonitor != null) { mUSBMonitor.unregister(); } super.onDestroy(); } }