mirror of
https://github.com/aljazceru/Android-nRF-Toolbox.git
synced 2025-12-21 08:24:22 +01:00
Add DFU module
This commit is contained in:
30
profile_dfu/build.gradle
Normal file
30
profile_dfu/build.gradle
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
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.log
|
||||||
|
implementation libs.nordic.dfu
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package no.nordicsemi.dfu
|
||||||
|
|
||||||
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
5
profile_dfu/src/main/AndroidManifest.xml
Normal file
5
profile_dfu/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="no.nordicsemi.dfu">
|
||||||
|
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package no.nordicsemi.dfu.data
|
||||||
|
|
||||||
|
class DFUData {
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package no.nordicsemi.dfu.data
|
||||||
|
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
internal class DFUDataHolder @Inject constructor() {
|
||||||
|
|
||||||
|
private val _data = MutableStateFlow(DFUData())
|
||||||
|
val data: StateFlow<DFUData> = _data
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* 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 no.nordicsemi.android.dfu.DfuBaseService
|
||||||
|
import no.nordicsemi.dfu.view.NotificationActivity
|
||||||
|
|
||||||
|
class DFUService : DfuBaseService() {
|
||||||
|
|
||||||
|
override fun getNotificationTarget(): Class<out Activity?>? {
|
||||||
|
/*
|
||||||
|
* 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 NotificationActivity::class.java
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isDebug(): Boolean {
|
||||||
|
// return BuildConfig.DEBUG;
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package no.nordicsemi.dfu.view
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import no.nordicsemi.dfu.data.DFUData
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun DFUContentView(state: DFUData, onEvent: (DFUViewEvent) -> Unit) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package no.nordicsemi.dfu.view
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DFUErrorView() {
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package no.nordicsemi.dfu.view
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DFUInstallingView() {
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package no.nordicsemi.dfu.view
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
|
import no.nordicsemi.android.theme.view.BackIconAppBar
|
||||||
|
import no.nordicsemi.android.utils.isServiceRunning
|
||||||
|
import no.nordicsemi.dfu.R
|
||||||
|
import no.nordicsemi.dfu.data.DFUData
|
||||||
|
import no.nordicsemi.dfu.repository.DFUService
|
||||||
|
import no.nordicsemi.dfu.viewmodel.DFUViewModel
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DFUScreen(finishAction: () -> Unit) {
|
||||||
|
val viewModel: DFUViewModel = hiltViewModel()
|
||||||
|
val state = viewModel.state.collectAsState().value
|
||||||
|
val isScreenActive = viewModel.isActive.collectAsState().value
|
||||||
|
|
||||||
|
val context = LocalContext.current
|
||||||
|
LaunchedEffect(isScreenActive) {
|
||||||
|
if (!isScreenActive) {
|
||||||
|
finishAction()
|
||||||
|
}
|
||||||
|
if (context.isServiceRunning(DFUService::class.java.name)) {
|
||||||
|
val intent = Intent(context, DFUService::class.java)
|
||||||
|
context.stopService(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchedEffect("start-service") {
|
||||||
|
if (!context.isServiceRunning(DFUService::class.java.name)) {
|
||||||
|
val intent = Intent(context, DFUService::class.java)
|
||||||
|
context.startService(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DFUView(state) { viewModel.onEvent(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun DFUView(state: DFUData, onEvent: (DFUViewEvent) -> Unit) {
|
||||||
|
Column {
|
||||||
|
BackIconAppBar(stringResource(id = R.string.dfu_title)) {
|
||||||
|
onEvent(OnDisconnectButtonClick)
|
||||||
|
}
|
||||||
|
|
||||||
|
DFUContentView(state) { onEvent(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package no.nordicsemi.dfu.view
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DFUSelectFileView() {
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package no.nordicsemi.dfu.view
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DFUSuccessView() {
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package no.nordicsemi.dfu.view
|
||||||
|
|
||||||
|
internal sealed class DFUViewEvent
|
||||||
|
|
||||||
|
internal object OnDisconnectButtonClick : DFUViewEvent()
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* 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.view
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.os.Bundle
|
||||||
|
|
||||||
|
class NotificationActivity : Activity() {
|
||||||
|
|
||||||
|
protected override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
// If this activity is the root activity of the task, the app is not running
|
||||||
|
if (isTaskRoot()) {
|
||||||
|
// Start the app before finishing
|
||||||
|
//TODO
|
||||||
|
// val parentIntent = Intent(this, FeaturesActivity::class.java)
|
||||||
|
// parentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
// val startAppIntent = Intent(this, DfuActivity::class.java)
|
||||||
|
// if (getIntent() != null && getIntent().getExtras() != null) startAppIntent.putExtras(
|
||||||
|
// getIntent().getExtras()
|
||||||
|
// )
|
||||||
|
// startActivities(arrayOf<Intent>(parentIntent, startAppIntent))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now finish, which will drop the user in to the activity that was at the top
|
||||||
|
// of the task stack
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package no.nordicsemi.dfu.viewmodel
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import no.nordicsemi.android.theme.viewmodel.CloseableViewModel
|
||||||
|
import no.nordicsemi.dfu.data.DFUDataHolder
|
||||||
|
import no.nordicsemi.dfu.view.DFUViewEvent
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
internal class DFUViewModel @Inject constructor(
|
||||||
|
private val dataHolder: DFUDataHolder
|
||||||
|
) : CloseableViewModel() {
|
||||||
|
|
||||||
|
val state = dataHolder.data
|
||||||
|
|
||||||
|
fun onEvent(event: DFUViewEvent) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
4
profile_dfu/src/main/res/values/strings.xml
Normal file
4
profile_dfu/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="dfu_title">DFU</string>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package no.nordicsemi.dfu
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,6 @@ dependencyResolutionManagement {
|
|||||||
maven { url 'https://jitpack.io' }
|
maven { url 'https://jitpack.io' }
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
jcenter() // Warning: this repository is going to shut down soon
|
|
||||||
}
|
}
|
||||||
|
|
||||||
versionCatalogs {
|
versionCatalogs {
|
||||||
@@ -17,6 +16,7 @@ dependencyResolutionManagement {
|
|||||||
alias('nordic-log').to('no.nordicsemi.android:log:2.3.0')
|
alias('nordic-log').to('no.nordicsemi.android:log:2.3.0')
|
||||||
alias('nordic-scanner').to('no.nordicsemi.android.support.v18:scanner:1.5.0')
|
alias('nordic-scanner').to('no.nordicsemi.android.support.v18:scanner:1.5.0')
|
||||||
alias('nordic-ui-scanner').to('no.nordicsemi.android.common:scanner:1.0.0')
|
alias('nordic-ui-scanner').to('no.nordicsemi.android.common:scanner:1.0.0')
|
||||||
|
alias('nordic-dfu').to('no.nordicsemi.android:dfu:1.12.1-beta01')
|
||||||
|
|
||||||
alias('localbroadcastmanager').to('androidx.localbroadcastmanager:localbroadcastmanager:1.0.0')
|
alias('localbroadcastmanager').to('androidx.localbroadcastmanager:localbroadcastmanager:1.0.0')
|
||||||
alias('material').to('com.google.android.material:material:1.5.0-beta01')
|
alias('material').to('com.google.android.material:material:1.5.0-beta01')
|
||||||
@@ -95,3 +95,4 @@ if (file('../Android-Common-Libraries').exists()) {
|
|||||||
// includeBuild('../Android-Scanner-Compat-Library')
|
// includeBuild('../Android-Scanner-Compat-Library')
|
||||||
//}
|
//}
|
||||||
include ':profile_uart'
|
include ':profile_uart'
|
||||||
|
include ':profile_dfu'
|
||||||
|
|||||||
Reference in New Issue
Block a user