OSDN Git Service

1e74b06ace6991e6668dac9d1f0a5e5d2e123a67
[gokigen/mangle.git] / app / src / main / java / jp / osdn / gokigen / gokigenassets / camera / vendor / theta / ThetaCameraControl.kt
1 package jp.osdn.gokigen.gokigenassets.camera.vendor.theta
2
3 import android.util.Log
4 import android.view.KeyEvent
5 import android.view.View
6 import androidx.appcompat.app.AppCompatActivity
7 import jp.osdn.gokigen.gokigenassets.camera.preference.ICameraPreferenceProvider
8 import jp.osdn.gokigen.gokigenassets.camera.interfaces.*
9 import jp.osdn.gokigen.gokigenassets.camera.vendor.theta.connection.ThetaCameraConnection
10 import jp.osdn.gokigen.gokigenassets.camera.vendor.theta.liveview.ThetaLiveViewControl
11 import jp.osdn.gokigen.gokigenassets.camera.vendor.theta.operation.ThetaMovieRecordingControl
12 import jp.osdn.gokigen.gokigenassets.camera.vendor.theta.operation.ThetaOptionSetControl
13 import jp.osdn.gokigen.gokigenassets.camera.vendor.theta.operation.ThetaSingleShotControl
14 import jp.osdn.gokigen.gokigenassets.camera.vendor.theta.status.ICaptureModeReceiver
15 import jp.osdn.gokigen.gokigenassets.camera.vendor.theta.status.ThetaCameraStatusWatcher
16 import jp.osdn.gokigen.gokigenassets.camera.vendor.theta.status.ThetaSessionHolder
17 import jp.osdn.gokigen.gokigenassets.constants.IApplicationConstantConvert.Companion.ID_BUTTON_SHUTTER
18 import jp.osdn.gokigen.gokigenassets.constants.IPreferenceConstantConvert.Companion.ID_PREFERENCE_CAPTURE_BOTH_CAMERA_AND_LIVE_VIEW
19 import jp.osdn.gokigen.gokigenassets.constants.IPreferenceConstantConvert.Companion.ID_PREFERENCE_CAPTURE_BOTH_CAMERA_AND_LIVE_VIEW_DEFAULT_VALUE
20 import jp.osdn.gokigen.gokigenassets.constants.IPreferenceConstantConvert.Companion.ID_PREFERENCE_CAPTURE_ONLY_LIVEVIEW_IMAGE
21 import jp.osdn.gokigen.gokigenassets.constants.IPreferenceConstantConvert.Companion.ID_PREFERENCE_CAPTURE_ONLY_LIVEVIEW_IMAGE_DEFAULT_VALUE
22 import jp.osdn.gokigen.gokigenassets.liveview.ICachePositionProvider
23 import jp.osdn.gokigen.gokigenassets.liveview.ILiveView
24 import jp.osdn.gokigen.gokigenassets.liveview.ILiveViewRefresher
25 import jp.osdn.gokigen.gokigenassets.liveview.image.CameraLiveViewListenerImpl
26 import jp.osdn.gokigen.gokigenassets.liveview.message.IMessageDrawer
27 import jp.osdn.gokigen.gokigenassets.liveview.storeimage.StoreImage
28 import jp.osdn.gokigen.gokigenassets.preference.PreferenceAccessWrapper
29 import jp.osdn.gokigen.gokigenassets.scene.IInformationReceiver
30 import jp.osdn.gokigen.gokigenassets.scene.IVibrator
31
32 class ThetaCameraControl(private val context: AppCompatActivity, private val vibrator : IVibrator, informationNotify: IInformationReceiver, private val preference: ICameraPreferenceProvider, statusReceiver : ICameraStatusReceiver, private val number : Int = 0, private val liveViewListener : CameraLiveViewListenerImpl = CameraLiveViewListenerImpl(context, informationNotify)) : ILiveViewController,
33     ICameraControl, View.OnClickListener, View.OnLongClickListener, ICaptureModeReceiver, ICameraShutter, IKeyDown, IZoomLensControl
34 {
35     private val sessionIdHolder = ThetaSessionHolder()
36     private val cameraConnection = ThetaCameraConnection(context, statusReceiver, sessionIdHolder, sessionIdHolder, this)
37     private val liveViewControl = ThetaLiveViewControl(liveViewListener)
38     private var indicator : IMessageDrawer? = null
39
40     private val statusWatcher = ThetaCameraStatusWatcher(sessionIdHolder, this)
41     private var isStatusWatch = false
42     private var isMovieRecording = false
43     private val storeImage = StoreImage(context, liveViewListener)
44     private lateinit var cachePositionProvider : ICachePositionProvider
45     private var cameraPositionId = 0
46
47     fun setIndicator(indicator : IMessageDrawer)
48     {
49         this.indicator = indicator
50     }
51
52     override fun getConnectionMethod(): String
53     {
54         return ("THETA")
55     }
56
57     override fun changeCaptureMode(mode : String)
58     {
59         val options = if (statusWatcher.captureMode.contains("image"))
60         {
61             // image -> video
62             "\"captureMode\" : \"video\""
63         }
64         else
65         {
66             // video -> image
67             "\"captureMode\" : \"image\""
68         }
69         ThetaOptionSetControl(sessionIdHolder).setOptions(options, sessionIdHolder.isApiLevelV21())
70     }
71
72     override fun changedCaptureMode(captureMode : String)
73     {
74         Log.v(TAG, " changedCaptureMode() : $captureMode")
75 /*
76         try
77         {
78             val isImage = captureMode.contains("image")
79             context.runOnUiThread {
80                 try
81                 {
82                     val view : ImageButton = context.findViewById(ID_BUTTON_SHUTTER)
83                     val iconId = if (isImage) { R.drawable.ic_baseline_videocam_24 } else { R.drawable.ic_baseline_camera_alt_24 }
84                     view.setImageDrawable(ContextCompat.getDrawable(context, iconId))
85                     view.invalidate()
86                 }
87                 catch (e : Exception)
88                 {
89                     e.printStackTrace()
90                 }
91             }
92         }
93         catch (e: Exception)
94         {
95             e.printStackTrace()
96         }
97 */
98     }
99
100     override fun initialize()
101     {
102         // TODO("Not yet implemented")
103     }
104
105     override fun startCamera(isPreviewView : Boolean, cameraSequence : Int)
106     {
107         try
108         {
109             if (cameraConnection.getConnectionStatus() != ICameraConnectionStatus.CameraConnectionStatus.CONNECTED)
110             {
111                 cameraConnection.startWatchWifiStatus(context)
112             }
113             else
114             {
115                 cameraConnection.connect()
116             }
117         }
118         catch (e : Exception)
119         {
120             e.printStackTrace()
121         }
122     }
123
124     override fun finishCamera(isPowerOff: Boolean)
125     {
126         try
127         {
128             if (isStatusWatch)
129             {
130                 statusWatcher.stopStatusWatch()
131                 isStatusWatch = false
132             }
133             cameraConnection.disconnect(isPowerOff)
134             cameraConnection.stopWatchWifiStatus(context)
135         }
136         catch (e : Exception)
137         {
138             e.printStackTrace()
139         }
140     }
141
142     override fun connectToCamera()
143     {
144         Log.v(TAG, " connectToCamera() : THETA ")
145         try
146         {
147             cameraConnection.connect()
148         }
149         catch (e : Exception)
150         {
151             e.printStackTrace()
152         }
153     }
154
155     override fun setRefresher(id : Int, refresher: ILiveViewRefresher, imageView: ILiveView, cachePosition : ICachePositionProvider)
156     {
157         try
158         {
159             liveViewListener.setRefresher(refresher)
160             imageView.setImageProvider(liveViewListener)
161             cachePositionProvider = cachePosition
162         }
163         catch (e : Exception)
164         {
165             e.printStackTrace()
166         }
167     }
168
169     override fun onClick(v: View?)
170     {
171         if (v == null)
172         {
173             return
174         }
175         when (v.id)
176         {
177             ID_BUTTON_SHUTTER -> { doShutter() }
178             else -> { }
179         }
180     }
181
182     override fun doShutter()
183     {
184         try
185         {
186             Log.v(TAG, " doShutter()")
187             val isNotDriveShutter = captureImageLiveView()
188             if (isNotDriveShutter)
189             {
190                 //  シャッターを駆動させない(けど、バイブレーションで通知する)
191                 vibrator.vibrate(IVibrator.VibratePattern.SIMPLE_SHORT)
192                 return
193             }
194             if (statusWatcher.captureMode.contains("image"))
195             {
196                 // image
197                 ThetaSingleShotControl(sessionIdHolder, vibrator, liveViewControl, statusWatcher).singleShot(sessionIdHolder.isApiLevelV21())
198             }
199             else
200             {
201                 // video
202                 ThetaMovieRecordingControl(sessionIdHolder, vibrator, liveViewControl, statusWatcher).movieControl(sessionIdHolder.isApiLevelV21())
203                 isMovieRecording = true
204             }
205         }
206         catch (e : Exception)
207         {
208             e.printStackTrace()
209             isMovieRecording = false
210         }
211     }
212
213     override fun doShutterOff()
214     {
215         try
216         {
217             if ((isMovieRecording)&&(!statusWatcher.captureMode.contains("image")))
218             {
219                 // video
220                 Log.v(TAG, " doShutterOff()")
221                 ThetaMovieRecordingControl(sessionIdHolder, vibrator, liveViewControl, statusWatcher).movieControl(sessionIdHolder.isApiLevelV21())
222             }
223         }
224         catch (e : Exception)
225         {
226             e.printStackTrace()
227         }
228         isMovieRecording = false
229     }
230
231     private fun captureImageLiveView() : Boolean
232     {
233         try
234         {
235             //  preferenceから設定を取得する
236             val captureBothCamera = PreferenceAccessWrapper(context).getBoolean(
237                 ID_PREFERENCE_CAPTURE_BOTH_CAMERA_AND_LIVE_VIEW,
238                 ID_PREFERENCE_CAPTURE_BOTH_CAMERA_AND_LIVE_VIEW_DEFAULT_VALUE
239             )
240             val notUseShutter = PreferenceAccessWrapper(context).getBoolean(
241                 ID_PREFERENCE_CAPTURE_ONLY_LIVEVIEW_IMAGE,
242                 ID_PREFERENCE_CAPTURE_ONLY_LIVEVIEW_IMAGE_DEFAULT_VALUE
243             )
244             if ((captureBothCamera)&&(liveViewListener.isImageReceived()))
245             {
246                 // ライブビュー画像を保管する場合...
247                 val thread = Thread { storeImage.doStore(cameraPositionId, true, cachePositionProvider.getCachePosition()) }
248                 try
249                 {
250                     thread.start()
251                 }
252                 catch (e: Exception)
253                 {
254                     e.printStackTrace()
255                 }
256             }
257             return (notUseShutter)
258         }
259         catch (e : Exception)
260         {
261             e.printStackTrace()
262         }
263         return (false)
264     }
265
266     companion object
267     {
268         private val TAG = ThetaCameraControl::class.java.simpleName
269     }
270
271     override fun startLiveView(isCameraScreen: Boolean)
272     {
273         Log.v(TAG, " startLiveView($isCameraScreen) ")
274         try
275         {
276             if (!isStatusWatch)
277             {
278                 statusWatcher.startStatusWatch(indicator, null)
279                 isStatusWatch = true
280             }
281             liveViewControl.setSessionIdProvider(sessionIdHolder)
282             liveViewControl.startLiveView()
283         }
284         catch (e : Exception)
285         {
286             e.printStackTrace()
287         }
288     }
289
290     override fun stopLiveView()
291     {
292         Log.v(TAG, " stopLiveView() ")
293         try
294         {
295             liveViewControl.stopLiveView()
296         }
297         catch (e : Exception)
298         {
299             e.printStackTrace()
300         }
301     }
302
303     override fun needRotateImage(): Boolean { return (false) }
304
305     override fun captureButtonReceiver(id : Int) : View.OnClickListener
306     {
307         cameraPositionId = id
308         return (this)
309     }
310
311     override fun onLongClickReceiver(id: Int): View.OnLongClickListener
312     {
313         cameraPositionId = id
314         return (this)
315     }
316
317     override fun keyDownReceiver(id: Int): IKeyDown
318     {
319         cameraPositionId = id
320         return (this)
321     }
322
323     override fun getDisplayInjector(): IDisplayInjector?
324     {
325         return (null)
326     }
327
328     override fun getFocusingControl(id: Int): IFocusingControl?
329     {
330         return (null)
331     }
332
333     override fun handleKeyDown(keyCode: Int, event: KeyEvent): Boolean
334     {
335         if ((event.action == KeyEvent.ACTION_DOWN)&&((keyCode == KeyEvent.KEYCODE_VOLUME_UP)||(keyCode == KeyEvent.KEYCODE_CAMERA)))
336         {
337             doShutter()
338             return (true)
339         }
340         return (false)
341     }
342
343     override fun onLongClick(v: View?): Boolean
344     {
345         return (false)
346     }
347
348     override fun setNeighborCameraControl(index: Int, camera0: ICameraControl?, camera1: ICameraControl?, camera2: ICameraControl?, camera3: ICameraControl?) { }
349     override fun setNeighborCameraControlFinished() { }
350
351     override fun getCameraStatus(): ICameraStatus
352     {
353         return (statusWatcher)
354     }
355
356     override fun getCameraNumber(): Int
357     {
358         return (number)
359     }
360
361     override fun getCameraShutter(id: Int): ICameraShutter { return (this) }
362     override fun getZoomControl(id: Int): IZoomLensControl { return (this) }
363
364     override fun canZoom(): Boolean { return (false) }
365     override fun updateStatus() { }
366     override fun getMaximumFocalLength(): Float { return (0.0f) }
367     override fun getMinimumFocalLength(): Float { return (0.0f) }
368     override fun getCurrentFocalLength(): Float { return (0.0f) }
369     override fun driveZoomLens(targetLength: Float) { }
370     override fun driveZoomLens(isZoomIn: Boolean) { }
371     override fun moveInitialZoomPosition() { }
372     override fun isDrivingZoomLens(): Boolean { return (false) }
373 }