1 /* 2 * Copyright (C) 2020 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 package com.android.tv.settings.privacy 17 18 import android.app.tvsettings.TvSettingsEnums 19 import android.content.Intent 20 import android.os.Bundle 21 import android.view.LayoutInflater 22 import android.view.View 23 import android.view.ViewGroup 24 import androidx.annotation.Keep 25 import androidx.lifecycle.Lifecycle 26 import androidx.lifecycle.lifecycleScope 27 import androidx.lifecycle.repeatOnLifecycle 28 import androidx.preference.Preference 29 import androidx.preference.PreferenceCategory 30 import com.android.tv.settings.R 31 import com.android.tv.settings.SettingsPreferenceFragment 32 import com.android.tv.settings.overlay.FlavorUtils 33 import com.android.tv.settings.util.InstrumentationUtils 34 import com.android.tv.settings.util.SliceUtils 35 import com.android.tv.settings.util.SliceUtilsKt 36 import com.android.tv.twopanelsettings.slices.CustomContentDescriptionPreference 37 import com.android.tv.twopanelsettings.slices.SlicePreference 38 import kotlinx.coroutines.launch 39 40 /** 41 * The Privacy policies screen in Settings. 42 */ 43 @Keep 44 class PrivacyFragment : SettingsPreferenceFragment() { 45 private var mOverlaySecuritySlicePreference: Preference? = null 46 private var mSecurityPreference: Preference? = null 47 private var mUpdateSlicePreference: Preference? = null 48 private val preferenceScreenResId: Int 49 get() = when (FlavorUtils.getFlavor(context)) { 50 FlavorUtils.FLAVOR_X, FlavorUtils.FLAVOR_VENDOR -> R.xml.privacy_x 51 else -> R.xml.privacy 52 } 53 onCreatePreferencesnull54 override fun onCreatePreferences(bundle: Bundle?, s: String?) { 55 setPreferencesFromResource(preferenceScreenResId, null) 56 } 57 onCreateViewnull58 override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, 59 savedInstanceState: Bundle?): View { 60 mOverlaySecuritySlicePreference = findPreference(KEY_OVERLAY_SECURITY) 61 mSecurityPreference = findPreference(KEY_SECURITY) 62 mUpdateSlicePreference = findPreference(KEY_UPDATE) 63 val accountPrefCategory = findPreference<PreferenceCategory>(KEY_ACCOUNT_SETTINGS_CATEGORY) 64 val assistantSlicePreference = findPreference<Preference>(KEY_ASSISTANT) 65 val purchasesSlicePreference = findPreference<Preference>(KEY_PURCHASES) 66 val adsPreference = findPreference<Preference>(KEY_ADS) 67 val deviceLockPreference = findPreference<Preference>(KEY_DEVICE_LOCK) 68 PrivacyToggle.MIC_TOGGLE.preparePreferenceWithSensorFragment(context, 69 findPreference(KEY_MIC), SensorFragment.TOGGLE_EXTRA) 70 PrivacyToggle.CAMERA_TOGGLE.preparePreferenceWithSensorFragment(context, 71 findPreference(KEY_CAMERA), SensorFragment.TOGGLE_EXTRA) 72 adsPreference?.onPreferenceClickListener = Preference.OnPreferenceClickListener { 73 val intent = Intent().setAction("com.google.android.gms.settings.ADS_PRIVACY") 74 startActivity(intent) 75 true 76 } 77 if (adsPreference is CustomContentDescriptionPreference) { 78 adsPreference.contentDescription = resources.getString(R.string.ads_content_description) 79 } 80 if (FlavorUtils.getFeatureFactory(requireContext()).getBasicModeFeatureProvider() 81 .isBasicMode(requireContext())) { 82 accountPrefCategory?.isVisible = false 83 assistantSlicePreference?.isVisible = false 84 purchasesSlicePreference?.isVisible = false 85 showSecurityPreference(mSecurityPreference, mOverlaySecuritySlicePreference) 86 mUpdateSlicePreference?.isVisible = false 87 deviceLockPreference?.isVisible = deviceLockPreference is SlicePreference 88 && SliceUtils.isSliceProviderValid(context, deviceLockPreference.uri) 89 } else { 90 deviceLockPreference?.isVisible = false; 91 assistantSlicePreference?.isVisible = assistantSlicePreference is SlicePreference 92 && SliceUtils.isSliceProviderValid(context, assistantSlicePreference.uri) 93 purchasesSlicePreference?.isVisible = purchasesSlicePreference is SlicePreference 94 && SliceUtils.isSliceProviderValid(context, purchasesSlicePreference.uri) 95 accountPrefCategory?.isVisible = assistantSlicePreference?.isVisible == true 96 || purchasesSlicePreference?.isVisible == true 97 viewLifecycleOwner.lifecycleScope.launch { 98 lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { 99 if (isOverlaySecuritySlicePreferenceEnabled(mOverlaySecuritySlicePreference)) { 100 showOverlaySecuritySlicePreference( 101 mOverlaySecuritySlicePreference, mSecurityPreference) 102 } else { 103 showSecurityPreference(mSecurityPreference, mOverlaySecuritySlicePreference) 104 } 105 mUpdateSlicePreference?.isVisible = 106 isUpdateSlicePreferenceEnabled(mUpdateSlicePreference) 107 } 108 } 109 } 110 return checkNotNull(super.onCreateView(inflater, container, savedInstanceState)) 111 } 112 isOverlaySecuritySlicePreferenceEnablednull113 private suspend fun isOverlaySecuritySlicePreferenceEnabled( 114 overlaySecuritySlicePreference: Preference?): Boolean { 115 return (overlaySecuritySlicePreference is SlicePreference 116 && SliceUtilsKt.isSettingsSliceEnabled( 117 requireContext(), 118 overlaySecuritySlicePreference.uri, 119 TOP_LEVEL_SLICE_URI)) 120 } 121 showOverlaySecuritySlicePreferencenull122 private fun showOverlaySecuritySlicePreference( 123 overlaySecuritySlicePreference: Preference?, 124 securityPreference: Preference?) { 125 overlaySecuritySlicePreference?.isVisible = true 126 securityPreference?.isVisible = false 127 } 128 showSecurityPreferencenull129 private fun showSecurityPreference( 130 securityPreference: Preference?, 131 overlaySecuritySlicePreference: Preference?) { 132 securityPreference?.isVisible = true 133 overlaySecuritySlicePreference?.isVisible = false 134 } 135 isUpdateSlicePreferenceEnablednull136 private suspend fun isUpdateSlicePreferenceEnabled( 137 updateSlicePreference: Preference?): Boolean { 138 return (updateSlicePreference is SlicePreference 139 && SliceUtilsKt.isSettingsSliceEnabled( 140 requireContext(), 141 updateSlicePreference.uri, 142 TOP_LEVEL_SLICE_URI)) 143 } 144 onPreferenceTreeClicknull145 override fun onPreferenceTreeClick(preference: Preference): Boolean { 146 when (preference.key) { 147 KEY_USAGE -> InstrumentationUtils.logEntrySelected(TvSettingsEnums.PRIVACY_DIAGNOSTICS) 148 KEY_ADS -> InstrumentationUtils.logEntrySelected(TvSettingsEnums.PRIVACY_ADS) 149 } 150 return super.onPreferenceTreeClick(preference) 151 } 152 getPageIdnull153 override fun getPageId(): Int { 154 return TvSettingsEnums.PRIVACY 155 } 156 157 companion object { 158 private const val KEY_ACCOUNT_SETTINGS_CATEGORY = "accountSettings" 159 private const val KEY_USAGE = "usageAndDiag" 160 private const val KEY_ADS = "ads" 161 private const val KEY_ASSISTANT = "assistant" 162 private const val KEY_PURCHASES = "purchases" 163 private const val KEY_DEVICE_LOCK = "deviceLock" 164 private const val KEY_SECURITY = "security" 165 private const val KEY_OVERLAY_SECURITY = "overlay_security" 166 private const val KEY_MIC = "microphone" 167 private const val KEY_CAMERA = "camera" 168 private const val KEY_UPDATE = "update" 169 private const val TOP_LEVEL_SLICE_URI = "top_level_settings_slice_uri" 170 } 171 } 172