• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.wm.shell.desktopmode.education
18 
19 import android.content.Context
20 import android.testing.AndroidTestingRunner
21 import androidx.datastore.core.DataStore
22 import androidx.datastore.core.DataStoreFactory
23 import androidx.datastore.dataStoreFile
24 import androidx.test.core.app.ApplicationProvider
25 import androidx.test.filters.SmallTest
26 import androidx.test.platform.app.InstrumentationRegistry
27 import com.android.wm.shell.desktopmode.education.data.AppHandleEducationDatastoreRepository
28 import com.android.wm.shell.desktopmode.education.data.WindowingEducationProto
29 import com.android.wm.shell.util.GMAIL_PACKAGE_NAME
30 import com.android.wm.shell.util.createWindowingEducationProto
31 import com.google.common.truth.Truth.assertThat
32 import java.io.File
33 import java.time.Duration
34 import kotlinx.coroutines.CoroutineScope
35 import kotlinx.coroutines.Dispatchers
36 import kotlinx.coroutines.ExperimentalCoroutinesApi
37 import kotlinx.coroutines.SupervisorJob
38 import kotlinx.coroutines.cancel
39 import kotlinx.coroutines.flow.first
40 import kotlinx.coroutines.test.StandardTestDispatcher
41 import kotlinx.coroutines.test.runTest
42 import kotlinx.coroutines.test.setMain
43 import org.junit.After
44 import org.junit.Before
45 import org.junit.Test
46 import org.junit.runner.RunWith
47 
48 @SmallTest
49 @RunWith(AndroidTestingRunner::class)
50 @ExperimentalCoroutinesApi
51 class AppHandleEducationDatastoreRepositoryTest {
52     private val testContext: Context = InstrumentationRegistry.getInstrumentation().targetContext
53     private lateinit var testDatastore: DataStore<WindowingEducationProto>
54     private lateinit var datastoreRepository: AppHandleEducationDatastoreRepository
55     private lateinit var datastoreScope: CoroutineScope
56 
57     @Before
setUpnull58     fun setUp() {
59         Dispatchers.setMain(StandardTestDispatcher())
60         datastoreScope = CoroutineScope(Dispatchers.Unconfined + SupervisorJob())
61         testDatastore =
62             DataStoreFactory.create(
63                 serializer =
64                     AppHandleEducationDatastoreRepository.Companion
65                         .WindowingEducationProtoSerializer,
66                 scope = datastoreScope,
67             ) {
68                 testContext.dataStoreFile(APP_HANDLE_EDUCATION_DATASTORE_TEST_FILE)
69             }
70         datastoreRepository = AppHandleEducationDatastoreRepository(testDatastore)
71     }
72 
73     @After
tearDownnull74     fun tearDown() {
75         File(ApplicationProvider.getApplicationContext<Context>().filesDir, "datastore")
76             .deleteRecursively()
77 
78         datastoreScope.cancel()
79     }
80 
81     @Test
getWindowingEducationProto_returnsCorrectProtonull82     fun getWindowingEducationProto_returnsCorrectProto() =
83         runTest(StandardTestDispatcher()) {
84             val windowingEducationProto =
85                 createWindowingEducationProto(
86                     appHandleHintViewedTimestampMillis = 123L,
87                     appHandleHintUsedTimestampMillis = 124L,
88                     appUsageStats = mapOf(GMAIL_PACKAGE_NAME to 2),
89                     appUsageStatsLastUpdateTimestampMillis = 125L,
90                 )
91             testDatastore.updateData { windowingEducationProto }
92 
93             val resultProto = datastoreRepository.windowingEducationProto()
94 
95             assertThat(resultProto).isEqualTo(windowingEducationProto)
96         }
97 
98     @Test
updateAppUsageStats_updatesDatastoreProtonull99     fun updateAppUsageStats_updatesDatastoreProto() =
100         runTest(StandardTestDispatcher()) {
101             val appUsageStats = mapOf(GMAIL_PACKAGE_NAME to 3)
102             val appUsageStatsLastUpdateTimestamp = Duration.ofMillis(123L)
103             val windowingEducationProto =
104                 createWindowingEducationProto(
105                     appUsageStats = appUsageStats,
106                     appUsageStatsLastUpdateTimestampMillis =
107                         appUsageStatsLastUpdateTimestamp.toMillis(),
108                 )
109 
110             datastoreRepository.updateAppUsageStats(appUsageStats, appUsageStatsLastUpdateTimestamp)
111 
112             val result = testDatastore.data.first()
113             assertThat(result).isEqualTo(windowingEducationProto)
114         }
115 
116     @Test
updateAppHandleHintViewedTimestampMillis_updatesDatastoreProtonull117     fun updateAppHandleHintViewedTimestampMillis_updatesDatastoreProto() =
118         runTest(StandardTestDispatcher()) {
119             datastoreRepository.updateAppHandleHintViewedTimestampMillis(true)
120 
121             val result = testDatastore.data.first().hasAppHandleHintViewedTimestampMillis()
122             assertThat(result).isEqualTo(true)
123         }
124 
125     @Test
updateEnterDesktopModeHintViewedTimestampMillis_updatesDatastoreProtonull126     fun updateEnterDesktopModeHintViewedTimestampMillis_updatesDatastoreProto() =
127         runTest(StandardTestDispatcher()) {
128             datastoreRepository.updateEnterDesktopModeHintViewedTimestampMillis(true)
129 
130             val result = testDatastore.data.first().hasEnterDesktopModeHintViewedTimestampMillis()
131             assertThat(result).isEqualTo(true)
132         }
133 
134     @Test
updateExitDesktopModeHintViewedTimestampMillis_updatesDatastoreProtonull135     fun updateExitDesktopModeHintViewedTimestampMillis_updatesDatastoreProto() =
136         runTest(StandardTestDispatcher()) {
137             datastoreRepository.updateExitDesktopModeHintViewedTimestampMillis(true)
138 
139             val result = testDatastore.data.first().hasExitDesktopModeHintViewedTimestampMillis()
140             assertThat(result).isEqualTo(true)
141         }
142 
143     @Test
updateAppHandleHintUsedTimestampMillis_updatesDatastoreProtonull144     fun updateAppHandleHintUsedTimestampMillis_updatesDatastoreProto() =
145         runTest(StandardTestDispatcher()) {
146             datastoreRepository.updateAppHandleHintUsedTimestampMillis(true)
147 
148             val result = testDatastore.data.first().hasAppHandleHintUsedTimestampMillis()
149             assertThat(result).isEqualTo(true)
150         }
151 
152     companion object {
153         private const val APP_HANDLE_EDUCATION_DATASTORE_TEST_FILE = "app_handle_education_test.pb"
154     }
155 }
156