1 /*
<lambda>null2  * Copyright 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 androidx.core.telecom.test.ui
18 
19 import android.Manifest
20 import android.app.role.RoleManager
21 import android.content.pm.PackageManager
22 import android.os.Build
23 import androidx.activity.compose.rememberLauncherForActivityResult
24 import androidx.activity.result.contract.ActivityResultContracts
25 import androidx.compose.runtime.Composable
26 import androidx.compose.runtime.getValue
27 import androidx.compose.runtime.mutableStateOf
28 import androidx.compose.runtime.remember
29 import androidx.compose.runtime.setValue
30 import androidx.compose.ui.platform.LocalContext
31 import androidx.core.telecom.test.ui.calling.OngoingCallsViewModel
32 import androidx.lifecycle.viewmodel.compose.viewModel
33 import androidx.navigation.compose.NavHost
34 import androidx.navigation.compose.rememberNavController
35 
36 /** Compose UI for the application, which handles navigation between screens */
37 @Composable
38 fun CallingApp(isSupported: Boolean) {
39     val navController = rememberNavController()
40     val context = LocalContext.current
41     val roleManager = context.getSystemService(RoleManager::class.java)
42     var isGranted by remember { mutableStateOf(roleManager.isRoleHeld(RoleManager.ROLE_DIALER)) }
43     val roleIntent by remember {
44         mutableStateOf(roleManager.createRequestRoleIntent(RoleManager.ROLE_DIALER))
45     }
46     var isBtPermRequestSuggested by remember {
47         mutableStateOf(
48             // Telecom handles getting the name for UDC+
49             Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
50                 context.checkSelfPermission(Manifest.permission.BLUETOOTH_CONNECT) !=
51                     PackageManager.PERMISSION_GRANTED
52         )
53     }
54     val btPermlauncher =
55         rememberLauncherForActivityResult(contract = ActivityResultContracts.RequestPermission()) {
56             isBtGranted ->
57             isBtPermRequestSuggested = !isBtGranted
58             navController.launchAudioRouteDialog()
59         }
60 
61     val ongoingCallsViewModel: OngoingCallsViewModel = viewModel()
62 
63     val startRoute =
64         when (isSupported) {
65             true -> {
66                 when (isGranted) {
67                     true -> NavRoute.CALLS
68                     false -> NavRoute.ROLE_REQUESTS
69                 }
70             }
71             false -> NavRoute.NOT_SUPPORTED
72         }
73     // Following encapsulation guidelines from
74     // https://developer.android.com/guide/navigation/design/encapsulate
75     NavHost(navController, startDestination = startRoute) {
76         notSupportedDestination()
77         roleRequestsDestination(roleIntent) { isGranted = it }
78         callsDestination(
79             ongoingCallsViewModel,
80             onShowAudioRouting = {
81                 if (isBtPermRequestSuggested) {
82                     btPermlauncher.launch(Manifest.permission.BLUETOOTH_CONNECT)
83                 } else {
84                     navController.launchAudioRouteDialog()
85                 }
86             },
87             onMoveToSettings = { navController.moveToSettingsDestination() }
88         )
89         audioRouteDialog(
90             ongoingCallsViewModel,
91             onDismissDialog = { navController.popBackStack() },
92             onChangeAudioRoute = { ongoingCallsViewModel.onChangeAudioRoute(it) }
93         )
94         settingsDestination()
95     }
96 }
97