Implement BottomNavigation for BluetoothX Testapp
Test: build
Relnote: NA
Change-Id: I0366404840ffe4d7cb3c67b19c55f6a04cef8e46
diff --git a/bluetooth/integration-tests/testapp/build.gradle b/bluetooth/integration-tests/testapp/build.gradle
index 8e1ddf0..07c8703 100644
--- a/bluetooth/integration-tests/testapp/build.gradle
+++ b/bluetooth/integration-tests/testapp/build.gradle
@@ -50,11 +50,16 @@
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.appcompat:appcompat:1.6.0")
+ implementation(libs.material)
+
implementation("androidx.activity:activity-ktx:1.6.1")
implementation("androidx.fragment:fragment-ktx:1.5.5")
implementation(libs.constraintLayout)
+ implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.5.1")
+ implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1")
+
implementation("androidx.navigation:navigation-fragment-ktx:2.5.3")
implementation("androidx.navigation:navigation-ui-ktx:2.5.3")
}
diff --git a/bluetooth/integration-tests/testapp/src/main/AndroidManifest.xml b/bluetooth/integration-tests/testapp/src/main/AndroidManifest.xml
index f6c02c5..1f1625b 100644
--- a/bluetooth/integration-tests/testapp/src/main/AndroidManifest.xml
+++ b/bluetooth/integration-tests/testapp/src/main/AndroidManifest.xml
@@ -5,7 +5,7 @@
<application
android:allowBackup="false"
android:label="@string/app_name"
- android:theme="@style/Theme.AppCompat.Light"
+ android:theme="@style/Theme.TestApp"
tools:ignore="GoogleAppIndexingWarning,MissingApplicationIcon">
<activity
android:name=".MainActivity"
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/MainActivity.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/MainActivity.kt
index 3e27ff9..3066bdc 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/MainActivity.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/MainActivity.kt
@@ -22,11 +22,11 @@
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.bluetooth.integration.testapp.databinding.ActivityMainBinding
-import androidx.core.view.WindowCompat
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
-import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
+import androidx.navigation.ui.setupWithNavController
+import com.google.android.material.bottomnavigation.BottomNavigationView
class MainActivity : AppCompatActivity() {
@@ -41,19 +41,22 @@
}
}
- private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
- WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
- val navController = findNavController(R.id.nav_host_fragment)
- appBarConfiguration = AppBarConfiguration(navController.graph)
+ val navView: BottomNavigationView = binding.navView
+
+ val navController = findNavController(R.id.nav_host_fragment_activity_main)
+ val appBarConfiguration = AppBarConfiguration(
+ setOf(R.id.navigation_fwk, R.id.navigation_btx)
+ )
setupActionBarWithNavController(navController, appBarConfiguration)
+ navView.setupWithNavController(navController)
}
override fun onResume() {
@@ -67,9 +70,4 @@
)
)
}
-
- override fun onSupportNavigateUp(): Boolean {
- val navController = findNavController(R.id.nav_host_fragment)
- return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
- }
}
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/bluetoothx/BtxFragment.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/bluetoothx/BtxFragment.kt
index 8edffdd..fb39613 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/bluetoothx/BtxFragment.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/bluetoothx/BtxFragment.kt
@@ -23,10 +23,9 @@
import android.view.ViewGroup
import androidx.bluetooth.core.BluetoothManager
-import androidx.bluetooth.integration.testapp.R
import androidx.bluetooth.integration.testapp.databinding.FragmentBtxBinding
import androidx.fragment.app.Fragment
-import androidx.navigation.fragment.findNavController
+import androidx.lifecycle.ViewModelProvider
class BtxFragment : Fragment() {
@@ -34,6 +33,8 @@
const val TAG = "BtxFragment"
}
+ private lateinit var btxViewModel: BtxViewModel
+
private var _binding: FragmentBtxBinding? = null
// This property is only valid between onCreateView and onDestroyView.
@@ -44,6 +45,10 @@
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
+ Log.d(TAG, "onCreateView() called with: inflater = $inflater, " +
+ "container = $container, savedInstanceState = $savedInstanceState")
+ btxViewModel = ViewModelProvider(this).get(BtxViewModel::class.java)
+
_binding = FragmentBtxBinding.inflate(inflater, container, false)
return binding.root
}
@@ -51,10 +56,6 @@
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- binding.buttonPrevious.setOnClickListener {
- findNavController().navigate(R.id.action_BtxFragment_to_FwkFragment)
- }
-
binding.buttonScan.setOnClickListener {
scan()
}
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/bluetoothx/BtxViewModel.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/bluetoothx/BtxViewModel.kt
new file mode 100644
index 0000000..587047c
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/bluetoothx/BtxViewModel.kt
@@ -0,0 +1,35 @@
+/*
+ * 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
+ *
+ * http://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 androidx.bluetooth.integration.testapp.ui.bluetoothx
+
+import android.util.Log
+import androidx.lifecycle.ViewModel
+
+class BtxViewModel : ViewModel() {
+
+ companion object {
+ const val TAG = "BtxViewModel"
+ }
+
+ init {
+ Log.d(TAG, "init called")
+ }
+
+ override fun onCleared() {
+ Log.d(TAG, "onCleared() called")
+ }
+}
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/framework/FwkFragment.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/framework/FwkFragment.kt
index 5257eae..3230f45 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/framework/FwkFragment.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/framework/FwkFragment.kt
@@ -35,7 +35,7 @@
import androidx.bluetooth.integration.testapp.R
import androidx.bluetooth.integration.testapp.databinding.FragmentFwkBinding
import androidx.fragment.app.Fragment
-import androidx.navigation.fragment.findNavController
+import androidx.lifecycle.ViewModelProvider
class FwkFragment : Fragment() {
@@ -68,6 +68,8 @@
}
}
+ private lateinit var fwkViewModel: FwkViewModel
+
private var _binding: FragmentFwkBinding? = null
// This property is only valid between onCreateView and onDestroyView.
@@ -78,6 +80,10 @@
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
+ Log.d(TAG, "onCreateView() called with: inflater = $inflater, " +
+ "container = $container, savedInstanceState = $savedInstanceState")
+ fwkViewModel = ViewModelProvider(this)[FwkViewModel::class.java]
+
_binding = FragmentFwkBinding.inflate(inflater, container, false)
return binding.root
}
@@ -85,10 +91,6 @@
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- binding.buttonNext.setOnClickListener {
- findNavController().navigate(R.id.action_FwkFragment_to_BtxFragment)
- }
-
binding.buttonScan.setOnClickListener {
scan()
}
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/framework/FwkViewModel.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/framework/FwkViewModel.kt
new file mode 100644
index 0000000..d72fa738
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/framework/FwkViewModel.kt
@@ -0,0 +1,44 @@
+/*
+ * 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
+ *
+ * http://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 androidx.bluetooth.integration.testapp.ui.framework
+
+import android.util.Log
+import androidx.lifecycle.ViewModel
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.SupervisorJob
+import kotlinx.coroutines.cancel
+
+class FwkViewModel(
+ private val coroutineScope: CoroutineScope =
+ CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
+) : ViewModel() {
+
+ companion object {
+ const val TAG = "FwkViewModel"
+ }
+
+ init {
+ Log.d(TAG, "init called")
+ }
+
+ override fun onCleared() {
+ Log.d(TAG, "onCleared() called")
+
+ coroutineScope.cancel()
+ }
+}
diff --git a/bluetooth/integration-tests/testapp/src/main/res/drawable/ic_bluetooth_24.xml b/bluetooth/integration-tests/testapp/src/main/res/drawable/ic_bluetooth_24.xml
new file mode 100644
index 0000000..34e9311
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/res/drawable/ic_bluetooth_24.xml
@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="#000000"
+ android:viewportHeight="24" android:viewportWidth="24"
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="@android:color/white" android:pathData="M17.71,7.71L12,2h-1v7.59L6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 11,14.41L11,22h1l5.71,-5.71 -4.3,-4.29 4.3,-4.29zM13,5.83l1.88,1.88L13,9.59L13,5.83zM14.88,16.29L13,18.17v-3.76l1.88,1.88z"/>
+</vector>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/drawable/ic_filter_frames_24.xml b/bluetooth/integration-tests/testapp/src/main/res/drawable/ic_filter_frames_24.xml
new file mode 100644
index 0000000..244584b
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/res/drawable/ic_filter_frames_24.xml
@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="#000000"
+ android:viewportHeight="24" android:viewportWidth="24"
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="@android:color/white" android:pathData="M20,4h-4l-4,-4 -4,4L4,4c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2zM20,20L4,20L4,6h4.52l3.52,-3.5L15.52,6L20,6v14zM18,8L6,8v10h12"/>
+</vector>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/layout/activity_main.xml b/bluetooth/integration-tests/testapp/src/main/res/layout/activity_main.xml
index 8f063c6..8d6e2c6 100644
--- a/bluetooth/integration-tests/testapp/src/main/res/layout/activity_main.xml
+++ b/bluetooth/integration-tests/testapp/src/main/res/layout/activity_main.xml
@@ -14,22 +14,36 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-<androidx.coordinatorlayout.widget.CoordinatorLayout
+<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:fitsSystemWindows="true"
- tools:context=".MainActivity">
+ android:paddingTop="?attr/actionBarSize">
+
+ <com.google.android.material.bottomnavigation.BottomNavigationView
+ android:id="@+id/nav_view"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="0dp"
+ android:layout_marginEnd="0dp"
+ android:background="?android:attr/windowBackground"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintLeft_toLeftOf="parent"
+ app:layout_constraintRight_toRightOf="parent"
+ app:menu="@menu/bottom_nav_menu" />
<fragment
- android:id="@+id/nav_host_fragment"
+ android:id="@+id/nav_host_fragment_activity_main"
android:name="androidx.navigation.fragment.NavHostFragment"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
app:defaultNavHost="true"
+ app:layout_constraintBottom_toTopOf="@id/nav_view"
+ app:layout_constraintLeft_toLeftOf="parent"
+ app:layout_constraintRight_toRightOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_graph" />
-</androidx.coordinatorlayout.widget.CoordinatorLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_btx.xml b/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_btx.xml
index 0e75c18..de44e10 100644
--- a/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_btx.xml
+++ b/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_btx.xml
@@ -14,7 +14,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
@@ -25,16 +24,6 @@
tools:context=".ui.bluetoothx.BtxFragment">
<Button
- android:id="@+id/button_previous"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="16dp"
- android:layout_marginEnd="16dp"
- android:text="@string/previous"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
-
- <Button
android:id="@+id/button_scan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_fwk.xml b/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_fwk.xml
index 0b9be5f..ab03645 100644
--- a/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_fwk.xml
+++ b/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_fwk.xml
@@ -24,16 +24,6 @@
android:padding="16dp"
tools:context=".ui.framework.FwkFragment">
- <Button
- android:id="@+id/button_next"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="16dp"
- android:layout_marginEnd="16dp"
- android:text="@string/next"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
-
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/switch_advertise"
android:layout_width="wrap_content"
diff --git a/bluetooth/integration-tests/testapp/src/main/res/menu/bottom_nav_menu.xml b/bluetooth/integration-tests/testapp/src/main/res/menu/bottom_nav_menu.xml
new file mode 100644
index 0000000..887bc11
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/res/menu/bottom_nav_menu.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ 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
+
+ http://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.
+ -->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item
+ android:id="@+id/navigation_fwk"
+ android:icon="@drawable/ic_filter_frames_24"
+ android:title="@string/title_fwk" />
+
+ <item
+ android:id="@+id/navigation_btx"
+ android:icon="@drawable/ic_bluetooth_24"
+ android:title="@string/title_btx" />
+
+</menu>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/navigation/nav_graph.xml b/bluetooth/integration-tests/testapp/src/main/res/navigation/nav_graph.xml
index 8cb583c..6fb7139 100644
--- a/bluetooth/integration-tests/testapp/src/main/res/navigation/nav_graph.xml
+++ b/bluetooth/integration-tests/testapp/src/main/res/navigation/nav_graph.xml
@@ -14,31 +14,22 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
- app:startDestination="@id/FwkFragment">
+ app:startDestination="@id/navigation_fwk">
<fragment
- android:id="@+id/FwkFragment"
+ android:id="@+id/navigation_fwk"
android:name="androidx.bluetooth.integration.testapp.ui.framework.FwkFragment"
- android:label="@string/fwk_fragment_label"
- tools:layout="@layout/fragment_fwk">
- <action
- android:id="@+id/action_FwkFragment_to_BtxFragment"
- app:destination="@id/BtxFragment" />
- </fragment>
+ android:label="@string/title_fwk"
+ tools:layout="@layout/fragment_fwk" />
<fragment
- android:id="@+id/BtxFragment"
+ android:id="@+id/navigation_btx"
android:name="androidx.bluetooth.integration.testapp.ui.bluetoothx.BtxFragment"
- android:label="@string/btx_fragment_label"
- tools:layout="@layout/fragment_btx">
- <action
- android:id="@+id/action_BtxFragment_to_FwkFragment"
- app:destination="@id/FwkFragment" />
- </fragment>
+ android:label="@string/title_btx"
+ tools:layout="@layout/fragment_btx" />
</navigation>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/values/colors.xml b/bluetooth/integration-tests/testapp/src/main/res/values/colors.xml
new file mode 100644
index 0000000..7bfe85b
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/res/values/colors.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ 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
+
+ http://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.
+ -->
+<resources>
+ <color name="purple_200">#FFBB86FC</color>
+ <color name="purple_500">#FF6200EE</color>
+ <color name="purple_700">#FF3700B3</color>
+ <color name="teal_200">#FF03DAC5</color>
+ <color name="teal_700">#FF018786</color>
+ <color name="black">#FF000000</color>
+ <color name="white">#FFFFFFFF</color>
+</resources>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml b/bluetooth/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml
index ff75011..cb3aeef5 100644
--- a/bluetooth/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml
+++ b/bluetooth/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml
@@ -14,20 +14,16 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
<resources>
<string name="app_name">BluetoothX Test App</string>
- <!-- Strings used for fragments for navigation -->
- <string name="fwk_fragment_label">Framework Bluetooth Fragment</string>
- <string name="btx_fragment_label">BluetoothX Fragment</string>
- <string name="next">Next</string>
- <string name="previous">Previous</string>
+ <string name="title_fwk">Framework</string>
+ <string name="title_btx">BluetoothX</string>
<string name="scan_using_fwk">Scan using Framework Bluetooth APIs</string>
<string name="scan_using_btx">Scan using BluetoothX APIs</string>
- <string name="scan_start_message">Scan should have started. Results are in Logcat</string>
+ <string name="scan_start_message">Scan started. Results are in Logcat</string>
<string name="advertise_using_fwk">Advertise using Framework Bluetooth APIs</string>
<string name="advertise_start_message">Advertise started</string>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/values/themes.xml b/bluetooth/integration-tests/testapp/src/main/res/values/themes.xml
new file mode 100644
index 0000000..4c6fedf
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/res/values/themes.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ 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
+
+ http://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.
+ -->
+<resources xmlns:tools="http://schemas.android.com/tools">
+ <!-- Base application theme. -->
+ <style name="Theme.TestApp" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
+ <!-- Primary brand color. -->
+ <item name="colorPrimary">@color/purple_500</item>
+ <item name="colorPrimaryVariant">@color/purple_700</item>
+ <item name="colorOnPrimary">@color/white</item>
+ <!-- Secondary brand color. -->
+ <item name="colorSecondary">@color/teal_200</item>
+ <item name="colorSecondaryVariant">@color/teal_700</item>
+ <item name="colorOnSecondary">@color/black</item>
+ <!-- Status bar color. -->
+ <item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
+ <!-- Customize your theme here. -->
+ </style>
+</resources>