Android UVC驱动外接摄像头

写在前面:
这篇文章转自:
https://blog.csdn.net/luzhenyuxfcy/article/details/50883910
最近做一个UVC深度摄像头的demo,需要取出数据。 找到了博主的博客,下载博主的源码后,一直找不到设备、图像无法显示。经过一翻折腾,发现我的设备与博主的两个地方不同:设备节点、分辨率。修改这两个地方后,设备正运行了。
UVCCamera.class

    //private static final String DEFAULT_USBFS = "/dev/bus/usb";
    private static final String DEFAULT_USBFS = "/dev/vedio1";


    //public static final int DEFAULT_PREVIEW_WIDTH = 640;
    //public static final int DEFAULT_PREVIEW_HEIGHT = 480;

    public static final int DEFAULT_PREVIEW_WIDTH = 224;
    public static final int DEFAULT_PREVIEW_HEIGHT = 688;
如果后期使用,可以下载我修改后的代码,使用前下载一个usbwebcamera 软件,看你的设备是否支持otg接uvc摄像头 https://blog.csdn.net/qq_31939617/article/details/82348796
深度摄像头的数据包含了灰阶图和深度图,取出后数据包含两部分,我已成功取出两种数据,并做显示,后面有时间的话,再放上来。

UVC驱动外接摄像头

简单记录一下开发中遇到的手机驱动外接摄像头,目前只能针对个别机型,像小米,魅族MX2,ZTE测试过是可行的,Lenovo,VIVO,华为由于关闭了外接设备,并不支持外接摄像头。摄像头要支持UVC软驱。另外要注意,摄像头预览分辨率要是手机/平板分辨率和摄像头支持的分辨率交集,Demo中将查看分辨率的代码解开(代码改为true)可以查看两者支持的分辨率。还是有很多问题的,距离商用还有一段距离,仅供参考,还请感兴趣的大牛联系完善。

在平板测试过程中发现性能比较好的品牌平板表现良好,不过遇到一个棘手的问题就是HOME与BACk键交叉使用会导致图像不再显示,手机显示蛮好,平板表现比较次。

项目创建

本项目在EC下创建取名为UVCDemo,包名:com.serenegiant.uvccamera,我们先把底层库引入:


如果会NDK的话请研究jni文件:


资源文件:


权限如下:


    
    
  1. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  2. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  3. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  4. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
  5. <uses-permission android:name="android.permission.CAMERA"/>
上述权限并不是都要有,由于肯定牵扯到联网所以要有网络相关的权限,根据需求增删(本项目所用如下)


    
    
  1. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  2. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  3. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  4. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
  5. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  6. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  7. <uses-permission android:name="android.permission.INTERNET" />
  8. <uses-permission android:name="android.permission.CAMERA"/>
  9. <!-- 屏蔽HOME键需要的权限 -->
  10. <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
  11. <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
  12. <!-- 开机自启动需要的权限 -->
  13. <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

核心代码


原理是使用UVCCamera来控制、管理与外接设备的连接,UVCCameraTextureView控件进行图像的预览,USBMonitor进行驱动的连接和断开
先在需要的地方添加控件:

     
     
  1. <com.serenegiant.usb.widget.UVCCameraTextureView
  2. android:id= “@+id/camera_view”
  3. android:layout_width= “match_parent”
  4. android:layout_height= “match_parent”
  5. android:layout_centerHorizontal= “true”
  6. android:layout_centerVertical= “true” />
我在CaptureActivity初始化:

     
     
  1. final View view = findViewById(R.id.camera_view);
  2. mUVCCameraView = (CameraViewInterface)view;
  3. mUVCCameraView.setAspectRatio(PREVIEW_WIDTH / ( float)PREVIEW_HEIGHT); //TODO
  4. mUSBMonitor = new USBMonitor( this, mOnDeviceConnectListener);
  5. mHandler = CameraHandler.createHandler( this, mUVCCameraView);
我通过CameraHandler将事件分发出去,里面包含了对外接摄像头的所有操作,拍照啊、录像啊、释放资源啊等等
在使用“.so”库的时候记得添加库才能使用本地语言

     
     
  1. System.loadLibrary( “usb100”);
  2. System.loadLibrary( “uvc”);
  3. System.loadLibrary( “UVCCamera”);
预览的调用等都是通过调用native的方法c++实现的

     
     
  1. /**
  2. * start preview
  3. */
  4. public void startPreview() {
  5. if (mCtrlBlock != null) {
  6. nativeStartPreview(mNativePtr);
  7. }
  8. }
  9. /**
  10. * stop preview
  11. */
  12. public void stopPreview() {
  13. setFrameCallback( null, 0);
  14. if (mCtrlBlock != null) {
  15. nativeStopPreview(mNativePtr);
  16. }
  17. }
驱动连接方面,我们自定义一个规则

     
     
  1. <?xml version=“1.0” encoding=“utf-8”?>
  2. <usb>
  3. <usb-device class=“239” subclass=“2” /> <!– all device of UVC –>
  4. </usb>
驱动列表是通过Android的USBManager获取得到的

     
     
  1. /**
  2. * Returns a HashMap containing all USB devices currently attached.
  3. * USB device name is the key for the returned HashMap.
  4. * The result will be empty if no devices are attached, or if
  5. * USB host mode is inactive or unsupported.
  6. *
  7. * @return HashMap containing all connected USB devices.
  8. */
  9. public HashMap<String,UsbDevice> getDeviceList() {
  10. Bundle bundle = new Bundle();
  11. try {
  12. mService.getDeviceList(bundle);
  13. HashMap<String,UsbDevice> result = new HashMap<String,UsbDevice>();
  14. for (String name : bundle.keySet()) {
  15. result.put(name, (UsbDevice)bundle.get(name));
  16. }
  17. return result;
  18. } catch (RemoteException e) {
  19. Log.e(TAG, “RemoteException in getDeviceList”, e);
  20. return null;
  21. }
  22. }


项目源码

UVCCamera

     
     
  1. package com.serenegiant.usb;
  2. /*
  3. * UVCCamera
  4. * library and sample to access to UVC web camera on non-rooted Android device
  5. *
  6. * Copyright (c) 2014-2015 saki t_saki@serenegiant.com
  7. *
  8. * File name: UVCCamera.java
  9. *
  10. * Licensed under the Apache License, Version 2.0 (the “License”);
  11. * you may not use this file except in compliance with the License.
  12. * You may obtain a copy of the License at
  13. *
  14. * http://www.apache.org/licenses/LICENSE-2.0
  15. *
  16. * Unless required by applicable law or agreed to in writing, software
  17. * distributed under the License is distributed on an “AS IS” BASIS,
  18. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19. * See the License for the specific language governing permissions and
  20. * limitations under the License.
  21. *
  22. * All files in the folder are under this Apache License, Version 2.0.
  23. * Files in the jni/libjpeg, jni/libusb, jin/libuvc, jni/rapidjson folder may have a different license, see the respective files.
  24. */
  25. import java.util.ArrayList;
  26. import java.util.List;
  27. import org.json.JSONArray;
  28. import org.json.JSONException;
  29. import org.json.JSONObject;
  30. import android.graphics.SurfaceTexture;
  31. import android.hardware.usb.UsbDevice;
  32. import android.text.TextUtils;
  33. import android.util.Log;
  34. import android.view.Surface;
  35. import android.view.SurfaceHolder;
  36. import com.serenegiant.usb.USBMonitor.UsbControlBlock;
  37. public class UVCCamera {
  38. private static final boolean DEBUG = false; // TODO set false when releasing
  39. private static final String TAG = UVCCamera.class.getSimpleName();
  40. private static final String DEFAULT_USBFS = “/dev/bus/usb”;
  41. public static final int DEFAULT_PREVIEW_WIDTH = 1600; //640
  42. public static final int DEFAULT_PREVIEW_HEIGHT = 1200; //480
  43. public static final int DEFAULT_PREVIEW_MODE = 0;
  44. public static final float DEFAULT_BANDWIDTH = 1.0f;
  45. public static final int FRAME_FORMAT_YUYV = 0;
  46. public static final int FRAME_FORMAT_MJPEG = 1;
  47. public static final int PIXEL_FORMAT_RAW = 0;
  48. public static final int PIXEL_FORMAT_YUV = 1;
  49. public static final int PIXEL_FORMAT_RGB565 = 2;
  50. public static final int PIXEL_FORMAT_RGBX = 3;
  51. public static final int PIXEL_FORMAT_YUV420SP = 4;
  52. public static final int PIXEL_FORMAT_NV21 = 5; // = YVU420SemiPlanar
  53. //——————————————————————————–
  54. public static final int CTRL_SCANNING = 0x00000001; // D0: Scanning Mode
  55. public static final int CTRL_AE = 0x00000002; // D1: Auto-Exposure Mode
  56. public static final int CTRL_AE_PRIORITY = 0x00000004; // D2: Auto-Exposure Priority
  57. public static final int CTRL_AE_ABS = 0x00000008; // D3: Exposure Time (Absolute)
  58. public static final int CTRL_AR_REL = 0x00000010; // D4: Exposure Time (Relative)
  59. public static final int CTRL_FOCUS_ABS = 0x00000020; // D5: Focus (Absolute)
  60. public static final int CTRL_FOCUS_REL = 0x00000040; // D6: Focus (Relative)
  61. public static final int CTRL_IRIS_ABS = 0x00000080; // D7: Iris (Absolute)
  62. public static final int CTRL_IRIS_REL = 0x00000100; // D8: Iris (Relative)
  63. public static final int CTRL_ZOOM_ABS = 0x00000200; // D9: Zoom (Absolute)
  64. public static final int CTRL_ZOOM_REL = 0x00000400; // D10: Zoom (Relative)
  65. public static final int CTRL_PANTILT_ABS = 0x00000800; // D11: PanTilt (Absolute)
  66. public static final int CTRL_PANTILT_REL = 0x00001000; // D12: PanTilt (Relative)
  67. public static final int CTRL_ROLL_ABS = 0x00002000; // D13: Roll (Absolute)
  68. public static final int CTRL_ROLL_REL = 0x00004000; // D14: Roll (Relative)
  69. public static final int CTRL_FOCUS_AUTO = 0x00020000; // D17: Focus, Auto
  70. public static final int CTRL_PRIVACY = 0x00040000; // D18: Privacy
  71. public static final int CTRL_FOCUS_SIMPLE = 0x00080000; // D19: Focus, Simple
  72. public static final int CTRL_WINDOW = 0x00100000; // D20: Window
  73. public static final int PU_BRIGHTNESS = 0x80000001; // D0: Brightness
  74. public static final int PU_CONTRAST = 0x80000002; // D1: Contrast
  75. public static final int PU_HUE = 0x80000004; // D2: Hue
  76. public static final int PU_SATURATION = 0x80000008; // D3: Saturation
  77. public static final int PU_SHARPNESS = 0x80000010; // D4: Sharpness
  78. public static final int PU_GAMMA = 0x80000020; // D5: Gamma
  79. public static final int PU_WB_TEMP = 0x80000040; // D6: White Balance Temperature
  80. public static final int PU_WB_COMPO = 0x80000080; // D7: White Balance Component
  81. public static final int PU_BACKLIGHT = 0x80000100; // D8: Backlight Compensation
  82. public static final int PU_GAIN = 0x80000200; // D9: Gain
  83. public static final int PU_POWER_LF = 0x80000400; // D10: Power Line Frequency
  84. public static final int PU_HUE_AUTO = 0x80000800; // D11: Hue, Auto
  85. public static final int PU_WB_TEMP_AUTO = 0x80001000; // D12: White Balance Temperature, Auto
  86. public static final int PU_WB_COMPO_AUTO = 0x80002000; // D13: White Balance Component, Auto
  87. public static final int PU_DIGITAL_MULT = 0x80004000; // D14: Digital Multiplier
  88. public static final int PU_DIGITAL_LIMIT = 0x80008000; // D15: Digital Multiplier Limit
  89. public static final int PU_AVIDEO_STD = 0x80010000; // D16: Analog Video Standard
  90. public static final int PU_AVIDEO_LOCK = 0x80020000; // D17: Analog Video Lock Status
  91. public static final int PU_CONTRAST_AUTO = 0x80040000; // D18: Contrast, Auto
  92. // uvc_status_class from libuvc.h
  93. public static final int STATUS_CLASS_CONTROL = 0x10;
  94. public static final int STATUS_CLASS_CONTROL_CAMERA = 0x11;
  95. public static final int STATUS_CLASS_CONTROL_PROCESSING = 0x12;
  96. // uvc_status_attribute from libuvc.h
  97. public static final int STATUS_ATTRIBUTE_VALUE_CHANGE = 0x00;
  98. public static final int STATUS_ATTRIBUTE_INFO_CHANGE = 0x01;
  99. public static final int STATUS_ATTRIBUTE_FAILURE_CHANGE = 0x02;
  100. public static final int STATUS_ATTRIBUTE_UNKNOWN = 0xff;
  101. private static boolean isLoaded;
  102. static {
  103. if (!isLoaded) {
  104. System.loadLibrary( “usb100”);
  105. System.loadLibrary( “uvc”);
  106. System.loadLibrary( “UVCCamera”);
  107. isLoaded = true;
  108. }
  109. }
  110. private UsbControlBlock mCtrlBlock;
  111. protected long mControlSupports; // カメラコントロールでサポートしている機能フラグ
  112. protected long mProcSupports; // プロセッシングユニットでサポートしている機能フラグ
  113. protected int mCurrentPreviewMode = 0;
  114. protected int mCurrentPreviewWidth = DEFAULT_PREVIEW_WIDTH, mCurrentPreviewHeight = DEFAULT_PREVIEW_HEIGHT;
  115. protected String mSupportedSize;
  116. // these fields from here are accessed from native code and do not change name and remove
  117. protected long mNativePtr;
  118. protected int mScanningModeMin, mScanningModeMax, mScanningModeDef;
  119. protected int mExposureModeMin, mExposureModeMax, mExposureModeDef;
  120. protected int mExposurePriorityMin, mExposurePriorityMax, mExposurePriorityDef;
  121. protected int mExposureMin, mExposureMax, mExposureDef;
  122. protected int mAutoFocusMin, mAutoFocusMax, mAutoFocusDef;
  123. protected int mFocusMin, mFocusMax, mFocusDef;
  124. protected int mFocusRelMin, mFocusRelMax, mFocusRelDef;
  125. protected int mFocusSimpleMin, mFocusSimpleMax, mFocusSimpleDef;
  126. protected int mIrisMin, mIrisMax, mIrisDef;
  127. protected int mIrisRelMin, mIrisRelMax, mIrisRelDef;
  128. protected int mPanMin, mPanMax, mPanDef;
  129. protected int mTiltMin, mTiltMax, mTiltDef;
  130. protected int mRollMin, mRollMax, mRollDef;
  131. protected int mPanRelMin, mPanRelMax, mPanRelDef;
  132. protected int mTiltRelMin, mTiltRelMax, mTiltRelDef;
  133. protected int mRollRelMin, mRollRelMax, mRollRelDef;
  134. protected int mPrivacyMin, mPrivacyMax, mPrivacyDef;
  135. protected int mAutoWhiteBlanceMin, mAutoWhiteBlanceMax, mAutoWhiteBlanceDef;
  136. protected int mAutoWhiteBlanceCompoMin, mAutoWhiteBlanceCompoMax, mAutoWhiteBlanceCompoDef;
  137. protected int mWhiteBlanceMin, mWhiteBlanceMax, mWhiteBlanceDef;
  138. protected int mWhiteBlanceCompoMin, mWhiteBlanceCompoMax, mWhiteBlanceCompoDef;
  139. protected int mWhiteBlanceRelMin, mWhiteBlanceRelMax, mWhiteBlanceRelDef;
  140. protected int mBacklightCompMin, mBacklightCompMax, mBacklightCompDef;
  141. protected int mBrightnessMin, mBrightnessMax, mBrightnessDef;
  142. protected int mContrastMin, mContrastMax, mContrastDef;
  143. protected int mSharpnessMin, mSharpnessMax, mSharpnessDef;
  144. protected int mGainMin, mGainMax, mGainDef;
  145. protected int mGammaMin, mGammaMax, mGammaDef;
  146. protected int mSaturationMin, mSaturationMax, mSaturationDef;
  147. protected int mHueMin, mHueMax, mHueDef;
  148. protected int mZoomMin, mZoomMax, mZoomDef;
  149. protected int mZoomRelMin, mZoomRelMax, mZoomRelDef;
  150. protected int mPowerlineFrequencyMin, mPowerlineFrequencyMax, mPowerlineFrequencyDef;
  151. protected int mMultiplierMin, mMultiplierMax, mMultiplierDef;
  152. protected int mMultiplierLimitMin, mMultiplierLimitMax, mMultiplierLimitDef;
  153. protected int mAnalogVideoStandardMin, mAnalogVideoStandardMax, mAnalogVideoStandardDef;
  154. protected int mAnalogVideoLockStateMin, mAnalogVideoLockStateMax, mAnalogVideoLockStateDef;
  155. // until here
  156. /**
  157. * the sonctructor of this class should be call within the thread that has a looper
  158. * (UI thread or a thread that called Looper.prepare)
  159. */
  160. public UVCCamera() {
  161. mNativePtr = nativeCreate();
  162. mSupportedSize = null;
  163. }
  164. /**
  165. * connect to a UVC camera
  166. * USB permission is necessary before this method is called
  167. * @param ctrlBlock
  168. */
  169. public void open(final UsbControlBlock ctrlBlock) {
  170. mCtrlBlock = ctrlBlock;
  171. nativeConnect(mNativePtr,
  172. mCtrlBlock.getVenderId(), mCtrlBlock.getProductId(),
  173. mCtrlBlock.getFileDescriptor(),
  174. getUSBFSName(mCtrlBlock));
  175. if (mNativePtr != 0 && TextUtils.isEmpty(mSupportedSize)) {
  176. mSupportedSize = nativeGetSupportedSize(mNativePtr);
  177. }
  178. nativeSetPreviewSize(mNativePtr, DEFAULT_PREVIEW_WIDTH, DEFAULT_PREVIEW_HEIGHT, DEFAULT_PREVIEW_MODE, DEFAULT_BANDWIDTH);
  179. }
  180. /**
  181. * set status callback
  182. * @param callback
  183. */
  184. public void setStatusCallback(final IStatusCallback callback) {
  185. if (mNativePtr != 0) {
  186. nativeSetStatusCallback(mNativePtr, callback);
  187. }
  188. }
  189. /**
  190. * set button callback
  191. * @param callback
  192. */
  193. public void setButtonCallback(final IButtonCallback callback) {
  194. if (mNativePtr != 0) {
  195. nativeSetButtonCallback(mNativePtr, callback);
  196. }
  197. }
  198. /**
  199. * close and release UVC camera
  200. */
  201. public void close() {
  202. stopPreview();
  203. if (mNativePtr != 0) {
  204. nativeRelease(mNativePtr);
  205. }
  206. mCtrlBlock = null;
  207. mControlSupports = mProcSupports = 0;
  208. mCurrentPreviewMode = - 1;
  209. }
  210. public UsbDevice getDevice() {
  211. return mCtrlBlock != null ? mCtrlBlock.getDevice() : null;
  212. }
  213. public String getDeviceName(){
  214. return mCtrlBlock != null ? mCtrlBlock.getDeviceName() : null;
  215. }
  216. public UsbControlBlock getUsbControlBlock() {
  217. return mCtrlBlock;
  218. }
  219. public synchronized String getSupportedSize() {
  220. return !TextUtils.isEmpty(mSupportedSize) ? mSupportedSize : (mSupportedSize = nativeGetSupportedSize(mNativePtr));
  221. }
  222. public Size getPreviewSize() {
  223. Size result = null;
  224. final List<Size> list = getSupportedSizeList();
  225. for ( final Size sz: list) {
  226. if ((sz.width == mCurrentPreviewWidth)
  227. || (sz.height == mCurrentPreviewHeight)) {
  228. result =sz;
  229. break;
  230. }
  231. }
  232. return result;
  233. }
  234. /**
  235. * Set preview size and preview mode
  236. * @param width
  237. @param height
  238. @param mode 0:yuyv, other:MJPEG
  239. */
  240. public void setPreviewSize(final int width, final int height) {
  241. setPreviewSize(width, height, mCurrentPreviewMode, 0);
  242. }
  243. /**
  244. * Set preview size and preview mode
  245. * @param width
  246. @param height
  247. @param mode 0:yuyv, other:MJPEG
  248. */
  249. public void setPreviewSize(final int width, final int height, final int mode) {
  250. setPreviewSize(width, height, mode, 0);
  251. }
  252. /**
  253. * Set preview size and preview mode
  254. * @param width
  255. @param height
  256. @param mode 0:yuyv, other:MJPEG
  257. @param bandwidth [0.0f,1.0f]
  258. */
  259. public void setPreviewSize(final int width, final int height, final int mode, final float bandwidth) {
  260. if ((width == 0) || (height == 0))
  261. throw new IllegalArgumentException( “invalid preview size”);
  262. if (mNativePtr != 0) {
  263. final int result = nativeSetPreviewSize(mNativePtr, width, height, mode, bandwidth);
  264. if (result != 0)
  265. throw new IllegalArgumentException( “Failed to set preview size”);
  266. mCurrentPreviewMode = mode;
  267. mCurrentPreviewWidth = width;
  268. mCurrentPreviewHeight = height;
  269. }
  270. }
  271. public List<Size> getSupportedSizeList() {
  272. final int type = (mCurrentPreviewMode > 0) ? 6 : 4;
  273. return getSupportedSize(type, mSupportedSize);
  274. }
  275. public static List<Size> getSupportedSize(final int type, final String supportedSize) {
  276. final List<Size> result = new ArrayList<Size>();
  277. if (!TextUtils.isEmpty(supportedSize))
  278. try {
  279. final JSONObject json = new JSONObject(supportedSize);
  280. final JSONArray formats = json.getJSONArray( “formats”);
  281. final int format_nums = formats.length();
  282. for ( int i = 0; i < format_nums; i++) {
  283. final JSONObject format = formats.getJSONObject(i);
  284. final int format_type = format.getInt( “type”);
  285. if ((format_type == type) || (type == - 1)) {
  286. addSize(format, format_type, result);
  287. }
  288. }
  289. } catch ( final JSONException e) {
  290. }
  291. return result;
  292. }
  293. private static final void addSize(final JSONObject format, final int type, final List<Size> size_list) throws JSONException {
  294. final JSONArray size = format.getJSONArray( “size”);
  295. final int size_nums = size.length();
  296. for ( int j = 0; j < size_nums; j++) {
  297. final String[] sz = size.getString(j).split( “x”);
  298. try {
  299. size_list.add( new Size(type, j, Integer.parseInt(sz[ 0]), Integer.parseInt(sz[ 1])));
  300. } catch ( final Exception e) {
  301. break;
  302. }
  303. }
  304. }
  305. /**
  306. * set preview surface with SurfaceHolder</br>
  307. * you can use SurfaceHolder came from SurfaceView/GLSurfaceView
  308. * @param holder
  309. */
  310. public void setPreviewDisplay(final SurfaceHolder holder) {
  311. nativeSetPreviewDisplay(mNativePtr, holder.getSurface());
  312. }
  313. /**
  314. * set preview surface with SurfaceTexture.
  315. * this method require API >= 14
  316. * @param texture
  317. */
  318. public void setPreviewTexture(final SurfaceTexture texture) { // API >= 11
  319. final Surface surface = new Surface(texture); // XXX API >= 14
  320. nativeSetPreviewDisplay(mNativePtr, surface);
  321. }
  322. /**
  323. * set preview surface with Surface
  324. * @param Surface
  325. */
  326. public void setPreviewDisplay(final Surface surface) {
  327. nativeSetPreviewDisplay(mNativePtr, surface);
  328. }
  329. /**
  330. * set frame callback
  331. * @param callback
  332. * @param pixelFormat
  333. */
  334. public void setFrameCallback(final IFrameCallback callback, final int pixelFormat) {
  335. if (mNativePtr != 0) {
  336. nativeSetFrameCallback(mNativePtr, callback, pixelFormat);
  337. }
  338. }
  339. /**
  340. * start preview
  341. */
  342. public void startPreview() {
  343. if (mCtrlBlock != null) {
  344. nativeStartPreview(mNativePtr);
  345. }
  346. }
  347. /**
  348. * stop preview
  349. */
  350. public void stopPreview() {
  351. setFrameCallback( null, 0);
  352. if (mCtrlBlock != null) {
  353. nativeStopPreview(mNativePtr);
  354. }
  355. }
  356. /**
  357. * destroy UVCCamera object
  358. */
  359. public void destroy() {
  360. close();
  361. if (mNativePtr != 0) {
  362. nativeDestroy(mNativePtr);
  363. mNativePtr = 0;
  364. }
  365. }
  366. // wrong result may return when you call this just after camera open.
  367. // it is better to wait several hundreads millseconds.
  368. public boolean checkSupportFlag(final long flag) {
  369. updateCameraParams();
  370. if ((flag & 0x80000000) == 0x80000000)
  371. return ((mProcSupports & flag) == (flag & 0x7ffffffF));
  372. else
  373. return (mControlSupports & flag) == flag;
  374. }
  375. //================================================================================
  376. public synchronized void setAutoFocus(final boolean autoFocus) {
  377. if (mNativePtr != 0) {
  378. nativeSetAutoFocus(mNativePtr, autoFocus);
  379. }
  380. }
  381. public synchronized boolean getAutoFocus() {
  382. boolean result = true;
  383. if (mNativePtr != 0) {
  384. result = nativeGetAutoFocus(mNativePtr) > 0;
  385. }
  386. return result;
  387. }
  388. //================================================================================
  389. /**
  390. * @param focus[%]
  391. */
  392. public synchronized void setFocus(final int focus) {
  393. if (mNativePtr != 0) {
  394. final float range = Math.abs(mFocusMax - mFocusMin);
  395. if (range > 0)
  396. nativeSetFocus(mNativePtr, ( int)(focus / 100.f * range) + mFocusMin);
  397. }
  398. }
  399. /**
  400. * @param focus_abs
  401. * @return forcus[%]
  402. */
  403. public synchronized int getFocus(final int focus_abs) {
  404. int result = 0;
  405. if (mNativePtr != 0) {
  406. nativeUpdateFocusLimit(mNativePtr);
  407. final float range = Math.abs(mFocusMax - mFocusMin);
  408. if (range > 0) {
  409. result = ( int)((focus_abs - mFocusMin) * 100.f / range);
  410. }
  411. }
  412. return result;
  413. }
  414. /**
  415. * @return focus[%]
  416. */
  417. public synchronized int getFocus() {
  418. return getFocus(nativeGetFocus(mNativePtr));
  419. }
  420. public synchronized void resetFocus() {
  421. if (mNativePtr != 0) {
  422. nativeSetFocus(mNativePtr, mFocusDef);
  423. }
  424. }
  425. //================================================================================
  426. public synchronized void setAutoWhiteBlance(final boolean autoWhiteBlance) {
  427. if (mNativePtr != 0) {
  428. nativeSetAutoWhiteBlance(mNativePtr, autoWhiteBlance);
  429. }
  430. }
  431. public synchronized boolean getAutoWhiteBlance() {
  432. boolean result = true;
  433. if (mNativePtr != 0) {
  434. result = nativeGetAutoWhiteBlance(mNativePtr) > 0;
  435. }
  436. return result;
  437. }
  438. //================================================================================
  439. /**
  440. * @param whiteBlance[%]
  441. */
  442. public synchronized void setWhiteBlance(final int whiteBlance) {
  443. if (mNativePtr != 0) {
  444. final float range = Math.abs(mWhiteBlanceMax - mWhiteBlanceMin);
  445. if (range > 0)
  446. nativeSetWhiteBlance(mNativePtr, ( int)(whiteBlance / 100.f * range) + mWhiteBlanceMin);
  447. }
  448. }
  449. /**
  450. * @param whiteBlance_abs
  451. * @return whiteBlance[%]
  452. */
  453. public synchronized int getWhiteBlance(final int whiteBlance_abs) {
  454. int result = 0;
  455. if (mNativePtr != 0) {
  456. nativeUpdateWhiteBlanceLimit(mNativePtr);
  457. final float range = Math.abs(mWhiteBlanceMax - mWhiteBlanceMin);
  458. if (range > 0) {
  459. result = ( int)((whiteBlance_abs - mWhiteBlanceMin) * 100.f / range);
  460. }
  461. }
  462. return result;
  463. }
  464. /**
  465. * @return white blance[%]
  466. */
  467. public synchronized int getWhiteBlance() {
  468. return getFocus(nativeGetWhiteBlance(mNativePtr));
  469. }
  470. public synchronized void resetWhiteBlance() {
  471. if (mNativePtr != 0) {
  472. nativeSetWhiteBlance(mNativePtr, mWhiteBlanceDef);
  473. }
  474. }
  475. //================================================================================
  476. /**
  477. * @param brightness[%]
  478. */
  479. public synchronized void setBrightness(final int brightness) {
  480. if (mNativePtr != 0) {
  481. final float range = Math.abs(mBrightnessMax - mBrightnessMin);
  482. if (range > 0)
  483. nativeSetBrightness(mNativePtr, ( int)(brightness / 100.f * range) + mBrightnessMin);
  484. }
  485. }
  486. /**
  487. * @param brightness_abs
  488. * @return brightness[%]
  489. */
  490. public synchronized int getBrightness(final int brightness_abs) {
  491. int result = 0;
  492. if (mNativePtr != 0) {
  493. nativeUpdateBrightnessLimit(mNativePtr);
  494. final float range = Math.abs(mBrightnessMax - mBrightnessMin);
  495. if (range > 0) {
  496. result = ( int)((brightness_abs - mBrightnessMin) * 100.f / range);
  497. }
  498. }
  499. return result;
  500. }
  501. /**
  502. * @return brightness[%]
  503. */
  504. public synchronized int getBrightness() {
  505. return getBrightness(nativeGetBrightness(mNativePtr));
  506. }
  507. public synchronized void resetBrightness() {
  508. if (mNativePtr != 0) {
  509. nativeSetBrightness(mNativePtr, mBrightnessDef);
  510. }
  511. }
  512. //================================================================================
  513. /**
  514. * @param contrast[%]
  515. */
  516. public synchronized void setContrast(final int contrast) {
  517. if (mNativePtr != 0) {
  518. nativeUpdateContrastLimit(mNativePtr);
  519. final float range = Math.abs(mContrastMax - mContrastMin);
  520. if (range > 0)
  521. nativeSetContrast(mNativePtr, ( int)(contrast / 100.f * range) + mContrastMin);
  522. }
  523. }
  524. /**
  525. * @param contrast_abs
  526. * @return contrast[%]
  527. */
  528. public synchronized int getContrast(final int contrast_abs) {
  529. int result = 0;
  530. if (mNativePtr != 0) {
  531. final float range = Math.abs(mContrastMax - mContrastMin);
  532. if (range > 0) {
  533. result = ( int)((contrast_abs - mContrastMin) * 100.f / range);
  534. }
  535. }
  536. return result;
  537. }
  538. /**
  539. * @return contrast[%]
  540. */
  541. public synchronized int getContrast() {
  542. return getContrast(nativeGetContrast(mNativePtr));
  543. }
  544. public synchronized void resetContrast() {
  545. if (mNativePtr != 0) {
  546. nativeSetContrast(mNativePtr, mContrastDef);
  547. }
  548. }
  549. //================================================================================
  550. /**
  551. * @param sharpness[%]
  552. */
  553. public synchronized void setSharpness(final int sharpness) {
  554. if (mNativePtr != 0) {
  555. final float range = Math.abs(mSharpnessMax - mSharpnessMin);
  556. if (range > 0)
  557. nativeSetSharpness(mNativePtr, ( int)(sharpness / 100.f * range) + mSharpnessMin);
  558. }
  559. }
  560. /**
  561. * @param sharpness_abs
  562. * @return sharpness[%]
  563. */
  564. public synchronized int getSharpness(final int sharpness_abs) {
  565. int result = 0;
  566. if (mNativePtr != 0) {
  567. nativeUpdateSharpnessLimit(mNativePtr);
  568. final float range = Math.abs(mSharpnessMax - mSharpnessMin);
  569. if (range > 0) {
  570. result = ( int)((sharpness_abs - mSharpnessMin) * 100.f / range);
  571. }
  572. }
  573. return result;
  574. }
  575. /**
  576. * @return sharpness[%]
  577. */
  578. public synchronized int getSharpness() {
  579. return getSharpness(nativeGetSharpness(mNativePtr));
  580. }
  581. public synchronized void resetSharpness() {
  582. if (mNativePtr != 0) {
  583. nativeSetSharpness(mNativePtr, mSharpnessDef);
  584. }
  585. }
  586. //================================================================================
  587. /**
  588. * @param gain[%]
  589. */
  590. public synchronized void setGain(final int gain) {
  591. if (mNativePtr != 0) {
  592. final float range = Math.abs(mGainMax - mGainMin);
  593. if (range > 0)
  594. nativeSetGain(mNativePtr, ( int)(gain / 100.f * range) + mGainMin);
  595. }
  596. }
  597. /**
  598. * @param gain_abs
  599. * @return gain[%]
  600. */
  601. public synchronized int getGain(final int gain_abs) {
  602. int result = 0;
  603. if (mNativePtr != 0) {
  604. nativeUpdateGainLimit(mNativePtr);
  605. final float range = Math.abs(mGainMax - mGainMin);
  606. if (range > 0) {
  607. result = ( int)((gain_abs - mGainMin) * 100.f / range);
  608. }
  609. }
  610. return result;
  611. }
  612. /**
  613. * @return gain[%]
  614. */
  615. public synchronized int getGain() {
  616. return getGain(nativeGetGain(mNativePtr));
  617. }
  618. public synchronized void resetGain() {
  619. if (mNativePtr != 0) {
  620. nativeSetGain(mNativePtr, mGainDef);
  621. }
  622. }
  623. //================================================================================
  624. /**
  625. * @param gamma[%]
  626. */
  627. public synchronized void setGamma(final int gamma) {
  628. if (mNativePtr != 0) {
  629. final float range = Math.abs(mGammaMax - mGammaMin);
  630. if (range > 0)
  631. nativeSetGamma(mNativePtr, ( int)(gamma / 100.f * range) + mGammaMin);
  632. }
  633. }
  634. /**
  635. * @param gamma_abs
  636. * @return gamma[%]
  637. */
  638. public synchronized int getGamma(final int gamma_abs) {
  639. int result = 0;
  640. if (mNativePtr != 0) {
  641. nativeUpdateGammaLimit(mNativePtr);
  642. final float range = Math.abs(mGammaMax - mGammaMin);
  643. if (range > 0) {
  644. result = ( int)((gamma_abs - mGammaMin) * 100.f / range);
  645. }
  646. }
  647. return result;
  648. }
  649. /**
  650. * @return gamma[%]
  651. */
  652. public synchronized int getGamma() {
  653. return getGamma(nativeGetGamma(mNativePtr));
  654. }
  655. public synchronized void resetGamma() {
  656. if (mNativePtr != 0) {
  657. nativeSetGamma(mNativePtr, mGammaDef);
  658. }
  659. }
  660. //================================================================================
  661. /**
  662. * @param saturation[%]
  663. */
  664. public synchronized void setSaturation(final int saturation) {
  665. if (mNativePtr != 0) {
  666. final float range = Math.abs(mSaturationMax - mSaturationMin);
  667. if (range > 0)
  668. nativeSetSaturation(mNativePtr, ( int)(saturation / 100.f * range) + mSaturationMin);
  669. }
  670. }
  671. /**
  672. * @param saturation_abs
  673. * @return saturation[%]
  674. */
  675. public synchronized int getSaturation(final int saturation_abs) {
  676. int result = 0;
  677. if (mNativePtr != 0) {
  678. nativeUpdateSaturationLimit(mNativePtr);
  679. final float range = Math.abs(mSaturationMax - mSaturationMin);
  680. if (range > 0) {
  681. result = ( int)((saturation_abs - mSaturationMin) * 100.f / range);
  682. }
  683. }
  684. return result;
  685. }
  686. /**
  687. * @return saturation[%]
  688. */
  689. public synchronized int getSaturation() {
  690. return getSaturation(nativeGetSaturation(mNativePtr));
  691. }
  692. public synchronized void resetSaturation() {
  693. if (mNativePtr != 0) {
  694. nativeSetSaturation(mNativePtr, mSaturationDef);
  695. }
  696. }
  697. //================================================================================
  698. /**
  699. * @param hue[%]
  700. */
  701. public synchronized void setHue(final int hue) {
  702. if (mNativePtr != 0) {
  703. final float range = Math.abs(mHueMax - mHueMin);
  704. if (range > 0)
  705. nativeSetHue(mNativePtr, ( int)(hue / 100.f * range) + mHueMin);
  706. }
  707. }
  708. /**
  709. * @param hue_abs
  710. * @return hue[%]
  711. */
  712. public synchronized int getHue(final int hue_abs) {
  713. int result = 0;
  714. if (mNativePtr != 0) {
  715. nativeUpdateHueLimit(mNativePtr);
  716. final float range = Math.abs(mHueMax - mHueMin);
  717. if (range > 0) {
  718. result = ( int)((hue_abs - mHueMin) * 100.f / range);
  719. }
  720. }
  721. return result;
  722. }
  723. /**
  724. * @return hue[%]
  725. */
  726. public synchronized int getHue() {
  727. return getHue(nativeGetHue(mNativePtr));
  728. }
  729. public synchronized void resetHue() {
  730. if (mNativePtr != 0) {
  731. nativeSetHue(mNativePtr, mSaturationDef);
  732. }
  733. }
  734. //================================================================================
  735. public void setPowerlineFrequency(final int frequency) {
  736. if (mNativePtr != 0)
  737. nativeSetPowerlineFrequency(mNativePtr, frequency);
  738. }
  739. public int getPowerlineFrequency() {
  740. return nativeGetPowerlineFrequency(mNativePtr);
  741. }
  742. //================================================================================
  743. /**
  744. * this may not work well with some combination of camera and device
  745. * @param zoom[%]
  746. */
  747. public synchronized void setZoom(final int zoom) {
  748. if (mNativePtr != 0) {
  749. final float range = Math.abs(mZoomMax - mZoomMin);
  750. if (range > 0) {
  751. final int z = ( int)(zoom / 100.f * range) + mZoomMin;
  752. // Log.d(TAG, “setZoom:zoom=” + zoom + ” ,value=” + z);
  753. nativeSetZoom(mNativePtr, z);
  754. }
  755. }
  756. }
  757. /**
  758. * @param zoom_abs
  759. * @return zoom[%]
  760. */
  761. public synchronized int getZoom(final int zoom_abs) {
  762. int result = 0;
  763. if (mNativePtr != 0) {
  764. nativeUpdateZoomLimit(mNativePtr);
  765. final float range = Math.abs(mZoomMax - mZoomMin);
  766. if (range > 0) {
  767. result = ( int)((zoom_abs - mZoomMin) * 100.f / range);
  768. }
  769. }
  770. return result;
  771. }
  772. /**
  773. * @return zoom[%]
  774. */
  775. public synchronized int getZoom() {
  776. return getZoom(nativeGetZoom(mNativePtr));
  777. }
  778. public synchronized void resetZoom() {
  779. if (mNativePtr != 0) {
  780. nativeSetZoom(mNativePtr, mZoomDef);
  781. }
  782. }
  783. //================================================================================
  784. public synchronized void updateCameraParams() {
  785. if (mNativePtr != 0) {
  786. if ((mControlSupports == 0) || (mProcSupports == 0)) {
  787. // サポートしている機能フラグを取得
  788. if (mControlSupports == 0)
  789. mControlSupports = nativeGetCtrlSupports(mNativePtr);
  790. if (mProcSupports == 0)
  791. mProcSupports = nativeGetProcSupports(mNativePtr);
  792. // 設定値を取得
  793. if ((mControlSupports != 0) && (mProcSupports != 0)) {
  794. nativeUpdateBrightnessLimit(mNativePtr);
  795. nativeUpdateContrastLimit(mNativePtr);
  796. nativeUpdateSharpnessLimit(mNativePtr);
  797. nativeUpdateGainLimit(mNativePtr);
  798. nativeUpdateGammaLimit(mNativePtr);
  799. nativeUpdateSaturationLimit(mNativePtr);
  800. nativeUpdateHueLimit(mNativePtr);
  801. nativeUpdateZoomLimit(mNativePtr);
  802. nativeUpdateWhiteBlanceLimit(mNativePtr);
  803. nativeUpdateFocusLimit(mNativePtr);
  804. }
  805. if (DEBUG) {
  806. dumpControls(mControlSupports);
  807. dumpProc(mProcSupports);
  808. Log.v(TAG, String.format( “Brightness:min=%d,max=%d,def=%d”, mBrightnessMin, mBrightnessMax, mBrightnessDef));
  809. Log.v(TAG, String.format( “Contrast:min=%d,max=%d,def=%d”, mContrastMin, mContrastMax, mContrastDef));
  810. Log.v(TAG, String.format( “Sharpness:min=%d,max=%d,def=%d”, mSharpnessMin, mSharpnessMax, mSharpnessDef));
  811. Log.v(TAG, String.format( “Gain:min=%d,max=%d,def=%d”, mGainMin, mGainMax, mGainDef));
  812. Log.v(TAG, String.format( “Gamma:min=%d,max=%d,def=%d”, mGammaMin, mGammaMax, mGammaDef));
  813. Log.v(TAG, String.format( “Saturation:min=%d,max=%d,def=%d”, mSaturationMin, mSaturationMax, mSaturationDef));
  814. Log.v(TAG, String.format( “Hue:min=%d,max=%d,def=%d”, mHueMin, mHueMax, mHueDef));
  815. Log.v(TAG, String.format( “Zoom:min=%d,max=%d,def=%d”, mZoomMin, mZoomMax, mZoomDef));
  816. Log.v(TAG, String.format( “WhiteBlance:min=%d,max=%d,def=%d”, mWhiteBlanceMin, mWhiteBlanceMax, mWhiteBlanceDef));
  817. Log.v(TAG, String.format( “Focus:min=%d,max=%d,def=%d”, mFocusMin, mFocusMax, mFocusDef));
  818. }
  819. }
  820. } else {
  821. mControlSupports = mProcSupports = 0;
  822. }
  823. }
  824. private static final String[] SUPPORTS_CTRL = {
  825. “D0: Scanning Mode”,
  826. “D1: Auto-Exposure Mode”,
  827. “D2: Auto-Exposure Priority”,
  828. “D3: Exposure Time (Absolute)”,
  829. “D4: Exposure Time (Relative)”,
  830. “D5: Focus (Absolute)”,
  831. “D6: Focus (Relative)”,
  832. “D7: Iris (Absolute)”,
  833. “D8: Iris (Relative)”,
  834. “D9: Zoom (Absolute)”,
  835. “D10: Zoom (Relative)”,
  836. “D11: PanTilt (Absolute)”,
  837. “D12: PanTilt (Relative)”,
  838. “D13: Roll (Absolute)”,
  839. “D14: Roll (Relative)”,
  840. “D15: Reserved”,
  841. “D16: Reserved”,
  842. “D17: Focus, Auto”,
  843. “D18: Privacy”,
  844. “D19: Focus, Simple”,
  845. “D20: Window”,
  846. “D21: Region of Interest”,
  847. “D22: Reserved, set to zero”,
  848. “D23: Reserved, set to zero”,
  849. };
  850. private static final String[] SUPPORTS_PROC = {
  851. “D0: Brightness”,
  852. “D1: Contrast”,
  853. “D2: Hue”,
  854. “D3: Saturation”,
  855. “D4: Sharpness”,
  856. “D5: Gamma”,
  857. “D6: White Balance Temperature”,
  858. “D7: White Balance Component”,
  859. “D8: Backlight Compensation”,
  860. “D9: Gain”,
  861. “D10: Power Line Frequency”,
  862. “D11: Hue, Auto”,
  863. “D12: White Balance Temperature, Auto”,
  864. “D13: White Balance Component, Auto”,
  865. “D14: Digital Multiplier”,
  866. “D15: Digital Multiplier Limit”,
  867. “D16: Analog Video Standard”,
  868. “D17: Analog Video Lock Status”,
  869. “D18: Contrast, Auto”,
  870. “D19: Reserved. Set to zero”,
  871. “D20: Reserved. Set to zero”,
  872. “D21: Reserved. Set to zero”,
  873. “D22: Reserved. Set to zero”,
  874. “D23: Reserved. Set to zero”,
  875. };
  876. private static final void dumpControls(final long controlSupports) {
  877. Log.i(TAG, String.format( “controlSupports=%x”, controlSupports));
  878. for ( int i = 0; i < SUPPORTS_CTRL.length; i++) {
  879. Log.i(TAG, SUPPORTS_CTRL[i] + ((controlSupports & ( 0x1 << i)) != 0 ? “=enabled” : “=disabled”));
  880. }
  881. }
  882. private static final void dumpProc(final long procSupports) {
  883. Log.i(TAG, String.format( “procSupports=%x”, procSupports));
  884. for ( int i = 0; i < SUPPORTS_PROC.length; i++) {
  885. Log.i(TAG, SUPPORTS_PROC[i] + ((procSupports & ( 0x1 << i)) != 0 ? “=enabled” : “=disabled”));
  886. }
  887. }
  888. private final String getUSBFSName(final UsbControlBlock ctrlBlock) {
  889. String result = null;
  890. final String name = ctrlBlock.getDeviceName();
  891. final String[] v = !TextUtils.isEmpty(name) ? name.split( “/”) : null;
  892. if ((v != null) && (v.length > 2)) {
  893. final StringBuilder sb = new StringBuilder(v[ 0]);
  894. for ( int i = 1; i < v.length - 2; i++)
  895. sb.append( “/”).append(v[i]);
  896. result = sb.toString();
  897. }
  898. if (TextUtils.isEmpty(result)) {
  899. Log.w(TAG, “failed to get USBFS path, try to use default path:” + name);
  900. result = DEFAULT_USBFS;
  901. }
  902. return result;
  903. }
  904. // #nativeCreate and #nativeDestroy are not static methods.
  905. private final native long nativeCreate();
  906. private final native void nativeDestroy(final long id_camera);
  907. private static final native int nativeConnect(final long id_camera, final int venderId, final int productId, final int fileDescriptor, String usbfs);
  908. private static final native int nativeRelease(final long id_camera);
  909. private static final native int nativeSetStatusCallback(final long mNativePtr, final IStatusCallback callback);
  910. private static final native int nativeSetButtonCallback(final long mNativePtr, final IButtonCallback callback);
  911. private static final native int nativeSetPreviewSize(final long id_camera, final int width, final int height, final int mode, final float bandwidth);
  912. private static final native String nativeGetSupportedSize(final long id_camera);
  913. private static final native int nativeStartPreview(final long id_camera);
  914. private static final native int nativeStopPreview(final long id_camera);
  915. private static final native int nativeSetPreviewDisplay(final long id_camera, final Surface surface);
  916. private static final native int nativeSetFrameCallback(final long mNativePtr, final IFrameCallback callback, final int pixelFormat);
  917. //**********************************************************************
  918. /**
  919. * start movie capturing(this should call while previewing)
  920. * @param surface
  921. */
  922. public void startCapture(final Surface surface) {
  923. if (mCtrlBlock != null && surface != null) {
  924. nativeSetCaptureDisplay(mNativePtr, surface);
  925. } else
  926. throw new NullPointerException( “startCapture”);
  927. }
  928. /**
  929. * stop movie capturing
  930. */
  931. public void stopCapture() {
  932. if (mCtrlBlock != null) {
  933. nativeSetCaptureDisplay(mNativePtr, null);
  934. }
  935. }
  936. private static final native int nativeSetCaptureDisplay(final long id_camera, final Surface surface);
  937. private static final native long nativeGetCtrlSupports(final long id_camera);
  938. private static final native long nativeGetProcSupports(final long id_camera);
  939. private final native int nativeUpdateScanningModeLimit(final long id_camera);
  940. private static final native int nativeSetScanningMode(final long id_camera, final int scanning_mode);
  941. private static final native int nativeGetScanningMode(final long id_camera);
  942. private final native int nativeUpdateExposureModeLimit(final long id_camera);
  943. private static final native int nativeSetExposureMode(final long id_camera, final int exposureMode);
  944. private static final native int nativeGetExposureMode(final long id_camera);
  945. private final native int nativeUpdateExposurePriorityLimit(final long id_camera);
  946. private static final native int nativeSetExposurePriority(final long id_camera, final int priority);
  947. private static final native int nativeGetExposurePriority(final long id_camera);
  948. private final native int nativeUpdateExposureLimit(final long id_camera);
  949. private static final native int nativeSetExposure(final long id_camera, final int exposure);
  950. private static final native int nativeGetExposure(final long id_camera);
  951. private final native int nativeUpdateExposureRelLimit(final long id_camera);
  952. private static final native int nativeSetExposureRel(final long id_camera, final int exposure_rel);
  953. private static final native int nativeGetExposureRel(final long id_camera);
  954. private final native int nativeUpdateAutoFocusLimit(final long id_camera);
  955. private static final native int nativeSetAutoFocus(final long id_camera, final boolean autofocus);
  956. private static final native int nativeGetAutoFocus(final long id_camera);
  957. private final native int nativeUpdateFocusLimit(final long id_camera);
  958. private static final native int nativeSetFocus(final long id_camera, final int focus);
  959. private static final native int nativeGetFocus(final long id_camera);
  960. private final native int nativeUpdateFocusRelLimit(final long id_camera);
  961. private static final native int nativeSetFocusRel(final long id_camera, final int focus_rel);
  962. private static final native int nativeGetFocusRel(final long id_camera);
  963. private final native int nativeUpdateIrisLimit(final long id_camera);
  964. private static final native int nativeSetIris(final long id_camera, final int iris);
  965. private static final native int nativeGetIris(final long id_camera);
  966. private final native int nativeUpdateIrisRelLimit(final long id_camera);
  967. private static final native int nativeSetIrisRel(final long id_camera, final int iris_rel);
  968. private static final native int nativeGetIrisRel(final long id_camera);
  969. private final native int nativeUpdatePanLimit(final long id_camera);
  970. private static final native int nativeSetPan(final long id_camera, final int pan);
  971. private static final native int nativeGetPan(final long id_camera);
  972. private final native int nativeUpdatePanRelLimit(final long id_camera);
  973. private static final native int nativeSetPanRel(final long id_camera, final int pan_rel);
  974. private static final native int nativeGetPanRel(final long id_camera);
  975. private final native int nativeUpdateTiltLimit(final long id_camera);
  976. private static final native int nativeSetTilt(final long id_camera, final int tilt);
  977. private static final native int nativeGetTilt(final long id_camera);
  978. private final native int nativeUpdateTiltRelLimit(final long id_camera);
  979. private static final native int nativeSetTiltRel(final long id_camera, final int tilt_rel);
  980. private static final native int nativeGetTiltRel(final long id_camera);
  981. private final native int nativeUpdateRollLimit(final long id_camera);
  982. private static final native int nativeSetRoll(final long id_camera, final int roll);
  983. private static final native int nativeGetRoll(final long id_camera);
  984. private final native int nativeUpdateRollRelLimit(final long id_camera);
  985. private static final native int nativeSetRollRel(final long id_camera, final int roll_rel);
  986. private static final native int nativeGetRollRel(final long id_camera);
  987. private final native int nativeUpdateAutoWhiteBlanceLimit(final long id_camera);
  988. private static final native int nativeSetAutoWhiteBlance(final long id_camera, final boolean autoWhiteBlance);
  989. private static final native int nativeGetAutoWhiteBlance(final long id_camera);
  990. private final native int nativeUpdateAutoWhiteBlanceCompoLimit(final long id_camera);
  991. private static final native int nativeSetAutoWhiteBlanceCompo(final long id_camera, final boolean autoWhiteBlanceCompo);
  992. private static final native int nativeGetAutoWhiteBlanceCompo(final long id_camera);
  993. private final native int nativeUpdateWhiteBlanceLimit(final long id_camera);
  994. private static final native int nativeSetWhiteBlance(final long id_camera, final int whiteBlance);
  995. private static final native int nativeGetWhiteBlance(final long id_camera);
  996. private final native int nativeUpdateWhiteBlanceCompoLimit(final long id_camera);
  997. private static final native int nativeSetWhiteBlanceCompo(final long id_camera, final int whiteBlance_compo);
  998. private static final native int nativeGetWhiteBlanceCompo(final long id_camera);
  999. private final native int nativeUpdateBacklightCompLimit(final long id_camera);
  1000. private static final native int nativeSetBacklightComp(final long id_camera, final int backlight_comp);
  1001. private static final native int nativeGetBacklightComp(final long id_camera);
  1002. private final native int nativeUpdateBrightnessLimit(final long id_camera);
  1003. private static final native int nativeSetBrightness(final long id_camera, final int brightness);
  1004. private static final native int nativeGetBrightness(final long id_camera);
  1005. private final native int nativeUpdateContrastLimit(final long id_camera);
  1006. private static final native int nativeSetContrast(final long id_camera, final int contrast);
  1007. private static final native int nativeGetContrast(final long id_camera);
  1008. private final native int nativeUpdateAutoContrastLimit(final long id_camera);
  1009. private static final native int nativeSetAutoContrast(final long id_camera, final boolean autocontrast);
  1010. private static final native int nativeGetAutoContrast(final long id_camera);
  1011. private final native int nativeUpdateSharpnessLimit(final long id_camera);
  1012. private static final native int nativeSetSharpness(final long id_camera, final int sharpness);
  1013. private static final native int nativeGetSharpness(final long id_camera);
  1014. private final native int nativeUpdateGainLimit(final long id_camera);
  1015. private static final native int nativeSetGain(final long id_camera, final int gain);
  1016. private static final native int nativeGetGain(final long id_camera);
  1017. private final native int nativeUpdateGammaLimit(final long id_camera);
  1018. private static final native int nativeSetGamma(final long id_camera, final int gamma);
  1019. private static final native int nativeGetGamma(final long id_camera);
  1020. private final native int nativeUpdateSaturationLimit(final long id_camera);
  1021. private static final native int nativeSetSaturation(final long id_camera, final int saturation);
  1022. private static final native int nativeGetSaturation(final long id_camera);
  1023. private final native int nativeUpdateHueLimit(final long id_camera);
  1024. private static final native int nativeSetHue(final long id_camera, final int hue);
  1025. private static final native int nativeGetHue(final long id_camera);
  1026. private final native int nativeUpdateAutoHueLimit(final long id_camera);
  1027. private static final native int nativeSetAutoHue(final long id_camera, final boolean autohue);
  1028. private static final native int nativeGetAutoHue(final long id_camera);
  1029. private final native int nativeUpdatePowerlineFrequencyLimit(final long id_camera);
  1030. private static final native int nativeSetPowerlineFrequency(final long id_camera, final int frequency);
  1031. private static final native int nativeGetPowerlineFrequency(final long id_camera);
  1032. private final native int nativeUpdateZoomLimit(final long id_camera);
  1033. private static final native int nativeSetZoom(final long id_camera, final int zoom);
  1034. private static final native int nativeGetZoom(final long id_camera);
  1035. private final native int nativeUpdateZoomRelLimit(final long id_camera);
  1036. private static final native int nativeSetZoomRel(final long id_camera, final int zoom_rel);
  1037. private static final native int nativeGetZoomRel(final long id_camera);
  1038. private final native int nativeUpdateDigitalMultiplierLimit(final long id_camera);
  1039. private static final native int nativeSetDigitalMultiplier(final long id_camera, final int multiplier);
  1040. private static final native int nativeGetDigitalMultiplier(final long id_camera);
  1041. private final native int nativeUpdateDigitalMultiplierLimitLimit(final long id_camera);
  1042. private static final native int nativeSetDigitalMultiplierLimit(final long id_camera, final int multiplier_limit);
  1043. private static final native int nativeGetDigitalMultiplierLimit(final long id_camera);
  1044. private final native int nativeUpdateAnalogVideoStandardLimit(final long id_camera);
  1045. private static final native int nativeSetAnalogVideoStandard(final long id_camera, final int standard);
  1046. private static final native int nativeGetAnalogVideoStandard(final long id_camera);
  1047. private final native int nativeUpdateAnalogVideoLockStateLimit(final long id_camera);
  1048. private static final native int nativeSetAnalogVideoLoackState(final long id_camera, final int state);
  1049. private static final native int nativeGetAnalogVideoLoackState(final long id_camera);
  1050. private final native int nativeUpdatePrivacyLimit(final long id_camera);
  1051. private static final native int nativeSetPrivacy(final long id_camera, final boolean privacy);
  1052. private static final native int nativeGetPrivacy(final long id_camera);
  1053. }

UVCCameraTextureView


     
     
  1. package com.serenegiant.usb.widget;
  2. /*
  3. * UVCCamera
  4. * library and sample to access to UVC web camera on non-rooted Android device
  5. *
  6. * Copyright (c) 2015 saki t_saki@serenegiant.com
  7. *
  8. * File name: UVCCameraTextureView.java
  9. *
  10. * Licensed under the Apache License, Version 2.0 (the “License”);
  11. * you may not use this file except in compliance with the License.
  12. * You may obtain a copy of the License at
  13. *
  14. * http://www.apache.org/licenses/LICENSE-2.0
  15. *
  16. * Unless required by applicable law or agreed to in writing, software
  17. * distributed under the License is distributed on an “AS IS” BASIS,
  18. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19. * See the License for the specific language governing permissions and
  20. * limitations under the License.
  21. *
  22. * All files in the folder are under this Apache License, Version 2.0.
  23. * Files in the jni/libjpeg, jni/libusb, jin/libuvc, jni/rapidjson folder may have a different license, see the respective files.
  24. */
  25. import android.content.Context;
  26. import android.graphics.Bitmap;
  27. import android.graphics.SurfaceTexture;
  28. import android.util.AttributeSet;
  29. import android.util.Log;
  30. import android.view.TextureView;
  31. import com.serenegiant.usb.encode.MediaEncoder;
  32. /**
  33. * change the view size with keeping the specified aspect ratio.
  34. * if you set this view with in a FrameLayout and set property “android:layout_gravity=”center”,
  35. * you can show this view in the center of screen and keep the aspect ratio of content
  36. * XXX it is better that can set the aspect raton a a xml property
  37. */
  38. public class UVCCameraTextureView extends TextureView // API >= 14
  39. implements TextureView.SurfaceTextureListener, CameraViewInterface {
  40. private static final boolean DEBUG = true; // TODO set false on release
  41. private static final String TAG = “UVCCameraTextureView”;
  42. private double mRequestedAspect = - 1.0;
  43. private boolean mHasSurface;
  44. private final Object mCaptureSync = new Object();
  45. private Bitmap mTempBitmap;
  46. private boolean mReqesutCaptureStillImage;
  47. public UVCCameraTextureView(final Context context) {
  48. this(context, null, 0);
  49. }
  50. public UVCCameraTextureView(final Context context, final AttributeSet attrs) {
  51. this(context, attrs, 0);
  52. }
  53. public UVCCameraTextureView(final Context context, final AttributeSet attrs, final int defStyle) {
  54. super(context, attrs, defStyle);
  55. setSurfaceTextureListener( this);
  56. }
  57. @Override
  58. public void onResume() {
  59. if (DEBUG) Log.v(TAG, “onResume:”);
  60. }
  61. @Override
  62. public void onPause() {
  63. if (DEBUG) Log.v(TAG, “onPause:”);
  64. if (mTempBitmap != null) {
  65. mTempBitmap.recycle();
  66. mTempBitmap = null;
  67. }
  68. }
  69. @Override
  70. public void setAspectRatio(final double aspectRatio) {
  71. if (aspectRatio < 0) {
  72. throw new IllegalArgumentException();
  73. }
  74. if (mRequestedAspect != aspectRatio) {
  75. mRequestedAspect = aspectRatio;
  76. requestLayout();
  77. }
  78. }
  79. @Override
  80. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  81. if (mRequestedAspect > 0) {
  82. int initialWidth = MeasureSpec.getSize(widthMeasureSpec);
  83. int initialHeight = MeasureSpec.getSize(heightMeasureSpec);
  84. final int horizPadding = getPaddingLeft() + getPaddingRight();
  85. final int vertPadding = getPaddingTop() + getPaddingBottom();
  86. initialWidth -= horizPadding;
  87. initialHeight -= vertPadding;
  88. final double viewAspectRatio = ( double)initialWidth / initialHeight;
  89. final double aspectDiff = mRequestedAspect / viewAspectRatio - 1;
  90. if (Math.abs(aspectDiff) > 0.01) {
  91. if (aspectDiff > 0) {
  92. // width priority decision
  93. initialHeight = ( int) (initialWidth / mRequestedAspect);
  94. } else {
  95. // height priority decison
  96. initialWidth = ( int) (initialHeight * mRequestedAspect);
  97. }
  98. initialWidth += horizPadding;
  99. initialHeight += vertPadding;
  100. widthMeasureSpec = MeasureSpec.makeMeasureSpec(initialWidth, MeasureSpec.EXACTLY);
  101. heightMeasureSpec = MeasureSpec.makeMeasureSpec(initialHeight, MeasureSpec.EXACTLY);
  102. }
  103. }
  104. super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  105. }
  106. @Override
  107. public void onSurfaceTextureAvailable(final SurfaceTexture surface, final int width, final int height) {
  108. if (DEBUG) Log.v(TAG, “onSurfaceTextureAvailable:” + surface);
  109. // mRenderHandler = RenderHandler.createHandler(surface);
  110. mHasSurface = true;
  111. }
  112. @Override
  113. public void onSurfaceTextureSizeChanged(final SurfaceTexture surface, final int width, final int height) {
  114. if (DEBUG) Log.v(TAG, “onSurfaceTextureSizeChanged:” + surface);
  115. mTempBitmap = null;
  116. }
  117. @Override
  118. public boolean onSurfaceTextureDestroyed(final SurfaceTexture surface) {
  119. if (DEBUG) Log.v(TAG, “onSurfaceTextureDestroyed:” + surface);
  120. mHasSurface = false;
  121. return true;
  122. }
  123. @Override
  124. public void onSurfaceTextureUpdated(final SurfaceTexture surface) {
  125. synchronized (mCaptureSync) {
  126. if (mReqesutCaptureStillImage) {
  127. mReqesutCaptureStillImage = false;
  128. if (mTempBitmap == null)
  129. // TODO modify this to change output image size
  130. mTempBitmap = getBitmap( 1600, 1200); //3264,2448
  131. else
  132. getBitmap(mTempBitmap);
  133. mCaptureSync.notifyAll();
  134. }
  135. }
  136. }
  137. @Override
  138. public boolean hasSurface() {
  139. return mHasSurface;
  140. }
  141. /**
  142. * capture preview image as a bitmap
  143. * this method blocks current thread until bitmap is ready
  144. * if you call this method at almost same time from different thread,
  145. * the returned bitmap will be changed while you are processing the bitmap
  146. * (because we return same instance of bitmap on each call for memory saving)
  147. * if you need to call this method from multiple thread,
  148. * you should change this method(copy and return)
  149. */
  150. @Override
  151. public Bitmap captureStillImage() {
  152. synchronized (mCaptureSync) {
  153. mReqesutCaptureStillImage = true;
  154. try {
  155. mCaptureSync.wait();
  156. } catch ( final InterruptedException e) {
  157. }
  158. return mTempBitmap;
  159. }
  160. }
  161. @Override
  162. public void setVideoEncoder(final MediaEncoder encoder) {
  163. }
  164. }

USBMonitor


     
     
  1. package com.serenegiant.usb;
  2. /*
  3. * UVCCamera
  4. * library and sample to access to UVC web camera on non-rooted Android device
  5. *
  6. * Copyright (c) 2014-2015 saki t_saki@serenegiant.com
  7. *
  8. * File name: USBMonitor.java
  9. *
  10. * Licensed under the Apache License, Version 2.0 (the “License”);
  11. * you may not use this file except in compliance with the License.
  12. * You may obtain a copy of the License at
  13. *
  14. * http://www.apache.org/licenses/LICENSE-2.0
  15. *
  16. * Unless required by applicable law or agreed to in writing, software
  17. * distributed under the License is distributed on an “AS IS” BASIS,
  18. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19. * See the License for the specific language governing permissions and
  20. * limitations under the License.
  21. *
  22. * All files in the folder are under this Apache License, Version 2.0.
  23. * Files in the jni/libjpeg, jni/libusb, jin/libuvc, jni/rapidjson folder may have a different license, see the respective files.
  24. */
  25. import java.lang.ref.WeakReference;
  26. import java.util.ArrayList;
  27. import java.util.HashMap;
  28. import java.util.Iterator;
  29. import java.util.List;
  30. import java.util.Set;
  31. import java.util.concurrent.ConcurrentHashMap;
  32. import android.app.PendingIntent;
  33. import android.content.BroadcastReceiver;
  34. import android.content.Context;
  35. import android.content.Intent;
  36. import android.content.IntentFilter;
  37. import android.hardware.usb.UsbDevice;
  38. import android.hardware.usb.UsbDeviceConnection;
  39. import android.hardware.usb.UsbInterface;
  40. import android.hardware.usb.UsbManager;
  41. import android.os.Handler;
  42. import android.util.Log;
  43. import android.util.SparseArray;
  44. public final class USBMonitor {
  45. private static final boolean DEBUG = false; // TODO set false on production
  46. private static final String TAG = “USBMonitor”;
  47. private static final String ACTION_USB_PERMISSION_BASE = “com.serenegiant.USB_PERMISSION.”;
  48. private final String ACTION_USB_PERMISSION = ACTION_USB_PERMISSION_BASE + hashCode();
  49. public static final String ACTION_USB_DEVICE_ATTACHED = “android.hardware.usb.action.USB_DEVICE_ATTACHED”;
  50. private final ConcurrentHashMap<UsbDevice, UsbControlBlock> mCtrlBlocks = new ConcurrentHashMap<UsbDevice, UsbControlBlock>();
  51. private final WeakReference<Context> mWeakContext;
  52. private final UsbManager mUsbManager;
  53. private final OnDeviceConnectListener mOnDeviceConnectListener;
  54. private PendingIntent mPermissionIntent = null;
  55. private List<DeviceFilter> mDeviceFilters = new ArrayList<DeviceFilter>();
  56. private final Handler mHandler = new Handler();
  57. public interface OnDeviceConnectListener {
  58. /**
  59. * called when device attached
  60. * @param device
  61. */
  62. public void onAttach(UsbDevice device);
  63. /**
  64. * called when device dettach(after onDisconnect)
  65. * @param device
  66. */
  67. public void onDettach(UsbDevice device);
  68. /**
  69. * called after device opend
  70. * @param device
  71. * @param createNew
  72. */
  73. public void onConnect(UsbDevice device, UsbControlBlock ctrlBlock, boolean createNew);
  74. /**
  75. * called when USB device removed or its power off (this callback is called after device closing)
  76. * @param device
  77. * @param ctrlBlock
  78. */
  79. public void onDisconnect(UsbDevice device, UsbControlBlock ctrlBlock);
  80. /**
  81. * called when canceled or could not get permission from user
  82. */
  83. public void onCancel();
  84. }
  85. public USBMonitor(final Context context, final OnDeviceConnectListener listener) {
  86. if (DEBUG) Log.v(TAG, “USBMonitor:Constructor”);
  87. /* if (listener == null)
  88. throw new IllegalArgumentException(“OnDeviceConnectListener should not null.”); */
  89. mWeakContext = new WeakReference<Context>(context);
  90. mUsbManager = (UsbManager)context.getSystemService(Context.USB_SERVICE);
  91. mOnDeviceConnectListener = listener;
  92. if (DEBUG) Log.v(TAG, “USBMonitor:mUsbManager=” + mUsbManager);
  93. }
  94. public void destroy() {
  95. if (DEBUG) Log.i(TAG, “destroy:”);
  96. unregister();
  97. final Set<UsbDevice> keys = mCtrlBlocks.keySet();
  98. if (keys != null) {
  99. UsbControlBlock ctrlBlock;
  100. try {
  101. for ( final UsbDevice key: keys) {
  102. ctrlBlock = mCtrlBlocks.remove(key);
  103. ctrlBlock.close();
  104. }
  105. } catch ( final Exception e) {
  106. Log.e(TAG, “destroy:”, e);
  107. }
  108. mCtrlBlocks.clear();
  109. }
  110. }
  111. /**
  112. * register BroadcastReceiver to monitor USB events
  113. */
  114. public synchronized void register() {
  115. if (mPermissionIntent == null) {
  116. if (DEBUG) Log.i(TAG, “register:”);
  117. final Context context = mWeakContext.get();
  118. if (context != null) {
  119. mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
  120. final IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
  121. filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
  122. context.registerReceiver(mUsbReceiver, filter);
  123. }
  124. mDeviceCounts = 0;
  125. mHandler.postDelayed(mDeviceCheckRunnable, 1000);
  126. }
  127. }
  128. /**
  129. * unregister BroadcastReceiver
  130. */
  131. public synchronized void unregister() {
  132. if (mPermissionIntent != null) {
  133. if (DEBUG) Log.i(TAG, “unregister:”);
  134. final Context context = mWeakContext.get();
  135. if (context != null) {
  136. context.unregisterReceiver(mUsbReceiver);
  137. }
  138. mPermissionIntent = null;
  139. }
  140. mDeviceCounts = 0;
  141. mHandler.removeCallbacks(mDeviceCheckRunnable);
  142. }
  143. public synchronized boolean isRegistered() {
  144. return mPermissionIntent != null;
  145. }
  146. /**
  147. * set device filter
  148. * @param filter
  149. */
  150. public void setDeviceFilter(final DeviceFilter filter) {
  151. mDeviceFilters.clear();
  152. mDeviceFilters.add(filter);
  153. }
  154. /**
  155. * set device filters
  156. * @param filters
  157. */
  158. public void setDeviceFilter(final List<DeviceFilter> filters) {
  159. mDeviceFilters.clear();
  160. mDeviceFilters.addAll(filters);
  161. }
  162. /**
  163. * return the number of connected USB devices that matched device filter
  164. * @return
  165. */
  166. public int getDeviceCount() {
  167. return getDeviceList().size();
  168. }
  169. /**
  170. * return device list, return empty list if no device matched
  171. * @return
  172. */
  173. public List<UsbDevice> getDeviceList() {
  174. return getDeviceList(mDeviceFilters);
  175. }
  176. /**
  177. * return device list, return empty list if no device matched
  178. * @param filters
  179. * @return
  180. */
  181. public List<UsbDevice> getDeviceList(final List<DeviceFilter> filters) {
  182. final HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
  183. final List<UsbDevice> result = new ArrayList<UsbDevice>();
  184. if (deviceList != null) {
  185. for ( final DeviceFilter filter: filters) {
  186. final Iterator<UsbDevice> iterator = deviceList.values().iterator();
  187. UsbDevice device;
  188. while (iterator.hasNext()) {
  189. device = iterator.next();
  190. if ((filter == null) || (filter.matches(device))) {
  191. result.add(device);
  192. }
  193. }
  194. }
  195. }
  196. return result;
  197. }
  198. /**
  199. * return device list, return empty list if no device matched
  200. * @param filter
  201. * @return
  202. */
  203. public List<UsbDevice> getDeviceList(final DeviceFilter filter) {
  204. final HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
  205. final List<UsbDevice> result = new ArrayList<UsbDevice>();
  206. if (deviceList != null) {
  207. final Iterator<UsbDevice> iterator = deviceList.values().iterator();
  208. UsbDevice device;
  209. while (iterator.hasNext()) {
  210. device = iterator.next();
  211. if ((filter == null) || (filter.matches(device))) {
  212. result.add(device);
  213. }
  214. }
  215. }
  216. return result;
  217. }
  218. /**
  219. * get USB device list
  220. * @return
  221. */
  222. public Iterator<UsbDevice> getDevices() {
  223. Iterator<UsbDevice> iterator = null;
  224. final HashMap<String, UsbDevice> list = mUsbManager.getDeviceList();
  225. if (list != null)
  226. iterator = list.values().iterator();
  227. return iterator;
  228. }
  229. /**
  230. * output device list to LogCat
  231. */
  232. public final void dumpDevices() {
  233. final HashMap<String, UsbDevice> list = mUsbManager.getDeviceList();
  234. if (list != null) {
  235. final Set<String> keys = list.keySet();
  236. if (keys != null && keys.size() > 0) {
  237. final StringBuilder sb = new StringBuilder();
  238. for ( final String key: keys) {
  239. final UsbDevice device = list.get(key);
  240. final int num_interface = device != null ? device.getInterfaceCount() : 0;
  241. sb.setLength( 0);
  242. for ( int i = 0; i < num_interface; i++) {
  243. sb.append(String.format( “interface%d:%s”, i, device.getInterface(i).toString()));
  244. }
  245. Log.i(TAG, “key=” + key + “:” + device + “:” + sb.toString());
  246. }
  247. } else {
  248. Log.i(TAG, “no device”);
  249. }
  250. } else {
  251. Log.i(TAG, “no device”);
  252. }
  253. }
  254. /**
  255. * return whether the specific Usb device has permission
  256. * @param device
  257. * @return
  258. */
  259. public boolean hasPermission(final UsbDevice device) {
  260. return device != null && mUsbManager.hasPermission(device);
  261. }
  262. /**
  263. * request permission to access to USB device
  264. * @param device
  265. */
  266. public synchronized void requestPermission(final UsbDevice device) {
  267. if (DEBUG) Log.v(TAG, “requestPermission:device=” + device);
  268. if (mPermissionIntent != null) {
  269. if (device != null) {
  270. if (mUsbManager.hasPermission(device)) {
  271. processConnect(device);
  272. } else {
  273. mUsbManager.requestPermission(device, mPermissionIntent);
  274. }
  275. } else {
  276. processCancel(device);
  277. }
  278. } else {
  279. processCancel(device);
  280. }
  281. }
  282. /**
  283. * BroadcastReceiver for USB permission
  284. */
  285. private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
  286. @Override
  287. public void onReceive(final Context context, final Intent intent) {
  288. final String action = intent.getAction();
  289. if (ACTION_USB_PERMISSION.equals(action)) {
  290. synchronized (USBMonitor. this) {
  291. final UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
  292. if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
  293. if (device != null) {
  294. processConnect(device);
  295. }
  296. } else {
  297. processCancel(device);
  298. }
  299. }
  300. } else if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
  301. final UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
  302. processAttach(device);
  303. } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
  304. final UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
  305. if (device != null) {
  306. UsbControlBlock ctrlBlock = null;
  307. ctrlBlock = mCtrlBlocks.remove(device);
  308. if (ctrlBlock != null) {
  309. ctrlBlock.close();
  310. }
  311. mDeviceCounts = 0;
  312. processDettach(device);
  313. }
  314. }
  315. }
  316. };
  317. private volatile int mDeviceCounts = 0;
  318. private final Runnable mDeviceCheckRunnable = new Runnable() {
  319. @Override
  320. public void run() {
  321. final int n = getDeviceCount();
  322. if (n != mDeviceCounts) {
  323. if (n > mDeviceCounts) {
  324. mDeviceCounts = n;
  325. if (mOnDeviceConnectListener != null)
  326. mOnDeviceConnectListener.onAttach( null);
  327. }
  328. }
  329. mHandler.postDelayed( this, 2000); // confirm every 2 seconds
  330. }
  331. };
  332. private final void processConnect(final UsbDevice device) {
  333. if (DEBUG) Log.v(TAG, “processConnect:”);
  334. mHandler.post( new Runnable() {
  335. @Override
  336. public void run() {
  337. UsbControlBlock ctrlBlock;
  338. final boolean createNew;
  339. ctrlBlock = mCtrlBlocks.get(device);
  340. if (ctrlBlock == null) {
  341. ctrlBlock = new UsbControlBlock(USBMonitor. this, device);
  342. mCtrlBlocks.put(device, ctrlBlock);
  343. createNew = true;
  344. } else {
  345. createNew = false;
  346. }
  347. if (mOnDeviceConnectListener != null) {
  348. final UsbControlBlock ctrlB = ctrlBlock;
  349. mOnDeviceConnectListener.onConnect(device, ctrlB, createNew);
  350. }
  351. }
  352. });
  353. }
  354. private final void processCancel(final UsbDevice device) {
  355. if (DEBUG) Log.v(TAG, “processCancel:”);
  356. if (mOnDeviceConnectListener != null) {
  357. mHandler.post( new Runnable() {
  358. @Override
  359. public void run() {
  360. mOnDeviceConnectListener.onCancel();
  361. }
  362. });
  363. }
  364. }
  365. private final void processAttach(final UsbDevice device) {
  366. if (DEBUG) Log.v(TAG, “processAttach:”);
  367. if (mOnDeviceConnectListener != null) {
  368. mHandler.post( new Runnable() {
  369. @Override
  370. public void run() {
  371. mOnDeviceConnectListener.onAttach(device);
  372. }
  373. });
  374. }
  375. }
  376. private final void processDettach(final UsbDevice device) {
  377. if (DEBUG) Log.v(TAG, “processDettach:”);
  378. if (mOnDeviceConnectListener != null) {
  379. mHandler.post( new Runnable() {
  380. @Override
  381. public void run() {
  382. mOnDeviceConnectListener.onDettach(device);
  383. }
  384. });
  385. }
  386. }
  387. public static final class UsbControlBlock {
  388. private final WeakReference<USBMonitor> mWeakMonitor;
  389. private final WeakReference<UsbDevice> mWeakDevice;
  390. protected UsbDeviceConnection mConnection;
  391. private final SparseArray<UsbInterface> mInterfaces = new SparseArray<UsbInterface>();
  392. /**
  393. * this class needs permission to access USB device before constructing
  394. * @param monitor
  395. * @param device
  396. */
  397. public UsbControlBlock(final USBMonitor monitor, final UsbDevice device) {
  398. if (DEBUG) Log.i(TAG, “UsbControlBlock:constructor”);
  399. mWeakMonitor = new WeakReference<USBMonitor>(monitor);
  400. mWeakDevice = new WeakReference<UsbDevice>(device);
  401. mConnection = monitor.mUsbManager.openDevice(device);
  402. final String name = device.getDeviceName();
  403. if (mConnection != null) {
  404. if (DEBUG) {
  405. final int desc = mConnection.getFileDescriptor();
  406. final byte[] rawDesc = mConnection.getRawDescriptors();
  407. Log.i(TAG, “UsbControlBlock:name=” + name + “, desc=” + desc + “, rawDesc=” + rawDesc);
  408. }
  409. } else {
  410. Log.e(TAG, “could not connect to device “ + name);
  411. }
  412. }
  413. public UsbDevice getDevice() {
  414. return mWeakDevice.get();
  415. }
  416. public String getDeviceName() {
  417. final UsbDevice device = mWeakDevice.get();
  418. return device != null ? device.getDeviceName() : “”;
  419. }
  420. public UsbDeviceConnection getUsbDeviceConnection() {
  421. return mConnection;
  422. }
  423. public synchronized int getFileDescriptor() {
  424. return mConnection != null ? mConnection.getFileDescriptor() : - 1;
  425. }
  426. public byte[] getRawDescriptors() {
  427. return mConnection != null ? mConnection.getRawDescriptors() : null;
  428. }
  429. public int getVenderId() {
  430. final UsbDevice device = mWeakDevice.get();
  431. return device != null ? device.getVendorId() : 0;
  432. }
  433. public int getProductId() {
  434. final UsbDevice device = mWeakDevice.get();
  435. return device != null ? device.getProductId() : 0;
  436. }
  437. public synchronized String getSerial() {
  438. return mConnection != null ? mConnection.getSerial() : null;
  439. }
  440. /**
  441. * open specific interface
  442. * @param interfaceIndex
  443. * @return
  444. */
  445. public synchronized UsbInterface open(final int interfaceIndex) {
  446. if (DEBUG) Log.i(TAG, “UsbControlBlock#open:” + interfaceIndex);
  447. final UsbDevice device = mWeakDevice.get();
  448. UsbInterface intf = null;
  449. intf = mInterfaces.get(interfaceIndex);
  450. if (intf == null) {
  451. intf = device.getInterface(interfaceIndex);
  452. if (intf != null) {
  453. synchronized (mInterfaces) {
  454. mInterfaces.append(interfaceIndex, intf);
  455. }
  456. }
  457. }
  458. return intf;
  459. }
  460. /**
  461. * close specified interface. USB device itself still keep open.
  462. * @param interfaceIndex
  463. */
  464. public void close(final int interfaceIndex) {
  465. UsbInterface intf = null;
  466. synchronized (mInterfaces) {
  467. intf = mInterfaces.get(interfaceIndex);
  468. if (intf != null) {
  469. mInterfaces.delete(interfaceIndex);
  470. mConnection.releaseInterface(intf);
  471. }
  472. }
  473. }
  474. /**
  475. * close specified interface. USB device itself still keep open.
  476. */
  477. public synchronized void close() {
  478. if (DEBUG) Log.i(TAG, “UsbControlBlock#close:”);
  479. if (mConnection != null) {
  480. final int n = mInterfaces.size();
  481. int key;
  482. UsbInterface intf;
  483. for ( int i = 0; i < n; i++) {
  484. key = mInterfaces.keyAt(i);
  485. intf = mInterfaces.get(key);
  486. mConnection.releaseInterface(intf);
  487. }
  488. mConnection.close();
  489. mConnection = null;
  490. final USBMonitor monitor = mWeakMonitor.get();
  491. if (monitor != null) {
  492. if (monitor.mOnDeviceConnectListener != null) {
  493. final UsbDevice device = mWeakDevice.get();
  494. monitor.mOnDeviceConnectListener.onDisconnect(device, this);
  495. }
  496. monitor.mCtrlBlocks.remove(getDevice());
  497. }
  498. }
  499. }
  500. /* @Override
  501. protected void finalize() throws Throwable {
  502. close();
  503. super.finalize();
  504. } */
  505. }
  506. }



  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 19
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值