diff --git a/.github/workflows/buildAndTest.yaml b/.github/workflows/buildAndTest.yaml index 70eeb8a16f..b1cc75c223 100644 --- a/.github/workflows/buildAndTest.yaml +++ b/.github/workflows/buildAndTest.yaml @@ -10,6 +10,11 @@ on: permissions: contents: read +env: + ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{secrets.ORG_GRADLE_PROJECT_SIGNINGINMEMORYKEYID}} + ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{secrets.ORG_GRADLE_PROJECT_SIGNINGINMEMORYKEYPASSWORD}} + ORG_GRADLE_PROJECT_signingInMemoryKey: ${{secrets.ORG_GRADLE_PROJECT_SIGNINGINMEMORYKEY}} + jobs: build: runs-on: macos-latest diff --git a/demos/demo-android/app/build.gradle b/demos/demo-android/app/build.gradle index d393ca8552..475728845b 100755 --- a/demos/demo-android/app/build.gradle +++ b/demos/demo-android/app/build.gradle @@ -76,7 +76,7 @@ dependencies { implementation 'com.jakewharton.timber:timber:5.0.1' implementation 'io.coil-kt:coil-compose:2.2.2' implementation "io.ktor:ktor-client-cio:$ktor_version" - implementation "com.ricoh360.thetaclient:theta-client:1.13.0" + implementation "com.ricoh360.thetaclient:theta-client:1.13.1" testImplementation 'org.junit.jupiter:junit-jupiter:5.9.0' testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version" diff --git a/demos/demo-ios/Podfile b/demos/demo-ios/Podfile index 4ff66a17be..da27d630f1 100644 --- a/demos/demo-ios/Podfile +++ b/demos/demo-ios/Podfile @@ -7,5 +7,5 @@ target 'SdkSample' do use_frameworks! # Pods for SdkSample - pod 'THETAClient', '1.13.0' + pod 'THETAClient', '1.13.1' end diff --git a/demos/demo-react-native/package.json b/demos/demo-react-native/package.json index 37ce418c91..f5e05e8ede 100644 --- a/demos/demo-react-native/package.json +++ b/demos/demo-react-native/package.json @@ -13,7 +13,7 @@ "dependencies": { "@react-navigation/native": "^6.1.0", "@react-navigation/native-stack": "^6.9.5", - "theta-client-react-native": "1.13.0", + "theta-client-react-native": "1.13.1", "react": "18.2.0", "react-native": "0.71.14", "react-native-safe-area-context": "^4.4.1", diff --git a/docs/tutorial-android.ja.md b/docs/tutorial-android.ja.md index a76892fd4b..2dbd3cfaf6 100644 --- a/docs/tutorial-android.ja.md +++ b/docs/tutorial-android.ja.md @@ -4,7 +4,7 @@ - モジュールの`build.gradle`の`dependencies`に次を追加します。 ``` - implementation "com.ricoh360.thetaclient:theta-client:1.13.0" + implementation "com.ricoh360.thetaclient:theta-client:1.13.1" ``` - 本 SDK を使用したアプリケーションが動作するスマートフォンと THETA を無線 LAN 接続しておきます。 diff --git a/docs/tutorial-android.md b/docs/tutorial-android.md index 20b672aafe..869de25bf8 100644 --- a/docs/tutorial-android.md +++ b/docs/tutorial-android.md @@ -5,7 +5,7 @@ - Add following descriptions to the `dependencies` of your module's `build.gradle`. ``` - implementation "com.ricoh360.thetaclient:theta-client:1.13.0" + implementation "com.ricoh360.thetaclient:theta-client:1.13.1" ``` - Connect the wireless LAN between THETA and the smartphone that runs on the application using this SDK. diff --git a/flutter/android/build.gradle b/flutter/android/build.gradle index c3e9469591..07b95b37c6 100644 --- a/flutter/android/build.gradle +++ b/flutter/android/build.gradle @@ -52,7 +52,7 @@ android { testImplementation("org.mockito:mockito-core:5.0.0") implementation("com.soywiz.korlibs.krypto:krypto:4.0.10") - implementation("com.ricoh360.thetaclient:theta-client:1.13.0") + implementation("com.ricoh360.thetaclient:theta-client:1.13.1") } testOptions { diff --git a/flutter/android/src/main/kotlin/com/ricoh360/thetaclient/theta_client_flutter/ConvertUtil.kt b/flutter/android/src/main/kotlin/com/ricoh360/thetaclient/theta_client_flutter/ConvertUtil.kt index a036bfe660..7425e39298 100644 --- a/flutter/android/src/main/kotlin/com/ricoh360/thetaclient/theta_client_flutter/ConvertUtil.kt +++ b/flutter/android/src/main/kotlin/com/ricoh360/thetaclient/theta_client_flutter/ConvertUtil.kt @@ -1253,7 +1253,7 @@ fun toStartedNotifyParam(value: String): Map { data class SetAccessPointParams( val ssid: String, val ssidStealth: Boolean?, - val authMode: AuthModeEnum, + val authMode: AuthModeEnum?, val password: String?, val connectionPriority: Int?, val dns1: String?, @@ -1264,9 +1264,7 @@ data class SetAccessPointParams( fun toSetAccessPointParams(arguments: Map<*, *>): SetAccessPointParams { val ssid = arguments[KEY_SSID] as? String ?: throw IllegalArgumentException(KEY_SSID) val ssidStealth = arguments[KEY_SSID_STEALTH] as? Boolean - val authMode = (arguments[KEY_AUTH_MODE] as? String?)?.let { - AuthModeEnum.valueOf(it) - } ?: throw IllegalArgumentException(KEY_AUTH_MODE) + val authMode = (arguments[KEY_AUTH_MODE] as? String?)?.let { AuthModeEnum.valueOf(it) } val password = arguments[KEY_PASSWORD] as? String val connectionPriority = arguments[KEY_CONNECTION_PRIORITY] as? Int val dns1 = arguments[KEY_DNS1] as? String diff --git a/flutter/android/src/main/kotlin/com/ricoh360/thetaclient/theta_client_flutter/ThetaClientFlutterPlugin.kt b/flutter/android/src/main/kotlin/com/ricoh360/thetaclient/theta_client_flutter/ThetaClientFlutterPlugin.kt index d64ddd859a..b29c65c358 100644 --- a/flutter/android/src/main/kotlin/com/ricoh360/thetaclient/theta_client_flutter/ThetaClientFlutterPlugin.kt +++ b/flutter/android/src/main/kotlin/com/ricoh360/thetaclient/theta_client_flutter/ThetaClientFlutterPlugin.kt @@ -459,6 +459,12 @@ class ThetaClientFlutterPlugin : FlutterPlugin, MethodCallHandler { } } + "setAccessPointConnectionPriority" -> { + scope.launch { + setAccessPointConnectionPriority(call, result) + } + } + "deleteAccessPoint" -> { scope.launch { deleteAccessPoint(call, result) @@ -1758,6 +1764,23 @@ class ThetaClientFlutterPlugin : FlutterPlugin, MethodCallHandler { } } + suspend fun setAccessPointConnectionPriority(call: MethodCall, result: Result) { + if (thetaRepository == null) { + result.error(errorCode, messageNotInit, null) + return + } + try { + val arguments = call.arguments as Map<*, *> + val ssid = arguments[KEY_SSID] as? String ?: throw IllegalArgumentException(KEY_SSID) + val connectionPriority = arguments[KEY_CONNECTION_PRIORITY] as? Int ?: throw IllegalArgumentException(KEY_CONNECTION_PRIORITY) + val ssidStealth = arguments[KEY_SSID_STEALTH] as? Boolean ?: throw IllegalArgumentException(KEY_SSID_STEALTH) + thetaRepository?.setAccessPointConnectionPriority(ssid, connectionPriority, ssidStealth) + result.success(null) + } catch (e: Exception) { + result.error(e.javaClass.simpleName, e.message, null) + } + } + suspend fun deleteAccessPoint(call: MethodCall, result: Result) { if (thetaRepository == null) { result.error(errorCode, messageNotInit, null) diff --git a/flutter/ios/Classes/ConvertUtil.swift b/flutter/ios/Classes/ConvertUtil.swift index 5ba6d40eba..f560074310 100644 --- a/flutter/ios/Classes/ConvertUtil.swift +++ b/flutter/ios/Classes/ConvertUtil.swift @@ -1456,7 +1456,7 @@ func toStartedNotifyParam(value: String) -> [String: Any] { struct SetAccessPointParams { let ssid: String let ssidStealth: KotlinBoolean? - let authMode: ThetaRepository.AuthModeEnum + let authMode: ThetaRepository.AuthModeEnum? let password: String? let connectionPriority: KotlinInt? let dns1: String? @@ -1469,16 +1469,7 @@ func toSetAccessPointParams(params: [String: Any?]) throws -> SetAccessPointPara throw ThetaClientError.invalidArgument(KEY_SSID) } let ssidStealth = toKotlinBoolean(value: params[KEY_SSID_STEALTH] as? Bool) - guard let authMode = params[KEY_AUTH_MODE] as? String else { - throw ThetaClientError.invalidArgument(KEY_AUTH_MODE) - } - guard - let authModeEnum = getEnumValue( - values: ThetaRepository.AuthModeEnum.values(), name: authMode - ) - else { - throw ThetaClientError.invalidArgument(KEY_AUTH_MODE) - } + let authModeEnum = getEnumValue(values: ThetaRepository.AuthModeEnum.values(), name: (params[KEY_AUTH_MODE] as? String) ?? "") let password = params[KEY_PASSWORD] as? String let connectionPriority = toKotlinInt(value: params[KEY_CONNECTION_PRIORITY] as? Int) let dns1 = params[KEY_DNS1] as? String diff --git a/flutter/ios/Classes/SwiftThetaClientFlutterPlugin.swift b/flutter/ios/Classes/SwiftThetaClientFlutterPlugin.swift index 053c28de48..0efa681adc 100644 --- a/flutter/ios/Classes/SwiftThetaClientFlutterPlugin.swift +++ b/flutter/ios/Classes/SwiftThetaClientFlutterPlugin.swift @@ -242,6 +242,8 @@ public class SwiftThetaClientFlutterPlugin: NSObject, FlutterPlugin, FlutterStre setAccessPointDynamically(call: call, result: result) case "setAccessPointStatically": setAccessPointStatically(call: call, result: result) + case "setAccessPointConnectionPriority": + setAccessPointConnectionPriority(call: call, result: result) case "deleteAccessPoint": deleteAccessPoint(call: call, result: result) case "getMySetting": @@ -1748,6 +1750,48 @@ public class SwiftThetaClientFlutterPlugin: NSObject, FlutterPlugin, FlutterStre } } + func setAccessPointConnectionPriority(call: FlutterMethodCall, result: @escaping FlutterResult) { + guard let thetaRepository else { + let flutterError = FlutterError(code: SwiftThetaClientFlutterPlugin.errorCode, message: SwiftThetaClientFlutterPlugin.messageNotInit, details: nil) + result(flutterError) + return + } + guard + let arguments = call.arguments as? [String: Any?] + else { + let flutterError = FlutterError(code: SwiftThetaClientFlutterPlugin.errorCode, message: SwiftThetaClientFlutterPlugin.messageNoArgument, details: nil) + result(flutterError) + return + } + do { + guard let ssid = arguments[KEY_SSID] as? String else { + throw ThetaClientError.invalidArgument(KEY_SSID) + } + guard let connectionPriority = arguments[KEY_CONNECTION_PRIORITY] as? Int32 else { + throw ThetaClientError.invalidArgument(KEY_CONNECTION_PRIORITY) + } + guard let ssidStealth = arguments[KEY_SSID_STEALTH] as? Bool else { + throw ThetaClientError.invalidArgument(KEY_SSID_STEALTH) + } + thetaRepository.setAccessPointConnectionPriority( + ssid: ssid, + connectionPriority: connectionPriority, + ssidStealth: ssidStealth, + completionHandler: { error in + if let thetaError = error { + let flutterError = FlutterError(code: SwiftThetaClientFlutterPlugin.errorCode, message: thetaError.localizedDescription, details: nil) + result(flutterError) + } else { + result(nil) + } + } + ) + } catch { + let flutterError = FlutterError(code: SwiftThetaClientFlutterPlugin.errorCode, message: error.localizedDescription, details: nil) + result(flutterError) + } + } + func deleteAccessPoint(call: FlutterMethodCall, result: @escaping FlutterResult) { guard let thetaRepository else { let flutterError = FlutterError(code: SwiftThetaClientFlutterPlugin.errorCode, message: SwiftThetaClientFlutterPlugin.messageNotInit, details: nil) diff --git a/flutter/ios/theta_client_flutter.podspec b/flutter/ios/theta_client_flutter.podspec index ba9a598bf9..2f42194f56 100644 --- a/flutter/ios/theta_client_flutter.podspec +++ b/flutter/ios/theta_client_flutter.podspec @@ -4,7 +4,7 @@ # Pod::Spec.new do |s| s.name = 'theta_client_flutter' - s.version = '1.13.0' + s.version = '1.13.1' s.summary = 'theta-client plugin project.' s.description = <<-DESC theta-client Flutter plugin project. @@ -17,7 +17,7 @@ Pod::Spec.new do |s| s.dependency 'Flutter' s.platform = :ios, '15.0' - s.dependency 'THETAClient', '1.13.0' + s.dependency 'THETAClient', '1.13.1' # Flutter.framework does not contain a i386 slice. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } diff --git a/flutter/lib/theta_client_flutter.dart b/flutter/lib/theta_client_flutter.dart index 134f7fedde..03f78d2f9a 100644 --- a/flutter/lib/theta_client_flutter.dart +++ b/flutter/lib/theta_client_flutter.dart @@ -330,7 +330,7 @@ class ThetaClientFlutter { /// - @throws If an error occurs in THETA. Future setAccessPointDynamically(String ssid, {bool? ssidStealth, - AuthModeEnum authMode = AuthModeEnum.none, + AuthModeEnum? authMode, String? password, int? connectionPriority, Proxy? proxy}) { @@ -354,7 +354,7 @@ class ThetaClientFlutter { /// - @throws If an error occurs in THETA. Future setAccessPointStatically(String ssid, {bool? ssidStealth, - AuthModeEnum authMode = AuthModeEnum.none, + AuthModeEnum? authMode, String? password, int? connectionPriority, required String ipAddress, @@ -377,6 +377,18 @@ class ThetaClientFlutter { proxy); } + /// Updates the connection priority of the access point. + /// + /// - @param ssid SSID of the access point. + /// - @param connectionPriority Connection priority (1 to 5). Default is 1. Theta X fixed to 1 (The access point registered later has a higher priority.) + /// - @param ssidStealth True if SSID stealth is enabled. Default is false. + /// - @throws If an error occurs in THETA. + Future setAccessPointConnectionPriority( + String ssid, int connectionPriority, bool ssidStealth) { + return ThetaClientFlutterPlatform.instance.setAccessPointConnectionPriority( + ssid, connectionPriority, ssidStealth); + } + /// Deletes access point information used in client mode. /// Only the access points registered with [setAccessPoint] can be deleted. /// diff --git a/flutter/lib/theta_client_flutter_method_channel.dart b/flutter/lib/theta_client_flutter_method_channel.dart index 2b466d9f1a..c38554d6ce 100644 --- a/flutter/lib/theta_client_flutter_method_channel.dart +++ b/flutter/lib/theta_client_flutter_method_channel.dart @@ -1070,14 +1070,14 @@ class MethodChannelThetaClientFlutter extends ThetaClientFlutterPlatform { Future setAccessPointDynamically( String ssid, bool? ssidStealth, - AuthModeEnum authMode, + AuthModeEnum? authMode, String? password, int? connectionPriority, Proxy? proxy) async { final Map params = { 'ssid': ssid, 'ssidStealth': ssidStealth, - 'authMode': authMode.rawValue, + 'authMode': authMode?.rawValue, 'password': password, 'connectionPriority': connectionPriority, 'proxy': proxy != null ? ConvertUtils.convertProxyParam(proxy) : null @@ -1090,7 +1090,7 @@ class MethodChannelThetaClientFlutter extends ThetaClientFlutterPlatform { Future setAccessPointStatically( String ssid, bool? ssidStealth, - AuthModeEnum authMode, + AuthModeEnum? authMode, String? password, int? connectionPriority, String ipAddress, @@ -1102,7 +1102,7 @@ class MethodChannelThetaClientFlutter extends ThetaClientFlutterPlatform { final Map params = { 'ssid': ssid, 'ssidStealth': ssidStealth, - 'authMode': authMode.rawValue, + 'authMode': authMode?.rawValue, 'password': password, 'connectionPriority': connectionPriority, 'ipAddress': ipAddress, @@ -1115,6 +1115,18 @@ class MethodChannelThetaClientFlutter extends ThetaClientFlutterPlatform { return methodChannel.invokeMethod('setAccessPointStatically', params); } + @override + Future setAccessPointConnectionPriority( + String ssid, int connectionPriority, bool ssidStealth) async { + final Map params = { + 'ssid': ssid, + 'ssidStealth': ssidStealth, + 'connectionPriority': connectionPriority, + }; + return methodChannel.invokeMethod( + 'setAccessPointConnectionPriority', params); + } + @override Future deleteAccessPoint(String ssid) async { return methodChannel.invokeMethod('deleteAccessPoint', ssid); diff --git a/flutter/lib/theta_client_flutter_platform_interface.dart b/flutter/lib/theta_client_flutter_platform_interface.dart index fc469c698e..aee3232114 100644 --- a/flutter/lib/theta_client_flutter_platform_interface.dart +++ b/flutter/lib/theta_client_flutter_platform_interface.dart @@ -361,7 +361,7 @@ abstract class ThetaClientFlutterPlatform extends PlatformInterface { Future setAccessPointDynamically( String ssid, bool? ssidStealth, - AuthModeEnum authMode, + AuthModeEnum? authMode, String? password, int? connectionPriority, Proxy? proxy) { @@ -372,7 +372,7 @@ abstract class ThetaClientFlutterPlatform extends PlatformInterface { Future setAccessPointStatically( String ssid, bool? ssidStealth, - AuthModeEnum authMode, + AuthModeEnum? authMode, String? password, int? connectionPriority, String ipAddress, @@ -385,6 +385,12 @@ abstract class ThetaClientFlutterPlatform extends PlatformInterface { 'setAccessPointStatically() has not been implemented.'); } + Future setAccessPointConnectionPriority( + String ssid, int connectionPriority, bool ssidStealth) { + throw UnimplementedError( + 'setAccessPointConnectionPriority() has not been implemented.'); + } + Future deleteAccessPoint(String ssid) { throw UnimplementedError('deleteAccessPoint() has not been implemented.'); } diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index f22786eae7..a374749bde 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: theta_client_flutter description: THETA Client Flutter plugin project. -version: 1.13.0 +version: 1.13.1 homepage: environment: diff --git a/flutter/test/theta_client_flutter_method_channel_test.dart b/flutter/test/theta_client_flutter_method_channel_test.dart index 43baa22225..bc14d03568 100644 --- a/flutter/test/theta_client_flutter_method_channel_test.dart +++ b/flutter/test/theta_client_flutter_method_channel_test.dart @@ -1442,6 +1442,25 @@ void main() { proxy); }); + test('setAccessPointConnectionPriority', () async { + const ssid = 'ssid_test'; + const ssidStealth = true; + const connectionPriority = 2; + + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(channel, (MethodCall methodCall) async { + expect(methodCall.method, 'setAccessPointConnectionPriority'); + + var arguments = methodCall.arguments as Map; + expect(arguments['ssid'], ssid); + expect(arguments['ssidStealth'], ssidStealth); + expect(arguments['connectionPriority'], connectionPriority); + return Future.value(); + }); + await platform.setAccessPointConnectionPriority( + ssid, connectionPriority, ssidStealth); + }); + test('deleteAccessPoint', () async { const ssid = 'ssid_test'; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger diff --git a/flutter/test/theta_client_flutter_test.dart b/flutter/test/theta_client_flutter_test.dart index 1f789363c6..31cf75bb4a 100644 --- a/flutter/test/theta_client_flutter_test.dart +++ b/flutter/test/theta_client_flutter_test.dart @@ -377,7 +377,7 @@ class MockThetaClientFlutterPlatform Future setAccessPointDynamically( String ssid, bool? ssidStealth, - AuthModeEnum authMode, + AuthModeEnum? authMode, String? password, int? connectionPriority, Proxy? proxy) { @@ -388,7 +388,7 @@ class MockThetaClientFlutterPlatform Future setAccessPointStatically( String ssid, bool? ssidStealth, - AuthModeEnum authMode, + AuthModeEnum? authMode, String? password, int? connectionPriority, String ipAddress, @@ -400,6 +400,12 @@ class MockThetaClientFlutterPlatform return Future.value(); } + @override + Future setAccessPointConnectionPriority( + String ssid, int connectionPriority, bool ssidStealth) { + return Future.value(); + } + @override Future deleteAccessPoint(String ssid) { return Future.value(); diff --git a/kotlin-multiplatform/build.gradle.kts b/kotlin-multiplatform/build.gradle.kts index 2bb5b87642..b373f9de0e 100644 --- a/kotlin-multiplatform/build.gradle.kts +++ b/kotlin-multiplatform/build.gradle.kts @@ -17,7 +17,7 @@ dependencies { dokkaPlugin("org.jetbrains.dokka:versioning-plugin:1.9.20") } -val thetaClientVersion = "1.13.0" +val thetaClientVersion = "1.13.1" group = "com.ricoh360.thetaclient" version = thetaClientVersion diff --git a/kotlin-multiplatform/src/commonMain/kotlin/com/ricoh360/thetaclient/ThetaRepository.kt b/kotlin-multiplatform/src/commonMain/kotlin/com/ricoh360/thetaclient/ThetaRepository.kt index 51c43f792a..b178e61b4d 100644 --- a/kotlin-multiplatform/src/commonMain/kotlin/com/ricoh360/thetaclient/ThetaRepository.kt +++ b/kotlin-multiplatform/src/commonMain/kotlin/com/ricoh360/thetaclient/ThetaRepository.kt @@ -8828,10 +8828,10 @@ class ThetaRepository internal constructor(val endpoint: String, config: Config? internal suspend fun setAccessPoint( ssid: String, ssidStealth: Boolean? = null, - authMode: AuthModeEnum = AuthModeEnum.NONE, + authMode: AuthModeEnum? = null, password: String? = null, connectionPriority: Int? = null, - ipAddressAllocation: IpAddressAllocation, + ipAddressAllocation: IpAddressAllocation? = null, ipAddress: String? = null, subnetMask: String? = null, defaultGateway: String? = null, @@ -8839,10 +8839,14 @@ class ThetaRepository internal constructor(val endpoint: String, config: Config? dns2: String? = null, proxy: Proxy? = null, ) { + if (cameraModel == ThetaModel.THETA_A1 && authMode == AuthModeEnum.NONE) { + throw ThetaWebApiException("${cameraModel?.value} does not allow authMode to be set to none.") + } + val params = SetAccessPointParams( ssid = ssid, ssidStealth = ssidStealth, - security = authMode.value, + security = authMode?.value, password = password, connectionPriority = connectionPriority, ipAddressAllocation = ipAddressAllocation, @@ -8884,7 +8888,7 @@ class ThetaRepository internal constructor(val endpoint: String, config: Config? suspend fun setAccessPointDynamically( ssid: String, ssidStealth: Boolean? = null, - authMode: AuthModeEnum = AuthModeEnum.NONE, + authMode: AuthModeEnum? = null, password: String? = null, connectionPriority: Int? = null, proxy: Proxy? = null, @@ -8921,7 +8925,7 @@ class ThetaRepository internal constructor(val endpoint: String, config: Config? suspend fun setAccessPointStatically( ssid: String, ssidStealth: Boolean? = null, - authMode: AuthModeEnum = AuthModeEnum.NONE, + authMode: AuthModeEnum? = null, password: String? = null, connectionPriority: Int? = null, ipAddress: String, @@ -8947,6 +8951,24 @@ class ThetaRepository internal constructor(val endpoint: String, config: Config? ) } + /** + * Updates the connection priority of the access point. + * + * @param ssid SSID + * @param connectionPriority Connection priority (1 to 5). Default is 1. Theta X fixed to 1 (The access point registered later has a higher priority.) + * @param ssidStealth SSID stealth. Default is false. + * @exception ThetaWebApiException If an error occurs in THETA. + * @exception NotConnectedException + */ + @Throws(Throwable::class) + suspend fun setAccessPointConnectionPriority(ssid: String, connectionPriority: Int, ssidStealth: Boolean) { + setAccessPoint( + ssid = ssid, + ssidStealth = ssidStealth, + connectionPriority = connectionPriority, + ) + } + /** * Deletes access point information used in client mode. * Only the access points registered with [setAccessPoint] can be deleted. diff --git a/kotlin-multiplatform/src/commonTest/kotlin/com/ricoh360/thetaclient/repository/SetAccessPointTest.kt b/kotlin-multiplatform/src/commonTest/kotlin/com/ricoh360/thetaclient/repository/SetAccessPointTest.kt index a22690952f..d222b38d27 100644 --- a/kotlin-multiplatform/src/commonTest/kotlin/com/ricoh360/thetaclient/repository/SetAccessPointTest.kt +++ b/kotlin-multiplatform/src/commonTest/kotlin/com/ricoh360/thetaclient/repository/SetAccessPointTest.kt @@ -38,10 +38,10 @@ class SetAccessPointTest { request: HttpRequestData, ssid: String, ssidStealth: Boolean, - security: AuthenticationMode, + security: AuthenticationMode?, password: String?, connectionPriority: Int, - ipAddressAllocation: IpAddressAllocation, + ipAddressAllocation: IpAddressAllocation?, ipAddress: String?, subnetMask: String?, defaultGateway: String?, @@ -89,7 +89,6 @@ class SetAccessPointTest { val proxy = ThetaRepository.Proxy(use = true, url = "https://xxx", port = 8081, userid = "abc", password = "pwpwpw111") MockApiClient.onRequest = { request -> - // check request checkRequest( request, ssid, @@ -139,7 +138,6 @@ class SetAccessPointTest { val proxy = ThetaRepository.Proxy(use = true, url = "https://xxx", port = 8081, userid = "abc", password = "pwpwpw111") MockApiClient.onRequest = { request -> - // check request checkRequest( request, ssid, @@ -176,6 +174,44 @@ class SetAccessPointTest { assertTrue(true, "response is normal.") } + /** + * call setAccessPointConnectionPriority. + */ + @Test + fun setAccessPointConnectionPriorityTest() = runTest { + val ssid = "ssid_test" + val ssidStealth = true + val connectionPriority = 2 + + MockApiClient.onRequest = { request -> + checkRequest( + request, + ssid, + ssidStealth, + null, + null, + connectionPriority, + null, + null, + null, + null, + null, + null, + null + ) + + ByteReadChannel(Resource("src/commonTest/resources/setAccessPoint/set_access_point_done.json").readText()) + } + + val thetaRepository = ThetaRepository(endpoint) + thetaRepository.setAccessPointConnectionPriority( + ssid = ssid, + ssidStealth = ssidStealth, + connectionPriority = connectionPriority, + ) + assertTrue(true, "response is normal.") + } + /** * Error not json response to setAccessPoint call */ @@ -401,4 +437,78 @@ class SetAccessPointTest { assertTrue(e.message!!.indexOf("time", 0, true) >= 0, "timeout exception") } } + + @Test + fun setAccessPointAuthModeExceptionTest() = runTest { + MockApiClient.onRequest = { _ -> + ByteReadChannel(Resource("src/commonTest/resources/listAccessPoints/list_access_points_empty_done.json").readText()) + } + + val thetaRepository = ThetaRepository(endpoint) + thetaRepository.cameraModel = ThetaRepository.ThetaModel.THETA_A1 + try { + val ssid = "ssid_test" + val authMode = ThetaRepository.AuthModeEnum.NONE + val ipAddressAllocation = IpAddressAllocation.STATIC + + thetaRepository.setAccessPoint( + ssid = ssid, + authMode = authMode, + ipAddressAllocation = ipAddressAllocation, + ) + assertTrue(false, "response is normal.") + } catch (e: ThetaRepository.ThetaWebApiException) { + assertTrue(e.message!!.contains("does not allow authMode to be set to none."), "authMode exception") + } + } + + @Test + fun setAccessPointDynamicallyAuthModeExceptionTest() = runTest { + MockApiClient.onRequest = { _ -> + ByteReadChannel(Resource("src/commonTest/resources/listAccessPoints/list_access_points_empty_done.json").readText()) + } + + val thetaRepository = ThetaRepository(endpoint) + thetaRepository.cameraModel = ThetaRepository.ThetaModel.THETA_A1 + try { + val ssid = "ssid_test" + val authMode = ThetaRepository.AuthModeEnum.NONE + + thetaRepository.setAccessPointDynamically( + ssid = ssid, + authMode = authMode + ) + assertTrue(false, "response is normal.") + } catch (e: ThetaRepository.ThetaWebApiException) { + assertTrue(e.message!!.contains("does not allow authMode to be set to none."), "authMode exception") + } + } + + @Test + fun setAccessPointStaticallyAuthModeExceptionTest() = runTest { + MockApiClient.onRequest = { _ -> + ByteReadChannel(Resource("src/commonTest/resources/listAccessPoints/list_access_points_empty_done.json").readText()) + } + + val thetaRepository = ThetaRepository(endpoint) + thetaRepository.cameraModel = ThetaRepository.ThetaModel.THETA_A1 + try { + val ssid = "ssid_test" + val authMode = ThetaRepository.AuthModeEnum.NONE + val ipAddress = "192.168.1.2" + val subnetMask = "255.255.255.0" + val defaultGateway = "192.168.1.3" + + thetaRepository.setAccessPointStatically( + ssid = ssid, + authMode = authMode, + ipAddress = ipAddress, + subnetMask = subnetMask, + defaultGateway = defaultGateway + ) + assertTrue(false, "response is normal.") + } catch (e: ThetaRepository.ThetaWebApiException) { + assertTrue(e.message!!.contains("does not allow authMode to be set to none."), "authMode exception") + } + } } diff --git a/react-native/android/build.gradle b/react-native/android/build.gradle index db81b0b49c..b799932b90 100644 --- a/react-native/android/build.gradle +++ b/react-native/android/build.gradle @@ -136,7 +136,7 @@ dependencies { implementation "com.facebook.react:react-native:+" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3" - implementation "com.ricoh360.thetaclient:theta-client:1.13.0" + implementation "com.ricoh360.thetaclient:theta-client:1.13.1" // From node_modules } diff --git a/react-native/android/src/main/java/com/ricoh360/thetaclientreactnative/Converter.kt b/react-native/android/src/main/java/com/ricoh360/thetaclientreactnative/Converter.kt index 15f66a202b..dbe709b88b 100644 --- a/react-native/android/src/main/java/com/ricoh360/thetaclientreactnative/Converter.kt +++ b/react-native/android/src/main/java/com/ricoh360/thetaclientreactnative/Converter.kt @@ -1450,7 +1450,7 @@ fun toSleepDelay(objects: ReadableMap): SleepDelay? { data class SetAccessPointParams( val ssid: String, val ssidStealth: Boolean?, - val authMode: AuthModeEnum, + val authMode: AuthModeEnum?, val password: String?, val connectionPriority: Int?, val dns1: String?, @@ -1466,7 +1466,6 @@ fun toSetAccessPointParams(objects: ReadableMap): SetAccessPointParams { null } val authMode = objects.getString(KEY_AUTH_MODE)?.let { AuthModeEnum.valueOf(it) } - ?: throw IllegalArgumentException(KEY_AUTH_MODE) val password = objects.getString(KEY_PASSWORD) val connectionPriority = if (objects.hasKey(KEY_CONNECTION_PRIORITY)) { objects.getInt(KEY_CONNECTION_PRIORITY) diff --git a/react-native/android/src/main/java/com/ricoh360/thetaclientreactnative/ThetaClientSdkModule.kt b/react-native/android/src/main/java/com/ricoh360/thetaclientreactnative/ThetaClientSdkModule.kt index 9281ce58b6..0674b627d2 100644 --- a/react-native/android/src/main/java/com/ricoh360/thetaclientreactnative/ThetaClientSdkModule.kt +++ b/react-native/android/src/main/java/com/ricoh360/thetaclientreactnative/ThetaClientSdkModule.kt @@ -1950,6 +1950,35 @@ class ThetaClientReactNativeModule( } } + /** + * setAccessPointConnectionPriority - Updates the connection priority of the access point. + * @param ssid ssid to set + * @param connectionPriority connectionPriority to set + * @param ssidStealth ssidStealth to set + * @param promise promise to set result + */ + @ReactMethod + fun setAccessPointConnectionPriority( + ssid: String, + connectionPriority: Int, + ssidStealth: Boolean, + promise: Promise + ) { + val theta = theta + if (theta == null) { + promise.reject(Exception(messageNotInit)) + return + } + launch { + try { + theta.setAccessPointConnectionPriority(ssid, connectionPriority, ssidStealth) + promise.resolve(true) + } catch (t: Throwable) { + promise.reject(t) + } + } + } + /** * deleteAccessPoint - delete access point related ssid * @param ssid ssid to delete diff --git a/react-native/ios/ConvertUtil.swift b/react-native/ios/ConvertUtil.swift index eda5f52f48..066575c4ee 100644 --- a/react-native/ios/ConvertUtil.swift +++ b/react-native/ios/ConvertUtil.swift @@ -1835,7 +1835,7 @@ func toTimeout(params: [String: Any]) -> ThetaRepository.Timeout? { struct SetAccessPointParams { let ssid: String let ssidStealth: KotlinBoolean? - let authMode: ThetaRepository.AuthModeEnum + let authMode: ThetaRepository.AuthModeEnum? let password: String? let connectionPriority: KotlinInt? let dns1: String? @@ -1848,16 +1848,7 @@ func toSetAccessPointParams(params: [String: Any?]) throws -> SetAccessPointPara throw ThetaClientError.invalidArgument(KEY_SSID) } let ssidStealth = toKotlinBoolean(value: params[KEY_SSID_STEALTH] as? Bool) - guard let authMode = params[KEY_AUTH_MODE] as? String else { - throw ThetaClientError.invalidArgument(KEY_AUTH_MODE) - } - guard - let authModeEnum = getEnumValue( - values: ThetaRepository.AuthModeEnum.values(), name: authMode - ) - else { - throw ThetaClientError.invalidArgument(KEY_AUTH_MODE) - } + let authModeEnum = getEnumValue(values: ThetaRepository.AuthModeEnum.values(), name: (params[KEY_AUTH_MODE] as? String) ?? "") let password = params[KEY_PASSWORD] as? String let connectionPriority = toKotlinInt(value: params[KEY_CONNECTION_PRIORITY] as? Int) let dns1 = params[KEY_DNS1] as? String diff --git a/react-native/ios/ThetaClientReactNative.m b/react-native/ios/ThetaClientReactNative.m index 813fb5f080..2809b65c28 100644 --- a/react-native/ios/ThetaClientReactNative.m +++ b/react-native/ios/ThetaClientReactNative.m @@ -235,6 +235,12 @@ @interface RCT_EXTERN_MODULE(ThetaClientReactNative, NSObject) withResolver:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject) +RCT_EXTERN_METHOD(setAccessPointConnectionPriority:(NSString *)ssid + connectionPriority: (int)connectionPriority + ssidStealth: (BOOL)ssidStealth + withResolver:(RCTPromiseResolveBlock)resolve + withRejecter:(RCTPromiseRejectBlock)reject) + RCT_EXTERN_METHOD(deleteAccessPoint:(NSString *)ssid withResolver:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject) diff --git a/react-native/ios/ThetaClientReactNative.swift b/react-native/ios/ThetaClientReactNative.swift index c0cbe672bc..11dfd86bf5 100644 --- a/react-native/ios/ThetaClientReactNative.swift +++ b/react-native/ios/ThetaClientReactNative.swift @@ -2216,6 +2216,37 @@ class ThetaClientReactNative: RCTEventEmitter { } } + @objc( + setAccessPointConnectionPriority: + connectionPriority: + ssidStealth: + withResolver: + withRejecter: + ) + func setAccessPointConnectionPriority( + ssid: String, + connectionPriority: Int, + ssidStealth: Bool, + resolve: @escaping RCTPromiseResolveBlock, + reject: @escaping RCTPromiseRejectBlock + ) { + guard let thetaRepository else { + reject(ERROR_CODE_ERROR, MESSAGE_NOT_INIT, nil) + return + } + do { + thetaRepository.setAccessPointConnectionPriority(ssid: ssid, connectionPriority: Int32(connectionPriority), ssidStealth: ssidStealth) { error in + if let error { + reject(ERROR_CODE_ERROR, error.localizedDescription, error) + } else { + resolve(true) + } + } + } catch { + reject(ERROR_CODE_ERROR, error.localizedDescription, error) + } + } + @objc(deleteAccessPoint:withResolver:withRejecter:) func deleteAccessPoint( ssid: String, diff --git a/react-native/package.json b/react-native/package.json index 38ba0c265d..7191f45350 100644 --- a/react-native/package.json +++ b/react-native/package.json @@ -1,6 +1,6 @@ { "name": "theta-client-react-native", - "version": "1.13.0", + "version": "1.13.1", "description": "This library provides a way to control RICOH THETA using.", "main": "lib/commonjs/index", "module": "lib/module/index", diff --git a/react-native/src/theta-repository/theta-repository.ts b/react-native/src/theta-repository/theta-repository.ts index 36dbe2c96c..12ea81050f 100644 --- a/react-native/src/theta-repository/theta-repository.ts +++ b/react-native/src/theta-repository/theta-repository.ts @@ -1,4 +1,4 @@ -import { AccessPoint, AuthModeEnum } from './access-point'; +import type { AccessPoint, AuthModeEnum } from './access-point'; import type { FileTypeEnum, StorageEnum, ThetaFiles } from './theta-files'; import type { ThetaState } from './theta-state'; import type { ThetaInfo, ThetaModel } from './theta-info'; @@ -533,13 +533,8 @@ export function setAccessPointDynamically( proxy?: Proxy; } ): Promise { - const { - ssidStealth, - authMode = AuthModeEnum.NONE, - password, - connectionPriority, - proxy, - } = params ?? {}; + const { ssidStealth, authMode, password, connectionPriority, proxy } = + params ?? {}; return ThetaClientReactNative.setAccessPointDynamically({ ssid, ssidStealth, @@ -575,7 +570,7 @@ export function setAccessPointStatically( defaultGateway: string, params?: { ssidStealth?: boolean; - authMode: AuthModeEnum; + authMode?: AuthModeEnum; password?: string; connectionPriority?: number; dns1?: string; @@ -585,7 +580,7 @@ export function setAccessPointStatically( ): Promise { const { ssidStealth, - authMode = AuthModeEnum.NONE, + authMode, password, connectionPriority, dns1, @@ -607,6 +602,27 @@ export function setAccessPointStatically( }); } +/** + * Updates the connection priority of the access point. + * + * @function setAccessPointConnectionPriority + * @param {string} ssid SSID of the access point. + * @param {number} connectionPriority Connection priority 1 to 5. + * @param {boolean} ssidStealth True if SSID stealth is enabled. + * @return promise of boolean result + */ +export function setAccessPointConnectionPriority( + ssid: string, + connectionPriority: number, + ssidStealth: boolean +): Promise { + return ThetaClientReactNative.setAccessPointConnectionPriority( + ssid, + connectionPriority, + ssidStealth + ); +} + /** * Deletes access point information used in client mode. * diff --git a/react-native/theta-client-react-native.podspec b/react-native/theta-client-react-native.podspec index 76cfa4fe1c..1731e45287 100644 --- a/react-native/theta-client-react-native.podspec +++ b/react-native/theta-client-react-native.podspec @@ -17,7 +17,7 @@ Pod::Spec.new do |s| s.source_files = "ios/**/*.{h,m,mm,swift}" s.dependency "React-Core" - s.dependency "THETAClient", "1.13.0" + s.dependency "THETAClient", "1.13.1" # Don't install the dependencies when we run `pod install` in the old architecture. if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then