OSDN Git Service

c521bd637fd140bf7621a8a5c525c3d344925037
[gokigen/mangle.git] / app / src / main / java / jp / osdn / gokigen / gokigenassets / camera / vendor / theta / connection / ThetaCameraConnectSequence.kt
1 package jp.osdn.gokigen.gokigenassets.camera.vendor.theta.connection
2
3 import android.util.Log
4 import androidx.appcompat.app.AppCompatActivity
5 import jp.osdn.gokigen.gokigenassets.camera.interfaces.ICameraConnection
6 import jp.osdn.gokigen.gokigenassets.camera.interfaces.ICameraConnectionStatus
7 import jp.osdn.gokigen.gokigenassets.camera.interfaces.ICameraStatusReceiver
8 import jp.osdn.gokigen.gokigenassets.camera.vendor.theta.status.IThetaSessionIdNotifier
9 import jp.osdn.gokigen.gokigenassets.constants.IStringResourceConstantConvert.Companion.ID_STRING_CAMERA_CONNECT_RESPONSE_NG
10 import jp.osdn.gokigen.gokigenassets.constants.IStringResourceConstantConvert.Companion.ID_STRING_CAMERA_NOT_FOUND
11 import jp.osdn.gokigen.gokigenassets.constants.IStringResourceConstantConvert.Companion.ID_STRING_CONNECT_CONNECTED
12 import jp.osdn.gokigen.gokigenassets.utils.communication.SimpleHttpClient
13 import org.json.JSONObject
14
15 class ThetaCameraConnectSequence(private val context: AppCompatActivity, private val cameraStatusReceiver: ICameraStatusReceiver, private val sessionIdNotifier: IThetaSessionIdNotifier, private val cameraConnection : ICameraConnection, private val executeUrl : String = "http://192.168.1.1") : Runnable
16 {
17     private var useThetaV21: Boolean = false
18     private val httpClient = SimpleHttpClient()
19
20     override fun run()
21     {
22         // 使用する API Levelを決める
23         useThetaV21 = decideApiLevel()
24         try
25         {
26             Log.v(TAG, "Theta API v2.1 : $useThetaV21")
27             if (useThetaV21)
28             {
29                 // API Level V2.1を使用して通信する
30                 connectApiV21()
31             }
32             else
33             {
34                 // API Level V2 を使用して通信する
35                 connectApiV2()
36             }
37         }
38         catch (e: Exception)
39         {
40             e.printStackTrace()
41         }
42     }
43
44     /**
45      *
46      */
47     private fun decideApiLevel(): Boolean
48     {
49         var apiLevelIsV21 = false
50         try
51         {
52             val oscInfoUrl = "$executeUrl/osc/info"
53             val timeoutMs = 3000
54             val response: String = httpClient.httpGet(oscInfoUrl, timeoutMs)
55             Log.v(TAG, " $oscInfoUrl $response")
56             if (response.isNotEmpty())
57             {
58                 val apiLevelArray = JSONObject(response).getJSONArray("apiLevel")
59                 val size = apiLevelArray.length()
60                 for (index in 0 until size)
61                 {
62                     val api = apiLevelArray.getInt(index)
63                     if (api == 1)  //if (api == 1 && useThetaV21)
64                     {
65                         apiLevelIsV21 = false
66                         break
67                     }
68                     if (api == 2)  //if (api == 2 && useThetaV21)
69                     {
70                         apiLevelIsV21 = true
71                         break
72                     }
73                 }
74             }
75         }
76         catch (e: Exception)
77         {
78             e.printStackTrace()
79         }
80         return (apiLevelIsV21)
81     }
82
83     /**
84      *
85      */
86     private fun connectApiV2()
87     {
88         val commandsExecuteUrl = "$executeUrl/osc/commands/execute"
89         val startSessionData = "{\"name\":\"camera.startSession\",\"parameters\":{\"timeout\":0}}"
90         val getStateUrl = "$executeUrl/osc/state"
91         val timeoutMs = 2000
92         try
93         {
94             val response: String? = httpClient.httpPost(commandsExecuteUrl, startSessionData, timeoutMs)
95             Log.v(TAG, " $commandsExecuteUrl $startSessionData $response")
96             val response2: String? = httpClient.httpPost(getStateUrl, "", timeoutMs)
97             Log.v(TAG, " $getStateUrl $response2")
98             if ((response2 != null) && (response2.isNotEmpty()))
99             {
100                 try
101                 {
102                     val jsonObject = JSONObject(response2)
103                     val sessionId = jsonObject.getJSONObject("state").getString("sessionId")
104                     sessionIdNotifier.receivedSessionId(sessionId)
105                     onConnectNotify()
106                     return
107                 }
108                 catch (e: Exception)
109                 {
110                     e.printStackTrace()
111                 }
112             }
113             // 応答なし、を応答する。
114             cameraConnection.alertConnectingFailed(context.getString(ID_STRING_CAMERA_CONNECT_RESPONSE_NG))
115         }
116         catch (e: Exception)
117         {
118             e.printStackTrace()
119             cameraConnection.alertConnectingFailed(e.localizedMessage)
120         }
121     }
122
123     private fun connectApiV21()
124     {
125         val commandsExecuteUrl = "$executeUrl/osc/commands/execute"
126         val startSessionData = "{\"name\":\"camera.startSession\",\"parameters\":{\"timeout\":0}}"
127         val getStateUrl = "$executeUrl/osc/state"
128         val timeoutMs = 3000
129         try
130         {
131             val responseS: String? = httpClient.httpPostWithHeader(
132                 commandsExecuteUrl,
133                 startSessionData,
134                 null,
135                 "application/json;charset=utf-8",
136                 timeoutMs
137             )
138             Log.v(TAG, " [ $commandsExecuteUrl ] $startSessionData ::: $responseS")
139             val response: String? =
140                 httpClient.httpPostWithHeader(getStateUrl, "", null, null, timeoutMs)
141             Log.v(TAG, " ($getStateUrl) $response")
142             if ((response != null) && (response.isNotEmpty()))
143             {
144                 var apiLevel = 1
145                 var sessionId: String? = null
146                 val jsonObject = JSONObject(response)
147                 try
148                 {
149                     apiLevel = jsonObject.getJSONObject("state").getInt("_apiVersion")
150                 }
151                 catch (e: Exception)
152                 {
153                     e.printStackTrace()
154                 }
155                 if (apiLevel == 1)
156                 {
157                     try
158                     {
159                         sessionId = jsonObject.getJSONObject("state").getString("sessionId")
160                         sessionIdNotifier.receivedSessionId(sessionId)
161                     }
162                     catch (e: Exception)
163                     {
164                         e.printStackTrace()
165                     }
166                 }
167                 if (apiLevel != 2)
168                 {
169                     // API Levelを 1 から 2 に変える
170                     val setApiLevelData = "{\"name\":\"camera.setOptions\",\"parameters\":{\"sessionId\" : \"$sessionId\", \"options\":{ \"clientVersion\":2}}}"
171                     val response3: String? = httpClient.httpPostWithHeader(
172                         commandsExecuteUrl,
173                         setApiLevelData,
174                         null,
175                         "application/json;charset=utf-8",
176                         timeoutMs
177                     )
178                     Log.v(TAG, " $commandsExecuteUrl $setApiLevelData $response3")
179                 }
180                 onConnectNotify()
181             }
182             else
183             {
184                 cameraConnection.alertConnectingFailed(context.getString(ID_STRING_CAMERA_NOT_FOUND))
185             }
186         }
187         catch (e: Exception)
188         {
189             e.printStackTrace()
190             cameraConnection.alertConnectingFailed(e.localizedMessage)
191         }
192     }
193
194     private fun onConnectNotify()
195     {
196         try
197         {
198             val thread = Thread { // カメラとの接続確立を通知する
199                 cameraStatusReceiver.onStatusNotify(context.getString(ID_STRING_CONNECT_CONNECTED))
200                 cameraStatusReceiver.onCameraConnected()
201                 Log.v(TAG, "onConnectNotify()")
202                 cameraConnection.forceUpdateConnectionStatus(ICameraConnectionStatus.CameraConnectionStatus.CONNECTED)
203             }
204             thread.start()
205         }
206         catch (e: Exception)
207         {
208             e.printStackTrace()
209         }
210     }
211
212     companion object
213     {
214         private val TAG = ThetaCameraConnectSequence::class.java.simpleName
215     }
216 }