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