diff --git a/lib_service/src/main/java/no/nordicsemi/android/service/BleProfileService.kt b/lib_service/src/main/java/no/nordicsemi/android/service/BleProfileService.kt deleted file mode 100644 index 8098fa5c..00000000 --- a/lib_service/src/main/java/no/nordicsemi/android/service/BleProfileService.kt +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2015, Nordic Semiconductor - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package no.nordicsemi.android.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.widget.Toast -import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import no.nordicsemi.android.ble.BleManager -import no.nordicsemi.android.log.ILogSession -import no.nordicsemi.android.log.Logger -import no.nordicsemi.ui.scanner.DiscoveredBluetoothDevice - -@AndroidEntryPoint -abstract class BleProfileService : Service() { - - protected val scope = CloseableCoroutineScope(SupervisorJob() + Dispatchers.Main.immediate) - - protected abstract val manager: BleManager - - /** - * Returns a handler that is created in onCreate(). - * The handler may be used to postpone execution of some operations or to run them in UI thread. - */ - private var handler: Handler? = null - - private var activityIsChangingConfiguration = false - - /** - * Returns the log session that can be used to append log entries. The method returns `null` if the nRF Logger app was not installed. It is safe to use logger when - * [.onServiceStarted] has been called. - * - * @return the log session - */ - private var logSession: ILogSession? = null - private set - - override fun onCreate() { - super.onCreate() - handler = Handler() - } - - protected fun stopIfDisconnected(status: BleManagerStatus) { - if (status == BleManagerStatus.DISCONNECTED) { - scope.close() - stopSelf() - } - } - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - /** - * This method returns whether autoConnect option should be used. - * - * @return true to use autoConnect feature, false (default) otherwise. - */ - protected open fun shouldAutoConnect(): Boolean { - return false - } - - override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - super.onStartCommand(intent, flags, startId) - - val device = intent!!.getParcelableExtra(DEVICE_DATA)!!.device - - manager.connect(device) - .useAutoConnect(shouldAutoConnect()) - .retry(3, 100) - .enqueue() - - return START_REDELIVER_INTENT - } - - override fun onTaskRemoved(rootIntent: Intent) { - super.onTaskRemoved(rootIntent) - // This method is called when user removed the app from Recents. - // By default, the service will be killed and recreated immediately after that. - // However, all managed devices will be lost and devices will be disconnected. - stopSelf() - } - - override fun onDestroy() { - super.onDestroy() - - // shutdown the manager - manager.disconnect().enqueue() - Logger.i(logSession, "Service destroyed") - logSession = null - handler = null - } - - /** - * This method should return false if the service needs to do some asynchronous work after if has disconnected from the device. - * In that case the [.stopService] method must be called when done. - * - * @return true (default) to automatically stop the service when device is disconnected. False otherwise. - */ - protected fun stopWhenDisconnected(): Boolean { - return true - } - - private fun stopService() { - // user requested disconnection. We must stop the service - Logger.v(logSession, "Stopping service...") - stopSelf() - } - - /** - * Shows a message as a Toast notification. This method is thread safe, you can call it from any thread - * - * @param messageResId an resource id of the message to be shown - */ - protected fun showToast(messageResId: Int) { - handler?.post { - Toast.makeText(this@BleProfileService, messageResId, Toast.LENGTH_SHORT).show() - } - } - - /** - * Shows a message as a Toast notification. This method is thread safe, you can call it from any thread - * - * @param message a message to be shown - */ - protected fun showToast(message: String?) { - handler?.post { - Toast.makeText(this@BleProfileService, message, Toast.LENGTH_SHORT).show() - } - } - - /** - * Returns `true` if the device is connected to the sensor. - * - * @return `true` if device is connected to the sensor, `false` otherwise - */ - protected val isConnected: Boolean - get() = manager.isConnected -} diff --git a/lib_service/src/main/java/no/nordicsemi/android/service/ForegroundBleService.kt b/lib_service/src/main/java/no/nordicsemi/android/service/ForegroundBleService.kt deleted file mode 100644 index 437b1f42..00000000 --- a/lib_service/src/main/java/no/nordicsemi/android/service/ForegroundBleService.kt +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2015, Nordic Semiconductor - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package no.nordicsemi.android.service - -import android.app.Notification -import android.app.NotificationChannel -import android.app.NotificationManager -import android.app.PendingIntent -import android.content.Intent -import android.os.Build -import androidx.annotation.RequiresApi -import androidx.core.app.NotificationCompat -import androidx.core.content.ContextCompat - -private const val CHANNEL_ID = "FOREGROUND_BLE_SERVICE" - -abstract class ForegroundBleService : BleProfileService() { - - override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - val result = super.onStartCommand(intent, flags, startId) - startForegroundService() - return result - } - - override fun onDestroy() { - // when user has disconnected from the sensor, we have to cancel the notification that we've created some milliseconds before using unbindService - cancelNotification() - stopForegroundService() - super.onDestroy() - } - - /** - * Sets the service as a foreground service - */ - private fun startForegroundService() { - // when the activity closes we need to show the notification that user is connected to the peripheral sensor - // We start the service as a foreground service as Android 8.0 (Oreo) onwards kills any running background services - val notification = createNotification(R.string.csc_notification_connected_message, 0) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - startForeground(NOTIFICATION_ID, notification) - } else { - val nm = getSystemService(NOTIFICATION_SERVICE) as NotificationManager - nm.notify(NOTIFICATION_ID, notification) - } - } - - /** - * Stops the service as a foreground service - */ - private fun stopForegroundService() { - // when the activity rebinds to the service, remove the notification and stop the foreground service - // on devices running Android 8.0 (Oreo) or above - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - stopForeground(true) - } else { - cancelNotification() - } - } - - /** - * Creates the notification - * - * @param messageResId the message resource id. The message must have one String parameter,

- * f.e. `%s is connected` - * @param defaults - */ - private fun createNotification(messageResId: Int, defaults: Int): Notification { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - createNotificationChannel(CHANNEL_ID) - } - - val intent: Intent? = packageManager.getLaunchIntentForPackage(packageName) - val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE) - - return NotificationCompat.Builder(this, CHANNEL_ID) - .setContentTitle(getString(R.string.app_name)) - .setContentText(getString(messageResId, manager.bluetoothDevice?.name ?: "Device")) - .setSmallIcon(R.drawable.ic_notification_icon) - .setColor(ContextCompat.getColor(this, R.color.md_theme_primary)) - .setContentIntent(pendingIntent) - .build() - } - - @RequiresApi(Build.VERSION_CODES.O) - private fun createNotificationChannel(channelName: String) { - val channel = NotificationChannel( - channelName, - getString(R.string.channel_connected_devices_title), - NotificationManager.IMPORTANCE_LOW - ) - channel.description = getString(R.string.channel_connected_devices_description) - channel.setShowBadge(false) - channel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC - val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager - notificationManager.createNotificationChannel(channel) - } - - /** - * Cancels the existing notification. If there is no active notification this method does nothing - */ - private fun cancelNotification() { - val nm = getSystemService(NOTIFICATION_SERVICE) as NotificationManager - nm.cancel(NOTIFICATION_ID) - } - - companion object { - private const val NOTIFICATION_ID = 200 - } -} diff --git a/profile_dfu/build.gradle b/profile_dfu/build.gradle deleted file mode 100644 index 3ea76c0a..00000000 --- a/profile_dfu/build.gradle +++ /dev/null @@ -1,32 +0,0 @@ -apply from: rootProject.file("library.gradle") -apply plugin: 'kotlin-parcelize' - -dependencies { - implementation project(":lib_service") - implementation project(":lib_theme") - implementation project(":lib_utils") - - implementation libs.chart - - implementation libs.nordic.ble.common - implementation libs.nordic.theme - implementation libs.nordic.navigation - - implementation libs.nordic.log - implementation libs.nordic.dfu - implementation libs.nordic.ui.scanner - - implementation libs.bundles.compose - implementation libs.androidx.core - implementation libs.material - implementation libs.lifecycle.activity - implementation libs.lifecycle.service - implementation libs.compose.lifecycle - implementation libs.compose.activity - - testImplementation libs.test.junit - androidTestImplementation libs.android.test.junit - androidTestImplementation libs.android.test.espresso - androidTestImplementation libs.android.test.compose.ui - debugImplementation libs.android.test.compose.tooling -} diff --git a/profile_dfu/src/androidTest/java/no/nordicsemi/dfu/ExampleInstrumentedTest.kt b/profile_dfu/src/androidTest/java/no/nordicsemi/dfu/ExampleInstrumentedTest.kt deleted file mode 100644 index 1910519d..00000000 --- a/profile_dfu/src/androidTest/java/no/nordicsemi/dfu/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,22 +0,0 @@ -package no.nordicsemi.dfu - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("no.nordicsemi.dfu.test", appContext.packageName) - } -} \ No newline at end of file diff --git a/profile_dfu/src/main/AndroidManifest.xml b/profile_dfu/src/main/AndroidManifest.xml deleted file mode 100644 index ee941bfa..00000000 --- a/profile_dfu/src/main/AndroidManifest.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUData.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUData.kt deleted file mode 100644 index 085d7684..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUData.kt +++ /dev/null @@ -1,22 +0,0 @@ -package no.nordicsemi.dfu.data - -import no.nordicsemi.ui.scanner.DiscoveredBluetoothDevice - -internal sealed class DFUData - -internal data class NoFileSelectedState( - val isError: Boolean = false -) : DFUData() - -internal data class FileReadyState( - val file: ZipFile, - val device: DiscoveredBluetoothDevice -) : DFUData() - -internal data class FileInstallingState( - val status: DFUServiceStatus = Idle -) : DFUData() - -internal object UploadSuccessState : DFUData() - -internal data class UploadFailureState(val message: String?) : DFUData() diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUFile.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUFile.kt deleted file mode 100644 index b2c33005..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUFile.kt +++ /dev/null @@ -1,10 +0,0 @@ -package no.nordicsemi.dfu.data - -import android.net.Uri - -data class ZipFile( - val uri: Uri, - val name: String, - val path: String?, - val size: Long -) diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUFileManager.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUFileManager.kt deleted file mode 100644 index 7ad99841..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUFileManager.kt +++ /dev/null @@ -1,62 +0,0 @@ -package no.nordicsemi.dfu.data - -import android.content.Context -import android.net.Uri -import android.provider.MediaStore -import android.util.Log -import androidx.core.net.toFile -import dagger.hilt.android.qualifiers.ApplicationContext -import javax.inject.Inject - -class DFUFileManager @Inject constructor( - @ApplicationContext - private val context: Context -) { - - private val TAG = "DFU_FILE_MANAGER" - - fun createFile(uri: Uri): ZipFile? { - return try { - createFromFile(uri) - } catch (e: Exception) { - Log.e(TAG, "Error during creation file from uri.", e) - try { - createFromContentResolver(uri) - } catch (e: Exception) { - Log.e(TAG, "Error during loading file from content resolver.", e) - null - } - } - } - - private fun createFromFile(uri: Uri): ZipFile { - val file = uri.toFile() - return ZipFile(uri, file.name, file.path, file.length()) - } - - private fun createFromContentResolver(uri: Uri): ZipFile? { - val data = context.contentResolver.query(uri, null, null, null, null) - - return if (data != null && data.moveToNext()) { - - val displayNameIndex = data.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME) - val fileSizeIndex = data.getColumnIndex(MediaStore.MediaColumns.SIZE) - val dataIndex = data.getColumnIndex(MediaStore.MediaColumns.DATA) - - val fileName = data.getString(displayNameIndex) - val fileSize = data.getInt(fileSizeIndex) - val filePath = if (dataIndex != -1) { - data.getString(dataIndex) - } else { - null - } - - data.close() - - ZipFile(uri, fileName, filePath, fileSize.toLong()) - } else { - Log.d(TAG, "Data loaded from ContentResolver is empty.") - null - } - } -} diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUManager.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUManager.kt deleted file mode 100644 index 988e2f44..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUManager.kt +++ /dev/null @@ -1,28 +0,0 @@ -package no.nordicsemi.dfu.data - -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext -import no.nordicsemi.android.dfu.DfuServiceInitiator -import no.nordicsemi.dfu.repository.DFUService -import no.nordicsemi.ui.scanner.DiscoveredBluetoothDevice -import javax.inject.Inject - -class DFUManager @Inject constructor( - @ApplicationContext - private val context: Context -) { - - fun install(file: ZipFile, device: DiscoveredBluetoothDevice) { - val starter = DfuServiceInitiator(device.address()) - .setDeviceName(device.displayName()) -// .setKeepBond(keepBond) -// .setForceDfu(forceDfu) -// .setPacketsReceiptNotificationsEnabled(enablePRNs) -// .setPacketsReceiptNotificationsValue(numberOfPackets) - .setPrepareDataObjectDelay(400) - .setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true) - - starter.setZip(file.uri, file.path) - starter.start(context, DFUService::class.java) - } -} diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUProgressManager.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUProgressManager.kt deleted file mode 100644 index 0ebebea1..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUProgressManager.kt +++ /dev/null @@ -1,86 +0,0 @@ -package no.nordicsemi.dfu.data - -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext -import dagger.hilt.android.scopes.ViewModelScoped -import kotlinx.coroutines.flow.MutableStateFlow -import no.nordicsemi.android.dfu.DfuProgressListenerAdapter -import no.nordicsemi.android.dfu.DfuServiceListenerHelper -import javax.inject.Inject - -@ViewModelScoped -internal class DFUProgressManager @Inject constructor( - @ApplicationContext - private val context: Context -) : DfuProgressListenerAdapter() { - - val status = MutableStateFlow(Idle) - - override fun onDeviceConnecting(deviceAddress: String) { - status.value = Connecting - } - - override fun onDeviceConnected(deviceAddress: String) { - status.value = Connected - } - - override fun onDfuProcessStarting(deviceAddress: String) { - status.value = Starting - } - - override fun onDfuProcessStarted(deviceAddress: String) { - status.value = Started - } - - override fun onEnablingDfuMode(deviceAddress: String) { - status.value = EnablingDfu - } - - override fun onProgressChanged( - deviceAddress: String, - percent: Int, - speed: Float, - avgSpeed: Float, - currentPart: Int, - partsTotal: Int - ) { - status.value = ProgressUpdate(percent) - } - - override fun onFirmwareValidating(deviceAddress: String) { - status.value = Validating - } - - override fun onDeviceDisconnecting(deviceAddress: String?) { - status.value = Disconnecting - } - - override fun onDeviceDisconnected(deviceAddress: String) { - status.value = Disconnected - } - - override fun onDfuCompleted(deviceAddress: String) { - status.value = Completed - } - - override fun onDfuAborted(deviceAddress: String) { - status.value = Aborted - } - - override fun onError( - deviceAddress: String, - error: Int, - errorType: Int, - message: String? - ) { - status.value = Error(message) - } - - fun registerListener() { - DfuServiceListenerHelper.registerProgressListener(context, this) - } - - fun unregisterListener() { - DfuServiceListenerHelper.unregisterProgressListener(context, this) - } -} diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFURepository.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFURepository.kt deleted file mode 100644 index ad29b682..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFURepository.kt +++ /dev/null @@ -1,60 +0,0 @@ -package no.nordicsemi.dfu.data - -import android.net.Uri -import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asSharedFlow -import kotlinx.coroutines.flow.asStateFlow -import no.nordicsemi.android.service.BleManagerStatus -import no.nordicsemi.ui.scanner.DiscoveredBluetoothDevice -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -internal class DFURepository @Inject constructor( - private val fileManger: DFUFileManager -) { - - private val _data = MutableStateFlow(NoFileSelectedState()) - val data: StateFlow = _data.asStateFlow() - - private val _command = MutableSharedFlow(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_LATEST) - val command = _command.asSharedFlow() - - private val _status = MutableStateFlow(BleManagerStatus.CONNECTING) - val status = _status.asStateFlow() - - fun setZipFile(file: Uri, device: DiscoveredBluetoothDevice) { - val currentState = _data.value as NoFileSelectedState - _data.value = fileManger.createFile(file)?.let { - FileReadyState(it, device) - } ?: currentState.copy(isError = true) - } - - fun setSuccess() { - _data.value = UploadSuccessState - } - - fun setError(message: String?) { - _data.value = UploadFailureState(message) - } - - fun install() { - _data.value = FileInstallingState() - } - - fun sendNewCommand(command: DisconnectCommand) { - _command.tryEmit(command) - } - - fun setNewStatus(status: BleManagerStatus) { - _status.value = status - } - - fun clear() { - _status.value = BleManagerStatus.CONNECTING - _data.value = NoFileSelectedState() - } -} diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUServiceCommand.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUServiceCommand.kt deleted file mode 100644 index fb0399b9..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUServiceCommand.kt +++ /dev/null @@ -1,3 +0,0 @@ -package no.nordicsemi.dfu.data - -internal object DisconnectCommand diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUServiceStatus.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUServiceStatus.kt deleted file mode 100644 index bc011d09..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/data/DFUServiceStatus.kt +++ /dev/null @@ -1,17 +0,0 @@ -package no.nordicsemi.dfu.data - -internal sealed class DFUServiceStatus - -internal object Idle : DFUServiceStatus() -internal object Connecting : DFUServiceStatus() -internal object Connected : DFUServiceStatus() -internal object Starting : DFUServiceStatus() -internal object Started : DFUServiceStatus() -internal object EnablingDfu : DFUServiceStatus() -internal data class ProgressUpdate(val progress: Int): DFUServiceStatus() -internal object Validating : DFUServiceStatus() -internal object Disconnecting : DFUServiceStatus() -internal object Disconnected : DFUServiceStatus() -internal object Completed : DFUServiceStatus() -internal object Aborted : DFUServiceStatus() -internal data class Error(val message: String?): DFUServiceStatus() diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/repository/DFUService.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/repository/DFUService.kt deleted file mode 100644 index 865b005f..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/repository/DFUService.kt +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2015, Nordic Semiconductor - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package no.nordicsemi.dfu.repository - -import android.app.Activity -import android.app.Notification -import android.app.NotificationChannel -import android.app.NotificationManager -import android.content.Context -import android.os.Build -import androidx.annotation.RequiresApi -import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import no.nordicsemi.android.dfu.DfuBaseService -import no.nordicsemi.android.service.BleManagerStatus -import no.nordicsemi.android.service.CloseableCoroutineScope -import no.nordicsemi.dfu.R -import no.nordicsemi.dfu.data.DFURepository -import javax.inject.Inject - -@AndroidEntryPoint -internal class DFUService : DfuBaseService() { - - private val scope = CloseableCoroutineScope(SupervisorJob() + Dispatchers.Main.immediate) - - @Inject - lateinit var repository: DFURepository - - override fun onCreate() { - super.onCreate() - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - createDfuNotificationChannel(this) - } - - repository.command.onEach { - stopSelf() - }.launchIn(scope) - - repository.setNewStatus(BleManagerStatus.OK) - } - - override fun getNotificationTarget(): Class? { - /* - * As a target activity the NotificationActivity is returned, not the MainActivity. This is because the notification must create a new task: - * - * intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - * - * when user press it. Using NotificationActivity we can check whether the new activity is a root activity (that means no other activity was open before) - * or that there is other activity already open. In the later case the notificationActivity will just be closed. System will restore the previous activity. - * However if the application has been closed during upload and user click the notification a NotificationActivity will be launched as a root activity. - * It will create and start the main activity and terminate itself. - * - * This method may be used to restore the target activity in case the application was closed or is open. It may also be used to recreate an activity - * history (see NotificationActivity). - */ - return Class.forName("no.nordicsemi.android.nrftoolbox.MainActivity") as Class - } - - override fun isDebug(): Boolean { - // return BuildConfig.DEBUG; - return true - } - - @RequiresApi(api = Build.VERSION_CODES.O) - private fun createDfuNotificationChannel(context: Context) { - val channel = NotificationChannel( - NOTIFICATION_CHANNEL_DFU, - context.getString(R.string.dfu_channel_name), - NotificationManager.IMPORTANCE_LOW - ) - channel.description = context.getString(R.string.dfu_channel_description) - channel.setShowBadge(false) - channel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC - val notificationManager = - context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager - notificationManager?.createNotificationChannel(channel) - } - - override fun onDestroy() { - repository.setNewStatus(BleManagerStatus.DISCONNECTED) - super.onDestroy() - scope.close() - } -} diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUContentView.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUContentView.kt deleted file mode 100644 index baa7e38a..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUContentView.kt +++ /dev/null @@ -1,27 +0,0 @@ -package no.nordicsemi.dfu.view - -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.padding -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import no.nordicsemi.android.utils.exhaustive -import no.nordicsemi.dfu.data.DFUData -import no.nordicsemi.dfu.data.FileInstallingState -import no.nordicsemi.dfu.data.FileReadyState -import no.nordicsemi.dfu.data.NoFileSelectedState -import no.nordicsemi.dfu.data.UploadFailureState -import no.nordicsemi.dfu.data.UploadSuccessState - -@Composable -internal fun DFUContentView(state: DFUData, onEvent: (DFUViewEvent) -> Unit) { - Box(modifier = Modifier.padding(16.dp)) { - when (state) { - is NoFileSelectedState -> DFUSelectMainFileView(state, onEvent) - is FileReadyState -> DFUSummaryView(state, onEvent) - UploadSuccessState -> DFUSuccessView(onEvent) - is UploadFailureState -> DFUErrorView(state, onEvent) - is FileInstallingState -> DFUInstallingView(state, onEvent) - }.exhaustive - } -} diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUErrorView.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUErrorView.kt deleted file mode 100644 index fd70bf97..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUErrorView.kt +++ /dev/null @@ -1,51 +0,0 @@ -package no.nordicsemi.dfu.view - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.size -import androidx.compose.material3.Button -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import no.nordicsemi.android.theme.view.ScreenSection -import no.nordicsemi.dfu.R -import no.nordicsemi.dfu.data.UploadFailureState - -@Composable -internal fun DFUErrorView(state: UploadFailureState, onEvent: (DFUViewEvent) -> Unit) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - ScreenSection { - val errorColor = MaterialTheme.colorScheme.error - - Icon( - painter = painterResource(id = R.drawable.ic_fail_circle), - contentDescription = stringResource(id = R.string.dfu_failure_icon_description), - tint = errorColor - ) - - - Spacer(modifier = Modifier.size(8.dp)) - - val error = state.message ?: stringResource(id = R.string.dfu_unknown_error) - Text( - text = error, - color = errorColor, - style = MaterialTheme.typography.titleLarge - ) - - Spacer(modifier = Modifier.size(16.dp)) - } - - Spacer(modifier = Modifier.size(16.dp)) - - Button(onClick = { onEvent(OnPauseButtonClick) }) { - Text(text = stringResource(id = R.string.dfu_close)) - } - } -} diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUInstallingView.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUInstallingView.kt deleted file mode 100644 index 05622b8f..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUInstallingView.kt +++ /dev/null @@ -1,22 +0,0 @@ -package no.nordicsemi.dfu.view - -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.height -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import androidx.compose.material3.CircularProgressIndicator -import no.nordicsemi.android.theme.view.ScreenSection -import no.nordicsemi.dfu.data.FileInstallingState - -@Composable -internal fun DFUInstallingView(state: FileInstallingState, onEvent: (DFUViewEvent) -> Unit) { - ScreenSection { - CircularProgressIndicator() - - Spacer(modifier = Modifier.height(16.dp)) - - Text(text = state.status.toDisplayString()) - } -} diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUMappers.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUMappers.kt deleted file mode 100644 index cd19de20..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUMappers.kt +++ /dev/null @@ -1,40 +0,0 @@ -package no.nordicsemi.dfu.view - -import androidx.compose.runtime.Composable -import androidx.compose.ui.res.stringResource -import no.nordicsemi.dfu.R -import no.nordicsemi.dfu.data.Aborted -import no.nordicsemi.dfu.data.Completed -import no.nordicsemi.dfu.data.Connected -import no.nordicsemi.dfu.data.Connecting -import no.nordicsemi.dfu.data.DFUServiceStatus -import no.nordicsemi.dfu.data.Disconnected -import no.nordicsemi.dfu.data.Disconnecting -import no.nordicsemi.dfu.data.EnablingDfu -import no.nordicsemi.dfu.data.Error -import no.nordicsemi.dfu.data.Idle -import no.nordicsemi.dfu.data.ProgressUpdate -import no.nordicsemi.dfu.data.Started -import no.nordicsemi.dfu.data.Starting -import no.nordicsemi.dfu.data.Validating - -@Composable -internal fun DFUServiceStatus.toDisplayString(): String { - val displayStatus = when (this) { - Aborted -> stringResource(id = R.string.dfu_display_status_aborted) - Completed -> stringResource(id = R.string.dfu_display_status_completed) - Connected -> stringResource(id = R.string.dfu_display_status_connected) - Connecting -> stringResource(id = R.string.dfu_display_status_connecting) - Disconnected -> stringResource(id = R.string.dfu_display_status_disconnected) - Disconnecting -> stringResource(id = R.string.dfu_display_status_disconnecting) - EnablingDfu -> stringResource(id = R.string.dfu_display_status_enabling) - is Error -> message ?: stringResource(id = R.string.dfu_display_status_error) - Idle -> stringResource(id = R.string.dfu_display_status_idle) - is ProgressUpdate -> stringResource(id = R.string.dfu_display_status_progress_update, progress) - Started -> stringResource(id = R.string.dfu_display_status_started) - Starting -> stringResource(id = R.string.dfu_display_status_starting) - Validating -> stringResource(id = R.string.dfu_display_status_validating) - } - - return stringResource(id = R.string.dfu_display_status, displayStatus) -} diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUScreen.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUScreen.kt deleted file mode 100644 index cef26cf3..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUScreen.kt +++ /dev/null @@ -1,27 +0,0 @@ -package no.nordicsemi.dfu.view - -import androidx.compose.foundation.layout.Column -import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.ui.res.stringResource -import androidx.hilt.navigation.compose.hiltViewModel -import no.nordicsemi.android.theme.view.BackIconAppBar -import no.nordicsemi.dfu.R -import no.nordicsemi.dfu.viewmodel.DFUViewModel - -@Composable -fun DFUScreen() { - val viewModel: DFUViewModel = hiltViewModel() - val state = viewModel.state.collectAsState().value - - Column { - BackIconAppBar(stringResource(id = R.string.dfu_title)) { - viewModel.onEvent(OnDisconnectButtonClick) - } - -// when (state) { -// is DisplayDataState -> DFUContentView(state.data) { viewModel.onEvent(it) } -// LoadingState -> DeviceConnectingView() -// }.exhaustive - } -} diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUSelectMainFileView.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUSelectMainFileView.kt deleted file mode 100644 index 324a0468..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUSelectMainFileView.kt +++ /dev/null @@ -1,70 +0,0 @@ -package no.nordicsemi.dfu.view - -import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.size -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Settings -import androidx.compose.material3.Button -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import no.nordicsemi.android.dfu.DfuBaseService -import no.nordicsemi.android.theme.view.ScreenSection -import no.nordicsemi.android.theme.view.SectionTitle -import no.nordicsemi.dfu.R -import no.nordicsemi.dfu.data.NoFileSelectedState - -@Composable -internal fun DFUSelectMainFileView(state: NoFileSelectedState, onEvent: (DFUViewEvent) -> Unit) { - ScreenSection { - SectionTitle( - icon = Icons.Default.Settings, - title = stringResource(id = R.string.dfu_choose_file) - ) - - Spacer(modifier = Modifier.size(8.dp)) - - Text( - text = stringResource(id = R.string.dfu_choose_info), - style = MaterialTheme.typography.bodyMedium - ) - - if (state.isError) { - Spacer(modifier = Modifier.size(8.dp)) - - Text( - text = stringResource(id = R.string.dfu_load_file_error), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.error - ) - } - - Spacer(modifier = Modifier.size(8.dp)) - - ButtonsRow(onEvent) - } -} - -@Composable -private fun ButtonsRow(onEvent: (DFUViewEvent) -> Unit) { - - val fileType = rememberSaveable { mutableStateOf(DfuBaseService.MIME_TYPE_ZIP) } - - val launcher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { uri -> - uri?.let { onEvent(OnZipFileSelected(it)) } - } - - Button(onClick = { - fileType.value = DfuBaseService.MIME_TYPE_ZIP - launcher.launch(fileType.value) - }) { - Text(text = stringResource(id = R.string.dfu_select_zip)) - } -} diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUState.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUState.kt deleted file mode 100644 index d4acd25b..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUState.kt +++ /dev/null @@ -1,9 +0,0 @@ -package no.nordicsemi.dfu.view - -import no.nordicsemi.dfu.data.DFUData - -internal sealed class DFUViewState - -internal object LoadingState : DFUViewState() - -internal data class DisplayDataState(val data: DFUData) : DFUViewState() diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUSuccessView.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUSuccessView.kt deleted file mode 100644 index 996c1731..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUSuccessView.kt +++ /dev/null @@ -1,47 +0,0 @@ -package no.nordicsemi.dfu.view - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.size -import androidx.compose.material3.Button -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.colorResource -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import no.nordicsemi.android.theme.view.ScreenSection -import no.nordicsemi.dfu.R - -@Composable -internal fun DFUSuccessView(onEvent: (DFUViewEvent) -> Unit) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - ScreenSection { - val successColor = colorResource(id = no.nordicsemi.android.material.you.R.color.nordicGrass) - - Icon( - painter = painterResource(id = R.drawable.ic_success_circle), - contentDescription = stringResource(id = R.string.dfu_success_icon_description), - tint = successColor - ) - - Spacer(modifier = Modifier.size(8.dp)) - - Text( - text = stringResource(id = R.string.dfu_success), - color = successColor, - style = MaterialTheme.typography.titleLarge - ) - } - - Spacer(modifier = Modifier.size(16.dp)) - - Button(onClick = { onEvent(OnPauseButtonClick) }) { - Text(text = stringResource(id = R.string.dfu_done)) - } - } -} diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUSummaryView.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUSummaryView.kt deleted file mode 100644 index a7d66c3f..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUSummaryView.kt +++ /dev/null @@ -1,110 +0,0 @@ -package no.nordicsemi.dfu.view - -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Notifications -import androidx.compose.material3.Button -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import no.nordicsemi.android.theme.view.ScreenSection -import no.nordicsemi.android.theme.view.SectionTitle -import no.nordicsemi.dfu.R -import no.nordicsemi.dfu.data.FileReadyState -import no.nordicsemi.dfu.data.ZipFile -import no.nordicsemi.ui.scanner.DiscoveredBluetoothDevice - -@Composable -internal fun DFUSummaryView(state: FileReadyState, onEvent: (DFUViewEvent) -> Unit) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - DeviceDetailsView(state.device) - - Spacer(modifier = Modifier.height(16.dp)) - - FileDetailsView(state.file) - - Spacer(modifier = Modifier.height(16.dp)) - - Button(onClick = { onEvent(OnInstallButtonClick) }) { - Text(text = stringResource(id = R.string.dfu_install)) - } - } -} - -@Composable -internal fun DeviceDetailsView(device: DiscoveredBluetoothDevice) { - ScreenSection { - Row( - horizontalArrangement = Arrangement.Center, - verticalAlignment = Alignment.CenterVertically - ) { - Image( - painter = painterResource(id = R.drawable.ic_bluetooth), - contentDescription = null, - colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSecondary), - modifier = Modifier - .background( - color = MaterialTheme.colorScheme.secondary, - shape = CircleShape - ) - .padding(8.dp) - ) - - Spacer(modifier = Modifier.size(8.dp)) - - Column( - modifier = Modifier - .fillMaxWidth() - .weight(1f) - ) { - Text( - text = device.displayName() ?: "No name", - style = MaterialTheme.typography.titleMedium - ) - Text(text = device.displayAddress(), style = MaterialTheme.typography.bodyMedium) - } - } - } -} - -@Composable -private fun FileDetailsView(file: ZipFile) { - val fileName = file.name - val fileLength = file.size - - ScreenSection { - SectionTitle( - icon = Icons.Default.Notifications, - title = stringResource(id = R.string.dfu_zip_file_details) - ) - - Spacer(modifier = Modifier.size(16.dp)) - - Column( - modifier = Modifier.fillMaxWidth(), - horizontalAlignment = Alignment.Start - ) { - Text(text = stringResource(id = R.string.dfu_file_name, fileName)) - - Spacer(modifier = Modifier.size(4.dp)) - - Text(text = stringResource(id = R.string.dfu_file_size, fileLength)) - } - } -} diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUViewEvent.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUViewEvent.kt deleted file mode 100644 index 69c779e3..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/view/DFUViewEvent.kt +++ /dev/null @@ -1,15 +0,0 @@ -package no.nordicsemi.dfu.view - -import android.net.Uri - -internal sealed class DFUViewEvent - -internal data class OnZipFileSelected(val file: Uri) : DFUViewEvent() - -internal object OnInstallButtonClick : DFUViewEvent() - -internal object OnPauseButtonClick : DFUViewEvent() - -internal object OnStopButtonClick : DFUViewEvent() - -internal object OnDisconnectButtonClick : DFUViewEvent() diff --git a/profile_dfu/src/main/java/no/nordicsemi/dfu/viewmodel/DFUViewModel.kt b/profile_dfu/src/main/java/no/nordicsemi/dfu/viewmodel/DFUViewModel.kt deleted file mode 100644 index 4e44e20e..00000000 --- a/profile_dfu/src/main/java/no/nordicsemi/dfu/viewmodel/DFUViewModel.kt +++ /dev/null @@ -1,102 +0,0 @@ -package no.nordicsemi.dfu.viewmodel - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.stateIn -import no.nordicsemi.android.navigation.CancelDestinationResult -import no.nordicsemi.android.navigation.DestinationResult -import no.nordicsemi.android.navigation.NavigationManager -import no.nordicsemi.android.navigation.SuccessDestinationResult -import no.nordicsemi.android.service.BleManagerStatus -import no.nordicsemi.android.service.ServiceManager -import no.nordicsemi.android.utils.exhaustive -import no.nordicsemi.android.utils.getDevice -import no.nordicsemi.dfu.data.* -import no.nordicsemi.dfu.repository.DFUService -import no.nordicsemi.dfu.view.* -import no.nordicsemi.ui.scanner.DiscoveredBluetoothDevice -import no.nordicsemi.ui.scanner.ScannerDestinationId -import javax.inject.Inject - -@HiltViewModel -internal class DFUViewModel @Inject constructor( - private val repository: DFURepository, - private val progressManager: DFUProgressManager, - private val dfuManager: DFUManager, - private val serviceManager: ServiceManager, - private val navigationManager: NavigationManager -) : ViewModel() { - - private var device: DiscoveredBluetoothDevice? = null - - val state = repository.data.combine(progressManager.status) { state, status -> - (state as? FileInstallingState) - ?.run { createInstallingStateWithNewStatus(state, status) } - ?: state - }.combine(repository.status) { data, status -> -// when (status) { -// BleManagerStatus.CONNECTING -> LoadingState -// BleManagerStatus.OK, -// BleManagerStatus.DISCONNECTED -> DisplayDataState(data) -// } - }.stateIn(viewModelScope, SharingStarted.Lazily, LoadingState) - - init { - progressManager.registerListener() - } - - private fun handleArgs(args: DestinationResult?) { - when (args) { - is CancelDestinationResult -> navigationManager.navigateUp() - is SuccessDestinationResult -> { - device = args.getDevice() - serviceManager.startService(DFUService::class.java, args.getDevice()) - } - null -> navigationManager.navigateTo(ScannerDestinationId) - }.exhaustive - } - - fun onEvent(event: DFUViewEvent) { - when (event) { - OnDisconnectButtonClick -> closeScreen() - OnInstallButtonClick -> { - dfuManager.install(requireFile(), device!!) - repository.install() - } - OnPauseButtonClick -> closeScreen() - OnStopButtonClick -> closeScreen() - is OnZipFileSelected -> repository.setZipFile(event.file, device!!) - }.exhaustive - } - - private fun closeScreen() { - repository.sendNewCommand(DisconnectCommand) - repository.clear() - } - - private fun requireFile(): ZipFile { - return (repository.data.value as FileReadyState).file - } - - private fun createInstallingStateWithNewStatus( - state: FileInstallingState, - status: DFUServiceStatus - ): FileInstallingState { - if (status is Error) { - repository.setError(status.message) - } - if (status is Completed) { - repository.setSuccess() - } - return state.copy(status = status) - } - - override fun onCleared() { - super.onCleared() - repository.clear() - progressManager.unregisterListener() - } -} diff --git a/profile_dfu/src/main/res/drawable/ic_fail_circle.xml b/profile_dfu/src/main/res/drawable/ic_fail_circle.xml deleted file mode 100644 index 2a183c48..00000000 --- a/profile_dfu/src/main/res/drawable/ic_fail_circle.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/profile_dfu/src/main/res/drawable/ic_success_circle.xml b/profile_dfu/src/main/res/drawable/ic_success_circle.xml deleted file mode 100644 index a9ca6d97..00000000 --- a/profile_dfu/src/main/res/drawable/ic_success_circle.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/profile_dfu/src/main/res/values/strings.xml b/profile_dfu/src/main/res/values/strings.xml deleted file mode 100644 index 702ba669..00000000 --- a/profile_dfu/src/main/res/values/strings.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - DFU - - Done - Close - Pause - Stop - Install - - Select .dat - Select .zip - Select .hex - - An error occurred during loading the file. Please try with another file. - - Zip file details - Hex file details - - Distribution packet (ZIP) - Soft Device - Bootloader - Application - - Choose file - Please select .zip or .hex file with bootloader, application or soft device. - Please select .dat file. - - File managers - Please select - Confirm - Dismiss - - Operation success - Operation failed - - Aborted - Completed - Connected - Connecting - Disconnected - Disconnecting - Enabling DFU - Error - Idle - %d\%% - Started - Starting - Validating - Status: %s - - Success! - Unknown error. - - File name: %s - File size: %d bytes - diff --git a/profile_dfu/src/test/java/no/nordicsemi/dfu/ExampleUnitTest.kt b/profile_dfu/src/test/java/no/nordicsemi/dfu/ExampleUnitTest.kt deleted file mode 100644 index b24a6af4..00000000 --- a/profile_dfu/src/test/java/no/nordicsemi/dfu/ExampleUnitTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package no.nordicsemi.dfu - -import org.junit.Assert.assertEquals -import org.junit.Test - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 797bd488..f9e2c581 100644 --- a/settings.gradle +++ b/settings.gradle @@ -91,7 +91,6 @@ include ':app' include ':profile_bps' include ':profile_cgms' include ':profile_csc' -include ':profile_dfu' include ':profile_gls' include ':profile_hrs' include ':profile_hts'