1 /*
2  * Copyright (C) 2016 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.content.res.TypedArray;
23 import android.os.UserHandle;
24 import android.util.AttributeSet;
25 import android.util.TypedValue;
26 import android.view.View;
27 import android.widget.TextView;
28 
29 import androidx.core.content.res.TypedArrayUtils;
30 import androidx.preference.PreferenceManager;
31 import androidx.preference.PreferenceViewHolder;
32 import androidx.preference.SwitchPreference;
33 
34 /**
35  * Version of SwitchPreference that can be disabled by a device admin
36  * using a user restriction.
37  */
38 public class RestrictedSwitchPreference extends SwitchPreference {
39     RestrictedPreferenceHelper mHelper;
40     boolean mUseAdditionalSummary = false;
41     CharSequence mRestrictedSwitchSummary;
42 
RestrictedSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)43     public RestrictedSwitchPreference(Context context, AttributeSet attrs,
44             int defStyleAttr, int defStyleRes) {
45         super(context, attrs, defStyleAttr, defStyleRes);
46         setWidgetLayoutResource(R.layout.restricted_switch_widget);
47         mHelper = new RestrictedPreferenceHelper(context, this, attrs);
48         if (attrs != null) {
49             final TypedArray attributes = context.obtainStyledAttributes(attrs,
50                     R.styleable.RestrictedSwitchPreference);
51             final TypedValue useAdditionalSummary = attributes.peekValue(
52                     R.styleable.RestrictedSwitchPreference_useAdditionalSummary);
53             if (useAdditionalSummary != null) {
54                 mUseAdditionalSummary =
55                         (useAdditionalSummary.type == TypedValue.TYPE_INT_BOOLEAN
56                                 && useAdditionalSummary.data != 0);
57             }
58 
59             final TypedValue restrictedSwitchSummary = attributes.peekValue(
60                     R.styleable.RestrictedSwitchPreference_restrictedSwitchSummary);
61             if (restrictedSwitchSummary != null
62                     && restrictedSwitchSummary.type == TypedValue.TYPE_STRING) {
63                 if (restrictedSwitchSummary.resourceId != 0) {
64                     mRestrictedSwitchSummary =
65                         context.getText(restrictedSwitchSummary.resourceId);
66                 } else {
67                     mRestrictedSwitchSummary = restrictedSwitchSummary.string;
68                 }
69             }
70         }
71         if (mUseAdditionalSummary) {
72             setLayoutResource(R.layout.restricted_switch_preference);
73             useAdminDisabledSummary(false);
74         }
75     }
76 
RestrictedSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr)77     public RestrictedSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
78         this(context, attrs, defStyleAttr, 0);
79     }
80 
RestrictedSwitchPreference(Context context, AttributeSet attrs)81     public RestrictedSwitchPreference(Context context, AttributeSet attrs) {
82         this(context, attrs, TypedArrayUtils.getAttr(context, R.attr.switchPreferenceStyle,
83                 android.R.attr.switchPreferenceStyle));
84     }
85 
RestrictedSwitchPreference(Context context)86     public RestrictedSwitchPreference(Context context) {
87         this(context, null);
88     }
89 
90     @Override
onBindViewHolder(PreferenceViewHolder holder)91     public void onBindViewHolder(PreferenceViewHolder holder) {
92         super.onBindViewHolder(holder);
93         mHelper.onBindViewHolder(holder);
94 
95         CharSequence switchSummary;
96         if (mRestrictedSwitchSummary == null) {
97             switchSummary = getContext().getText(isChecked()
98                 ? R.string.enabled_by_admin : R.string.disabled_by_admin);
99         } else {
100             switchSummary = mRestrictedSwitchSummary;
101         }
102 
103         final View restrictedIcon = holder.findViewById(R.id.restricted_icon);
104         final View switchWidget = holder.findViewById(android.R.id.switch_widget);
105         if (restrictedIcon != null) {
106             restrictedIcon.setVisibility(isDisabledByAdmin() ? View.VISIBLE : View.GONE);
107         }
108         if (switchWidget != null) {
109             switchWidget.setVisibility(isDisabledByAdmin() ? View.GONE : View.VISIBLE);
110         }
111 
112         if (mUseAdditionalSummary) {
113             final TextView additionalSummaryView = (TextView) holder.findViewById(
114                     R.id.additional_summary);
115             if (additionalSummaryView != null) {
116                 if (isDisabledByAdmin()) {
117                     additionalSummaryView.setText(switchSummary);
118                     additionalSummaryView.setVisibility(View.VISIBLE);
119                 } else {
120                     additionalSummaryView.setVisibility(View.GONE);
121                 }
122             }
123         } else {
124             final TextView summaryView = (TextView) holder.findViewById(android.R.id.summary);
125             if (summaryView != null) {
126                 if (isDisabledByAdmin()) {
127                     summaryView.setText(switchSummary);
128                     summaryView.setVisibility(View.VISIBLE);
129                 }
130                 // No need to change the visibility to GONE in the else case here since Preference
131                 // class would have already changed it if there is no summary to display.
132             }
133         }
134     }
135 
136     @Override
performClick()137     public void performClick() {
138         if (!mHelper.performClick()) {
139             super.performClick();
140         }
141     }
142 
useAdminDisabledSummary(boolean useSummary)143     public void useAdminDisabledSummary(boolean useSummary) {
144         mHelper.useAdminDisabledSummary(useSummary);
145     }
146 
147     @Override
onAttachedToHierarchy(PreferenceManager preferenceManager)148     protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
149         mHelper.onAttachedToHierarchy();
150         super.onAttachedToHierarchy(preferenceManager);
151     }
152 
checkRestrictionAndSetDisabled(String userRestriction)153     public void checkRestrictionAndSetDisabled(String userRestriction) {
154         mHelper.checkRestrictionAndSetDisabled(userRestriction, UserHandle.myUserId());
155     }
156 
checkRestrictionAndSetDisabled(String userRestriction, int userId)157     public void checkRestrictionAndSetDisabled(String userRestriction, int userId) {
158         mHelper.checkRestrictionAndSetDisabled(userRestriction, userId);
159     }
160 
161     @Override
setEnabled(boolean enabled)162     public void setEnabled(boolean enabled) {
163         if (enabled && isDisabledByAdmin()) {
164             mHelper.setDisabledByAdmin(null);
165             return;
166         }
167         super.setEnabled(enabled);
168     }
169 
setDisabledByAdmin(EnforcedAdmin admin)170     public void setDisabledByAdmin(EnforcedAdmin admin) {
171         if (mHelper.setDisabledByAdmin(admin)) {
172             notifyChanged();
173         }
174     }
175 
isDisabledByAdmin()176     public boolean isDisabledByAdmin() {
177         return mHelper.isDisabledByAdmin();
178     }
179 }
180