1 /* 2 * Copyright (C) 2019 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 package com.android.tv.twopanelsettings.slices 17 18 import android.app.PendingIntent 19 import android.app.slice.Slice 20 import android.content.Context 21 import android.content.Intent 22 import android.util.AttributeSet 23 import android.util.Log 24 import androidx.preference.TwoStatePreference 25 import com.android.tv.twopanelsettings.R 26 import com.android.tv.twopanelsettings.slices.EmbeddedSlicePreferenceHelper.SlicePreferenceListener 27 28 /** 29 * An embedded slice switch preference which would be embedded in common TvSettings preference 30 * items, but will automatically update its status and communicates with external apps through 31 * slice api. 32 */ 33 class EmbeddedSliceSwitchPreference : SliceSwitchPreference { 34 private val mHelper: EmbeddedSlicePreferenceHelper 35 private var mUri: String? = null 36 onAttachednull37 override fun onAttached() { 38 super.onAttached() 39 mHelper.onAttached() 40 } 41 onDetachednull42 override fun onDetached() { 43 super.onDetached() 44 mHelper.onDetached() 45 } 46 47 constructor(context: Context?) : super(context) { 48 init(null) 49 mHelper = EmbeddedSlicePreferenceHelper(this, mUri!!) 50 } 51 52 constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) { 53 init(attrs) 54 mHelper = EmbeddedSlicePreferenceHelper(this, mUri!!) 55 } 56 initnull57 private fun init(attrs: AttributeSet?) { 58 if (attrs != null) { 59 initStyleAttributes(attrs) 60 } 61 } 62 initStyleAttributesnull63 private fun initStyleAttributes(attrs: AttributeSet) { 64 val a = context.obtainStyledAttributes( 65 attrs, R.styleable.SlicePreference 66 ) 67 for (i in a.indexCount - 1 downTo 0) { 68 val attr = a.getIndex(i) 69 if (attr == R.styleable.SlicePreference_uri) { 70 mUri = a.getString(attr) 71 break 72 } 73 } 74 } 75 addListenernull76 fun addListener(listener: SlicePreferenceListener?) { 77 mHelper.mListener = listener 78 } 79 removeListenernull80 fun removeListener(listener: SlicePreferenceListener?) { 81 mHelper.mListener = null 82 } 83 updatenull84 fun update() { 85 title = mHelper.mNewPref!!.title 86 summary = mHelper.mNewPref!!.summary 87 icon = mHelper.mNewPref!!.icon 88 if (mHelper.mNewPref is TwoStatePreference) { 89 isChecked = (mHelper.mNewPref as TwoStatePreference).isChecked 90 } 91 if (mHelper.mNewPref is HasSliceAction) { 92 sliceAction = (mHelper.mNewPref as HasSliceAction).sliceAction 93 } 94 isVisible = true 95 } 96 onClicknull97 public override fun onClick() { 98 var newValue = !isChecked 99 try { 100 if (mAction == null) { 101 return 102 } 103 if (mAction.isToggle) { 104 // Update the intent extra state 105 val i: Intent = Intent().putExtra(Slice.EXTRA_TOGGLE_STATE, newValue) 106 mAction.actionItem!!.fireAction(context, i) 107 } else { 108 mAction.actionItem!!.fireAction(null, null) 109 } 110 } catch (e: PendingIntent.CanceledException) { 111 newValue = !newValue 112 Log.e(TAG, "PendingIntent for slice cannot be sent", e) 113 } 114 if (callChangeListener(newValue)) { 115 isChecked = newValue 116 } 117 } 118 119 companion object { 120 private const val TAG = "EmbeddedSliceSwitchPreference" 121 } 122 }