OSDN Git Service

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