From 4583772737cf84c2f207a4248af84d0494e64149 Mon Sep 17 00:00:00 2001 From: yunhanw-google Date: Wed, 26 Oct 2022 17:05:00 -0700 Subject: [PATCH] Decouple NetworkCredentialParcelable from ChipDeviceController (#23327) --- .../google/chip/chiptool/CHIPToolActivity.kt | 4 +- .../NetworkCredentialsParcelable.java | 170 ++++++++++++++++++ .../DeviceProvisioningFragment.kt | 26 ++- .../provisioning/EnterNetworkFragment.kt | 10 +- .../CHIPTool/chip-library/build.gradle | 3 +- .../devicecontroller/NetworkCredentials.java | 105 +++-------- 6 files changed, 220 insertions(+), 98 deletions(-) create mode 100644 examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/NetworkCredentialsParcelable.java diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/CHIPToolActivity.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/CHIPToolActivity.kt index 7f96d1ad292b89..ce37951915e283 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/CHIPToolActivity.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/CHIPToolActivity.kt @@ -28,7 +28,7 @@ import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment -import chip.devicecontroller.NetworkCredentials +import com.google.chip.chiptool.NetworkCredentialsParcelable import chip.setuppayload.SetupPayload import chip.setuppayload.SetupPayloadParser import chip.setuppayload.SetupPayloadParser.UnrecognizedQrCodeException @@ -133,7 +133,7 @@ class CHIPToolActivity : showFragment(AddressCommissioningFragment.newInstance(), false) } - override fun onNetworkCredentialsEntered(networkCredentials: NetworkCredentials) { + override fun onNetworkCredentialsEntered(networkCredentials: NetworkCredentialsParcelable) { showFragment(DeviceProvisioningFragment.newInstance(deviceInfo!!, networkCredentials)) } diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/NetworkCredentialsParcelable.java b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/NetworkCredentialsParcelable.java new file mode 100644 index 00000000000000..2194155f4f660b --- /dev/null +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/NetworkCredentialsParcelable.java @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2020-2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.google.chip.chiptool; + +import android.os.Parcel; +import android.os.Parcelable; +import androidx.annotation.Nullable; + +/** Class for holding WiFi or Thread credentials, but not both. */ +public class NetworkCredentialsParcelable implements Parcelable { + @Nullable private WiFiCredentials wifiCredentials; + @Nullable private ThreadCredentials threadCredentials; + + private NetworkCredentialsParcelable( + @Nullable WiFiCredentials wifiCredentials, @Nullable ThreadCredentials threadCredentials) { + this.wifiCredentials = wifiCredentials; + this.threadCredentials = threadCredentials; + } + + /** + * Return a NetworkCredentialsParcelable object with the given WiFiCredentials and null + * ThreadCredentials. + */ + public static NetworkCredentialsParcelable forWiFi(WiFiCredentials wifiCredentials) { + return new NetworkCredentialsParcelable(wifiCredentials, null); + } + + /** + * Return a NetworkCredentialsParcelable object with the given ThreadCredentials and null + * WiFiCredentials. + */ + public static NetworkCredentialsParcelable forThread(ThreadCredentials threadCredentials) { + return new NetworkCredentialsParcelable(null, threadCredentials); + } + + public WiFiCredentials getWiFiCredentials() { + return wifiCredentials; + } + + public ThreadCredentials getThreadCredentials() { + return threadCredentials; + } + + // Begin Parcelable implementation + + private NetworkCredentialsParcelable(Parcel in) { + wifiCredentials = in.readParcelable(WiFiCredentials.class.getClassLoader()); + threadCredentials = in.readParcelable(ThreadCredentials.class.getClassLoader()); + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel out, int flags) { + out.writeParcelable(wifiCredentials, 0); + out.writeParcelable(threadCredentials, 0); + } + + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + public NetworkCredentialsParcelable createFromParcel(Parcel in) { + return new NetworkCredentialsParcelable(in); + } + + public NetworkCredentialsParcelable[] newArray(int size) { + return new NetworkCredentialsParcelable[size]; + } + }; + + public static class WiFiCredentials implements Parcelable { + private final String ssid; + private final String password; + + public WiFiCredentials(String ssid, String password) { + this.ssid = ssid; + this.password = password; + } + + public String getSsid() { + return ssid; + } + + public String getPassword() { + return password; + } + + // Begin Parcelable implementation + + private WiFiCredentials(Parcel in) { + ssid = in.readString(); + password = in.readString(); + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel out, int flags) { + out.writeString(ssid); + out.writeString(password); + } + + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + public WiFiCredentials createFromParcel(Parcel in) { + return new WiFiCredentials(in); + } + + public WiFiCredentials[] newArray(int size) { + return new WiFiCredentials[size]; + } + }; + } + + public static class ThreadCredentials implements Parcelable { + private final byte[] operationalDataset; + + public ThreadCredentials(byte[] operationalDataset) { + this.operationalDataset = operationalDataset; + } + + public byte[] getOperationalDataset() { + return operationalDataset; + } + + // Begin Parcelable implementation + + private ThreadCredentials(Parcel in) { + operationalDataset = new byte[in.readInt()]; + in.readByteArray(operationalDataset); + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel out, int flags) { + out.writeInt(operationalDataset.length); + out.writeByteArray(operationalDataset); + } + + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + public ThreadCredentials createFromParcel(Parcel in) { + return new ThreadCredentials(in); + } + + public ThreadCredentials[] newArray(int size) { + return new ThreadCredentials[size]; + } + }; + } +} diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt index f97647ce4ab18a..f816fabce45ead 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt @@ -28,6 +28,7 @@ import android.widget.Toast import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import chip.devicecontroller.NetworkCredentials +import com.google.chip.chiptool.NetworkCredentialsParcelable import com.google.chip.chiptool.ChipClient import com.google.chip.chiptool.GenericChipDeviceListener import com.google.chip.chiptool.R @@ -46,7 +47,7 @@ class DeviceProvisioningFragment : Fragment() { private var gatt: BluetoothGatt? = null - private val networkCredentials: NetworkCredentials? + private val networkCredentialsParcelable: NetworkCredentialsParcelable? get() = arguments?.getParcelable(ARG_NETWORK_CREDENTIALS) private lateinit var scope: CoroutineScope @@ -120,7 +121,22 @@ class DeviceProvisioningFragment : Fragment() { val deviceId = DeviceIdUtil.getNextAvailableId(requireContext()) val connId = bluetoothManager.connectionId - deviceController.pairDevice(gatt, connId, deviceId, deviceInfo.setupPinCode, networkCredentials) + val network = NetworkCredentials() + var networkParcelable = checkNotNull(networkCredentialsParcelable) + + val wifi = networkParcelable.getWiFiCredentials() + if (wifi != null) + { + network.setWiFiCredentials(wifi.getSsid(), wifi.getPassword()) + } + + val thread = networkParcelable.getThreadCredentials() + if (thread != null) + { + network.setThreadCredentials(thread.getOperationalDataset()) + } + + deviceController.pairDevice(gatt, connId, deviceId, deviceInfo.setupPinCode, network) DeviceIdUtil.setNextAvailableId(requireContext(), deviceId + 1) } } @@ -191,17 +207,17 @@ class DeviceProvisioningFragment : Fragment() { private const val STATUS_PAIRING_SUCCESS = 0 /** - * Return a new instance of [DeviceProvisioningFragment]. [networkCredentials] can be null for + * Return a new instance of [DeviceProvisioningFragment]. [networkCredentialsParcelable] can be null for * IP commissioning. */ fun newInstance( deviceInfo: CHIPDeviceInfo, - networkCredentials: NetworkCredentials?, + networkCredentialsParcelable: NetworkCredentialsParcelable?, ): DeviceProvisioningFragment { return DeviceProvisioningFragment().apply { arguments = Bundle(2).apply { putParcelable(ARG_DEVICE_INFO, deviceInfo) - putParcelable(ARG_NETWORK_CREDENTIALS, networkCredentials) + putParcelable(ARG_NETWORK_CREDENTIALS, networkCredentialsParcelable) } } } diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/EnterNetworkFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/EnterNetworkFragment.kt index 9153b02c7fa266..5f0d024ee694a4 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/EnterNetworkFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/EnterNetworkFragment.kt @@ -23,9 +23,9 @@ import android.view.View import android.view.ViewGroup import android.widget.Toast import androidx.fragment.app.Fragment -import chip.devicecontroller.NetworkCredentials import com.google.chip.chiptool.R import com.google.chip.chiptool.util.FragmentUtil +import com.google.chip.chiptool.NetworkCredentialsParcelable import kotlinx.android.synthetic.main.enter_thread_network_fragment.channelEd import kotlinx.android.synthetic.main.enter_thread_network_fragment.masterKeyEd import kotlinx.android.synthetic.main.enter_thread_network_fragment.panIdEd @@ -44,7 +44,7 @@ class EnterNetworkFragment : Fragment() { ) interface Callback { - fun onNetworkCredentialsEntered(networkCredentials: NetworkCredentials) + fun onNetworkCredentialsEntered(networkCredentials: NetworkCredentialsParcelable) } override fun onCreateView( @@ -79,8 +79,8 @@ class EnterNetworkFragment : Fragment() { return } - val networkCredentials = NetworkCredentials.forWiFi( - NetworkCredentials.WiFiCredentials(ssid.toString(), pwd.toString()) + val networkCredentials = NetworkCredentialsParcelable.forWiFi( + NetworkCredentialsParcelable.WiFiCredentials(ssid.toString(), pwd.toString()) ) FragmentUtil.getHost(this, Callback::class.java) ?.onNetworkCredentialsEntered(networkCredentials) @@ -130,7 +130,7 @@ class EnterNetworkFragment : Fragment() { ) val networkCredentials = - NetworkCredentials.forThread(NetworkCredentials.ThreadCredentials(operationalDataset)) + NetworkCredentialsParcelable.forThread(NetworkCredentialsParcelable.ThreadCredentials(operationalDataset)) FragmentUtil.getHost(this, Callback::class.java) ?.onNetworkCredentialsEntered(networkCredentials) } diff --git a/examples/android/CHIPTool/chip-library/build.gradle b/examples/android/CHIPTool/chip-library/build.gradle index b6679efc9da1b4..429577ee6060aa 100644 --- a/examples/android/CHIPTool/chip-library/build.gradle +++ b/examples/android/CHIPTool/chip-library/build.gradle @@ -33,7 +33,8 @@ android { '../../../setup_payload/java/src', '../../../controller/java/zap-generated', '../../../controller/java/src', - '../../../platform/android/java' + '../../../platform/android/java', + '../app/src/main/java/com/google/chip/chiptool' ] } } diff --git a/src/controller/java/src/chip/devicecontroller/NetworkCredentials.java b/src/controller/java/src/chip/devicecontroller/NetworkCredentials.java index e2ec432bf06acb..adb98170677ce5 100644 --- a/src/controller/java/src/chip/devicecontroller/NetworkCredentials.java +++ b/src/controller/java/src/chip/devicecontroller/NetworkCredentials.java @@ -17,15 +17,15 @@ */ package chip.devicecontroller; -import android.os.Parcel; -import android.os.Parcelable; import javax.annotation.Nullable; /** Class for holding WiFi or Thread credentials, but not both. */ -public class NetworkCredentials implements Parcelable { +public class NetworkCredentials { @Nullable private WiFiCredentials wifiCredentials; @Nullable private ThreadCredentials threadCredentials; + public NetworkCredentials() {} + private NetworkCredentials( @Nullable WiFiCredentials wifiCredentials, @Nullable ThreadCredentials threadCredentials) { this.wifiCredentials = wifiCredentials; @@ -54,38 +54,23 @@ public ThreadCredentials getThreadCredentials() { return threadCredentials; } - // Begin Parcelable implementation - - private NetworkCredentials(Parcel in) { - wifiCredentials = in.readParcelable(WiFiCredentials.class.getClassLoader()); - threadCredentials = in.readParcelable(ThreadCredentials.class.getClassLoader()); - } - - public int describeContents() { - return 0; + public void setWiFiCredentials(String ssid, String password) { + wifiCredentials.set(ssid, password); } - public void writeToParcel(Parcel out, int flags) { - out.writeParcelable(wifiCredentials, 0); - out.writeParcelable(threadCredentials, 0); + public void setThreadCredentials(byte[] operationalDataset) { + threadCredentials.set(operationalDataset); } - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - public NetworkCredentials createFromParcel(Parcel in) { - return new NetworkCredentials(in); - } - - public NetworkCredentials[] newArray(int size) { - return new NetworkCredentials[size]; - } - }; - - public static class WiFiCredentials implements Parcelable { - private final String ssid; - private final String password; + public static class WiFiCredentials { + private String ssid; + private String password; public WiFiCredentials(String ssid, String password) { + set(ssid, password); + } + + public void set(String ssid, String password) { this.ssid = ssid; this.password = password; } @@ -97,71 +82,21 @@ public String getSsid() { public String getPassword() { return password; } - - // Begin Parcelable implementation - - private WiFiCredentials(Parcel in) { - ssid = in.readString(); - password = in.readString(); - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel out, int flags) { - out.writeString(ssid); - out.writeString(password); - } - - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - public WiFiCredentials createFromParcel(Parcel in) { - return new WiFiCredentials(in); - } - - public WiFiCredentials[] newArray(int size) { - return new WiFiCredentials[size]; - } - }; } - public static class ThreadCredentials implements Parcelable { - private final byte[] operationalDataset; + public static class ThreadCredentials { + private byte[] operationalDataset; public ThreadCredentials(byte[] operationalDataset) { + set(operationalDataset); + } + + public void set(byte[] operationalDataset) { this.operationalDataset = operationalDataset; } public byte[] getOperationalDataset() { return operationalDataset; } - - // Begin Parcelable implementation - - private ThreadCredentials(Parcel in) { - operationalDataset = new byte[in.readInt()]; - in.readByteArray(operationalDataset); - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel out, int flags) { - out.writeInt(operationalDataset.length); - out.writeByteArray(operationalDataset); - } - - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - public ThreadCredentials createFromParcel(Parcel in) { - return new ThreadCredentials(in); - } - - public ThreadCredentials[] newArray(int size) { - return new ThreadCredentials[size]; - } - }; } }