1 /*
2  * Copyright (C) 2023 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.settings.security;
17 
18 import static android.view.contentprotection.flags.Flags.manageDevicePolicyEnabled;
19 
20 import android.app.admin.DevicePolicyManager;
21 import android.content.ContentResolver;
22 import android.content.Context;
23 import android.os.UserHandle;
24 import android.provider.Settings;
25 import android.widget.CompoundButton;
26 import android.widget.CompoundButton.OnCheckedChangeListener;
27 
28 import androidx.annotation.NonNull;
29 import androidx.annotation.Nullable;
30 import androidx.annotation.VisibleForTesting;
31 import androidx.preference.Preference;
32 import androidx.preference.PreferenceScreen;
33 
34 import com.android.settings.R;
35 import com.android.settings.core.TogglePreferenceController;
36 import com.android.settings.widget.SettingsMainSwitchPreference;
37 import com.android.settingslib.RestrictedLockUtils;
38 import com.android.settingslib.RestrictedLockUtilsInternal;
39 
40 /** Preference controller for content protection toggle switch bar. */
41 public class ContentProtectionTogglePreferenceController extends TogglePreferenceController
42         implements OnCheckedChangeListener {
43 
44     @VisibleForTesting
45     static final String KEY_CONTENT_PROTECTION_PREFERENCE = "content_protection_user_consent";
46 
47     @Nullable private SettingsMainSwitchPreference mSwitchBar;
48 
49     @Nullable private RestrictedLockUtils.EnforcedAdmin mEnforcedAdmin;
50 
51     @NonNull private final ContentResolver mContentResolver;
52 
53     @DevicePolicyManager.ContentProtectionPolicy
54     private int mContentProtectionPolicy = DevicePolicyManager.CONTENT_PROTECTION_DISABLED;
55 
ContentProtectionTogglePreferenceController(Context context, String preferenceKey)56     public ContentProtectionTogglePreferenceController(Context context, String preferenceKey) {
57         super(context, preferenceKey);
58         mContentResolver = context.getContentResolver();
59 
60         if (manageDevicePolicyEnabled()) {
61             mEnforcedAdmin = getEnforcedAdmin();
62             mContentProtectionPolicy = getContentProtectionPolicy(getManagedProfile());
63         }
64     }
65 
66     @Override
getAvailabilityStatus()67     public int getAvailabilityStatus() {
68         return AVAILABLE;
69     }
70 
71     @Override
isChecked()72     public boolean isChecked() {
73         if (mEnforcedAdmin != null) {
74             if (!manageDevicePolicyEnabled()) {
75                 // If fully managed device, it should always unchecked
76                 return false;
77             }
78 
79             if (mContentProtectionPolicy == DevicePolicyManager.CONTENT_PROTECTION_DISABLED) {
80                 return false;
81             }
82             if (mContentProtectionPolicy == DevicePolicyManager.CONTENT_PROTECTION_ENABLED) {
83                 return true;
84             }
85         }
86         return Settings.Global.getInt(mContentResolver, KEY_CONTENT_PROTECTION_PREFERENCE, 0) >= 0;
87     }
88 
89     @Override
setChecked(boolean isChecked)90     public boolean setChecked(boolean isChecked) {
91         if (manageDevicePolicyEnabled()) {
92             if (mEnforcedAdmin != null
93                     && mContentProtectionPolicy
94                             != DevicePolicyManager.CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY) {
95                 return false;
96             }
97         }
98         Settings.Global.putInt(
99                 mContentResolver, KEY_CONTENT_PROTECTION_PREFERENCE, isChecked ? 1 : -1);
100         return true;
101     }
102 
103     @Override
displayPreference(PreferenceScreen screen)104     public void displayPreference(PreferenceScreen screen) {
105         super.displayPreference(screen);
106         final Preference preference = screen.findPreference(getPreferenceKey());
107 
108         if (preference instanceof SettingsMainSwitchPreference) {
109             mSwitchBar = (SettingsMainSwitchPreference) preference;
110             mSwitchBar.addOnSwitchChangeListener(this);
111         }
112     }
113 
114     // Workaround for SettingsMainSwitchPreference.setDisabledByAdmin without user restriction.
115     @Override
updateState(Preference preference)116     public void updateState(Preference preference) {
117         super.updateState(preference);
118 
119         if (!manageDevicePolicyEnabled()) {
120             // Assign the value to mEnforcedAdmin since it's needed in isChecked()
121             mEnforcedAdmin = getEnforcedAdmin();
122             mContentProtectionPolicy = DevicePolicyManager.CONTENT_PROTECTION_DISABLED;
123         }
124         if (mSwitchBar != null
125                 && mEnforcedAdmin != null
126                 && mContentProtectionPolicy
127                         != DevicePolicyManager.CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY) {
128             mSwitchBar.setDisabledByAdmin(mEnforcedAdmin);
129         }
130     }
131 
132     @Override
onCheckedChanged(CompoundButton buttonView, boolean isChecked)133     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
134         if (isChecked != isChecked()) {
135             setChecked(isChecked);
136         }
137     }
138 
139     @Override
getSliceHighlightMenuRes()140     public int getSliceHighlightMenuRes() {
141         return R.string.menu_key_security;
142     }
143 
144     @VisibleForTesting
145     @Nullable
getManagedProfile()146     protected UserHandle getManagedProfile() {
147         return ContentProtectionPreferenceUtils.getManagedProfile(mContext);
148     }
149 
150     @VisibleForTesting
151     @Nullable
getEnforcedAdmin()152     protected RestrictedLockUtils.EnforcedAdmin getEnforcedAdmin() {
153         return RestrictedLockUtilsInternal.getDeviceOwner(mContext);
154     }
155 
156     @VisibleForTesting
157     @DevicePolicyManager.ContentProtectionPolicy
getContentProtectionPolicy(@ullable UserHandle userHandle)158     protected int getContentProtectionPolicy(@Nullable UserHandle userHandle) {
159         return ContentProtectionPreferenceUtils.getContentProtectionPolicy(mContext, userHandle);
160     }
161 }
162