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