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