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