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 
17 package com.android.settings.widget;
18 
19 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
20 
21 import android.content.Context;
22 import android.util.AttributeSet;
23 import android.view.View;
24 
25 import com.android.settings.overlay.FeatureFactory;
26 import com.android.settingslib.RestrictedLockUtils;
27 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
28 import com.android.settingslib.widget.MainSwitchBar;
29 
30 /**
31  * A {@link MainSwitchBar} with a customized Switch and provides the metrics feature.
32  */
33 public class SettingsMainSwitchBar extends MainSwitchBar {
34 
35     /**
36      * Called before the checked state of the Switch has changed.
37      */
38     public interface OnBeforeCheckedChangeListener {
39 
40         /**
41          * @param isChecked The new checked state of switchView.
42          */
onBeforeCheckedChanged(boolean isChecked)43         boolean onBeforeCheckedChanged(boolean isChecked);
44     }
45 
46     private EnforcedAdmin mEnforcedAdmin;
47     private boolean mDisabledByAdmin;
48 
49     private final MetricsFeatureProvider mMetricsFeatureProvider;
50     private OnBeforeCheckedChangeListener mOnBeforeListener;
51 
52     private int mMetricsCategory;
53 
SettingsMainSwitchBar(Context context)54     public SettingsMainSwitchBar(Context context) {
55         this(context, null);
56     }
57 
SettingsMainSwitchBar(Context context, AttributeSet attrs)58     public SettingsMainSwitchBar(Context context, AttributeSet attrs) {
59         this(context, attrs, 0);
60     }
61 
SettingsMainSwitchBar(Context context, AttributeSet attrs, int defStyleAttr)62     public SettingsMainSwitchBar(Context context, AttributeSet attrs, int defStyleAttr) {
63         this(context, attrs, defStyleAttr, 0);
64     }
65 
SettingsMainSwitchBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)66     public SettingsMainSwitchBar(Context context, AttributeSet attrs, int defStyleAttr,
67             int defStyleRes) {
68         super(context, attrs, defStyleAttr, defStyleRes);
69         mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
70 
71         addOnSwitchChangeListener((switchView, isChecked) -> logMetrics(isChecked));
72     }
73 
74     /**
75      * If admin is not null, disables the text and switch but keeps the view clickable (unless the
76      * switch is disabled for other reasons). Otherwise, calls setEnabled.
77      */
setDisabledByAdmin(EnforcedAdmin admin)78     public void setDisabledByAdmin(EnforcedAdmin admin) {
79         mEnforcedAdmin = admin;
80         if (admin != null) {
81             super.setEnabled(true);
82             mDisabledByAdmin = true;
83             mTextView.setEnabled(false);
84             mSwitch.setEnabled(false);
85         } else {
86             mDisabledByAdmin = false;
87             mSwitch.setVisibility(View.VISIBLE);
88             setEnabled(isEnabled());
89         }
90     }
91 
92     @Override
setEnabled(boolean enabled)93     public void setEnabled(boolean enabled) {
94         if (enabled && mDisabledByAdmin) {
95             setDisabledByAdmin(null);
96             return;
97         }
98         super.setEnabled(enabled);
99     }
100 
101     /**
102      * Called by the restricted icon clicked.
103      */
104 
105     @Override
performClick()106     public boolean performClick() {
107         if (mDisabledByAdmin) {
108             performRestrictedClick();
109             return true;
110         }
111 
112         return mSwitch.performClick();
113     }
114 
115     @Override
setChecked(boolean checked)116     public void setChecked(boolean checked) {
117         if (mOnBeforeListener != null
118                 && mOnBeforeListener.onBeforeCheckedChanged(checked)) {
119             return;
120         }
121         super.setChecked(checked);
122     }
123 
124     /**
125      * Update the status of switch but doesn't notify the mOnBeforeListener.
126      */
setCheckedInternal(boolean checked)127     public void setCheckedInternal(boolean checked) {
128         super.setChecked(checked);
129     }
130 
131     /**
132      * Set the OnBeforeCheckedChangeListener.
133      */
setOnBeforeCheckedChangeListener(OnBeforeCheckedChangeListener listener)134     public void setOnBeforeCheckedChangeListener(OnBeforeCheckedChangeListener listener) {
135         mOnBeforeListener = listener;
136     }
137 
138     /**
139      * Set the metrics tag.
140      */
setMetricsCategory(int category)141     public void setMetricsCategory(int category) {
142         mMetricsCategory = category;
143     }
144 
logMetrics(boolean isChecked)145     private void logMetrics(boolean isChecked) {
146         mMetricsFeatureProvider.changed(mMetricsCategory, "switch_bar", isChecked ? 1 : 0);
147     }
148 
performRestrictedClick()149     private void performRestrictedClick() {
150         RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(), mEnforcedAdmin);
151         mMetricsFeatureProvider.clicked(mMetricsCategory, "switch_bar|restricted");
152     }
153 }
154