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.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
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
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
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
47 fun setIndicator(indicator : IMessageDrawer)
49 this.indicator = indicator
52 override fun getConnectionMethod(): String
57 override fun changeCaptureMode(mode : String)
59 val options = if (statusWatcher.captureMode.contains("image"))
62 "\"captureMode\" : \"video\""
67 "\"captureMode\" : \"image\""
69 ThetaOptionSetControl(sessionIdHolder).setOptions(options, sessionIdHolder.isApiLevelV21())
72 override fun changedCaptureMode(captureMode : String)
74 Log.v(TAG, " changedCaptureMode() : $captureMode")
78 val isImage = captureMode.contains("image")
79 context.runOnUiThread {
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))
100 override fun initialize()
102 // TODO("Not yet implemented")
105 override fun startCamera(isPreviewView : Boolean, cameraSequence : Int)
109 if (cameraConnection.getConnectionStatus() != ICameraConnectionStatus.CameraConnectionStatus.CONNECTED)
111 cameraConnection.startWatchWifiStatus(context)
115 cameraConnection.connect()
118 catch (e : Exception)
124 override fun finishCamera(isPowerOff: Boolean)
130 statusWatcher.stopStatusWatch()
131 isStatusWatch = false
133 cameraConnection.disconnect(isPowerOff)
134 cameraConnection.stopWatchWifiStatus(context)
136 catch (e : Exception)
142 override fun connectToCamera()
144 Log.v(TAG, " connectToCamera() : THETA ")
147 cameraConnection.connect()
149 catch (e : Exception)
155 override fun setRefresher(id : Int, refresher: ILiveViewRefresher, imageView: ILiveView, cachePosition : ICachePositionProvider)
159 liveViewListener.setRefresher(refresher)
160 imageView.setImageProvider(liveViewListener)
161 cachePositionProvider = cachePosition
163 catch (e : Exception)
169 override fun onClick(v: View?)
177 ID_BUTTON_SHUTTER -> { doShutter() }
182 override fun doShutter()
186 Log.v(TAG, " doShutter()")
187 val isNotDriveShutter = captureImageLiveView()
188 if (isNotDriveShutter)
190 // シャッターを駆動させない(けど、バイブレーションで通知する)
191 vibrator.vibrate(IVibrator.VibratePattern.SIMPLE_SHORT)
194 if (statusWatcher.captureMode.contains("image"))
197 ThetaSingleShotControl(sessionIdHolder, vibrator, liveViewControl, statusWatcher).singleShot(sessionIdHolder.isApiLevelV21())
202 ThetaMovieRecordingControl(sessionIdHolder, vibrator, liveViewControl, statusWatcher).movieControl(sessionIdHolder.isApiLevelV21())
203 isMovieRecording = true
206 catch (e : Exception)
209 isMovieRecording = false
213 override fun doShutterOff()
217 if ((isMovieRecording)&&(!statusWatcher.captureMode.contains("image")))
220 Log.v(TAG, " doShutterOff()")
221 ThetaMovieRecordingControl(sessionIdHolder, vibrator, liveViewControl, statusWatcher).movieControl(sessionIdHolder.isApiLevelV21())
224 catch (e : Exception)
228 isMovieRecording = false
231 private fun captureImageLiveView() : Boolean
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
240 val notUseShutter = PreferenceAccessWrapper(context).getBoolean(
241 ID_PREFERENCE_CAPTURE_ONLY_LIVEVIEW_IMAGE,
242 ID_PREFERENCE_CAPTURE_ONLY_LIVEVIEW_IMAGE_DEFAULT_VALUE
244 if ((captureBothCamera)&&(liveViewListener.isImageReceived()))
246 // ライブビュー画像を保管する場合...
247 val thread = Thread { storeImage.doStore(cameraPositionId, true, cachePositionProvider.getCachePosition()) }
257 return (notUseShutter)
259 catch (e : Exception)
268 private val TAG = ThetaCameraControl::class.java.simpleName
271 override fun startLiveView(isCameraScreen: Boolean)
273 Log.v(TAG, " startLiveView($isCameraScreen) ")
278 statusWatcher.startStatusWatch(indicator, null)
281 liveViewControl.setSessionIdProvider(sessionIdHolder)
282 liveViewControl.startLiveView()
284 catch (e : Exception)
290 override fun stopLiveView()
292 Log.v(TAG, " stopLiveView() ")
295 liveViewControl.stopLiveView()
297 catch (e : Exception)
303 override fun needRotateImage(): Boolean { return (false) }
305 override fun captureButtonReceiver(id : Int) : View.OnClickListener
307 cameraPositionId = id
311 override fun onLongClickReceiver(id: Int): View.OnLongClickListener
313 cameraPositionId = id
317 override fun keyDownReceiver(id: Int): IKeyDown
319 cameraPositionId = id
323 override fun getDisplayInjector(): IDisplayInjector?
328 override fun getFocusingControl(id: Int): IFocusingControl?
333 override fun handleKeyDown(keyCode: Int, event: KeyEvent): Boolean
335 if ((event.action == KeyEvent.ACTION_DOWN)&&((keyCode == KeyEvent.KEYCODE_VOLUME_UP)||(keyCode == KeyEvent.KEYCODE_CAMERA)))
343 override fun onLongClick(v: View?): Boolean
348 override fun setNeighborCameraControl(index: Int, camera0: ICameraControl?, camera1: ICameraControl?, camera2: ICameraControl?, camera3: ICameraControl?) { }
349 override fun setNeighborCameraControlFinished() { }
351 override fun getCameraStatus(): ICameraStatus
353 return (statusWatcher)
356 override fun getCameraNumber(): Int
361 override fun getCameraShutter(id: Int): ICameraShutter { return (this) }
362 override fun getZoomControl(id: Int): IZoomLensControl { return (this) }
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) }