1 /* 2 * 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.settings.security 18 19 import android.content.Intent 20 import android.content.pm.PackageManager 21 import android.security.advancedprotection.AdvancedProtectionManager 22 import android.security.advancedprotection.AdvancedProtectionManager.EXTRA_SUPPORT_DIALOG_FEATURE 23 import android.security.advancedprotection.AdvancedProtectionManager.EXTRA_SUPPORT_DIALOG_TYPE 24 import android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_CELLULAR_2G 25 import android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES 26 import android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_WEP 27 import android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_ENABLE_MTE 28 import android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION 29 import android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_DISABLED_SETTING 30 import android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_UNKNOWN 31 import android.util.Log 32 import android.view.WindowManager 33 import androidx.annotation.VisibleForTesting 34 import androidx.compose.material3.Icon 35 import androidx.compose.material3.Text 36 import androidx.compose.runtime.Composable 37 import androidx.compose.ui.res.painterResource 38 import com.android.settings.R 39 import com.android.settingslib.spa.SpaDialogWindowTypeActivity 40 import com.android.settingslib.spa.widget.dialog.AlertDialogButton 41 import com.android.settingslib.spa.widget.dialog.SettingsAlertDialogContent 42 import com.android.settingslib.wifi.WifiUtils.Companion.DIALOG_WINDOW_TYPE 43 44 class ActionDisabledByAdvancedProtectionDialog : SpaDialogWindowTypeActivity() { 45 46 @Composable Contentnull47 override fun Content() { 48 SettingsAlertDialogContent( 49 confirmButton = AlertDialogButton(getString(R.string.okay)) { 50 finish() 51 logDialogShown(learnMoreClicked = false) 52 }, 53 dismissButton = getSupportButtonIfExists(), 54 title = getString(R.string.disabled_by_advanced_protection_title), 55 icon = { 56 Icon( 57 painter = painterResource(R.drawable.ic_settings_safety_center), 58 contentDescription = null 59 ) 60 }, 61 text = { Text(getDialogMessage()) }) 62 } 63 getDialogMessagenull64 private fun getDialogMessage(): String { 65 val featureId = getIntentFeatureId() 66 val type = getIntentDialogueType() 67 val messageId = when (type) { 68 SUPPORT_DIALOG_TYPE_DISABLED_SETTING -> { 69 if (featureIdsWithSettingOn.contains(featureId)) { 70 R.string.disabled_by_advanced_protection_setting_is_on_message 71 } else if (featureIdsWithSettingOff.contains(featureId)) { 72 R.string.disabled_by_advanced_protection_setting_is_off_message 73 } else { 74 defaultMessageId 75 } 76 } 77 SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION -> { 78 if (featureId == FEATURE_ID_DISALLOW_WEP) { 79 R.string.disabled_by_advanced_protection_wep_action_message 80 } else { 81 R.string.disabled_by_advanced_protection_action_message 82 } 83 } 84 else -> defaultMessageId 85 } 86 return getString(messageId) 87 } 88 89 @VisibleForTesting getSupportButtonIfExistsnull90 fun getSupportButtonIfExists(): AlertDialogButton? { 91 try { 92 val helpIntentUri = getString( 93 com.android.internal.R.string.config_help_url_action_disabled_by_advanced_protection 94 ) 95 val helpIntent = Intent.parseUri(helpIntentUri, Intent.URI_INTENT_SCHEME) 96 if (helpIntent == null) return null 97 helpIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 98 val helpActivityInfo = packageManager.resolveActivity(helpIntent, /* flags */ 0) 99 ?.activityInfo 100 if (helpActivityInfo == null) return null 101 return AlertDialogButton( 102 getString(R.string.disabled_by_advanced_protection_help_button_title) 103 ) { 104 startActivity(helpIntent) 105 finish() 106 logDialogShown(learnMoreClicked = true) 107 } 108 } catch (e: Exception) { 109 Log.w(TAG, "Tried to set up help button, but this exception was thrown: ${e.message}") 110 } 111 return null 112 } 113 logDialogShownnull114 private fun logDialogShown(learnMoreClicked: Boolean) { 115 // We should always have this permission, but just in case we don't, we should not log. 116 if (checkSelfPermission(android.Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE) 117 != PackageManager.PERMISSION_GRANTED) { 118 return 119 } 120 121 this.getSystemService(AdvancedProtectionManager::class.java) 122 .logDialogShown(getIntentFeatureId(), getIntentDialogueType(), learnMoreClicked) 123 } 124 getDialogWindowTypenull125 override fun getDialogWindowType(): Int? = if (intent.hasExtra(DIALOG_WINDOW_TYPE)) { 126 intent.getIntExtra(DIALOG_WINDOW_TYPE, WindowManager.LayoutParams.TYPE_APPLICATION) 127 } else null 128 getIntentFeatureIdnull129 private fun getIntentFeatureId(): Int { 130 return intent.getIntExtra(EXTRA_SUPPORT_DIALOG_FEATURE, -1) 131 } 132 getIntentDialogueTypenull133 private fun getIntentDialogueType(): Int { 134 return intent.getIntExtra(EXTRA_SUPPORT_DIALOG_TYPE, SUPPORT_DIALOG_TYPE_UNKNOWN) 135 } 136 137 private companion object { 138 const val TAG = "AdvancedProtectionDlg" 139 val defaultMessageId = R.string.disabled_by_advanced_protection_action_message 140 val featureIdsWithSettingOn = setOf(FEATURE_ID_DISALLOW_CELLULAR_2G, FEATURE_ID_ENABLE_MTE) 141 val featureIdsWithSettingOff = 142 setOf(FEATURE_ID_DISALLOW_WEP, FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES) 143 } 144 } 145