OSDN Git Service

fadd4b94dd66a0dbc075d7a24747836c946dd861
[gokigen/mangle.git] / app / src / main / java / jp / osdn / gokigen / gokigenassets / camera / vendor / theta / connection / ThetaCameraConnection.kt
1 package jp.osdn.gokigen.gokigenassets.camera.vendor.theta.connection
2
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
27
28 /**
29  *
30  */
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
32 {
33     private val cameraExecutor: Executor = Executors.newFixedThreadPool(1)
34     private var connectionStatus: ICameraConnectionStatus.CameraConnectionStatus = ICameraConnectionStatus.CameraConnectionStatus.UNKNOWN
35     private var connectionReceiver = object : BroadcastReceiver()
36     {
37         override fun onReceive(context: Context, intent: Intent)
38         {
39             onReceiveBroadcastOfConnection(context, intent)
40         }
41     }
42
43     companion object
44     {
45         private val TAG = ThetaCameraConnection::class.java.simpleName
46     }
47
48     /**
49      *
50      *
51      */
52     private fun onReceiveBroadcastOfConnection(context: Context, intent: Intent)
53     {
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
57         if (action == null)
58         {
59             Log.v(TAG, "intent.getAction() : null")
60             return
61         }
62         try
63         {
64             @Suppress("DEPRECATION")
65             if (action == ConnectivityManager.CONNECTIVITY_ACTION)
66             {
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))
71                 {
72                     if (info.networkId != -1)
73                     {
74                         Log.v(TAG, "Network ID is -1, there is no currently connected network.")
75                     }
76                     // カメラと接続
77                     connectToCamera()
78                 }
79                 else
80                 {
81                     if (info == null)
82                     {
83                         Log.v(TAG, "NETWORK INFO IS NULL.")
84                     }
85                     else
86                     {
87                         Log.v(TAG, "isWifiEnabled : " + wifiManager.isWifiEnabled + " NetworkId : " + info.networkId)
88                     }
89                 }
90             }
91         }
92         catch (e: Exception)
93         {
94             Log.w(TAG, "onReceiveBroadcastOfConnection() EXCEPTION" + e.message)
95             e.printStackTrace()
96         }
97     }
98
99     /**
100      *
101      *
102      */
103     fun startWatchWifiStatus(context: Context)
104     {
105         Log.v(TAG, "startWatchWifiStatus()")
106         try
107         {
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)
114         }
115         catch (e : Exception)
116         {
117             e.printStackTrace()
118         }
119     }
120
121     /**
122      *
123      *
124      */
125     fun stopWatchWifiStatus(context: Context)
126     {
127         Log.v(TAG, "stopWatchWifiStatus()")
128         try
129         {
130             context.unregisterReceiver(connectionReceiver)
131             disconnect(false)
132         }
133         catch (e : Exception)
134         {
135             e.printStackTrace()
136         }
137     }
138
139     /**
140      *
141      *
142      */
143     fun disconnect(powerOff: Boolean)
144     {
145         Log.v(TAG, "disconnect()")
146         disconnectFromCamera(powerOff)
147         connectionStatus = ICameraConnectionStatus.CameraConnectionStatus.DISCONNECTED
148         statusReceiver.onCameraDisconnected()
149         liveViewControl.stopLiveView()
150     }
151
152     /**
153      *
154      *
155      */
156     fun connect()
157     {
158         Log.v(TAG, "connect()")
159         connectToCamera()
160     }
161
162     /**
163      *
164      *
165      */
166     override fun alertConnectingFailed(message: String?)
167     {
168         Log.v(TAG, "alertConnectingFailed() : $message")
169         val builder: AlertDialog.Builder = AlertDialog.Builder(context)
170             .setTitle(context.getString(ID_STRING_DIALOG_TITLE_CONNECT_FAILED))
171             .setMessage(message)
172             .setPositiveButton(context.getString(ID_STRING_DIALOG_BUTTON_RETRY)) { _, _ -> connect() }
173             .setNeutralButton(ID_STRING_DIALOG_BUTTON_NETWORK_SETTINGS) { _, _ ->
174                 try {
175                     // Wifi 設定画面を表示する
176                     context.startActivity(Intent(Settings.ACTION_WIFI_SETTINGS))
177                 } catch (ex: ActivityNotFoundException) {
178                     // Activity が存在しなかった...設定画面が起動できなかった
179                     Log.v(TAG, "android.content.ActivityNotFoundException...")
180
181                     // この場合は、再試行と等価な動きとする
182                     connect()
183                 } catch (e: Exception) {
184                     e.printStackTrace()
185                 }
186             }
187         context.runOnUiThread {
188             try
189             {
190                 builder.show()
191             }
192             catch (e: Exception)
193             {
194                 e.printStackTrace()
195             }
196         }
197     }
198
199     /**
200      *
201      *
202      */
203     override fun getConnectionStatus(): ICameraConnectionStatus.CameraConnectionStatus
204     {
205         Log.v(TAG, "getConnectionStatus()")
206         return connectionStatus
207     }
208
209     /**
210      *
211      *
212      */
213     override fun forceUpdateConnectionStatus(status: ICameraConnectionStatus.CameraConnectionStatus)
214     {
215         Log.v(TAG, "forceUpdateConnectionStatus()")
216         connectionStatus = status
217
218         if (status == ICameraConnectionStatus.CameraConnectionStatus.CONNECTED)
219         {
220             startLiveView()
221             //liveViewControl.startLiveView()
222         }
223         else if (status == ICameraConnectionStatus.CameraConnectionStatus.DISCONNECTED)
224         {
225             liveViewControl.stopLiveView()
226         }
227     }
228
229     /**
230      *
231      *
232      */
233     private fun startLiveView()
234     {
235         try
236         {
237 /*
238             val optionGet = ThetaOptionGetControl(sessionIdProvider)
239             optionGet.getOptions("[\"previewFormat\", \"previewFormatSupport\"]", (sessionIdProvider.sessionId.isBlank()),
240                     object : IOperationCallback { override fun operationExecuted(result: Int, resultStr: String?)
241                     {
242                         Log.v(TAG, " >>>>> optionGet.getOptions : $resultStr ")
243                     }})
244 */
245             val optionSet = ThetaOptionSetControl(sessionIdProvider)
246             optionSet.setOptions("\"captureMode\" : \"image\"", (sessionIdProvider.sessionId.isBlank()),
247                     object : IOperationCallback { override fun operationExecuted(result: Int, resultStr: String?)
248                     {
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?)
254                                 {
255                                     Log.v(TAG, " optionSet.setOptions(live view) : $resultStr ($previewFormat)")
256                                     liveViewControl.startLiveView()
257                                 }})
258                     }})
259         }
260         catch (e : Exception)
261         {
262             e.printStackTrace()
263         }
264     }
265
266
267     /**
268      * カメラとの切断処理
269      */
270     private fun disconnectFromCamera(powerOff: Boolean)
271     {
272         Log.v(TAG, "disconnectFromCamera() : $powerOff")
273         try
274         {
275             cameraExecutor.execute(ThetaCameraDisconnectSequence())
276         }
277         catch (e: Exception)
278         {
279             e.printStackTrace()
280         }
281     }
282
283     /**
284      * カメラとの接続処理
285      */
286     private fun connectToCamera()
287     {
288         Log.v(TAG, " connectToCamera()")
289         connectionStatus = ICameraConnectionStatus.CameraConnectionStatus.CONNECTING
290         try
291         {
292             cameraExecutor.execute(ThetaCameraConnectSequence(context, statusReceiver, sessionIdNotifier, this))
293         }
294         catch (e: Exception)
295         {
296             Log.v(TAG, "connectToCamera() EXCEPTION : " + e.message)
297             e.printStackTrace()
298         }
299     }
300 }