blob: 4f8173745b77d4f51def4fa8251564a61b0000f5 [file]
/*
* Copyright (C) 2026 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.settings.utils
import android.content.Context
import android.content.pm.ApplicationInfo
import android.os.Process
import android.os.UserHandle
import android.os.UserManager
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import com.android.settings.R
import com.android.settingslib.spa.widget.dialog.AlertDialogButton
import com.android.settingslib.spa.widget.dialog.AlertDialogPresenter
import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter
/** Utilities for HSU (Headless System User) apps. */
object HsuUtils {
/**
* Checks if the given app is a Headless System User (HSU) app.
*
* HSU apps run as the system user (User 0) on devices where the system user is headless. These
* apps are distinct from the current user's apps.
*/
@JvmStatic
fun isHsuApp(context: Context, app: ApplicationInfo): Boolean {
if (app.uid == Process.INVALID_UID) return false
return UserManager.isHeadlessSystemUserMode() &&
UserHandle.getUserId(app.uid) == UserHandle.USER_SYSTEM
}
/** Checks if the current user is an admin. */
@JvmStatic
fun isAdmin(context: Context): Boolean {
val userManager = context.getSystemService(UserManager::class.java)!!
return userManager.isAdminUser
}
/**
* Checks if the current user can control the given HSU app. Returns true if it's NOT an HSU
* app, or if it IS an HSU app and the user is an Admin.
*
* Non-admin users are restricted from modifying HSU apps to prevent system-wide impact.
*/
@JvmStatic
fun canControlHsuApp(context: Context, app: ApplicationInfo): Boolean {
if (!isHsuApp(context, app)) return true
return isAdmin(context)
}
/**
* Creates a presenter for the warning dialog shown when an admin attempts to modify an HSU app.
*
* This dialog warns the admin that changes will affect all users on the device.
*/
@Composable
fun rememberHsuAppWarningDialogPresenter(onConfirm: () -> Unit): AlertDialogPresenter {
return rememberAlertDialogPresenter(
confirmButton =
AlertDialogButton(text = stringResource(R.string.okay), onClick = onConfirm),
dismissButton = AlertDialogButton(stringResource(R.string.cancel)),
title = stringResource(R.string.hsu_app_warning_dialog_title),
text = { Text(stringResource(R.string.hsu_app_warning_dialog_message)) },
)
}
}