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.settingslib;
18 
19 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
20 
21 import android.content.Context;
22 import android.os.UserHandle;
23 import android.util.AttributeSet;
24 
25 import androidx.annotation.NonNull;
26 import androidx.annotation.Nullable;
27 import androidx.preference.PreferenceManager;
28 import androidx.preference.PreferenceViewHolder;
29 
30 import com.android.settingslib.widget.SelectorWithWidgetPreference;
31 
32 /**
33  * Selector with widget preference that can be disabled by a device admin using a user restriction.
34  */
35 public class RestrictedSelectorWithWidgetPreference extends SelectorWithWidgetPreference {
36     private RestrictedPreferenceHelper mHelper;
37 
38     /**
39      * Perform inflation from XML and apply a class-specific base style.
40      *
41      * @param context The {@link Context} this is associated with, through which it can access the
42      *     current theme, resources, {@link SharedPreferences}, etc.
43      * @param attrs The attributes of the XML tag that is inflating the preference
44      * @param defStyle An attribute in the current theme that contains a reference to a style
45      *     resource that supplies default values for the view. Can be 0 to not look for defaults.
46      */
RestrictedSelectorWithWidgetPreference( @onNull Context context, @NonNull AttributeSet attrs, int defStyle)47     public RestrictedSelectorWithWidgetPreference(
48             @NonNull Context context, @NonNull AttributeSet attrs, int defStyle) {
49         super(context, attrs, defStyle);
50         mHelper = new RestrictedPreferenceHelper(context, /* preference= */ this, attrs);
51     }
52 
53     /**
54      * Perform inflation from XML and apply a class-specific base style.
55      *
56      * @param context The {@link Context} this is associated with, through which it can access the
57      *     current theme, resources, {@link SharedPreferences}, etc.
58      * @param attrs The attributes of the XML tag that is inflating the preference
59      */
RestrictedSelectorWithWidgetPreference( @onNull Context context, @NonNull AttributeSet attrs)60     public RestrictedSelectorWithWidgetPreference(
61             @NonNull Context context, @NonNull AttributeSet attrs) {
62         super(context, attrs);
63         mHelper = new RestrictedPreferenceHelper(context, /* preference= */ this, attrs);
64     }
65 
66     /**
67      * Constructor to create a preference, which will display with a checkbox style.
68      *
69      * @param context The {@link Context} this is associated with.
70      * @param isCheckbox Whether this preference should display as a checkbox.
71      */
RestrictedSelectorWithWidgetPreference(@onNull Context context, boolean isCheckbox)72     public RestrictedSelectorWithWidgetPreference(@NonNull Context context, boolean isCheckbox) {
73         super(context, null);
74         mHelper =
75                 new RestrictedPreferenceHelper(context, /* preference= */ this, /* attrs= */ null);
76     }
77 
78     /**
79      * Constructor to create a preference.
80      *
81      * @param context The Context this is associated with.
82      */
RestrictedSelectorWithWidgetPreference(@onNull Context context)83     public RestrictedSelectorWithWidgetPreference(@NonNull Context context) {
84         this(context, null);
85         mHelper =
86                 new RestrictedPreferenceHelper(context, /* preference= */ this, /* attrs= */ null);
87     }
88 
89     @Override
onBindViewHolder(@onNull PreferenceViewHolder holder)90     public void onBindViewHolder(@NonNull PreferenceViewHolder holder) {
91         super.onBindViewHolder(holder);
92         mHelper.onBindViewHolder(holder);
93     }
94 
95     @Override
performClick()96     public void performClick() {
97         if (!mHelper.performClick()) {
98             super.performClick();
99         }
100     }
101 
102     @Override
onAttachedToHierarchy(@onNull PreferenceManager preferenceManager)103     protected void onAttachedToHierarchy(@NonNull PreferenceManager preferenceManager) {
104         mHelper.onAttachedToHierarchy();
105         super.onAttachedToHierarchy(preferenceManager);
106     }
107 
108     /**
109      * Set the user restriction and disable this preference.
110      *
111      * @param userRestriction constant from {@link android.os.UserManager}
112      */
checkRestrictionAndSetDisabled(@onNull String userRestriction)113     public void checkRestrictionAndSetDisabled(@NonNull String userRestriction) {
114         mHelper.checkRestrictionAndSetDisabled(userRestriction, UserHandle.myUserId());
115     }
116 
117     /**
118      * Set the user restriction and disable this preference for the given user.
119      *
120      * @param userRestriction constant from {@link android.os.UserManager}
121      * @param userId user to check the restriction for.
122      */
checkRestrictionAndSetDisabled(@onNull String userRestriction, int userId)123     public void checkRestrictionAndSetDisabled(@NonNull String userRestriction, int userId) {
124         mHelper.checkRestrictionAndSetDisabled(userRestriction, userId);
125     }
126 
127     /**
128      * Checks if the given setting is subject to Enhanced Confirmation Mode restrictions for this
129      * package. Marks the preference as disabled if so.
130      *
131      * @param settingIdentifier The key identifying the setting
132      * @param packageName the package to check the settingIdentifier for
133      */
checkEcmRestrictionAndSetDisabled( @onNull String settingIdentifier, @NonNull String packageName)134     public void checkEcmRestrictionAndSetDisabled(
135             @NonNull String settingIdentifier, @NonNull String packageName) {
136         mHelper.checkEcmRestrictionAndSetDisabled(settingIdentifier, packageName);
137     }
138 
139     @Override
setEnabled(boolean enabled)140     public void setEnabled(boolean enabled) {
141         if (enabled && isDisabledByAdmin()) {
142             mHelper.setDisabledByAdmin(/* admin= */ null);
143             return;
144         }
145         super.setEnabled(enabled);
146     }
147 
148     /**
149      * Check whether this preference is disabled by admin.
150      *
151      * @return true if this preference is disabled by admin.
152      */
isDisabledByAdmin()153     public boolean isDisabledByAdmin() {
154         return mHelper.isDisabledByAdmin();
155     }
156 
157     /**
158      * Disable preference based on the enforce admin.
159      *
160      * @param admin details of the admin who enforced the restriction. If it is {@code null}, then
161      *     this preference will be enabled. Otherwise, it will be disabled.
162      */
setDisabledByAdmin(@ullable EnforcedAdmin admin)163     public void setDisabledByAdmin(@Nullable EnforcedAdmin admin) {
164         if (mHelper.setDisabledByAdmin(admin)) {
165             notifyChanged();
166         }
167     }
168 }
169