blob: fcad5f19da3af9f41ba5cebbfe69fc93acc2c883 [file] [log] [blame]
/*
* Copyright (C) 2024 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 com.android.intentresolver
import android.os.UserHandle
import androidx.annotation.MainThread
import com.android.app.tracing.coroutines.runBlockingTraced as runBlocking
import com.android.intentresolver.annotation.JavaInterop
import com.android.intentresolver.domain.interactor.UserInteractor
import com.android.intentresolver.shared.model.Profile
import com.android.intentresolver.shared.model.User
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.first
@JavaInterop
@MainThread
class ProfileHelper
@Inject
constructor(interactor: UserInteractor, private val background: CoroutineDispatcher) {
private val launchedByHandle: UserHandle = interactor.launchedAs
val launchedAsProfile by lazy {
runBlocking(context = background) { interactor.launchedAsProfile.first() }
}
val profiles by lazy { runBlocking(context = background) { interactor.profiles.first() } }
// Map UserHandle back to a user within launchedByProfile
private val launchedByUser: User =
when (launchedByHandle) {
launchedAsProfile.primary.handle -> launchedAsProfile.primary
launchedAsProfile.clone?.handle -> requireNotNull(launchedAsProfile.clone)
else -> error("launchedByUser must be a member of launchedByProfile")
}
val launchedAsProfileType: Profile.Type = launchedAsProfile.type
val personalProfile = profiles.single { it.type == Profile.Type.PERSONAL }
val workProfile = profiles.singleOrNull { it.type == Profile.Type.WORK }
val privateProfile = profiles.singleOrNull { it.type == Profile.Type.PRIVATE }
val personalHandle = personalProfile.primary.handle
val workHandle = workProfile?.primary?.handle
val privateHandle = privateProfile?.primary?.handle
val cloneHandle = personalProfile.clone?.handle
val isLaunchedAsCloneProfile = launchedByUser == launchedAsProfile.clone
val cloneUserPresent = personalProfile.clone != null
val workProfilePresent = workProfile != null
val privateProfilePresent = privateProfile != null
// Name retained for ease of review, to be renamed later
val tabOwnerUserHandleForLaunch =
if (launchedByUser.role == User.Role.CLONE) {
// When started by clone user, return the profile owner instead
launchedAsProfile.primary.handle
} else {
// Otherwise the launched user is used
launchedByUser.handle
}
fun findProfile(handle: UserHandle): Profile? {
return profiles.firstOrNull { it.primary.handle == handle || it.clone?.handle == handle }
}
fun findProfileType(handle: UserHandle): Profile.Type? = findProfile(handle)?.type
// Name retained for ease of review, to be renamed later
fun getQueryIntentsHandle(handle: UserHandle): UserHandle? {
return if (isLaunchedAsCloneProfile && handle == personalHandle) {
cloneHandle
} else {
handle
}
}
}