optimised to retry usb

This commit is contained in:
sathwikcs
2024-12-31 11:43:51 +05:30
parent 0886f000bf
commit 36dc7e68a2
6 changed files with 236 additions and 67 deletions

View File

@@ -68,6 +68,7 @@
<activity <activity
android:name="com.example.hpostesting.presentation.usb_teminal.UsbTerminalActivity" android:name="com.example.hpostesting.presentation.usb_teminal.UsbTerminalActivity"
android:exported="false" android:exported="false"
android:launchMode="singleInstance"
android:screenOrientation="portrait" /> android:screenOrientation="portrait" />
<activity <activity
android:name="com.example.hpostesting.presentation.deviceinfo.DeviceActivity" android:name="com.example.hpostesting.presentation.deviceinfo.DeviceActivity"
@@ -198,6 +199,7 @@
android:exported="true" android:exported="true"
android:permission="" android:permission=""
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:launchMode="singleInstance"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
<intent-filter> <intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />

View File

@@ -73,8 +73,15 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
sharedPreference = getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
sharedPreference = getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
val action = intent?.action
if (action == UsbManager.ACTION_USB_DEVICE_ATTACHED || action == UsbManager.ACTION_USB_DEVICE_DETACHED) {
// If the activity is triggered by USB events, simply finish it
checkAndUpdateUsbConnection()
finish()
return
}
binding = ActivityMainBinding.inflate(layoutInflater) binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
binding.myToolbar.title = "Test Type" binding.myToolbar.title = "Test Type"
@@ -150,7 +157,7 @@ class MainActivity : AppCompatActivity() {
} }
(device.productId == 24577 && device.vendorId == 1027) || (device.productId == 8963 && device.vendorId == 1659) || (device.productId == 4614 && device.vendorId == 7111) -> { (device.productId == 24577 && device.vendorId == 1027) || (device.productId == 8963 && device.vendorId == 1659) || (device.productId == 4614 && device.vendorId == 7111) -> {
changeUI() // changeUI()
DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_TRUEHEME) DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_TRUEHEME)
Constants.DEVICE_TYPE_TRUEHEME Constants.DEVICE_TYPE_TRUEHEME
} }

View File

@@ -108,10 +108,13 @@ class UsbTerminalActivity : AppCompatActivity() {
setContentView(binding.root) setContentView(binding.root)
// setSupportActionBar(binding.myToolbar) // setSupportActionBar(binding.myToolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
doBoth()
}
fun doBoth(){
setupListener() setupListener()
connectUsb(false) connectUsb(false)
} }
private fun setupListener() { private fun setupListener() {
DataHolder.usbConnected.observe(this) { DataHolder.usbConnected.observe(this) {
Log.d("USB OBSERVE", "HemoCube called -> $it") Log.d("USB OBSERVE", "HemoCube called -> $it")
@@ -156,6 +159,9 @@ class UsbTerminalActivity : AppCompatActivity() {
.commit() .commit()
} }
@SuppressLint("MutableImplicitPendingIntent") @SuppressLint("MutableImplicitPendingIntent")
private fun requestUserPermission(manager: UsbManager, device: UsbDevice) { private fun requestUserPermission(manager: UsbManager, device: UsbDevice) {
val mPendingIntent: PendingIntent val mPendingIntent: PendingIntent

View File

@@ -16,14 +16,20 @@ package com.example.hpostesting.presentation.usb_teminal
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.text.InputType
import android.text.method.ScrollingMovementMethod import android.text.method.ScrollingMovementMethod
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.presentation.utils.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
@@ -36,49 +42,178 @@ class UsbTerminalFragment : Fragment() {
private lateinit var sharedPreferences: SharedPreferences private lateinit var sharedPreferences: SharedPreferences
private var startListening = MutableLiveData(false) private var startListening = MutableLiveData(false)
private var resultData: String = "" private var resultData: String = ""
private var fullCommand: String = ""
private var currentCommandIndex = 0
private var isCommandInProgress = false
private val commandHistory = StringBuilder()
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View { ): View {
binding = FragmentUsbTerminalBinding.inflate(inflater, container, false) binding = FragmentUsbTerminalBinding.inflate(inflater, container, false)
sharedPreferences = sharedPreferences = requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
return binding.root return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
initViews() initViews()
observeUsbConnection()
} }
private fun observeUsbConnection() {
DataHolder.usbConnected.observe(viewLifecycleOwner) { isConnected ->
if (isConnected) {
commandHistory.append("\n[Device Connected]")
listenToHemoCube()
if (isCommandInProgress && currentCommandIndex < fullCommand.length) {
(activity as UsbTerminalActivity).doBoth()
commandHistory.append("\n>> Continuing command: $fullCommand from position $currentCommandIndex")
updateMessageDisplay()
continueCommand()
}
} else {
commandHistory.append("\n[Device Disconnected]")
updateMessageDisplay()
isCommandInProgress = false
}
}
}
override fun onResume() {
super.onResume()
if (DataHolder.usbConnected.value == true) {
listenToHemoCube()
} else {
commandHistory.append("\n[Waiting for Device Connection]")
updateMessageDisplay()
}
(activity as UsbTerminalActivity).connectUsb(false)
}
override fun onPause() {
super.onPause()
isCommandInProgress = false
currentCommandIndex = 0
fullCommand = ""
(activity as UsbTerminalActivity).connectUsb(false)
}
private fun initViews() { private fun initViews() {
binding.messageCommand.movementMethod = ScrollingMovementMethod() with(binding) {
usbTerminalViewModel.messages.observe(viewLifecycleOwner) { messageCommand.movementMethod = ScrollingMovementMethod()
binding.messageCommand.text = it
} etCommands.apply {
binding.sendCommand.setOnClickListener { imeOptions = EditorInfo.IME_ACTION_DONE
callCommand(binding.etCommands.text.trim().toString()) setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
text?.toString()?.trim()?.let { command ->
if (command.isNotEmpty()) {
callCommand(command)
text?.clear()
}
}
true
} else false
}
}
sendCommand.setOnClickListener {
etCommands.text?.toString()?.trim()?.let { command ->
if (command.isNotEmpty()) {
callCommand(command)
etCommands.text?.clear()
}
}
}
} }
commandHistory.clear()
commandHistory.append("[Session Started]")
updateMessageDisplay()
listenToHemoCube() listenToHemoCube()
callCommand("I") callCommand("I")
} }
private fun callCommand(command: String) { private fun callCommand(command: String) {
commandHistory.append("\n>> $command")
updateMessageDisplay()
fullCommand = command
currentCommandIndex = 0
isCommandInProgress = true
usbTerminalViewModel.progressBar.postValue(true) usbTerminalViewModel.progressBar.postValue(true)
continueCommand()
}
private fun continueCommand() {
if (currentCommandIndex >= fullCommand.length) {
// Command execution completed
isCommandInProgress = false
usbTerminalViewModel.progressBar.postValue(false)
return
}
val currentChar = fullCommand[currentCommandIndex].toString()
commandHistory.append("\nExecuting command: $currentChar")
updateMessageDisplay()
// Send the command and wait for the full response sequence
(activity as UsbTerminalActivity).mService.sendAndListenToHemoCubeTxt( (activity as UsbTerminalActivity).mService.sendAndListenToHemoCubeTxt(
command, currentChar,
object : UsbServiceListener { object : UsbServiceListener {
private var responseStage = 0 // 0 for BS, 1 for BC
override fun onUsbRead(data: ByteArray?) { override fun onUsbRead(data: ByteArray?) {
//nothing data?.let {
val response = String(it).trim()
commandHistory.append("\nReceived response: $response")
updateMessageDisplay()
// Check response sequence
when (responseStage) {
0 -> if (response == "BS") {
responseStage = 1 // Wait for BC
} else {
handleWriteError()
}
1 -> if (response == "BC") {
responseStage = 0 // Response complete for current command
currentCommandIndex++ // Move to the next character
continueCommand() // Start next command
} else {
handleWriteError()
}
}
}
} }
override fun onUsbError(e: Exception?) { override fun onUsbError(e: Exception?) {
usbTerminalViewModel.progressBar.postValue(false) Log.e("USB", "Error: ${e?.message}")
(activity as UsbTerminalActivity).doBoth()
Toast.makeText(context, "USB Write Error: ${e?.localizedMessage}", Toast.LENGTH_SHORT).show()
} }
})
private fun handleWriteError() {
activity?.runOnUiThread {
Toast.makeText(context, "Reconnecting USB...", Toast.LENGTH_SHORT).show()
}
(activity as UsbTerminalActivity).doBoth()
// Optionally reset commands
isCommandInProgress = false
currentCommandIndex = 0
fullCommand = ""
}
}
)
} }
private fun listenToHemoCube() {
private fun listenToHemoCube() {
val fullReadOutput = StringBuilder() val fullReadOutput = StringBuilder()
startListening.postValue(true) startListening.postValue(true)
@@ -89,18 +224,51 @@ class UsbTerminalFragment : Fragment() {
val stringData = String(it) val stringData = String(it)
fullReadOutput.append(stringData) fullReadOutput.append(stringData)
resultData += stringData resultData += stringData
usbTerminalViewModel.messages.postValue(resultData) updateMessageDisplay()
} }
} }
override fun onUsbError(e: Exception?) { override fun onUsbError(e: Exception?) {
usbTerminalViewModel.messages.postValue(e!!.localizedMessage) val errorMessage = e!!.localizedMessage
commandHistory.append("\nError: $errorMessage")
updateMessageDisplay()
usbTerminalViewModel.progressBar.postValue(false) usbTerminalViewModel.progressBar.postValue(false)
activity?.runOnUiThread {
Toast.makeText(context, "USB Error: ${e.message}", Toast.LENGTH_SHORT).show()
}
} }
}) })
} catch (e: Exception) { } catch (e: Exception) {
usbTerminalViewModel.messages.postValue(e.localizedMessage) commandHistory.append("\nError: ${e.localizedMessage}")
updateMessageDisplay()
usbTerminalViewModel.progressBar.postValue(false)
Firebase.crashlytics.recordException(e) Firebase.crashlytics.recordException(e)
} }
} }
}
private fun updateMessageDisplay() {
val fullDisplay = commandHistory.toString() + "\n" + resultData
binding.messageCommand.text = fullDisplay
binding.messageCommand.post {
val scrollAmount = binding.messageCommand.layout.getLineTop(binding.messageCommand.lineCount) - binding.messageCommand.height
if (scrollAmount > 0) {
binding.messageCommand.scrollTo(0, scrollAmount)
}
}
}
private fun clearOutput() {
resultData = ""
commandHistory.clear()
commandHistory.append("[Output Cleared]")
updateMessageDisplay()
}
override fun onDestroyView() {
super.onDestroyView()
isCommandInProgress = false
currentCommandIndex = 0
fullCommand = ""
}
}

View File

@@ -11,59 +11,45 @@
~ // from ShanMukha Innovations Pvt. Ltd. ~ // from ShanMukha Innovations Pvt. Ltd.
--> -->
<RelativeLayout <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginStart="8dp" android:orientation="vertical"
android:layout_marginEnd="8dp" android:padding="16dp">
>
<TextView <TextView
android:id="@+id/message_command" android:id="@+id/messageCommand"
style="@style/title1_1"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="0dp"
android:layout_marginTop="10dp" android:layout_weight="1"
android:gravity="start|bottom" android:background="@android:color/darker_gray"
android:text="Start" android:padding="8dp"
android:scrollbars = "vertical" android:scrollbars="vertical"
android:layout_alignParentStart="true" android:textColor="@android:color/white" />
android:layout_alignParentEnd="true"
android:layout_above="@+id/ll_commands" <LinearLayout
android:visibility="visible"
android:textColor="@color/black"
android:textSize="18sp"
/>
<RelativeLayout
android:id="@+id/ll_commands"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:layout_marginTop="16dp"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:orientation="horizontal"> android:orientation="horizontal">
<EditText <EditText
android:id="@+id/et_commands" android:id="@+id/etCommands"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp" android:layout_weight="1"
android:hint="@string/commands" android:hint="Enter command"
android:layout_alignParentStart="true" android:inputType="text"
android:imeOptions="actionDone" android:maxLines="1"
android:textSize="18sp" android:minHeight="48dp" />
android:layout_marginBottom="10dp"
/>
<ImageView
android:id="@+id/send_command"
android:layout_width="32dp"
android:layout_height="26dp"
android:layout_alignParentEnd="true"
android:layout_centerInParent="true"
android:src="@drawable/ic_baseline_send_24"/>
</RelativeLayout>
<Button
android:id="@+id/sendCommand"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="Send" />
</RelativeLayout> </LinearLayout>
</LinearLayout>

View File

@@ -12,7 +12,7 @@
--> -->
<resources> <resources>
<string name="app_name">HPOS Testing</string> <string name="app_name">HPOS ALPHA Testing</string>
<string-array name="instrument"> <string-array name="instrument">
<item>TestRight</item> <item>TestRight</item>