1 /*
2  * Copyright (C) 2014 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;
18 
19 import android.content.Context;
20 import android.graphics.Bitmap;
21 import android.graphics.Canvas;
22 import android.graphics.Color;
23 import android.graphics.Paint;
24 import android.graphics.PorterDuff;
25 import android.graphics.PorterDuffColorFilter;
26 import android.graphics.Rect;
27 import android.graphics.Typeface;
28 import android.os.Build;
29 import android.os.Parcel;
30 import android.os.Parcelable;
31 import android.util.DisplayMetrics;
32 
33 /**
34  * A Parcelable class for Subscription Information.
35  */
36 public class SubscriptionInfo implements Parcelable {
37 
38     /**
39      * Size of text to render on the icon.
40      */
41     private static final int TEXT_SIZE = 16;
42 
43     /**
44      * Subscription Identifier, this is a device unique number
45      * and not an index into an array
46      */
47     private int mId;
48 
49     /**
50      * The GID for a SIM that maybe associated with this subscription, empty if unknown
51      */
52     private String mIccId;
53 
54     /**
55      * The index of the slot that currently contains the subscription
56      * and not necessarily unique and maybe INVALID_SLOT_ID if unknown
57      */
58     private int mSimSlotIndex;
59 
60     /**
61      * The name displayed to the user that identifies this subscription
62      */
63     private CharSequence mDisplayName;
64 
65     /**
66      * String that identifies SPN/PLMN
67      * TODO : Add a new field that identifies only SPN for a sim
68      */
69     private CharSequence mCarrierName;
70 
71     /**
72      * The source of the name, NAME_SOURCE_UNDEFINED, NAME_SOURCE_DEFAULT_SOURCE,
73      * NAME_SOURCE_SIM_SOURCE or NAME_SOURCE_USER_INPUT.
74      */
75     private int mNameSource;
76 
77     /**
78      * The color to be used for tinting the icon when displaying to the user
79      */
80     private int mIconTint;
81 
82     /**
83      * A number presented to the user identify this subscription
84      */
85     private String mNumber;
86 
87     /**
88      * Data roaming state, DATA_RAOMING_ENABLE, DATA_RAOMING_DISABLE
89      */
90     private int mDataRoaming;
91 
92     /**
93      * Sim Provisioning Status:
94      * {@See SubscriptionManager#SIM_PROVISIONED}
95      * {@See SubscriptionManager#SIM_UNPROVISIONED_COLD}
96      * {@See SubscriptionManager#SIM_UNPROVISIONED_OUT_OF_CREDIT}
97      */
98     private int mSimProvisioningStatus;
99 
100     /**
101      * SIM Icon bitmap
102      */
103     private Bitmap mIconBitmap;
104 
105     /**
106      * Mobile Country Code
107      */
108     private int mMcc;
109 
110     /**
111      * Mobile Network Code
112      */
113     private int mMnc;
114 
115     /**
116      * ISO Country code for the subscription's provider
117      */
118     private String mCountryIso;
119 
120     /**
121      * @hide
122      */
SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName, CharSequence carrierName, int nameSource, int iconTint, String number, int roaming, Bitmap icon, int mcc, int mnc, String countryIso, int simProvisioningStatus)123     public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
124             CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
125             Bitmap icon, int mcc, int mnc, String countryIso, int simProvisioningStatus) {
126         this.mId = id;
127         this.mIccId = iccId;
128         this.mSimSlotIndex = simSlotIndex;
129         this.mDisplayName = displayName;
130         this.mCarrierName = carrierName;
131         this.mNameSource = nameSource;
132         this.mIconTint = iconTint;
133         this.mNumber = number;
134         this.mDataRoaming = roaming;
135         this.mIconBitmap = icon;
136         this.mMcc = mcc;
137         this.mMnc = mnc;
138         this.mCountryIso = countryIso;
139         this.mSimProvisioningStatus = simProvisioningStatus;
140     }
141 
142     /**
143      * @return the subscription ID.
144      */
getSubscriptionId()145     public int getSubscriptionId() {
146         return this.mId;
147     }
148 
149     /**
150      * @return the ICC ID.
151      */
getIccId()152     public String getIccId() {
153         return this.mIccId;
154     }
155 
156     /**
157      * @return the slot index of this Subscription's SIM card.
158      */
getSimSlotIndex()159     public int getSimSlotIndex() {
160         return this.mSimSlotIndex;
161     }
162 
163     /**
164      * @return the name displayed to the user that identifies this subscription
165      */
getDisplayName()166     public CharSequence getDisplayName() {
167         return this.mDisplayName;
168     }
169 
170     /**
171      * Sets the name displayed to the user that identifies this subscription
172      * @hide
173      */
setDisplayName(CharSequence name)174     public void setDisplayName(CharSequence name) {
175         this.mDisplayName = name;
176     }
177 
178     /**
179      * @return the name displayed to the user that identifies Subscription provider name
180      */
getCarrierName()181     public CharSequence getCarrierName() {
182         return this.mCarrierName;
183     }
184 
185     /**
186      * Sets the name displayed to the user that identifies Subscription provider name
187      * @hide
188      */
setCarrierName(CharSequence name)189     public void setCarrierName(CharSequence name) {
190         this.mCarrierName = name;
191     }
192 
193     /**
194      * @return the source of the name, eg NAME_SOURCE_UNDEFINED, NAME_SOURCE_DEFAULT_SOURCE,
195      * NAME_SOURCE_SIM_SOURCE or NAME_SOURCE_USER_INPUT.
196      * @hide
197      */
getNameSource()198     public int getNameSource() {
199         return this.mNameSource;
200     }
201 
202     /**
203      * Creates and returns an icon {@code Bitmap} to represent this {@code SubscriptionInfo} in a user
204      * interface.
205      *
206      * @param context A {@code Context} to get the {@code DisplayMetrics}s from.
207      *
208      * @return A bitmap icon for this {@code SubscriptionInfo}.
209      */
createIconBitmap(Context context)210     public Bitmap createIconBitmap(Context context) {
211         int width = mIconBitmap.getWidth();
212         int height = mIconBitmap.getHeight();
213         DisplayMetrics metrics = context.getResources().getDisplayMetrics();
214 
215         // Create a new bitmap of the same size because it will be modified.
216         Bitmap workingBitmap = Bitmap.createBitmap(metrics, width, height, mIconBitmap.getConfig());
217 
218         Canvas canvas = new Canvas(workingBitmap);
219         Paint paint = new Paint();
220 
221         // Tint the icon with the color.
222         paint.setColorFilter(new PorterDuffColorFilter(mIconTint, PorterDuff.Mode.SRC_ATOP));
223         canvas.drawBitmap(mIconBitmap, 0, 0, paint);
224         paint.setColorFilter(null);
225 
226         // Write the sim slot index.
227         paint.setAntiAlias(true);
228         paint.setTypeface(Typeface.create("sans-serif", Typeface.NORMAL));
229         paint.setColor(Color.WHITE);
230         // Set text size scaled by density
231         paint.setTextSize(TEXT_SIZE * metrics.density);
232         // Convert sim slot index to localized string
233         final String index = String.format("%d", mSimSlotIndex + 1);
234         final Rect textBound = new Rect();
235         paint.getTextBounds(index, 0, 1, textBound);
236         final float xOffset = (width / 2.f) - textBound.centerX();
237         final float yOffset = (height / 2.f) - textBound.centerY();
238         canvas.drawText(index, xOffset, yOffset, paint);
239 
240         return workingBitmap;
241     }
242 
243     /**
244      * A highlight color to use in displaying information about this {@code PhoneAccount}.
245      *
246      * @return A hexadecimal color value.
247      */
getIconTint()248     public int getIconTint() {
249         return mIconTint;
250     }
251 
252     /**
253      * Sets the color displayed to the user that identifies this subscription
254      * @hide
255      */
setIconTint(int iconTint)256     public void setIconTint(int iconTint) {
257         this.mIconTint = iconTint;
258     }
259 
260     /**
261      * @return the number of this subscription.
262      */
getNumber()263     public String getNumber() {
264         return mNumber;
265     }
266 
267     /**
268      * @return the data roaming state for this subscription, either
269      * {@link SubscriptionManager#DATA_ROAMING_ENABLE} or {@link SubscriptionManager#DATA_ROAMING_DISABLE}.
270      */
getDataRoaming()271     public int getDataRoaming() {
272         return this.mDataRoaming;
273     }
274 
275     /**
276      * @return Sim Provisioning Status
277      * {@See SubscriptionManager#SIM_PROVISIONED}
278      * {@See SubscriptionManager#SIM_UNPROVISIONED_COLD}
279      * {@See SubscriptionManager#SIM_UNPROVISIONED_OUT_OF_CREDIT}
280      * @hide
281      */
getSimProvisioningStatus()282     public int getSimProvisioningStatus() {
283         return this.mSimProvisioningStatus;
284     }
285 
286     /**
287      * @return the MCC.
288      */
getMcc()289     public int getMcc() {
290         return this.mMcc;
291     }
292 
293     /**
294      * @return the MNC.
295      */
getMnc()296     public int getMnc() {
297         return this.mMnc;
298     }
299 
300     /**
301      * @return the ISO country code
302      */
getCountryIso()303     public String getCountryIso() {
304         return this.mCountryIso;
305     }
306 
307     public static final Parcelable.Creator<SubscriptionInfo> CREATOR = new Parcelable.Creator<SubscriptionInfo>() {
308         @Override
309         public SubscriptionInfo createFromParcel(Parcel source) {
310             int id = source.readInt();
311             String iccId = source.readString();
312             int simSlotIndex = source.readInt();
313             CharSequence displayName = source.readCharSequence();
314             CharSequence carrierName = source.readCharSequence();
315             int nameSource = source.readInt();
316             int iconTint = source.readInt();
317             String number = source.readString();
318             int dataRoaming = source.readInt();
319             int mcc = source.readInt();
320             int mnc = source.readInt();
321             String countryIso = source.readString();
322             int simProvisioningStatus = source.readInt();
323             Bitmap iconBitmap = Bitmap.CREATOR.createFromParcel(source);
324 
325             return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName,
326                     nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso,
327                     simProvisioningStatus);
328         }
329 
330         @Override
331         public SubscriptionInfo[] newArray(int size) {
332             return new SubscriptionInfo[size];
333         }
334     };
335 
336     @Override
writeToParcel(Parcel dest, int flags)337     public void writeToParcel(Parcel dest, int flags) {
338         dest.writeInt(mId);
339         dest.writeString(mIccId);
340         dest.writeInt(mSimSlotIndex);
341         dest.writeCharSequence(mDisplayName);
342         dest.writeCharSequence(mCarrierName);
343         dest.writeInt(mNameSource);
344         dest.writeInt(mIconTint);
345         dest.writeString(mNumber);
346         dest.writeInt(mDataRoaming);
347         dest.writeInt(mMcc);
348         dest.writeInt(mMnc);
349         dest.writeString(mCountryIso);
350         dest.writeInt(mSimProvisioningStatus);
351         mIconBitmap.writeToParcel(dest, flags);
352     }
353 
354     @Override
describeContents()355     public int describeContents() {
356         return 0;
357     }
358 
359     /**
360      * @hide
361      */
givePrintableIccid(String iccId)362     public static String givePrintableIccid(String iccId) {
363         String iccIdToPrint = null;
364         if (iccId != null) {
365             if (iccId.length() > 9 && !Build.IS_DEBUGGABLE) {
366                 iccIdToPrint = iccId.substring(0, 9) + "XXXXXXXXXXX";
367             } else {
368                 iccIdToPrint = iccId;
369             }
370         }
371         return iccIdToPrint;
372     }
373 
374     @Override
toString()375     public String toString() {
376         String iccIdToPrint = givePrintableIccid(mIccId);
377         return "{id=" + mId + ", iccId=" + iccIdToPrint + " simSlotIndex=" + mSimSlotIndex
378                 + " displayName=" + mDisplayName + " carrierName=" + mCarrierName
379                 + " nameSource=" + mNameSource + " iconTint=" + mIconTint
380                 + " dataRoaming=" + mDataRoaming + " iconBitmap=" + mIconBitmap + " mcc " + mMcc
381                 + " mnc " + mMnc + " SimProvisioningStatus " + mSimProvisioningStatus +"}";
382     }
383 }
384