diff --git a/network-awareness/db/api/current.api b/network-awareness/db/api/current.api index e99dc0f401..d84bbd1ec0 100644 --- a/network-awareness/db/api/current.api +++ b/network-awareness/db/api/current.api @@ -36,7 +36,7 @@ package com.google.android.horologist.networks.db { @androidx.room.Dao public interface NetworkUsageDao { method @androidx.room.Query("SELECT * FROM DataUsage WHERE day = :day") public kotlinx.coroutines.flow.Flow> getRecords(int day); method @androidx.room.Insert(onConflict=androidx.room.OnConflictStrategy.Companion.IGNORE) public suspend Object? insert(com.google.android.horologist.networks.db.DataUsage media, kotlin.coroutines.Continuation); - method @androidx.room.Query("UPDATE DataUsage SET bytesTotal = bytesTotal + :bytes WHERE day = :day") public suspend Object? updateBytes(int day, long bytes, kotlin.coroutines.Continuation); + method @androidx.room.Query("UPDATE DataUsage SET bytesTotal = bytesTotal + :bytes WHERE day = :day AND networkType = :networkType") public suspend Object? updateBytes(int day, long bytes, String networkType, kotlin.coroutines.Continuation); } @androidx.room.Database(entities={DataUsage::class}, version=1, exportSchema=false) @androidx.room.TypeConverters(NetworkUsageDatabase.Converters::class) public abstract class NetworkUsageDatabase extends androidx.room.RoomDatabase { diff --git a/network-awareness/db/src/main/java/com/google/android/horologist/networks/db/DBDataRequestRepository.kt b/network-awareness/db/src/main/java/com/google/android/horologist/networks/db/DBDataRequestRepository.kt index 02a02e369a..f8d721fd87 100644 --- a/network-awareness/db/src/main/java/com/google/android/horologist/networks/db/DBDataRequestRepository.kt +++ b/network-awareness/db/src/main/java/com/google/android/horologist/networks/db/DBDataRequestRepository.kt @@ -44,16 +44,17 @@ public class DBDataRequestRepository( override fun storeRequest(dataRequest: DataRequest) { val bytes = dataRequest.dataBytes + val networkType = dataRequest.networkInfo.type.name coroutineScope.launch { - var rows = networkUsageDao.updateBytes(day, bytes) + var rows = networkUsageDao.updateBytes(day, bytes, networkType) if (rows == 0) { rows = - networkUsageDao.insert(DataUsage(dataRequest.networkInfo.type.name, bytes, day)) + networkUsageDao.insert(DataUsage(networkType, bytes, day)) .toInt() if (rows == -1) { - networkUsageDao.updateBytes(day, bytes) + networkUsageDao.updateBytes(day, bytes, networkType) } } } @@ -68,10 +69,10 @@ public class DBDataRequestRepository( for (it in list) { when (it.networkType) { - "ble" -> ble += it.bytesTotal - "cell" -> cell += it.bytesTotal - "wifi" -> wifi += it.bytesTotal - "unknown" -> unknown += it.bytesTotal + NetworkType.BT.name -> ble += it.bytesTotal + NetworkType.Cell.name -> cell += it.bytesTotal + NetworkType.Wifi.name -> wifi += it.bytesTotal + NetworkType.Unknown.name -> unknown += it.bytesTotal } } diff --git a/network-awareness/db/src/main/java/com/google/android/horologist/networks/db/NetworkUsageDao.kt b/network-awareness/db/src/main/java/com/google/android/horologist/networks/db/NetworkUsageDao.kt index 84507b0f1c..8378f66b7f 100644 --- a/network-awareness/db/src/main/java/com/google/android/horologist/networks/db/NetworkUsageDao.kt +++ b/network-awareness/db/src/main/java/com/google/android/horologist/networks/db/NetworkUsageDao.kt @@ -24,8 +24,8 @@ import kotlinx.coroutines.flow.Flow @Dao public interface NetworkUsageDao { - @Query("UPDATE DataUsage SET bytesTotal = bytesTotal + :bytes WHERE day = :day") - public suspend fun updateBytes(day: Int, bytes: Long): Int + @Query("UPDATE DataUsage SET bytesTotal = bytesTotal + :bytes WHERE day = :day AND networkType = :networkType") + public suspend fun updateBytes(day: Int, bytes: Long, networkType: String): Int @Insert(onConflict = OnConflictStrategy.IGNORE) public suspend fun insert(media: DataUsage): Long diff --git a/network-awareness/db/src/test/java/com/google/android/horologist/networks/db/DBDataRequestRepositoryTest.kt b/network-awareness/db/src/test/java/com/google/android/horologist/networks/db/DBDataRequestRepositoryTest.kt new file mode 100644 index 0000000000..ca354e820e --- /dev/null +++ b/network-awareness/db/src/test/java/com/google/android/horologist/networks/db/DBDataRequestRepositoryTest.kt @@ -0,0 +1,86 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * 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 + * + * https://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.android.horologist.networks.db + +import com.google.android.horologist.networks.data.DataRequest +import com.google.android.horologist.networks.data.NetworkInfo +import com.google.android.horologist.networks.data.NetworkType +import com.google.android.horologist.networks.data.RequestType +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.RuntimeEnvironment +import org.robolectric.annotation.SQLiteMode + +@RunWith(RobolectricTestRunner::class) +@SQLiteMode(SQLiteMode.Mode.NATIVE) +class DBDataRequestRepositoryTest { + @Test + fun testInsertAndRead(): Unit = runBlocking { + val db = NetworkUsageDatabase.getDatabase(RuntimeEnvironment.getApplication()) + val dao = db.networkUsageDao() + val repository = DBDataRequestRepository(dao, this) + + assertThat(repository.currentPeriodUsage().first().dataByType).containsExactlyEntriesIn( + mapOf( + NetworkType.Wifi to 0L, + NetworkType.BT to 0L, + NetworkType.Cell to 0L, + NetworkType.Unknown to 0L, + ), + ) + + val wifiInfo = NetworkInfo.Wifi("wlan1", "Pretty Fly For a Wifi") + val btInfo = NetworkInfo.Bluetooth("bt1") + repository.storeRequest( + DataRequest( + requestType = RequestType.ImageRequest, + wifiInfo, + 1L, + ), + ) + repository.storeRequest( + DataRequest( + requestType = RequestType.LogsRequest, + wifiInfo, + 100L, + ), + ) + repository.storeRequest( + DataRequest( + requestType = RequestType.ApiRequest, + btInfo, + 10L, + ), + ) + + delay(1000) + + assertThat(repository.currentPeriodUsage().first().dataByType).containsExactlyEntriesIn( + mapOf( + NetworkType.Wifi to 101L, + NetworkType.BT to 10L, + NetworkType.Cell to 0L, + NetworkType.Unknown to 0L, + ), + ) + } +}