1 /*
<lambda>null2  * 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.multiuser.widget.domain
18 
19 import com.android.multiuser.widget.data.ActionsRepository
20 import com.android.multiuser.widget.data.UserDao
21 import com.android.multiuser.widget.data.model.Action
22 import com.android.multiuser.widget.data.model.User
23 import com.android.multiuser.widget.util.SHOULD_DISPLAY_ADD_USER_BUTTON
24 import com.android.multiuser.widget.viewmodel.ActionViewModel
25 import com.android.multiuser.widget.viewmodel.UserViewModel
26 import com.android.multiuser.widget.viewmodel.UsersViewModel
27 import kotlinx.coroutines.CoroutineDispatcher
28 import kotlinx.coroutines.Dispatchers
29 import kotlinx.coroutines.flow.Flow
30 import kotlinx.coroutines.flow.first
31 import kotlinx.coroutines.flow.flow
32 import kotlinx.coroutines.withContext
33 
34 /**
35  * Maps data from the local Room database into viewmodel [UsersViewModel].
36  */
37 class LoadUsersUseCase(
38     private val userDao: UserDao,
39     private val dispatcher: CoroutineDispatcher = Dispatchers.Default,
40     private val actionsRepository: ActionsRepository
41 ) {
42     suspend operator fun invoke(): Flow<UsersViewModel> = withContext(dispatcher) {
43         return@withContext loadUsersViewModel()
44     }
45 
46     private fun loadUsersViewModel(): Flow<UsersViewModel>  {
47         return flow {
48             val model = UsersViewModel(
49                 users = getUserViewModels(),
50                 actions = getActionViewModels(),
51             )
52             emit(model)
53         }
54     }
55 
56     private suspend fun getUserViewModels() =
57             userDao.getUsers().first().map { user -> mapUserToUserViewModel(user) }
58 
59     private suspend fun getActionViewModels(): List<ActionViewModel> {
60         // If the current user is an admin and SHOW_ADD_USER_BUTTON is set to true, include the
61         // button for adding users.
62         if(userDao.getCurrentUser().first().isAdmin && SHOULD_DISPLAY_ADD_USER_BUTTON) {
63             return listOf(mapActionToActionViewModel(actionsRepository.getAddUserAction()))
64         }
65 
66         return emptyList()
67     }
68 
69     private fun mapUserToUserViewModel(user: User): UserViewModel {
70         return UserViewModel(
71             iconPath = user.iconPath,
72             id = user.id,
73             name = user.name,
74             isSelected = user.isCurrentUser,
75             // contentDescription is auto-generated because user icons are selectable
76             contentDescription = null,
77         )
78     }
79 
80     private fun mapActionToActionViewModel(action: Action): ActionViewModel {
81         return ActionViewModel (
82             title = action.title,
83             resourceId = action.resourceId,
84             contentDescription = action.contentDescription
85         )
86     }
87 }
88