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
17package android.telephony;
18
19import android.content.Context;
20import android.graphics.Bitmap;
21import android.graphics.Canvas;
22import android.graphics.Color;
23import android.graphics.Paint;
24import android.graphics.PorterDuff;
25import android.graphics.PorterDuffColorFilter;
26import android.graphics.Rect;
27import android.graphics.Typeface;
28import android.os.Build;
29import android.os.Parcel;
30import android.os.Parcelable;
31import android.util.DisplayMetrics;
32
33/**
34 * A Parcelable class for Subscription Information.
35 */
36public 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     */
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     */
145    public int getSubscriptionId() {
146        return this.mId;
147    }
148
149    /**
150     * @return the ICC ID.
151     */
152    public String getIccId() {
153        return this.mIccId;
154    }
155
156    /**
157     * @return the slot index of this Subscription's SIM card.
158     */
159    public int getSimSlotIndex() {
160        return this.mSimSlotIndex;
161    }
162
163    /**
164     * @return the name displayed to the user that identifies this subscription
165     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
256    public void setIconTint(int iconTint) {
257        this.mIconTint = iconTint;
258    }
259
260    /**
261     * @return the number of this subscription.
262     */
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     */
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     */
282    public int getSimProvisioningStatus() {
283        return this.mSimProvisioningStatus;
284    }
285
286    /**
287     * @return the MCC.
288     */
289    public int getMcc() {
290        return this.mMcc;
291    }
292
293    /**
294     * @return the MNC.
295     */
296    public int getMnc() {
297        return this.mMnc;
298    }
299
300    /**
301     * @return the ISO country code
302     */
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
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
355    public int describeContents() {
356        return 0;
357    }
358
359    /**
360     * @hide
361     */
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
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