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 Icon bitmap
94     */
95    private Bitmap mIconBitmap;
96
97    /**
98     * Mobile Country Code
99     */
100    private int mMcc;
101
102    /**
103     * Mobile Network Code
104     */
105    private int mMnc;
106
107    /**
108     * ISO Country code for the subscription's provider
109     */
110    private String mCountryIso;
111
112    /**
113     * @hide
114     */
115    public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
116            CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
117            Bitmap icon, int mcc, int mnc, String countryIso) {
118        this.mId = id;
119        this.mIccId = iccId;
120        this.mSimSlotIndex = simSlotIndex;
121        this.mDisplayName = displayName;
122        this.mCarrierName = carrierName;
123        this.mNameSource = nameSource;
124        this.mIconTint = iconTint;
125        this.mNumber = number;
126        this.mDataRoaming = roaming;
127        this.mIconBitmap = icon;
128        this.mMcc = mcc;
129        this.mMnc = mnc;
130        this.mCountryIso = countryIso;
131    }
132
133    /**
134     * @return the subscription ID.
135     */
136    public int getSubscriptionId() {
137        return this.mId;
138    }
139
140    /**
141     * @return the ICC ID.
142     */
143    public String getIccId() {
144        return this.mIccId;
145    }
146
147    /**
148     * @return the slot index of this Subscription's SIM card.
149     */
150    public int getSimSlotIndex() {
151        return this.mSimSlotIndex;
152    }
153
154    /**
155     * @return the name displayed to the user that identifies this subscription
156     */
157    public CharSequence getDisplayName() {
158        return this.mDisplayName;
159    }
160
161    /**
162     * Sets the name displayed to the user that identifies this subscription
163     * @hide
164     */
165    public void setDisplayName(CharSequence name) {
166        this.mDisplayName = name;
167    }
168
169    /**
170     * @return the name displayed to the user that identifies Subscription provider name
171     */
172    public CharSequence getCarrierName() {
173        return this.mCarrierName;
174    }
175
176    /**
177     * Sets the name displayed to the user that identifies Subscription provider name
178     * @hide
179     */
180    public void setCarrierName(CharSequence name) {
181        this.mCarrierName = name;
182    }
183
184    /**
185     * @return the source of the name, eg NAME_SOURCE_UNDEFINED, NAME_SOURCE_DEFAULT_SOURCE,
186     * NAME_SOURCE_SIM_SOURCE or NAME_SOURCE_USER_INPUT.
187     * @hide
188     */
189    public int getNameSource() {
190        return this.mNameSource;
191    }
192
193    /**
194     * Creates and returns an icon {@code Bitmap} to represent this {@code SubscriptionInfo} in a user
195     * interface.
196     *
197     * @param context A {@code Context} to get the {@code DisplayMetrics}s from.
198     *
199     * @return A bitmap icon for this {@code SubscriptionInfo}.
200     */
201    public Bitmap createIconBitmap(Context context) {
202        int width = mIconBitmap.getWidth();
203        int height = mIconBitmap.getHeight();
204        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
205
206        // Create a new bitmap of the same size because it will be modified.
207        Bitmap workingBitmap = Bitmap.createBitmap(metrics, width, height, mIconBitmap.getConfig());
208
209        Canvas canvas = new Canvas(workingBitmap);
210        Paint paint = new Paint();
211
212        // Tint the icon with the color.
213        paint.setColorFilter(new PorterDuffColorFilter(mIconTint, PorterDuff.Mode.SRC_ATOP));
214        canvas.drawBitmap(mIconBitmap, 0, 0, paint);
215        paint.setColorFilter(null);
216
217        // Write the sim slot index.
218        paint.setAntiAlias(true);
219        paint.setTypeface(Typeface.create("sans-serif", Typeface.NORMAL));
220        paint.setColor(Color.WHITE);
221        // Set text size scaled by density
222        paint.setTextSize(TEXT_SIZE * metrics.density);
223        // Convert sim slot index to localized string
224        final String index = String.format("%d", mSimSlotIndex + 1);
225        final Rect textBound = new Rect();
226        paint.getTextBounds(index, 0, 1, textBound);
227        final float xOffset = (width / 2.f) - textBound.centerX();
228        final float yOffset = (height / 2.f) - textBound.centerY();
229        canvas.drawText(index, xOffset, yOffset, paint);
230
231        return workingBitmap;
232    }
233
234    /**
235     * A highlight color to use in displaying information about this {@code PhoneAccount}.
236     *
237     * @return A hexadecimal color value.
238     */
239    public int getIconTint() {
240        return mIconTint;
241    }
242
243    /**
244     * Sets the color displayed to the user that identifies this subscription
245     * @hide
246     */
247    public void setIconTint(int iconTint) {
248        this.mIconTint = iconTint;
249    }
250
251    /**
252     * @return the number of this subscription.
253     */
254    public String getNumber() {
255        return mNumber;
256    }
257
258    /**
259     * @return the data roaming state for this subscription, either
260     * {@link SubscriptionManager#DATA_ROAMING_ENABLE} or {@link SubscriptionManager#DATA_ROAMING_DISABLE}.
261     */
262    public int getDataRoaming() {
263        return this.mDataRoaming;
264    }
265
266    /**
267     * @return the MCC.
268     */
269    public int getMcc() {
270        return this.mMcc;
271    }
272
273    /**
274     * @return the MNC.
275     */
276    public int getMnc() {
277        return this.mMnc;
278    }
279
280    /**
281     * @return the ISO country code
282     */
283    public String getCountryIso() {
284        return this.mCountryIso;
285    }
286
287    public static final Parcelable.Creator<SubscriptionInfo> CREATOR = new Parcelable.Creator<SubscriptionInfo>() {
288        @Override
289        public SubscriptionInfo createFromParcel(Parcel source) {
290            int id = source.readInt();
291            String iccId = source.readString();
292            int simSlotIndex = source.readInt();
293            CharSequence displayName = source.readCharSequence();
294            CharSequence carrierName = source.readCharSequence();
295            int nameSource = source.readInt();
296            int iconTint = source.readInt();
297            String number = source.readString();
298            int dataRoaming = source.readInt();
299            int mcc = source.readInt();
300            int mnc = source.readInt();
301            String countryIso = source.readString();
302            Bitmap iconBitmap = Bitmap.CREATOR.createFromParcel(source);
303
304            return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName,
305                    nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso);
306        }
307
308        @Override
309        public SubscriptionInfo[] newArray(int size) {
310            return new SubscriptionInfo[size];
311        }
312    };
313
314    @Override
315    public void writeToParcel(Parcel dest, int flags) {
316        dest.writeInt(mId);
317        dest.writeString(mIccId);
318        dest.writeInt(mSimSlotIndex);
319        dest.writeCharSequence(mDisplayName);
320        dest.writeCharSequence(mCarrierName);
321        dest.writeInt(mNameSource);
322        dest.writeInt(mIconTint);
323        dest.writeString(mNumber);
324        dest.writeInt(mDataRoaming);
325        dest.writeInt(mMcc);
326        dest.writeInt(mMnc);
327        dest.writeString(mCountryIso);
328        mIconBitmap.writeToParcel(dest, flags);
329    }
330
331    @Override
332    public int describeContents() {
333        return 0;
334    }
335
336    /**
337     * @hide
338     */
339    public static String givePrintableIccid(String iccId) {
340        String iccIdToPrint = null;
341        if (iccId != null) {
342            if (iccId.length() > 9 && !Build.IS_DEBUGGABLE) {
343                iccIdToPrint = iccId.substring(0, 9) + Rlog.pii(false, iccId.substring(9));
344            } else {
345                iccIdToPrint = iccId;
346            }
347        }
348        return iccIdToPrint;
349    }
350
351    @Override
352    public String toString() {
353        String iccIdToPrint = givePrintableIccid(mIccId);
354        return "{id=" + mId + ", iccId=" + iccIdToPrint + " simSlotIndex=" + mSimSlotIndex
355                + " displayName=" + mDisplayName + " carrierName=" + mCarrierName
356                + " nameSource=" + mNameSource + " iconTint=" + mIconTint
357                + " dataRoaming=" + mDataRoaming + " iconBitmap=" + mIconBitmap + " mcc " + mMcc
358                + " mnc " + mMnc + "}";
359    }
360}
361