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 17 package com.android.tv.twopanelsettings.slices; 18 19 import static android.app.slice.Slice.EXTRA_TOGGLE_STATE; 20 21 import android.app.PendingIntent; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.res.TypedArray; 25 import android.util.AttributeSet; 26 import android.util.Log; 27 28 import androidx.annotation.Nullable; 29 import androidx.preference.TwoStatePreference; 30 31 import com.android.tv.twopanelsettings.R; 32 33 /** 34 * An embedded slice switch preference which would be embedded in common TvSettings preference 35 * items, but will automatically update its status and communicates with external apps through 36 * slice api. 37 */ 38 public class EmbeddedSliceSwitchPreference extends SliceSwitchPreference { 39 private static final String TAG = "EmbeddedSliceSwitchPreference"; 40 private final EmbeddedSlicePreferenceHelper mHelper; 41 private String mUri; 42 43 @Override onAttached()44 public void onAttached() { 45 super.onAttached(); 46 mHelper.onAttached(); 47 } 48 49 @Override onDetached()50 public void onDetached() { 51 super.onDetached(); 52 mHelper.onDetached(); 53 } 54 EmbeddedSliceSwitchPreference(Context context)55 public EmbeddedSliceSwitchPreference(Context context) { 56 super(context); 57 init(null); 58 mHelper = new EmbeddedSlicePreferenceHelper(this, mUri); 59 } 60 EmbeddedSliceSwitchPreference(Context context, AttributeSet attrs)61 public EmbeddedSliceSwitchPreference(Context context, AttributeSet attrs) { 62 super(context, attrs); 63 init(attrs); 64 mHelper = new EmbeddedSlicePreferenceHelper(this, mUri); 65 } 66 init(@ullable AttributeSet attrs)67 private void init(@Nullable AttributeSet attrs) { 68 if (attrs != null) { 69 initStyleAttributes(attrs); 70 } 71 } 72 initStyleAttributes(AttributeSet attrs)73 private void initStyleAttributes(AttributeSet attrs) { 74 final TypedArray a = getContext().obtainStyledAttributes( 75 attrs, R.styleable.SlicePreference); 76 for (int i = a.getIndexCount() - 1; i >= 0; i--) { 77 int attr = a.getIndex(i); 78 if (attr == R.styleable.SlicePreference_uri) { 79 mUri = a.getString(attr); 80 break; 81 } 82 } 83 } 84 addListener(EmbeddedSlicePreferenceHelper.SlicePreferenceListener listener)85 public void addListener(EmbeddedSlicePreferenceHelper.SlicePreferenceListener listener) { 86 mHelper.mListener = listener; 87 } 88 removeListener(EmbeddedSlicePreferenceHelper.SlicePreferenceListener listener)89 public void removeListener(EmbeddedSlicePreferenceHelper.SlicePreferenceListener listener) { 90 mHelper.mListener = null; 91 } 92 update()93 void update() { 94 setTitle(mHelper.mNewPref.getTitle()); 95 setSummary(mHelper.mNewPref.getSummary()); 96 setIcon(mHelper.mNewPref.getIcon()); 97 if (mHelper.mNewPref instanceof TwoStatePreference) { 98 setChecked(((TwoStatePreference) mHelper.mNewPref).isChecked()); 99 } 100 if (mHelper.mNewPref instanceof HasSliceAction) { 101 setSliceAction(((HasSliceAction) mHelper.mNewPref).getSliceAction()); 102 } 103 setVisible(true); 104 } 105 106 @Override onClick()107 public void onClick() { 108 boolean newValue = !isChecked(); 109 try { 110 if (mAction == null) { 111 return; 112 } 113 if (mAction.isToggle()) { 114 // Update the intent extra state 115 Intent i = new Intent().putExtra(EXTRA_TOGGLE_STATE, newValue); 116 mAction.getActionItem().fireAction(getContext(), i); 117 } else { 118 mAction.getActionItem().fireAction(null, null); 119 } 120 } catch (PendingIntent.CanceledException e) { 121 newValue = !newValue; 122 Log.e(TAG, "PendingIntent for slice cannot be sent", e); 123 } 124 if (callChangeListener(newValue)) { 125 setChecked(newValue); 126 } 127 } 128 } 129