1/*
2 * Copyright (C) 2007 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 */
16package com.android.internal.telephony;
17
18import java.io.FileDescriptor;
19import java.io.PrintWriter;
20
21import android.content.Context;
22import android.content.pm.PackageManager;
23import android.os.Binder;
24import android.telephony.PhoneNumberUtils;
25import android.telephony.Rlog;
26
27import com.android.internal.telephony.uicc.IsimRecords;
28
29public class PhoneSubInfo extends IPhoneSubInfo.Stub {
30    static final String LOG_TAG = "PhoneSubInfo";
31    private static final boolean DBG = true;
32    private static final boolean VDBG = false; // STOPSHIP if true
33
34    private Phone mPhone;
35    private Context mContext;
36    private static final String READ_PHONE_STATE =
37        android.Manifest.permission.READ_PHONE_STATE;
38    // TODO: change getCompleteVoiceMailNumber() to require READ_PRIVILEGED_PHONE_STATE
39    private static final String CALL_PRIVILEGED =
40        android.Manifest.permission.CALL_PRIVILEGED;
41    private static final String READ_PRIVILEGED_PHONE_STATE =
42        android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
43
44    public PhoneSubInfo(Phone phone) {
45        mPhone = phone;
46        mContext = phone.getContext();
47    }
48
49    public void dispose() {
50    }
51
52    @Override
53    protected void finalize() {
54        try {
55            super.finalize();
56        } catch (Throwable throwable) {
57            loge("Error while finalizing:", throwable);
58        }
59        if (DBG) log("PhoneSubInfo finalized");
60    }
61
62    /**
63     * Retrieves the unique device ID, e.g., IMEI for GSM phones and MEID for CDMA phones.
64     */
65    @Override
66    public String getDeviceId() {
67        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
68        return mPhone.getDeviceId();
69    }
70
71    /**
72     * Retrieves the software version number for the device, e.g., IMEI/SV
73     * for GSM phones.
74     */
75    @Override
76    public String getDeviceSvn() {
77        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
78        return mPhone.getDeviceSvn();
79    }
80
81    /**
82     * Retrieves the unique subscriber ID, e.g., IMSI for GSM phones.
83     */
84    @Override
85    public String getSubscriberId() {
86        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
87        return mPhone.getSubscriberId();
88    }
89
90    /**
91     * Retrieves the Group Identifier Level1 for GSM phones.
92     */
93    public String getGroupIdLevel1() {
94        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
95        return mPhone.getGroupIdLevel1();
96    }
97
98    /**
99     * Retrieves the serial number of the ICC, if applicable.
100     */
101    @Override
102    public String getIccSerialNumber() {
103        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
104        return mPhone.getIccSerialNumber();
105    }
106
107    /**
108     * Retrieves the phone number string for line 1.
109     */
110    @Override
111    public String getLine1Number() {
112        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
113        return mPhone.getLine1Number();
114    }
115
116    /**
117     * Retrieves the alpha identifier for line 1.
118     */
119    @Override
120    public String getLine1AlphaTag() {
121        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
122        return mPhone.getLine1AlphaTag();
123    }
124
125    /**
126     * Retrieves the MSISDN string.
127     */
128    @Override
129    public String getMsisdn() {
130        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
131        return mPhone.getMsisdn();
132    }
133
134    /**
135     * Retrieves the voice mail number.
136     */
137    @Override
138    public String getVoiceMailNumber() {
139        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
140        String number = PhoneNumberUtils.extractNetworkPortion(mPhone.getVoiceMailNumber());
141        if (VDBG) log("VM: PhoneSubInfo.getVoiceMailNUmber: " + number);
142        return number;
143    }
144
145    /**
146     * Retrieves the complete voice mail number.
147     *
148     * @hide
149     */
150    @Override
151    public String getCompleteVoiceMailNumber() {
152        mContext.enforceCallingOrSelfPermission(CALL_PRIVILEGED,
153                "Requires CALL_PRIVILEGED");
154        String number = mPhone.getVoiceMailNumber();
155        if (VDBG) log("VM: PhoneSubInfo.getCompleteVoiceMailNUmber: " + number);
156        return number;
157    }
158
159    /**
160     * Retrieves the alpha identifier associated with the voice mail number.
161     */
162    @Override
163    public String getVoiceMailAlphaTag() {
164        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
165        return mPhone.getVoiceMailAlphaTag();
166    }
167
168    /**
169     * Returns the IMS private user identity (IMPI) that was loaded from the ISIM.
170     * @return the IMPI, or null if not present or not loaded
171     */
172    @Override
173    public String getIsimImpi() {
174        mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
175                "Requires READ_PRIVILEGED_PHONE_STATE");
176        IsimRecords isim = mPhone.getIsimRecords();
177        if (isim != null) {
178            return isim.getIsimImpi();
179        } else {
180            return null;
181        }
182    }
183
184    /**
185     * Returns the IMS home network domain name that was loaded from the ISIM.
186     * @return the IMS domain name, or null if not present or not loaded
187     */
188    @Override
189    public String getIsimDomain() {
190        mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
191                "Requires READ_PRIVILEGED_PHONE_STATE");
192        IsimRecords isim = mPhone.getIsimRecords();
193        if (isim != null) {
194            return isim.getIsimDomain();
195        } else {
196            return null;
197        }
198    }
199
200    /**
201     * Returns the IMS public user identities (IMPU) that were loaded from the ISIM.
202     * @return an array of IMPU strings, with one IMPU per string, or null if
203     *      not present or not loaded
204     */
205    @Override
206    public String[] getIsimImpu() {
207        mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
208                "Requires READ_PRIVILEGED_PHONE_STATE");
209        IsimRecords isim = mPhone.getIsimRecords();
210        if (isim != null) {
211            return isim.getIsimImpu();
212        } else {
213            return null;
214        }
215    }
216
217    private void log(String s) {
218        Rlog.d(LOG_TAG, s);
219    }
220
221    private void loge(String s, Throwable e) {
222        Rlog.e(LOG_TAG, s, e);
223    }
224
225    @Override
226    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
227        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
228                != PackageManager.PERMISSION_GRANTED) {
229            pw.println("Permission Denial: can't dump PhoneSubInfo from from pid="
230                    + Binder.getCallingPid()
231                    + ", uid=" + Binder.getCallingUid());
232            return;
233        }
234
235        pw.println("Phone Subscriber Info:");
236        pw.println("  Phone Type = " + mPhone.getPhoneName());
237        pw.println("  Device ID = " + mPhone.getDeviceId());
238    }
239}
240