1 package jp.osdn.gokigen.gokigenassets.camera.vendor.theta.connection
3 import android.content.*
4 import android.net.ConnectivityManager
5 import android.net.wifi.WifiManager
6 import android.provider.Settings
7 import android.util.Log
8 import androidx.appcompat.app.AlertDialog
9 import androidx.appcompat.app.AppCompatActivity
10 import androidx.preference.PreferenceManager
11 import jp.osdn.gokigen.gokigenassets.camera.interfaces.ICameraConnection
12 import jp.osdn.gokigen.gokigenassets.camera.interfaces.ICameraConnectionStatus
13 import jp.osdn.gokigen.gokigenassets.camera.interfaces.ICameraStatusReceiver
14 import jp.osdn.gokigen.gokigenassets.camera.interfaces.ILiveViewController
15 import jp.osdn.gokigen.gokigenassets.camera.vendor.theta.operation.IOperationCallback
16 import jp.osdn.gokigen.gokigenassets.camera.vendor.theta.operation.ThetaOptionSetControl
17 import jp.osdn.gokigen.gokigenassets.camera.vendor.theta.status.IThetaSessionIdNotifier
18 import jp.osdn.gokigen.gokigenassets.camera.vendor.theta.status.IThetaSessionIdProvider
19 import jp.osdn.gokigen.gokigenassets.constants.IPreferenceConstantConvert.Companion.ID_PREFERENCE_THETA_LIVEVIEW_RESOLUTION
20 import jp.osdn.gokigen.gokigenassets.constants.IPreferenceConstantConvert.Companion.ID_PREFERENCE_THETA_LIVEVIEW_RESOLUTION_DEFAULT_VALUE
21 import jp.osdn.gokigen.gokigenassets.constants.IStringResourceConstantConvert.Companion.ID_STRING_CONNECT_CHECK_WIFI
22 import jp.osdn.gokigen.gokigenassets.constants.IStringResourceConstantConvert.Companion.ID_STRING_DIALOG_BUTTON_NETWORK_SETTINGS
23 import jp.osdn.gokigen.gokigenassets.constants.IStringResourceConstantConvert.Companion.ID_STRING_DIALOG_BUTTON_RETRY
24 import jp.osdn.gokigen.gokigenassets.constants.IStringResourceConstantConvert.Companion.ID_STRING_DIALOG_TITLE_CONNECT_FAILED
25 import java.util.concurrent.Executor
26 import java.util.concurrent.Executors
31 class ThetaCameraConnection(private val context: AppCompatActivity, private val statusReceiver: ICameraStatusReceiver, private val sessionIdNotifier: IThetaSessionIdNotifier, private val sessionIdProvider: IThetaSessionIdProvider, private val liveViewControl : ILiveViewController) : ICameraConnection, ICameraConnectionStatus
33 private val cameraExecutor: Executor = Executors.newFixedThreadPool(1)
34 private var connectionStatus: ICameraConnectionStatus.CameraConnectionStatus = ICameraConnectionStatus.CameraConnectionStatus.UNKNOWN
35 private var connectionReceiver = object : BroadcastReceiver()
37 override fun onReceive(context: Context, intent: Intent)
39 onReceiveBroadcastOfConnection(context, intent)
45 private val TAG = ThetaCameraConnection::class.java.simpleName
52 private fun onReceiveBroadcastOfConnection(context: Context, intent: Intent)
54 statusReceiver.onStatusNotify(context.getString(ID_STRING_CONNECT_CHECK_WIFI))
55 Log.v(TAG, context.getString(ID_STRING_CONNECT_CHECK_WIFI))
56 val action = intent.action
59 Log.v(TAG, "intent.getAction() : null")
64 @Suppress("DEPRECATION")
65 if (action == ConnectivityManager.CONNECTIVITY_ACTION)
67 Log.v(TAG, "onReceiveBroadcastOfConnection() : CONNECTIVITY_ACTION")
68 val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
69 val info = wifiManager.connectionInfo
70 if ((wifiManager.isWifiEnabled)&&(info != null))
72 if (info.networkId != -1)
74 Log.v(TAG, "Network ID is -1, there is no currently connected network.")
83 Log.v(TAG, "NETWORK INFO IS NULL.")
87 Log.v(TAG, "isWifiEnabled : " + wifiManager.isWifiEnabled + " NetworkId : " + info.networkId)
94 Log.w(TAG, "onReceiveBroadcastOfConnection() EXCEPTION" + e.message)
103 fun startWatchWifiStatus(context: Context)
105 Log.v(TAG, "startWatchWifiStatus()")
108 statusReceiver.onStatusNotify("prepare")
109 val filter = IntentFilter()
110 filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION)
111 @Suppress("DEPRECATION")
112 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION)
113 context.registerReceiver(connectionReceiver, filter)
115 catch (e : Exception)
125 fun stopWatchWifiStatus(context: Context)
127 Log.v(TAG, "stopWatchWifiStatus()")
130 context.unregisterReceiver(connectionReceiver)
133 catch (e : Exception)
143 fun disconnect(powerOff: Boolean)
145 Log.v(TAG, "disconnect()")
146 disconnectFromCamera(powerOff)
147 connectionStatus = ICameraConnectionStatus.CameraConnectionStatus.DISCONNECTED
148 statusReceiver.onCameraDisconnected()
149 liveViewControl.stopLiveView()
158 Log.v(TAG, "connect()")
166 override fun alertConnectingFailed(message: String?)
168 Log.v(TAG, "alertConnectingFailed() : $message")
169 val builder: AlertDialog.Builder = AlertDialog.Builder(context)
170 .setTitle(context.getString(ID_STRING_DIALOG_TITLE_CONNECT_FAILED))
172 .setPositiveButton(context.getString(ID_STRING_DIALOG_BUTTON_RETRY)) { _, _ -> connect() }
173 .setNeutralButton(ID_STRING_DIALOG_BUTTON_NETWORK_SETTINGS) { _, _ ->
176 context.startActivity(Intent(Settings.ACTION_WIFI_SETTINGS))
177 } catch (ex: ActivityNotFoundException) {
178 // Activity が存在しなかった...設定画面が起動できなかった
179 Log.v(TAG, "android.content.ActivityNotFoundException...")
181 // この場合は、再試行と等価な動きとする
183 } catch (e: Exception) {
187 context.runOnUiThread {
203 override fun getConnectionStatus(): ICameraConnectionStatus.CameraConnectionStatus
205 Log.v(TAG, "getConnectionStatus()")
206 return connectionStatus
213 override fun forceUpdateConnectionStatus(status: ICameraConnectionStatus.CameraConnectionStatus)
215 Log.v(TAG, "forceUpdateConnectionStatus()")
216 connectionStatus = status
218 if (status == ICameraConnectionStatus.CameraConnectionStatus.CONNECTED)
221 //liveViewControl.startLiveView()
223 else if (status == ICameraConnectionStatus.CameraConnectionStatus.DISCONNECTED)
225 liveViewControl.stopLiveView()
233 private fun startLiveView()
238 val optionGet = ThetaOptionGetControl(sessionIdProvider)
239 optionGet.getOptions("[\"previewFormat\", \"previewFormatSupport\"]", (sessionIdProvider.sessionId.isBlank()),
240 object : IOperationCallback { override fun operationExecuted(result: Int, resultStr: String?)
242 Log.v(TAG, " >>>>> optionGet.getOptions : $resultStr ")
245 val optionSet = ThetaOptionSetControl(sessionIdProvider)
246 optionSet.setOptions("\"captureMode\" : \"image\"", (sessionIdProvider.sessionId.isBlank()),
247 object : IOperationCallback { override fun operationExecuted(result: Int, resultStr: String?)
249 val previewFormat = PreferenceManager.getDefaultSharedPreferences(context).getString(ID_PREFERENCE_THETA_LIVEVIEW_RESOLUTION, ID_PREFERENCE_THETA_LIVEVIEW_RESOLUTION_DEFAULT_VALUE)
250 //val previewFormat= "{\"width\": 640, \"height\": 320, \"framerate\": 30}"
251 Log.v(TAG, " optionSet.setOptions(live view) : $resultStr : $previewFormat")
252 optionSet.setOptions("\"previewFormat\" : $previewFormat", (sessionIdProvider.sessionId.isBlank()),
253 object : IOperationCallback { override fun operationExecuted(result: Int, resultStr: String?)
255 Log.v(TAG, " optionSet.setOptions(live view) : $resultStr ($previewFormat)")
256 liveViewControl.startLiveView()
260 catch (e : Exception)
270 private fun disconnectFromCamera(powerOff: Boolean)
272 Log.v(TAG, "disconnectFromCamera() : $powerOff")
275 cameraExecutor.execute(ThetaCameraDisconnectSequence())
286 private fun connectToCamera()
288 Log.v(TAG, " connectToCamera()")
289 connectionStatus = ICameraConnectionStatus.CameraConnectionStatus.CONNECTING
292 cameraExecutor.execute(ThetaCameraConnectSequence(context, statusReceiver, sessionIdNotifier, this))
296 Log.v(TAG, "connectToCamera() EXCEPTION : " + e.message)