1 /*
2  * Copyright (C) 2016 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 android.telephony.mbms;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.text.TextUtils;
24 
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.Date;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Locale;
31 import java.util.Map;
32 import java.util.NoSuchElementException;
33 import java.util.Objects;
34 import java.util.Set;
35 
36 /**
37  * Describes a cell-broadcast service. This class should not be instantiated directly -- use
38  * {@link StreamingServiceInfo} or {@link FileServiceInfo}
39  */
40 public class ServiceInfo {
41     // arbitrary limit on the number of locale -> name pairs we support
42     final static int MAP_LIMIT = 1000;
43 
44     private final Map<Locale, String> names;
45     private final String className;
46     private final List<Locale> locales;
47     private final String serviceId;
48     private final Date sessionStartTime;
49     private final Date sessionEndTime;
50 
51     /** @hide */
ServiceInfo(Map<Locale, String> newNames, String newClassName, List<Locale> newLocales, String newServiceId, Date start, Date end)52     public ServiceInfo(Map<Locale, String> newNames, String newClassName, List<Locale> newLocales,
53             String newServiceId, Date start, Date end) {
54         if (newNames == null || newClassName == null
55                 || newLocales == null || newServiceId == null
56                 || start == null || end == null) {
57             throw new IllegalArgumentException("Bad ServiceInfo construction");
58         }
59         if (newNames.size() > MAP_LIMIT) {
60             throw new RuntimeException("bad map length " + newNames.size());
61         }
62         if (newLocales.size() > MAP_LIMIT) {
63             throw new RuntimeException("bad locales length " + newLocales.size());
64         }
65 
66         names = new HashMap(newNames.size());
67         names.putAll(newNames);
68         className = newClassName;
69         locales = new ArrayList(newLocales);
70         serviceId = newServiceId;
71         sessionStartTime = (Date)start.clone();
72         sessionEndTime = (Date)end.clone();
73     }
74 
75     /** @hide */
ServiceInfo(Parcel in)76     protected ServiceInfo(Parcel in) {
77         int mapCount = in.readInt();
78         if (mapCount > MAP_LIMIT || mapCount < 0) {
79             throw new RuntimeException("bad map length" + mapCount);
80         }
81         names = new HashMap(mapCount);
82         while (mapCount-- > 0) {
83             Locale locale = (java.util.Locale) in.readSerializable(java.util.Locale.class.getClassLoader(), java.util.Locale.class);
84             String name = in.readString();
85             names.put(locale, name);
86         }
87         className = in.readString();
88         int localesCount = in.readInt();
89         if (localesCount > MAP_LIMIT || localesCount < 0) {
90             throw new RuntimeException("bad locale length " + localesCount);
91         }
92         locales = new ArrayList<Locale>(localesCount);
93         while (localesCount-- > 0) {
94             Locale l = (java.util.Locale) in.readSerializable(java.util.Locale.class.getClassLoader(), java.util.Locale.class);
95             locales.add(l);
96         }
97         serviceId = in.readString();
98         sessionStartTime = (java.util.Date) in.readSerializable(java.util.Date.class.getClassLoader(), java.util.Date.class);
99         sessionEndTime = (java.util.Date) in.readSerializable(java.util.Date.class.getClassLoader(), java.util.Date.class);
100     }
101 
102     /** @hide */
writeToParcel(Parcel dest, int flags)103     public void writeToParcel(Parcel dest, int flags) {
104         Set<Locale> keySet = names.keySet();
105         dest.writeInt(keySet.size());
106         for (Locale l : keySet) {
107             dest.writeSerializable(l);
108             dest.writeString(names.get(l));
109         }
110         dest.writeString(className);
111         int localesCount = locales.size();
112         dest.writeInt(localesCount);
113         for (Locale l : locales) {
114             dest.writeSerializable(l);
115         }
116         dest.writeString(serviceId);
117         dest.writeSerializable(sessionStartTime);
118         dest.writeSerializable(sessionEndTime);
119     }
120 
121     /**
122      * Get the user-displayable name for this cell-broadcast service corresponding to the
123      * provided {@link Locale}.
124      * @param locale The {@link Locale} in which you want the name of the service. This must be a
125      *               value from the set returned by {@link #getNamedContentLocales()} -- an
126      *               {@link java.util.NoSuchElementException} may be thrown otherwise.
127      * @return The {@link CharSequence} providing the name of the service in the given
128      *         {@link Locale}
129      */
getNameForLocale(@onNull Locale locale)130     public @NonNull CharSequence getNameForLocale(@NonNull Locale locale) {
131         if (!names.containsKey(locale)) {
132             throw new NoSuchElementException("Locale not supported");
133         }
134         return names.get(locale);
135     }
136 
137     /**
138      * Return an unmodifiable set of the current {@link Locale}s that have a user-displayable name
139      * associated with them. The user-displayable name associated with any {@link Locale} in this
140      * set can be retrieved with {@link #getNameForLocale(Locale)}.
141      * @return An unmodifiable set of {@link Locale} objects corresponding to a user-displayable
142      * content name in that locale.
143      */
getNamedContentLocales()144     public @NonNull Set<Locale> getNamedContentLocales() {
145         return Collections.unmodifiableSet(names.keySet());
146     }
147 
148     /**
149      * The class name for this service - used to categorize and filter
150      */
getServiceClassName()151     public String getServiceClassName() {
152         return className;
153     }
154 
155     /**
156      * The languages available for this service content
157      */
getLocales()158     public List<Locale> getLocales() {
159         return locales;
160     }
161 
162     /**
163      * The carrier's identifier for the service.
164      */
getServiceId()165     public String getServiceId() {
166         return serviceId;
167     }
168 
169     /**
170      * The start time indicating when this service will be available.
171      */
getSessionStartTime()172     public Date getSessionStartTime() {
173         return sessionStartTime;
174     }
175 
176     /**
177      * The end time indicating when this session stops being available.
178      */
getSessionEndTime()179     public Date getSessionEndTime() {
180         return sessionEndTime;
181     }
182 
183     @Override
equals(Object o)184     public boolean equals(Object o) {
185         if (this == o) return true;
186         if (o == null) {
187             return false;
188         }
189         if (!(o instanceof ServiceInfo)) {
190             return false;
191         }
192         ServiceInfo that = (ServiceInfo) o;
193         return Objects.equals(names, that.names) &&
194                 Objects.equals(className, that.className) &&
195                 Objects.equals(locales, that.locales) &&
196                 Objects.equals(serviceId, that.serviceId) &&
197                 Objects.equals(sessionStartTime, that.sessionStartTime) &&
198                 Objects.equals(sessionEndTime, that.sessionEndTime);
199     }
200 
201     @Override
hashCode()202     public int hashCode() {
203         return Objects.hash(names, className, locales, serviceId, sessionStartTime, sessionEndTime);
204     }
205 }
206