1 package jp.osdn.gokigen.gokigenassets.camera.vendor.theta
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
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
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
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
48 fun setIndicator(indicator : IMessageDrawer)
50 this.indicator = indicator
53 override fun getConnectionMethod(): String
58 override fun changeCaptureMode(mode : String)
60 val options = if (statusWatcher.captureMode.contains("image"))
63 "\"captureMode\" : \"video\""
68 "\"captureMode\" : \"image\""
70 ThetaOptionSetControl(sessionIdHolder).setOptions(options, sessionIdHolder.isApiLevelV21())
73 override fun changedCaptureMode(captureMode : String)
75 Log.v(TAG, " changedCaptureMode() : $captureMode")
79 val isImage = captureMode.contains("image")
80 context.runOnUiThread {
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))
101 override fun initialize()
103 // TODO("Not yet implemented")
106 override fun startCamera(isPreviewView : Boolean, cameraSequence : Int)
110 if (cameraConnection.getConnectionStatus() != ICameraConnectionStatus.CameraConnectionStatus.CONNECTED)
112 cameraConnection.startWatchWifiStatus(context)
116 cameraConnection.connect()
119 catch (e : Exception)
125 override fun finishCamera()
131 statusWatcher.stopStatusWatch()
132 isStatusWatch = false
134 cameraConnection.disconnect(false)
135 cameraConnection.stopWatchWifiStatus(context)
137 catch (e : Exception)
143 override fun connectToCamera()
145 Log.v(TAG, " connectToCamera() : THETA ")
148 cameraConnection.connect()
150 catch (e : Exception)
156 override fun setRefresher(id : Int, refresher: ILiveViewRefresher, imageView: ILiveView, cachePosition : ICachePositionProvider)
160 liveViewListener.setRefresher(refresher)
161 imageView.setImageProvider(liveViewListener)
162 cachePositionProvider = cachePosition
164 catch (e : Exception)
170 override fun onClick(v: View?)
178 ID_BUTTON_SHUTTER -> { doShutter() }
183 override fun doShutter()
187 Log.v(TAG, " doShutter()")
188 val isNotDriveShutter = captureImageLiveView()
189 if (isNotDriveShutter)
191 // シャッターを駆動させない(けど、バイブレーションで通知する)
192 vibrator.vibrate(IVibrator.VibratePattern.SIMPLE_SHORT)
195 if (statusWatcher.captureMode.contains("image"))
198 ThetaSingleShotControl(sessionIdHolder, vibrator, liveViewControl, statusWatcher).singleShot(sessionIdHolder.isApiLevelV21())
203 ThetaMovieRecordingControl(sessionIdHolder, vibrator, liveViewControl, statusWatcher).movieControl(sessionIdHolder.isApiLevelV21())
204 isMovieRecording = true
207 catch (e : Exception)
210 isMovieRecording = false
214 override fun doShutterOff()
218 if ((isMovieRecording)&&(!statusWatcher.captureMode.contains("image")))
221 Log.v(TAG, " doShutterOff()")
222 ThetaMovieRecordingControl(sessionIdHolder, vibrator, liveViewControl, statusWatcher).movieControl(sessionIdHolder.isApiLevelV21())
225 catch (e : Exception)
229 isMovieRecording = false
232 private fun captureImageLiveView() : Boolean
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
241 val notUseShutter = PreferenceAccessWrapper(context).getBoolean(
242 ID_PREFERENCE_CAPTURE_ONLY_LIVEVIEW_IMAGE,
243 ID_PREFERENCE_CAPTURE_ONLY_LIVEVIEW_IMAGE_DEFAULT_VALUE
245 if ((captureBothCamera)&&(liveViewListener.isImageReceived()))
247 // ライブビュー画像を保管する場合...
248 val thread = Thread { storeImage.doStore(cameraPositionId, true, cachePositionProvider.getCachePosition()) }
258 return (notUseShutter)
260 catch (e : Exception)
269 private val TAG = ThetaCameraControl::class.java.simpleName
272 override fun startLiveView(isCameraScreen: Boolean)
274 Log.v(TAG, " startLiveView($isCameraScreen) ")
279 statusWatcher.startStatusWatch(indicator, null)
282 liveViewControl.setSessionIdProvider(sessionIdHolder)
283 liveViewControl.startLiveView()
285 catch (e : Exception)
291 override fun stopLiveView()
293 Log.v(TAG, " stopLiveView() ")
296 liveViewControl.stopLiveView()
298 catch (e : Exception)
304 override fun needRotateImage(): Boolean { return (false) }
306 override fun captureButtonReceiver(id : Int) : View.OnClickListener
308 cameraPositionId = id
312 override fun onLongClickReceiver(id: Int): View.OnLongClickListener
314 cameraPositionId = id
318 override fun keyDownReceiver(id: Int): IKeyDown
320 cameraPositionId = id
324 override fun getDisplayInjector(): IDisplayInjector?
329 override fun getFocusingControl(id: Int): IFocusingControl?
334 override fun handleKeyDown(keyCode: Int, event: KeyEvent): Boolean
336 if ((event.action == KeyEvent.ACTION_DOWN)&&((keyCode == KeyEvent.KEYCODE_VOLUME_UP)||(keyCode == KeyEvent.KEYCODE_CAMERA)))
344 override fun onLongClick(v: View?): Boolean
349 override fun setNeighborCameraControl(index: Int, camera0: ICameraControl?, camera1: ICameraControl?, camera2: ICameraControl?, camera3: ICameraControl?) { }
350 override fun setNeighborCameraControlFinished() { }
352 override fun getCameraStatus(): ICameraStatus
354 return (statusWatcher)
357 override fun getCameraNumber(): Int