blob: 38cc5d7fb5cec37144b5ed30c9b6a1ab248f7d19 [file] [log] [blame]
/*
* Copyright (c) 2020 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.Manifest
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import com.google.chip.chiptool.attestation.AttestationTestFragment
import com.google.chip.chiptool.clusterclient.*
import com.google.chip.chiptool.clusterclient.clusterinteraction.ClusterInteractionFragment
import com.google.chip.chiptool.databinding.SelectActionFragmentBinding
import com.google.chip.chiptool.provisioning.ProvisionNetworkType
import com.google.chip.chiptool.provisioning.UnpairDeviceFragment
import com.google.chip.chiptool.setuppayloadscanner.BarcodeFragment
import com.google.chip.chiptool.util.FragmentUtil
/** Fragment to select from various options to interact with a CHIP device. */
class SelectActionFragment : Fragment() {
private var _binding: SelectActionFragmentBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = SelectActionFragmentBinding.inflate(inflater, container, false)
binding.provisionWiFiCredentialsBtn.apply {
isEnabled = hasLocationPermission()
setOnClickListener { handleProvisionWiFiCredentialsClicked() }
}
binding.provisionThreadCredentialsBtn.apply {
isEnabled = hasLocationPermission()
setOnClickListener { handleProvisionThreadCredentialsClicked() }
}
binding.scanQrBtn.setOnClickListener { handleScanQrCodeClicked() }
binding.onOffClusterBtn.setOnClickListener { handleOnOffClicked() }
binding.sensorClustersBtn.setOnClickListener { handleSensorClicked() }
binding.multiAdminClusterBtn.setOnClickListener { handleMultiAdminClicked() }
binding.opCredClustersBtn.setOnClickListener { handleOpCredClicked() }
binding.basicClusterBtn.setOnClickListener { handleBasicClicked() }
binding.attestationTestBtn.setOnClickListener { handleAttestationTestClicked() }
binding.clusterInteractionBtn.setOnClickListener { handleClusterInteractionClicked() }
binding.provisionCustomFlowBtn.setOnClickListener{ handleProvisionCustomFlowClicked() }
binding.wildcardBtn.setOnClickListener { handleWildcardClicked() }
binding.unpairDeviceBtn.setOnClickListener{ handleUnpairDeviceClicked() }
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (savedInstanceState != null) return
if (hasLocationPermission()) return
val permissionRequest =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { grantResults
->
var granted = true
for (value in grantResults.values) {
if (!value) {
granted = false
}
}
if (granted) {
binding.provisionWiFiCredentialsBtn.isEnabled = true
binding.provisionThreadCredentialsBtn.isEnabled = true
} else {
binding.provisionWiFiCredentialsBtn.isEnabled = false
binding.provisionThreadCredentialsBtn.isEnabled = false
AlertDialog.Builder(requireContext())
.setTitle(R.string.location_permission_denied_title)
.setMessage(R.string.location_permission_denied_message)
.setPositiveButton(R.string.text_ok) { dialog, _ -> dialog.dismiss() }
.setCancelable(false)
.create()
.show()
}
}
val permissions: Array<String> =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
arrayOf(
Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_CONNECT,
Manifest.permission.ACCESS_FINE_LOCATION,
)
} else {
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION)
}
permissionRequest.launch(permissions)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
private fun hasLocationPermission(): Boolean {
val locationPermissionGranted =
ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
// Android 12 new permission
var bleScanPermissionGranted = true
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
bleScanPermissionGranted =
ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.BLUETOOTH_SCAN) ==
PackageManager.PERMISSION_GRANTED
}
return locationPermissionGranted && bleScanPermissionGranted
}
private fun getCallback() = FragmentUtil.getHost(this, Callback::class.java)
/** Interface for notifying the host. */
interface Callback {
/** Notifies listener of a click to manually input the CHIP device address. */
fun onShowDeviceAddressInput()
fun SetNetworkType(type: ProvisionNetworkType)
}
private fun showFragment(fragment: Fragment, showOnBack: Boolean = true) {
val fragmentTransaction = parentFragmentManager
.beginTransaction()
.replace(R.id.nav_host_fragment, fragment, fragment.javaClass.simpleName)
if (showOnBack) {
fragmentTransaction.addToBackStack(null)
}
fragmentTransaction.commit()
}
/**
* Notifies listener of Scan QR code button click.
*/
private fun handleScanQrCodeClicked() {
showFragment(BarcodeFragment.newInstance(), false)
}
/**
* Notifies listener of Light On/Off & Level Cluster button click.
*/
private fun handleOnOffClicked() {
showFragment(OnOffClientFragment.newInstance())
}
/**
* Notifies listener of Sensor Clusters button click.
*/
private fun handleSensorClicked() {
showFragment(SensorClientFragment.newInstance())
}
/**
* Notifies listener of Multi-admin Clusters button click.
*/
private fun handleMultiAdminClicked() {
showFragment(MultiAdminClientFragment.newInstance())
}
/**
* Notifies listener of Operational Credentials Clusters button click.
*/
private fun handleOpCredClicked() {
showFragment(OpCredClientFragment.newInstance())
}
/**
* Notifies listener of Basic Clusters button click.
*/
private fun handleBasicClicked() {
showFragment(BasicClientFragment.newInstance())
}
/**
* Notifies listener of attestation command button clicked.
*/
private fun handleAttestationTestClicked() {
showFragment(AttestationTestFragment.newInstance())
}
/**
* Notifies listener of cluster interaction button click.
*/
private fun handleClusterInteractionClicked() {
showFragment(ClusterInteractionFragment.newInstance())
}
/**
* Notifies listener of wildcard button click.
*/
private fun handleWildcardClicked() {
showFragment(WildcardFragment.newInstance())
}
/**
* Notifies listener of unpair button click.
*/
private fun handleUnpairDeviceClicked() {
showFragment(UnpairDeviceFragment.newInstance())
}
/**
* Notifies listener of provision-WiFi-credentials button click.
*/
private fun handleProvisionWiFiCredentialsClicked() {
getCallback()?.SetNetworkType(ProvisionNetworkType.WIFI)
showFragment(BarcodeFragment.newInstance(), false)
}
/**
* Notifies listener of provision-Thread-credentials button click.
*/
private fun handleProvisionThreadCredentialsClicked() {
getCallback()?.SetNetworkType(ProvisionNetworkType.THREAD)
showFragment(BarcodeFragment.newInstance(), false)
}
/**
* Notifies listener of provision-custom-flow button click.
*/
private fun handleProvisionCustomFlowClicked() {
showFragment(BarcodeFragment.newInstance(), false)
}
companion object {
@JvmStatic fun newInstance() = SelectActionFragment()
}
}