1 /* 2 * Copyright (C) 2017 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 android.content.Context; 20 import android.util.AttributeSet; 21 import android.view.MotionEvent; 22 import android.view.View; 23 import android.view.View.OnClickListener; 24 import android.widget.Switch; 25 26 import androidx.preference.PreferenceViewHolder; 27 28 import com.android.settings.R; 29 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; 30 import com.android.settingslib.RestrictedPreference; 31 32 /** 33 * A custom preference that provides inline switch toggle. It has a mandatory field for title, and 34 * optional fields for icon and sub-text. And it can be restricted by admin state. 35 */ 36 public class MasterSwitchPreference extends RestrictedPreference { 37 38 private Switch mSwitch; 39 private boolean mChecked; 40 private boolean mCheckedSet; 41 private boolean mEnableSwitch = true; 42 MasterSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)43 public MasterSwitchPreference(Context context, AttributeSet attrs, 44 int defStyleAttr, int defStyleRes) { 45 super(context, attrs, defStyleAttr, defStyleRes); 46 } 47 MasterSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr)48 public MasterSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) { 49 super(context, attrs, defStyleAttr); 50 } 51 MasterSwitchPreference(Context context, AttributeSet attrs)52 public MasterSwitchPreference(Context context, AttributeSet attrs) { 53 super(context, attrs); 54 } 55 MasterSwitchPreference(Context context)56 public MasterSwitchPreference(Context context) { 57 super(context); 58 } 59 60 @Override getSecondTargetResId()61 protected int getSecondTargetResId() { 62 return R.layout.restricted_preference_widget_master_switch; 63 } 64 65 @Override onBindViewHolder(PreferenceViewHolder holder)66 public void onBindViewHolder(PreferenceViewHolder holder) { 67 super.onBindViewHolder(holder); 68 final View switchWidget = holder.findViewById(R.id.switchWidget); 69 if (switchWidget != null) { 70 switchWidget.setVisibility(isDisabledByAdmin() ? View.GONE : View.VISIBLE); 71 switchWidget.setOnClickListener(new OnClickListener() { 72 @Override 73 public void onClick(View v) { 74 if (mSwitch != null && !mSwitch.isEnabled()) { 75 return; 76 } 77 setChecked(!mChecked); 78 if (!callChangeListener(mChecked)) { 79 setChecked(!mChecked); 80 } else { 81 persistBoolean(mChecked); 82 } 83 } 84 }); 85 86 // Consumes move events to ignore drag actions. 87 switchWidget.setOnTouchListener((v, event) -> { 88 return event.getActionMasked() == MotionEvent.ACTION_MOVE; 89 }); 90 } 91 92 mSwitch = (Switch) holder.findViewById(R.id.switchWidget); 93 if (mSwitch != null) { 94 mSwitch.setContentDescription(getTitle()); 95 mSwitch.setChecked(mChecked); 96 mSwitch.setEnabled(mEnableSwitch); 97 } 98 } 99 isChecked()100 public boolean isChecked() { 101 return mSwitch != null && mChecked; 102 } 103 setChecked(boolean checked)104 public void setChecked(boolean checked) { 105 // Always set checked the first time; don't assume the field's default of false. 106 final boolean changed = mChecked != checked; 107 if (changed || !mCheckedSet) { 108 mChecked = checked; 109 mCheckedSet = true; 110 if (mSwitch != null) { 111 mSwitch.setChecked(checked); 112 } 113 } 114 } 115 setSwitchEnabled(boolean enabled)116 public void setSwitchEnabled(boolean enabled) { 117 mEnableSwitch = enabled; 118 if (mSwitch != null) { 119 mSwitch.setEnabled(enabled); 120 } 121 } 122 123 /** 124 * If admin is not null, disables the switch. 125 * Otherwise, keep it enabled. 126 */ setDisabledByAdmin(EnforcedAdmin admin)127 public void setDisabledByAdmin(EnforcedAdmin admin) { 128 super.setDisabledByAdmin(admin); 129 setSwitchEnabled(admin == null); 130 } 131 getSwitch()132 public Switch getSwitch() { 133 return mSwitch; 134 } 135 136 @Override shouldHideSecondTarget()137 protected boolean shouldHideSecondTarget() { 138 return getSecondTargetResId() == 0; 139 } 140 } 141