1 /*
2  * Copyright (C) 2021 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.settings.service;
18 
19 import android.content.Intent;
20 import android.os.Bundle;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.util.ArrayMap;
24 
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.stream.Collectors;
30 
31 public class PreferenceParcelable implements Parcelable {
32     public static final byte TYPE_RPEFERENCE = 0;
33     public static final byte TYPE_PREFERENCE_CATEGORY = 1;
34     public static final byte TYPE_PREFERENCE_ACCESS_POINT = 2;
35     public static final byte TYPE_PREFERENCE_WIFI_COLLAPSE_CATEGORY = 3;
36 
37     private final String[] key;
38     private String title;
39     private String summary;
40     private String contentDescription;
41     private Bundle extras;
42     private Intent intent;
43 
44     // 0 : preference, 1 : preferenceCategory, 2 : AccessPointPreference
45     private byte type;
46 
47     // Provide extra information for particular type
48     private Map<String, String> infoMap;
49 
50     // 0 : not updated, 1 : unchecked, 2 : checked
51     private byte checked;
52 
53     // 0 : not updated, 1 : ininvisble, 2: visible
54     private byte visible;
55     private List<PreferenceParcelable> childPrefParcelables;
56 
getChildPreferences()57     public List<PreferenceParcelable> getChildPreferences() {
58         return childPrefParcelables;
59     }
60 
setChildPrefParcelables( List<PreferenceParcelable> childPrefParcelables)61     public void setChildPrefParcelables(
62             List<PreferenceParcelable> childPrefParcelables) {
63         this.childPrefParcelables = childPrefParcelables;
64     }
65 
getChildPrefParcelables()66     public List<PreferenceParcelable> getChildPrefParcelables() {
67         if (childPrefParcelables == null) {
68             childPrefParcelables = new ArrayList<>();
69         }
70         return childPrefParcelables;
71     }
72 
PreferenceParcelable(String key)73     public PreferenceParcelable(String key) {
74         this.key = new String[]{key};
75     }
76 
PreferenceParcelable(String[] key)77     public PreferenceParcelable(String[] key) {
78         this.key = key;
79     }
80 
PreferenceParcelable(String[] key, String title)81     public PreferenceParcelable(String[] key, String title) {
82         this.key = key;
83         this.title = title;
84     }
85 
PreferenceParcelable(String[] key, String title, String summary)86     public PreferenceParcelable(String[] key, String title, String summary) {
87         this(key, title);
88         this.summary = summary;
89     }
90 
getKey()91     public String[] getKey() {
92         return key;
93     }
94 
getTitle()95     public String getTitle() {
96         return title;
97     }
98 
setTitle(String title)99     public void setTitle(String title) {
100         this.title = title;
101     }
102 
getSummary()103     public String getSummary() {
104         return summary;
105     }
106 
setSummary(String summary)107     public void setSummary(String summary) {
108         this.summary = summary;
109     }
110 
111 
getContentDescription()112     public String getContentDescription() {
113         return contentDescription;
114     }
115 
getType()116     public int getType() {
117         return type;
118     }
119 
setType(byte type)120     public void setType(byte type) {
121         this.type = type;
122     }
123 
getInfoMap()124     public Map<String, String> getInfoMap() {
125         if (infoMap == null) {
126             infoMap = new ArrayMap<>();
127         }
128         return infoMap;
129     }
130 
setInfoMap(Map<String, String> info)131     public void setInfoMap(Map<String, String> info) {
132         this.infoMap = info;
133     }
134 
addInfo(String key, String value)135     public void addInfo(String key, String value) {
136         if (infoMap == null) {
137             infoMap = new ArrayMap<>();
138         }
139         infoMap.put(key, value);
140     }
141 
getInfo(String key)142     public String getInfo(String key) {
143         if (infoMap == null || !infoMap.containsKey(key)) {
144             return null;
145         }
146         return infoMap.get(key);
147     }
148 
149 
setContentDescription(String contentDescription)150     public void setContentDescription(String contentDescription) {
151         this.contentDescription = contentDescription;
152     }
153 
getChecked()154     public byte getChecked() {
155         return checked;
156     }
157 
setChecked(byte checked)158     public void setChecked(byte checked) {
159         this.checked = checked;
160     }
161 
setChecked(boolean checked)162     public void setChecked(boolean checked) {
163         setChecked(ServiceUtil.getChecked(checked));
164     }
165 
setVisible(boolean visible)166     public void setVisible(boolean visible) {
167         setVisible(ServiceUtil.getVisible(visible));
168     }
169 
getVisible()170     public byte getVisible() {
171         return visible;
172     }
173 
setVisible(byte visible)174     public void setVisible(byte visible) {
175         this.visible = visible;
176     }
177 
getExtras()178     public Bundle getExtras() {
179         return extras;
180     }
181 
setExtras(Bundle extras)182     public void setExtras(Bundle extras) {
183         this.extras = extras;
184     }
185 
getIntent()186     public Intent getIntent() {
187         return intent;
188     }
189 
setIntent(Intent intent)190     public void setIntent(Intent intent) {
191         this.intent = intent;
192     }
193 
initChildPreferences()194     public void initChildPreferences() {
195         childPrefParcelables = new ArrayList<>();
196     }
197 
addChildPrefParcelable(PreferenceParcelable childPrefParcelable)198     public void addChildPrefParcelable(PreferenceParcelable childPrefParcelable) {
199         if (childPrefParcelables == null) {
200             childPrefParcelables = new ArrayList<>();
201         }
202         childPrefParcelables.add(childPrefParcelable);
203     }
204 
205     @Override
toString()206     public String toString() {
207         return "PreferenceParcelable{" +
208                 "key='" + Arrays.toString(key) + '\'' +
209                 ", title='" + title + '\'' +
210                 ", summary='" + summary + '\'' +
211                 ", contentDescription='" + contentDescription + '\'' +
212                 ", type=" + type +
213                 ", extras=" + extras +
214                 ", intent=" + intent +
215                 ", infoMap=" + infoMap +
216                 ", checked=" + checked +
217                 ", visible=" + visible +
218                 ", childPrefParcelables=" + childPrefParcelables +
219                 '}';
220     }
221 
immutableCopy()222     public PreferenceParcelable immutableCopy() {
223         PreferenceParcelable copy = new PreferenceParcelable(Arrays.copyOf(key, key.length));
224         copy.setTitle(title);
225         copy.setSummary(summary);
226         copy.setType(type);
227         copy.setChecked(checked);
228         copy.setVisible(visible);
229         copy.setContentDescription(contentDescription);
230         if (extras != null) {
231             copy.setExtras(new Bundle(extras));
232         }
233         if (intent != null) {
234             copy.setIntent(new Intent(intent));
235         }
236         Map<String, String> infoMapCopy = new ArrayMap<>();
237         if (infoMap != null) {
238             infoMapCopy.putAll(infoMap);
239         }
240         copy.setInfoMap(infoMapCopy);
241         if (childPrefParcelables != null) {
242             copy.setChildPrefParcelables(childPrefParcelables.stream()
243                     .map(PreferenceParcelable::immutableCopy).collect(Collectors.toList()));
244         }
245         return copy;
246     }
247 
248     @Override
describeContents()249     public int describeContents() {
250         return 0;
251     }
252 
253     @Override
writeToParcel(Parcel dest, int flags)254     public void writeToParcel(Parcel dest, int flags) {
255         dest.writeStringArray(key);
256         dest.writeString(title);
257         dest.writeString(summary);
258         dest.writeString(contentDescription);
259         dest.writeByte(checked);
260         dest.writeByte(visible);
261         dest.writeByte(type);
262         dest.writeBundle(extras);
263         dest.writeParcelable(intent, flags);
264         dest.writeMap(infoMap);
265         dest.writeParcelableList(childPrefParcelables, flags);
266     }
267 
268     public static final Creator<PreferenceParcelable> CREATOR =
269             new Creator<PreferenceParcelable>() {
270                 @Override
271                 public PreferenceParcelable createFromParcel(Parcel source) {
272                     PreferenceParcelable preferenceParcelable = new PreferenceParcelable(
273                             source.createStringArray());
274                     preferenceParcelable.setTitle(source.readString());
275                     preferenceParcelable.setSummary(source.readString());
276                     preferenceParcelable.setContentDescription(source.readString());
277                     preferenceParcelable.setChecked(source.readByte());
278                     preferenceParcelable.setVisible(source.readByte());
279                     preferenceParcelable.setType(source.readByte());
280                     preferenceParcelable.setExtras(source.readBundle());
281                     preferenceParcelable.setIntent(
282                             source.readParcelable(Intent.class.getClassLoader()));
283                     source.readMap(preferenceParcelable.getInfoMap(), Map.class.getClassLoader());
284                     source.readParcelableList(
285                             preferenceParcelable.getChildPrefParcelables(),
286                             PreferenceParcelable.class.getClassLoader());
287                     return preferenceParcelable;
288                 }
289 
290                 @Override
291                 public PreferenceParcelable[] newArray(int size) {
292                     return new PreferenceParcelable[size];
293                 }
294             };
295 }