1 /* 2 * Copyright (C) 2024 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.os.Parcel 21 import android.os.Parcelable 22 import android.widget.CompoundButton 23 import android.widget.CompoundButton.OnCheckedChangeListener 24 import androidx.preference.TwoStatePreference 25 import com.android.settings.SettingsActivity 26 import com.android.settingslib.metadata.PreferenceAvailabilityProvider 27 import com.android.settingslib.widget.MainSwitchBar 28 29 /** Preference abstraction of the [MainSwitchBar] in settings activity. */ 30 class MainSwitchBarPreference(context: Context, private val metadata: MainSwitchBarMetadata) : 31 TwoStatePreference(context), OnCheckedChangeListener, MainSwitchBar.PreChangeListener { 32 33 // main switch bar might be null when configuration is just changed 34 private val mainSwitchBar: MainSwitchBar? 35 get() = (context as SettingsActivity).switchBar 36 setTitlenull37 override fun setTitle(title: CharSequence?) { 38 mainSwitchBar?.setTitle(title) 39 super.setTitle(title) 40 } 41 setSummarynull42 override fun setSummary(summary: CharSequence?) { 43 mainSwitchBar?.setSummary(summary) 44 super.setSummary(summary) 45 } 46 setEnablednull47 override fun setEnabled(enabled: Boolean) { 48 mainSwitchBar?.isEnabled = enabled 49 super.setEnabled(enabled) 50 } 51 52 // Preference.setVisible is final, we cannot override it updateVisibilitynull53 fun updateVisibility() { 54 // always make preference invisible, the UI visibility is reflected on MainSwitchBar 55 isVisible = false 56 val mainSwitchBar = mainSwitchBar ?: return 57 if ((metadata as? PreferenceAvailabilityProvider)?.isAvailable(context) != false) { 58 mainSwitchBar.show() 59 } else { 60 mainSwitchBar.hide() 61 } 62 } 63 setCheckednull64 override fun setChecked(checked: Boolean) { 65 val mainSwitchBar = mainSwitchBar ?: return 66 // remove listener to update UI only 67 mainSwitchBar.removeOnSwitchChangeListener(this) 68 mainSwitchBar.isChecked = checked 69 mainSwitchBar.addOnSwitchChangeListener(this) 70 } 71 onAttachednull72 override fun onAttached() { 73 super.onAttached() 74 val mainSwitchBar = mainSwitchBar!! 75 mainSwitchBar.setPreChangeListener(this) 76 mainSwitchBar.addOnSwitchChangeListener(this) 77 } 78 preChangenull79 override fun preChange(isCheck: Boolean) = callChangeListener(isCheck) 80 81 override fun onCheckedChanged(buttonView: CompoundButton, isChecked: Boolean) { 82 // prevent user from toggling the switch before data store operation is done 83 if (metadata.disableWidgetOnCheckedChanged) isEnabled = false 84 // once data store is updated, isEnabled will be reset due to rebind 85 persistBoolean(isChecked) 86 } 87 onDetachednull88 override fun onDetached() { 89 val mainSwitchBar = mainSwitchBar!! 90 mainSwitchBar.removeOnSwitchChangeListener(this) 91 mainSwitchBar.setPreChangeListener(null) 92 super.onDetached() 93 } 94 onSaveInstanceStatenull95 override fun onSaveInstanceState(): Parcelable = 96 SavedState(super.onSaveInstanceState()!!).also { 97 it.isEnabled = isEnabled 98 it.title = title 99 it.summary = summary 100 it.mainSwitchBarState = mainSwitchBar?.onSaveInstanceState() 101 } 102 onRestoreInstanceStatenull103 override fun onRestoreInstanceState(state: Parcelable?) { 104 val savedState = state as SavedState 105 super.onRestoreInstanceState(savedState.superState) 106 isEnabled = savedState.isEnabled 107 title = savedState.title 108 summary = savedState.summary 109 mainSwitchBar?.onRestoreInstanceState(savedState.mainSwitchBarState!!) 110 } 111 112 private class SavedState : BaseSavedState { 113 var isEnabled: Boolean = false 114 var title: CharSequence? = null 115 var summary: CharSequence? = null 116 var mainSwitchBarState: Parcelable? = null 117 118 constructor(source: Parcel) : super(source) { 119 isEnabled = source.readBoolean() 120 title = source.readCharSequence() 121 summary = source.readCharSequence() 122 val stateClass = MainSwitchBar.SavedState::class.java 123 mainSwitchBarState = source.readParcelable(stateClass.classLoader, stateClass) 124 } 125 126 constructor(superState: Parcelable) : super(superState) 127 writeToParcelnull128 override fun writeToParcel(dest: Parcel, flags: Int) { 129 super.writeToParcel(dest, flags) 130 dest.writeBoolean(isEnabled) 131 dest.writeCharSequence(title) 132 dest.writeCharSequence(summary) 133 dest.writeParcelable(mainSwitchBarState, flags) 134 } 135 136 companion object { 137 @JvmField 138 val CREATOR: Parcelable.Creator<SavedState> = 139 object : Parcelable.Creator<SavedState> { createFromParcelnull140 override fun createFromParcel(parcel: Parcel): SavedState { 141 return SavedState(parcel) 142 } 143 newArraynull144 override fun newArray(size: Int): Array<SavedState?> { 145 return arrayOfNulls(size) 146 } 147 } 148 } 149 } 150 } 151