diff --git a/app/build.gradle b/app/build.gradle index ae1050fb..ce7318f6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -94,6 +94,10 @@ android { disable 'NullSafeMutableLiveData' } + testOptions { + unitTests.includeAndroidResources true + } + // add API keys from environment variable if not set in apikeys.xml applicationVariants.all { variant -> ext.env = System.getenv() @@ -170,9 +174,10 @@ dependencies { implementation 'com.github.romandanylyk:PageIndicatorView:b1bad589b5' // Android Auto - googleImplementation 'androidx.car.app:app:1.2.0-rc01' - googleNormalImplementation 'androidx.car.app:app-projected:1.2.0-rc01' - googleAutomotiveImplementation 'androidx.car.app:app-automotive:1.2.0-rc01' + def carAppVersion = '1.2.0-rc01' + googleImplementation "androidx.car.app:app:$carAppVersion" + googleNormalImplementation "androidx.car.app:app-projected:$carAppVersion" + googleAutomotiveImplementation "androidx.car.app:app-automotive:$carAppVersion" // AnyMaps def anyMapsVersion = '3c67d7a1dc' @@ -220,10 +225,18 @@ dependencies { // debug tools implementation 'com.facebook.stetho:stetho:1.5.1' implementation 'com.facebook.stetho:stetho-okhttp3:1.5.1' + + // testing testImplementation 'junit:junit:4.13.2' testImplementation "com.squareup.okhttp3:mockwebserver:4.9.0" //noinspection GradleDependency testImplementation 'org.json:json:20080701' + + // testing for car app + testGoogleImplementation "androidx.car.app:app-testing:$carAppVersion" + testGoogleImplementation 'org.robolectric:robolectric:4.7.3' + testGoogleImplementation 'androidx.test:core:1.4.0' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' diff --git a/app/src/google/java/net/vonforst/evmap/auto/MapScreen.kt b/app/src/google/java/net/vonforst/evmap/auto/MapScreen.kt index bc4f1df3..e382c5bd 100644 --- a/app/src/google/java/net/vonforst/evmap/auto/MapScreen.kt +++ b/app/src/google/java/net/vonforst/evmap/auto/MapScreen.kt @@ -82,7 +82,9 @@ class MapScreen(ctx: CarContext, val session: EVMapSession) : Transformations.map(referenceData) { api.getFilters(it, carContext.stringProvider()) } private val filtersWithValue = filtersWithValue(filters, filterValues) - private val hardwareMan = ctx.getCarService(CarContext.HARDWARE_SERVICE) as CarHardwareManager + private val hardwareMan: CarHardwareManager by lazy { + ctx.getCarService(CarContext.HARDWARE_SERVICE) as CarHardwareManager + } private var energyLevel: EnergyLevel? = null private val permissions = if (BuildConfig.FLAVOR_automotive == "automotive") { listOf( @@ -366,16 +368,19 @@ class MapScreen(ctx: CarContext, val session: EVMapSession) : }) return - println("Setting up energy level listener") - - val exec = ContextCompat.getMainExecutor(carContext) - hardwareMan.carInfo.addEnergyLevelListener(exec, ::onEnergyLevelUpdated) + if (supportsCarApiLevel3(carContext)) { + println("Setting up energy level listener") + val exec = ContextCompat.getMainExecutor(carContext) + hardwareMan.carInfo.addEnergyLevelListener(exec, ::onEnergyLevelUpdated) + } } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) private fun removeListeners() { - println("Removing energy level listener") - hardwareMan.carInfo.removeEnergyLevelListener(::onEnergyLevelUpdated) + if (supportsCarApiLevel3(carContext)) { + println("Removing energy level listener") + hardwareMan.carInfo.removeEnergyLevelListener(::onEnergyLevelUpdated) + } } override fun onContentRefreshRequested() { diff --git a/app/src/testGoogle/java/net/vonforst/evmap/auto/CarAppTest.kt b/app/src/testGoogle/java/net/vonforst/evmap/auto/CarAppTest.kt new file mode 100644 index 00000000..f6572a87 --- /dev/null +++ b/app/src/testGoogle/java/net/vonforst/evmap/auto/CarAppTest.kt @@ -0,0 +1,42 @@ +package net.vonforst.evmap.auto + +import android.content.ComponentName +import android.content.Intent +import androidx.car.app.HandshakeInfo +import androidx.car.app.testing.SessionController +import androidx.car.app.testing.TestCarContext +import androidx.car.app.testing.TestScreenManager +import androidx.lifecycle.Lifecycle +import androidx.test.core.app.ApplicationProvider +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.Robolectric +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.internal.DoNotInstrument + +@RunWith(RobolectricTestRunner::class) +@DoNotInstrument +class CarAppTest { + private val testCarContext = + TestCarContext.createCarContext(ApplicationProvider.getApplicationContext()).apply { + updateHandshakeInfo(HandshakeInfo("auto.testing", 1)) + } + + @Test + fun onCreateScreen_returnsExpectedScreen() { + val service = Robolectric.setupService(CarAppService::class.java) + val session = service.onCreateSession() + val controller = SessionController( + session, testCarContext, + Intent().setComponent( + ComponentName(testCarContext, CarAppService::class.java) + ) + ) + controller.moveToState(Lifecycle.State.CREATED) + val screenCreated = + testCarContext.getCarService(TestScreenManager::class.java).screensPushed.last() + + // location permission required + assert(screenCreated is PermissionScreen) + } +} \ No newline at end of file