Skip to content

Commit

Permalink
[android] Add Soft-AP scanning using Android Wi-Fi Manager APIs. (#19787
Browse files Browse the repository at this point in the history
)

* After Wi-Fi AP list has been populated in the spinner
  * The user can select one from the spinner and connect to it.
  * Support OPEN authentication, no key management, and no encryption.

* After connected to the selected Wi-Fi AP
  * The user can then 'DISCOVER' the services around.

* After an IP address and its discriminator has been received
  * The user can 'COMMISSION' the device.
  • Loading branch information
pakls authored and pull[bot] committed Dec 5, 2023
1 parent cd1250c commit 1035776
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/android/CHIPTool/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.NFC" />

<application
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package com.google.chip.chiptool.provisioning

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.wifi.WifiManager
import android.net.wifi.ScanResult
import android.net.wifi.WifiConfiguration
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
Expand All @@ -19,6 +26,9 @@ import kotlinx.android.synthetic.main.address_commissioning_fragment.discoverBtn
import kotlinx.android.synthetic.main.address_commissioning_fragment.discoverListSpinner
import kotlinx.android.synthetic.main.address_commissioning_fragment.discriminatorEditText
import kotlinx.android.synthetic.main.address_commissioning_fragment.pincodeEditText
import kotlinx.android.synthetic.main.address_commissioning_fragment.wifiConnectBtn
import kotlinx.android.synthetic.main.address_commissioning_fragment.wifiScanBtn
import kotlinx.android.synthetic.main.address_commissioning_fragment.wifiScanListSpinner
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
Expand All @@ -27,6 +37,8 @@ import kotlinx.coroutines.launch

class AddressCommissioningFragment : Fragment() {
private val ipAddressList = ArrayList<String>()
private val wifiApList = ArrayList<String>()
private var wifiApSsid = String()
private val scope = CoroutineScope(Dispatchers.Main + Job())

override fun onCreateView(
Expand Down Expand Up @@ -69,6 +81,84 @@ class AddressCommissioningFragment : Fragment() {
discoverBtn.isEnabled = true
}
}

wifiConnectBtn.setOnClickListener { _ ->
wifiConnectBtn.isEnabled = false
val context = getActivity()
val wifiManager = context?.getSystemService(Context.WIFI_SERVICE) as WifiManager

// TODO : filter SSID with Information Element, OPEN authentication
var config : WifiConfiguration = WifiConfiguration();
config.SSID = "\"${wifiApSsid}\""
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)

Log.d(TAG, "Disconnect existing connection")
wifiManager.disconnect()
Log.d(TAG, "Add network ${config.SSID}")
var res = wifiManager.addNetwork(config)
if (res == -1) {
Log.d(TAG,"Add network failed")
} else {
var success = wifiManager.enableNetwork(res, true)
if (success) {
Log.d(TAG, "Enable network ${config.SSID} succeeded")
} else {
Log.d(TAG, "Enable network ${config.SSID} failed")
wifiConnectBtn.isEnabled = true
}
}
}

wifiScanBtn.setOnClickListener { _ ->
wifiScanBtn.isEnabled = false
val context = getActivity()
val wifiManager = context?.getSystemService(Context.WIFI_SERVICE) as WifiManager
val wifiScanReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d(TAG, "Scan result event received")
val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)
if (success) {
Log.d(TAG, "Scan succeeded")
val results = wifiManager.scanResults
updateWifiScanListSpinner(results)
} else {
Log.d(TAG, "Scan failed")
}
wifiScanBtn.isEnabled = true
}
}

val intentFilter = IntentFilter()
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)

context.registerReceiver(wifiScanReceiver, intentFilter)
val success = wifiManager.startScan()
if (!success) {
Log.d(TAG, "Scan not started")
// TODO: scan failure handling
} else {
Log.d(TAG, "Scan started")
}
}
}

private fun updateWifiScanListSpinner(scanResults : MutableList<ScanResult>) {
wifiApList.clear()
for (result in scanResults) {
if (result.SSID.toString().isNotEmpty())
wifiApList.add("${result.SSID}, ${result.BSSID}, ${result.level}")
}
requireActivity().runOnUiThread {
wifiScanListSpinner.adapter =
ArrayAdapter(requireContext(), android.R.layout.simple_spinner_dropdown_item, wifiApList)
wifiScanListSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
wifiApSsid = wifiApList[position].split(",")[0].trim()
Log.d(TAG, "ready to connect to $wifiApSsid")
}
override fun onNothingSelected(parent: AdapterView<*>) {}
}
}
}

private fun updateSpinner() {
Expand Down Expand Up @@ -98,4 +188,4 @@ class AddressCommissioningFragment : Fragment() {

fun newInstance(): AddressCommissioningFragment = AddressCommissioningFragment()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,24 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/address_commissioning_fragment_flow">

<Button
android:id="@+id/wifiScanBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/wifi_scan_btn_text"/>

<Spinner
android:id="@+id/wifiScanListSpinner"
android:padding="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<Button
android:id="@+id/wifiConnectBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/wifi_connect_btn_text"/>

<Button
android:id="@+id/discoverBtn"
android:layout_width="wrap_content"
Expand All @@ -108,4 +126,4 @@
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
2 changes: 2 additions & 0 deletions src/android/CHIPTool/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<string name="enter_pincode_label_text">Pincode</string>
<string name="commission_btn_text">Commission</string>
<string name="dns_discover_btn_text">Discover</string>
<string name="wifi_scan_btn_text">Wi-Fi Scan</string>

<string name="send_command_on_btn_text">On</string>
<string name="send_command_off_btn_text">Off</string>
Expand Down Expand Up @@ -163,4 +164,5 @@
<string name="select_a_command">Select a command</string>
<string name="select_a_cluster">Select a cluster</string>
<string name="endpoint_name">Endpoint: </string>
<string name="wifi_connect_btn_text">Connect</string>
</resources>

0 comments on commit 1035776

Please sign in to comment.