GsmMmiCode.java revision a8467dd0c524787104b1ccdddc5e8af10ba729ed
1c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/* 2c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Copyright (C) 2006 The Android Open Source Project 3c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 4c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 5c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * you may not use this file except in compliance with the License. 6c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * You may obtain a copy of the License at 7c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 8c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * http://www.apache.org/licenses/LICENSE-2.0 9c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 10c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Unless required by applicable law or agreed to in writing, software 11c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * distributed under the License is distributed on an "AS IS" BASIS, 12c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * See the License for the specific language governing permissions and 14c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * limitations under the License. 15c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 16c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 17c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepackage com.android.internal.telephony.gsm; 18c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 19c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Context; 2021fe62acc2d11ace0410b2b6d83263a96081c092duho.roimport android.content.res.Resources; 21c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.*; 22d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords; 23d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.UiccCardApplication; 24d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState; 25c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 26c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.*; 27c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.telephony.PhoneNumberUtils; 28c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.text.SpannableStringBuilder; 298697e0eb16fd00420efaf626ba4da3d548de3b59Magnus Karlssonimport android.text.BidiFormatter; 308697e0eb16fd00420efaf626ba4da3d548de3b59Magnus Karlssonimport android.text.TextDirectionHeuristics; 31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.text.TextUtils; 32ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog; 33c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 34c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport static com.android.internal.telephony.CommandsInterface.*; 35c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 36c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.regex.Pattern; 37c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.regex.Matcher; 38c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 39c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/** 40c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * The motto for this file is: 41c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 42c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * "NOTE: By using the # as a separator, most cases are expected to be unambiguous." 43c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * -- TS 22.030 6.5.2 44c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 45c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide} 46c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 47c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 48c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepublic final class GsmMmiCode extends Handler implements MmiCode { 49cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville static final String LOG_TAG = "GsmMmiCode"; 50c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 51c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville //***** Constants 52c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 53c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Max Size of the Short Code (aka Short String from TS 22.030 6.5.2) 54c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final int MAX_LENGTH_SHORT_CODE = 2; 55c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 56c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // TS 22.030 6.5.2 Every Short String USSD command will end with #-key 57c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // (known as #-String) 58c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final char END_OF_USSD_COMMAND = '#'; 59c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 60c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // From TS 22.030 6.5.2 61c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String ACTION_ACTIVATE = "*"; 62c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String ACTION_DEACTIVATE = "#"; 63c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String ACTION_INTERROGATE = "*#"; 64c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String ACTION_REGISTER = "**"; 65c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String ACTION_ERASURE = "##"; 66c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 67c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Supp Service codes from TS 22.030 Annex B 68c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 69c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville //Called line presentation 70c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_CLIP = "30"; 71c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_CLIR = "31"; 72c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 73c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Call Forwarding 74c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_CFU = "21"; 75c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_CFB = "67"; 76c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_CFNRy = "61"; 77c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_CFNR = "62"; 78c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 79c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_CF_All = "002"; 80c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_CF_All_Conditional = "004"; 81c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 82c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Call Waiting 83c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_WAIT = "43"; 84c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 85c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Call Barring 86c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_BAOC = "33"; 87c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_BAOIC = "331"; 88c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_BAOICxH = "332"; 89c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_BAIC = "35"; 90c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_BAICr = "351"; 91c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 92c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_BA_ALL = "330"; 93c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_BA_MO = "333"; 94c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_BA_MT = "353"; 95c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 96c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Supp Service Password registration 97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_PWD = "03"; 98c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 99c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // PIN/PIN2/PUK/PUK2 100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_PIN = "04"; 101c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_PIN2 = "042"; 102c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_PUK = "05"; 103c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String SC_PUK2 = "052"; 104c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville //***** Event Constants 106c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final int EVENT_SET_COMPLETE = 1; 108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final int EVENT_GET_CLIR_COMPLETE = 2; 109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final int EVENT_QUERY_CF_COMPLETE = 3; 110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final int EVENT_USSD_COMPLETE = 4; 111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final int EVENT_QUERY_COMPLETE = 5; 112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final int EVENT_SET_CFF_COMPLETE = 6; 113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final int EVENT_USSD_CANCEL_COMPLETE = 7; 114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville //***** Instance Variables 116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 11722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville GSMPhone mPhone; 11822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville Context mContext; 119e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka UiccCardApplication mUiccApplication; 120e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka IccRecords mIccRecords; 121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 12222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville String mAction; // One of ACTION_* 12322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville String mSc; // Service Code 12422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville String mSia, mSib, mSic; // Service Info a,b,c 12522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville String mPoundString; // Entire MMI string up to and including # 12622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville String mDialingNumber; 12722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville String mPwd; // For password registration 128c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** Set to true in processCode, not at newFromDialString time */ 13022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville private boolean mIsPendingUSSD; 131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 13222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville private boolean mIsUssdRequest; 133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 13422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville private boolean mIsCallFwdReg; 13522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville State mState = State.PENDING; 13622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville CharSequence mMessage; 137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville //***** Class Variables 139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 140c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // See TS 22.030 6.5.2 "Structure of the MMI" 142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static Pattern sPatternSuppService = Pattern.compile( 1449225578f29e449d30380fcf71defb1ac7e8a59dbJohn Wang "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)"); 145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/* 1 2 3 4 5 6 7 8 9 10 11 12 146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1 = Full string up to and including # 148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 2 = action (activation/interrogation/registration/erasure) 149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 3 = service code 150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 5 = SIA 151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 7 = SIB 152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 9 = SIC 1539225578f29e449d30380fcf71defb1ac7e8a59dbJohn Wang 10 = dialing number 154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville*/ 155c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final int MATCH_GROUP_POUND_STRING = 1; 157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 158c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final int MATCH_GROUP_ACTION = 2; 159c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville //(activation/interrogation/registration/erasure) 160c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 161c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final int MATCH_GROUP_SERVICE_CODE = 3; 162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final int MATCH_GROUP_SIA = 5; 163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final int MATCH_GROUP_SIB = 7; 164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final int MATCH_GROUP_SIC = 9; 165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final int MATCH_GROUP_PWD_CONFIRM = 11; 166c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final int MATCH_GROUP_DIALING_NUMBER = 12; 167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static private String[] sTwoDigitNumberPattern; 168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville //***** Public Class methods 170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Some dial strings in GSM are defined to do non-call setup 173c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * things, such as modify or query supplementary service settings (eg, call 174c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * forwarding). These are generally referred to as "MMI codes". 175c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * We look to see if the dial string contains a valid MMI code (potentially 176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * with a dial string at the end as well) and return info here. 177c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 178c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * If the dial string contains no MMI code, we return an instance with 179c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * only "dialingNumber" set 180c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 181c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Please see flow chart in TS 22.030 6.5.3.2 182c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static GsmMmiCode 185e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka newFromDialString(String dialString, GSMPhone phone, UiccCardApplication app) { 186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville Matcher m; 187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville GsmMmiCode ret = null; 188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 189c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville m = sPatternSuppService.matcher(dialString); 190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 191c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Is this formatted like a standard supplementary service code? 192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (m.matches()) { 193e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka ret = new GsmMmiCode(phone, app); 19422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mPoundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING)); 19522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mAction = makeEmptyNull(m.group(MATCH_GROUP_ACTION)); 19622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mSc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE)); 19722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mSia = makeEmptyNull(m.group(MATCH_GROUP_SIA)); 19822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mSib = makeEmptyNull(m.group(MATCH_GROUP_SIB)); 19922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mSic = makeEmptyNull(m.group(MATCH_GROUP_SIC)); 20022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mPwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM)); 20122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mDialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER)); 2029225578f29e449d30380fcf71defb1ac7e8a59dbJohn Wang // According to TS 22.030 6.5.2 "Structure of the MMI", 2039225578f29e449d30380fcf71defb1ac7e8a59dbJohn Wang // the dialing number should not ending with #. 2049225578f29e449d30380fcf71defb1ac7e8a59dbJohn Wang // The dialing number ending # is treated as unique USSD, 2059225578f29e449d30380fcf71defb1ac7e8a59dbJohn Wang // eg, *400#16 digit number# to recharge the prepaid card 2069225578f29e449d30380fcf71defb1ac7e8a59dbJohn Wang // in India operator(Mumbai MTNL) 20722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if(ret.mDialingNumber != null && 20822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mDialingNumber.endsWith("#") && 2099225578f29e449d30380fcf71defb1ac7e8a59dbJohn Wang dialString.endsWith("#")){ 2109225578f29e449d30380fcf71defb1ac7e8a59dbJohn Wang ret = new GsmMmiCode(phone, app); 21122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mPoundString = dialString; 2129225578f29e449d30380fcf71defb1ac7e8a59dbJohn Wang } 213c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (dialString.endsWith("#")) { 214c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // TS 22.030 sec 6.5.3.2 215c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // "Entry of any characters defined in the 3GPP TS 23.038 [8] Default Alphabet 216c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // (up to the maximum defined in 3GPP TS 24.080 [10]), followed by #SEND". 217c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 218e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka ret = new GsmMmiCode(phone, app); 21922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mPoundString = dialString; 220c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (isTwoDigitShortCode(phone.getContext(), dialString)) { 221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville //Is a country-specific exception to short codes as defined in TS 22.030, 6.5.3.2 222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ret = null; 223c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (isShortCode(dialString, phone)) { 224c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // this may be a short code, as defined in TS 22.030, 6.5.3.2 225e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka ret = new GsmMmiCode(phone, app); 22622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mDialingNumber = dialString; 227c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 228c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 229c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return ret; 230c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 231c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 232c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static GsmMmiCode 233c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville newNetworkInitiatedUssd (String ussdMessage, 234e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka boolean isUssdRequest, GSMPhone phone, UiccCardApplication app) { 235c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville GsmMmiCode ret; 236c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 237e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka ret = new GsmMmiCode(phone, app); 238c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 23922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mMessage = ussdMessage; 24022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mIsUssdRequest = isUssdRequest; 241c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 242c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // If it's a request, set to PENDING so that it's cancelable. 243c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (isUssdRequest) { 24422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mIsPendingUSSD = true; 24522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mState = State.PENDING; 246c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 24722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mState = State.COMPLETE; 248c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 249c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 250c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return ret; 251c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 252c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 253e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka static GsmMmiCode newFromUssdUserInput(String ussdMessge, 254e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka GSMPhone phone, 255e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka UiccCardApplication app) { 256e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka GsmMmiCode ret = new GsmMmiCode(phone, app); 257c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 25822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mMessage = ussdMessge; 25922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mState = State.PENDING; 26022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ret.mIsPendingUSSD = true; 261c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 262c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return ret; 263c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 264c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 265c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville //***** Private Class methods 266c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 267c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** make empty strings be null. 268c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Regexp returns empty strings for empty groups 269c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 270c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static String 271c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville makeEmptyNull (String s) { 272c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (s != null && s.length() == 0) return null; 273c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 274c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return s; 275c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 276c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 277c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** returns true of the string is empty or null */ 278c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static boolean 279c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville isEmptyOrNull(CharSequence s) { 280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return s == null || (s.length() == 0); 281c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 282c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 283c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 284c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static int 285c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville scToCallForwardReason(String sc) { 286c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (sc == null) { 287c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville throw new RuntimeException ("invalid call forward sc"); 288c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 289c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 290c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (sc.equals(SC_CF_All)) { 291c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return CommandsInterface.CF_REASON_ALL; 292c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (sc.equals(SC_CFU)) { 293c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return CommandsInterface.CF_REASON_UNCONDITIONAL; 294c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (sc.equals(SC_CFB)) { 295c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return CommandsInterface.CF_REASON_BUSY; 296c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (sc.equals(SC_CFNR)) { 297c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return CommandsInterface.CF_REASON_NOT_REACHABLE; 298c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (sc.equals(SC_CFNRy)) { 299c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return CommandsInterface.CF_REASON_NO_REPLY; 300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (sc.equals(SC_CF_All_Conditional)) { 301c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return CommandsInterface.CF_REASON_ALL_CONDITIONAL; 302c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 303c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville throw new RuntimeException ("invalid call forward sc"); 304c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 305c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 306c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 307c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static int 308c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville siToServiceClass(String si) { 309c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (si == null || si.length() == 0) { 310c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return SERVICE_CLASS_NONE; 311c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 312c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // NumberFormatException should cause MMI fail 313c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville int serviceCode = Integer.parseInt(si, 10); 314c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 315c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville switch (serviceCode) { 316c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 10: return SERVICE_CLASS_SMS + SERVICE_CLASS_FAX + SERVICE_CLASS_VOICE; 317c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 11: return SERVICE_CLASS_VOICE; 318c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 12: return SERVICE_CLASS_SMS + SERVICE_CLASS_FAX; 319c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 13: return SERVICE_CLASS_FAX; 320c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 321c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 16: return SERVICE_CLASS_SMS; 322c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 323c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 19: return SERVICE_CLASS_FAX + SERVICE_CLASS_VOICE; 324c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/* 325c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville Note for code 20: 326c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville From TS 22.030 Annex C: 327c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville "All GPRS bearer services" are not included in "All tele and bearer services" 328c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville and "All bearer services"." 329c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville....so SERVICE_CLASS_DATA, which (according to 27.007) includes GPRS 330c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville*/ 331c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 20: return SERVICE_CLASS_DATA_ASYNC + SERVICE_CLASS_DATA_SYNC; 332c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 333c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 21: return SERVICE_CLASS_PAD + SERVICE_CLASS_DATA_ASYNC; 334c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 22: return SERVICE_CLASS_PACKET + SERVICE_CLASS_DATA_SYNC; 335c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 24: return SERVICE_CLASS_DATA_SYNC; 336c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 25: return SERVICE_CLASS_DATA_ASYNC; 337c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 26: return SERVICE_CLASS_DATA_SYNC + SERVICE_CLASS_VOICE; 338c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 99: return SERVICE_CLASS_PACKET; 339c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 340c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville default: 341c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville throw new RuntimeException("unsupported MMI service code " + si); 342c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 343c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 344c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 345c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 346c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static int 347c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville siToTime (String si) { 348c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (si == null || si.length() == 0) { 349c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return 0; 350c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 351c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // NumberFormatException should cause MMI fail 352c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return Integer.parseInt(si, 10); 353c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 354c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 355c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 356c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static boolean 357c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville isServiceCodeCallForwarding(String sc) { 358c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return sc != null && 359c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville (sc.equals(SC_CFU) 360c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville || sc.equals(SC_CFB) || sc.equals(SC_CFNRy) 361c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville || sc.equals(SC_CFNR) || sc.equals(SC_CF_All) 362c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville || sc.equals(SC_CF_All_Conditional)); 363c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 364c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 365c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static boolean 366c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville isServiceCodeCallBarring(String sc) { 36721fe62acc2d11ace0410b2b6d83263a96081c092duho.ro Resources resource = Resources.getSystem(); 36821fe62acc2d11ace0410b2b6d83263a96081c092duho.ro if (sc != null) { 36921fe62acc2d11ace0410b2b6d83263a96081c092duho.ro String[] barringMMI = resource.getStringArray( 37021fe62acc2d11ace0410b2b6d83263a96081c092duho.ro com.android.internal.R.array.config_callBarringMMI); 37121fe62acc2d11ace0410b2b6d83263a96081c092duho.ro if (barringMMI != null) { 37221fe62acc2d11ace0410b2b6d83263a96081c092duho.ro for (String match : barringMMI) { 37321fe62acc2d11ace0410b2b6d83263a96081c092duho.ro if (sc.equals(match)) return true; 37421fe62acc2d11ace0410b2b6d83263a96081c092duho.ro } 37521fe62acc2d11ace0410b2b6d83263a96081c092duho.ro } 37621fe62acc2d11ace0410b2b6d83263a96081c092duho.ro } 37721fe62acc2d11ace0410b2b6d83263a96081c092duho.ro return false; 378c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 379c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 380c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static String 381c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville scToBarringFacility(String sc) { 382c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (sc == null) { 383c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville throw new RuntimeException ("invalid call barring sc"); 384c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 385c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 386c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (sc.equals(SC_BAOC)) { 387c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return CommandsInterface.CB_FACILITY_BAOC; 388c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (sc.equals(SC_BAOIC)) { 389c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return CommandsInterface.CB_FACILITY_BAOIC; 390c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (sc.equals(SC_BAOICxH)) { 391c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return CommandsInterface.CB_FACILITY_BAOICxH; 392c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (sc.equals(SC_BAIC)) { 393c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return CommandsInterface.CB_FACILITY_BAIC; 394c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (sc.equals(SC_BAICr)) { 395c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return CommandsInterface.CB_FACILITY_BAICr; 396c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (sc.equals(SC_BA_ALL)) { 397c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return CommandsInterface.CB_FACILITY_BA_ALL; 398c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (sc.equals(SC_BA_MO)) { 399c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return CommandsInterface.CB_FACILITY_BA_MO; 400c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (sc.equals(SC_BA_MT)) { 401c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return CommandsInterface.CB_FACILITY_BA_MT; 402c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 403c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville throw new RuntimeException ("invalid call barring sc"); 404c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 405c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 406c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 407c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville //***** Constructor 408c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 409e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka GsmMmiCode (GSMPhone phone, UiccCardApplication app) { 410c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // The telephony unit-test cases may create GsmMmiCode's 411c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // in secondary threads 412c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville super(phone.getHandler().getLooper()); 41322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone = phone; 41422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mContext = phone.getContext(); 415e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUiccApplication = app; 416e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (app != null) { 417e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mIccRecords = app.getIccRecords(); 418e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 419c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 420c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 421c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville //***** MmiCode implementation 422c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 423cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 424c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public State 425c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville getState() { 42622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mState; 427c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 428c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 429cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 430c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public CharSequence 431c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville getMessage() { 43222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mMessage; 433c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 434c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 435a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public Phone 436a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville getPhone() { 437a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return ((Phone) mPhone); 438a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 439a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 440c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // inherited javadoc suffices 441cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 442c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public void 443c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville cancel() { 444c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Complete or failed cannot be cancelled 44522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mState == State.COMPLETE || mState == State.FAILED) { 446c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return; 447c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 448c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 44922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.CANCELLED; 450c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 45122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mIsPendingUSSD) { 452c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /* 453c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * There can only be one pending USSD session, so tell the radio to 454c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * cancel it. 455c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 45622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.mCi.cancelPendingUssd(obtainMessage(EVENT_USSD_CANCEL_COMPLETE, this)); 457c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 458c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /* 459c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Don't call phone.onMMIDone here; wait for CANCEL_COMPLETE notice 460c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * from RIL. 461c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 462c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 463c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // TODO in cases other than USSD, it would be nice to cancel 464c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // the pending radio operation. This requires RIL cancellation 465c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // support, which does not presently exist. 466c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 46722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.onMMIDone (this); 468c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 469c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 470c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 471c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 472cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 473c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public boolean isCancelable() { 474c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /* Can only cancel pending USSD sessions. */ 47522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mIsPendingUSSD; 476c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 477c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 478c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville //***** Instance Methods 479c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 480c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** Does this dial string contain a structured or unstructured MMI code? */ 481c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville boolean 482c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville isMMI() { 48322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mPoundString != null; 484c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 485c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 486c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /* Is this a 1 or 2 digit "short code" as defined in TS 22.030 sec 6.5.3.2? */ 487c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville boolean 488c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville isShortCode() { 48922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mPoundString == null 49022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville && mDialingNumber != null && mDialingNumber.length() <= 2; 491c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 492c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 493c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 494c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static private boolean 495c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville isTwoDigitShortCode(Context context, String dialString) { 496ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "isTwoDigitShortCode"); 497c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 498c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (dialString == null || dialString.length() != 2) return false; 499c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 500c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (sTwoDigitNumberPattern == null) { 501c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sTwoDigitNumberPattern = context.getResources().getStringArray( 502c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.array.config_twoDigitNumberPattern); 503c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 504c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 505c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville for (String dialnumber : sTwoDigitNumberPattern) { 506ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "Two Digit Number Pattern " + dialnumber); 507c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (dialString.equals(dialnumber)) { 508ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "Two Digit Number Pattern -true"); 509c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return true; 510c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 511c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 512ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "Two Digit Number Pattern -false"); 513c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return false; 514c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 515c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 516c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 517c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Helper function for newFromDialString. Returns true if dialString appears 518c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * to be a short code AND conditions are correct for it to be treated as 519c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * such. 520c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 521c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static private boolean isShortCode(String dialString, GSMPhone phone) { 522c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Refer to TS 22.030 Figure 3.5.3.2: 523c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (dialString == null) { 524c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return false; 525c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 526c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 527c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Illegal dial string characters will give a ZERO length. 528c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // At this point we do not want to crash as any application with 529c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // call privileges may send a non dial string. 530c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // It return false as when the dialString is equal to NULL. 531c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (dialString.length() == 0) { 532c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return false; 533c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 534c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 535f4f5308a309d43fcfca8d0d5fbb54bc38c82ca3fYorke Lee if (PhoneNumberUtils.isLocalEmergencyNumber(phone.getContext(), dialString)) { 536c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return false; 537c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 538c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return isShortCodeUSSD(dialString, phone); 539c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 540c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 541c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 542c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 543c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Helper function for isShortCode. Returns true if dialString appears to be 544c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * a short code and it is a USSD structure 545c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 546c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * According to the 3PGG TS 22.030 specification Figure 3.5.3.2: A 1 or 2 547c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * digit "short code" is treated as USSD if it is entered while on a call or 548c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * does not satisfy the condition (exactly 2 digits && starts with '1'), there 549c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * are however exceptions to this rule (see below) 550c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 551c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Exception (1) to Call initiation is: If the user of the device is already in a call 552c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * and enters a Short String without any #-key at the end and the length of the Short String is 553c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * equal or less then the MAX_LENGTH_SHORT_CODE [constant that is equal to 2] 554c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 555c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * The phone shall initiate a USSD/SS commands. 556c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 557c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static private boolean isShortCodeUSSD(String dialString, GSMPhone phone) { 55810e574acd0992d22abce257b420d333f5a49e71dJeevaka Badrappan if (dialString != null && dialString.length() <= MAX_LENGTH_SHORT_CODE) { 559c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (phone.isInCall()) { 56010e574acd0992d22abce257b420d333f5a49e71dJeevaka Badrappan return true; 561c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 562c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 56310e574acd0992d22abce257b420d333f5a49e71dJeevaka Badrappan if (dialString.length() != MAX_LENGTH_SHORT_CODE || 56410e574acd0992d22abce257b420d333f5a49e71dJeevaka Badrappan dialString.charAt(0) != '1') { 56510e574acd0992d22abce257b420d333f5a49e71dJeevaka Badrappan return true; 566c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 567c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 568c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return false; 569c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 570c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 571c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 572c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * @return true if the Service Code is PIN/PIN2/PUK/PUK2-related 573c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 5743522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville boolean isPinPukCommand() { 57522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mSc != null && (mSc.equals(SC_PIN) || mSc.equals(SC_PIN2) 57622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville || mSc.equals(SC_PUK) || mSc.equals(SC_PUK2)); 577c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 578c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 579c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 580c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * See TS 22.030 Annex B. 581c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * In temporary mode, to suppress CLIR for a single call, enter: 582c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * " * 31 # [called number] SEND " 583c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * In temporary mode, to invoke CLIR for a single call enter: 584c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * " # 31 # [called number] SEND " 585c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 586c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville boolean 587c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville isTemporaryModeCLIR() { 58822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mSc != null && mSc.equals(SC_CLIR) && mDialingNumber != null 589c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville && (isActivate() || isDeactivate()); 590c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 591c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 592c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 593c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * returns CommandsInterface.CLIR_* 594c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * See also isTemporaryModeCLIR() 595c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 596c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville int 597c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville getCLIRMode() { 59822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mSc != null && mSc.equals(SC_CLIR)) { 599c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (isActivate()) { 600c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return CommandsInterface.CLIR_SUPPRESSION; 601c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (isDeactivate()) { 602c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return CommandsInterface.CLIR_INVOCATION; 603c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 604c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 605c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 606c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return CommandsInterface.CLIR_DEFAULT; 607c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 608c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 609c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville boolean isActivate() { 61022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mAction != null && mAction.equals(ACTION_ACTIVATE); 611c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 612c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 613c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville boolean isDeactivate() { 61422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mAction != null && mAction.equals(ACTION_DEACTIVATE); 615c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 616c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 617c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville boolean isInterrogate() { 61822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mAction != null && mAction.equals(ACTION_INTERROGATE); 619c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 620c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 621c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville boolean isRegister() { 62222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mAction != null && mAction.equals(ACTION_REGISTER); 623c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 624c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 625c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville boolean isErasure() { 62622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mAction != null && mAction.equals(ACTION_ERASURE); 627c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 628c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 629c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 630c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Returns true if this is a USSD code that's been submitted to the 631c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * network...eg, after processCode() is called 632c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 633c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public boolean isPendingUSSD() { 63422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mIsPendingUSSD; 635c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 636c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 638c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public boolean isUssdRequest() { 63922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mIsUssdRequest; 640c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 641c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 642c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** Process a MMI code or short code...anything that isn't a dialing number */ 643c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville void 644c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville processCode () { 645c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville try { 646c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (isShortCode()) { 647ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "isShortCode"); 648c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // These just get treated as USSD. 64922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sendUssd(mDialingNumber); 65022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (mDialingNumber != null) { 651c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // We should have no dialing numbers here 652c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville throw new RuntimeException ("Invalid or Unsupported MMI Code"); 65322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (mSc != null && mSc.equals(SC_CLIP)) { 654ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "is CLIP"); 655c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (isInterrogate()) { 65622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.mCi.queryCLIP( 657c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville obtainMessage(EVENT_QUERY_COMPLETE, this)); 658c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 659c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville throw new RuntimeException ("Invalid or Unsupported MMI Code"); 660c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 66122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (mSc != null && mSc.equals(SC_CLIR)) { 662ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "is CLIR"); 663c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (isActivate()) { 66422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.mCi.setCLIR(CommandsInterface.CLIR_INVOCATION, 665c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville obtainMessage(EVENT_SET_COMPLETE, this)); 666c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (isDeactivate()) { 66722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.mCi.setCLIR(CommandsInterface.CLIR_SUPPRESSION, 668c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville obtainMessage(EVENT_SET_COMPLETE, this)); 669c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (isInterrogate()) { 67022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.mCi.getCLIR( 671c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville obtainMessage(EVENT_GET_CLIR_COMPLETE, this)); 672c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 673c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville throw new RuntimeException ("Invalid or Unsupported MMI Code"); 674c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 67522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (isServiceCodeCallForwarding(mSc)) { 676ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "is CF"); 677c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 67822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville String dialingNumber = mSia; 67922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville int serviceClass = siToServiceClass(mSib); 68022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville int reason = scToCallForwardReason(mSc); 68122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville int time = siToTime(mSic); 682c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 683c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (isInterrogate()) { 68422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.mCi.queryCallForwardStatus( 685c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville reason, serviceClass, dialingNumber, 686c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville obtainMessage(EVENT_QUERY_CF_COMPLETE, this)); 687c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 688c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville int cfAction; 689c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 690c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (isActivate()) { 6915f6b9345f8fe5545f576d29fb7ff9f3405d9dc05Bin Li // 3GPP TS 22.030 6.5.2 6925f6b9345f8fe5545f576d29fb7ff9f3405d9dc05Bin Li // a call forwarding request with a single * would be 6935f6b9345f8fe5545f576d29fb7ff9f3405d9dc05Bin Li // interpreted as registration if containing a forwarded-to 6945f6b9345f8fe5545f576d29fb7ff9f3405d9dc05Bin Li // number, or an activation if not 6955f6b9345f8fe5545f576d29fb7ff9f3405d9dc05Bin Li if (isEmptyOrNull(dialingNumber)) { 6965f6b9345f8fe5545f576d29fb7ff9f3405d9dc05Bin Li cfAction = CommandsInterface.CF_ACTION_ENABLE; 69722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mIsCallFwdReg = false; 6985f6b9345f8fe5545f576d29fb7ff9f3405d9dc05Bin Li } else { 6995f6b9345f8fe5545f576d29fb7ff9f3405d9dc05Bin Li cfAction = CommandsInterface.CF_ACTION_REGISTRATION; 70022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mIsCallFwdReg = true; 7015f6b9345f8fe5545f576d29fb7ff9f3405d9dc05Bin Li } 702c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (isDeactivate()) { 703c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville cfAction = CommandsInterface.CF_ACTION_DISABLE; 704c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (isRegister()) { 705c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville cfAction = CommandsInterface.CF_ACTION_REGISTRATION; 706c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (isErasure()) { 707c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville cfAction = CommandsInterface.CF_ACTION_ERASURE; 708c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 709c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville throw new RuntimeException ("invalid action"); 710c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 711c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 712c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville int isSettingUnconditionalVoice = 713c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville (((reason == CommandsInterface.CF_REASON_UNCONDITIONAL) || 714c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville (reason == CommandsInterface.CF_REASON_ALL)) && 715c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville (((serviceClass & CommandsInterface.SERVICE_CLASS_VOICE) != 0) || 716c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville (serviceClass == CommandsInterface.SERVICE_CLASS_NONE))) ? 1 : 0; 717c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 718c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville int isEnableDesired = 719c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ((cfAction == CommandsInterface.CF_ACTION_ENABLE) || 720c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville (cfAction == CommandsInterface.CF_ACTION_REGISTRATION)) ? 1 : 0; 721c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 722ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "is CF setCallForward"); 72322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.mCi.setCallForward(cfAction, reason, serviceClass, 724c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville dialingNumber, time, obtainMessage( 725c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville EVENT_SET_CFF_COMPLETE, 726c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville isSettingUnconditionalVoice, 727c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville isEnableDesired, this)); 728c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 72922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (isServiceCodeCallBarring(mSc)) { 730c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // sia = password 731c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // sib = basic service group 732c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 73322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville String password = mSia; 73422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville int serviceClass = siToServiceClass(mSib); 73522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville String facility = scToBarringFacility(mSc); 736c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 737c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (isInterrogate()) { 73822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.mCi.queryFacilityLock(facility, password, 739c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville serviceClass, obtainMessage(EVENT_QUERY_COMPLETE, this)); 740c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (isActivate() || isDeactivate()) { 74122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.mCi.setFacilityLock(facility, isActivate(), password, 742c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville serviceClass, obtainMessage(EVENT_SET_COMPLETE, this)); 743c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 744c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville throw new RuntimeException ("Invalid or Unsupported MMI Code"); 745c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 746c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 74722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (mSc != null && mSc.equals(SC_PWD)) { 748c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // sia = fac 749c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // sib = old pwd 750c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // sic = new pwd 751c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // pwd = new pwd 752c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville String facility; 75322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville String oldPwd = mSib; 75422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville String newPwd = mSic; 755c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (isActivate() || isRegister()) { 756c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Even though ACTIVATE is acceptable, this is really termed a REGISTER 75722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mAction = ACTION_REGISTER; 758c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 75922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mSia == null) { 760c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // If sc was not specified, treat it as BA_ALL. 761c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville facility = CommandsInterface.CB_FACILITY_BA_ALL; 762c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 76322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville facility = scToBarringFacility(mSia); 764c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 76522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (newPwd.equals(mPwd)) { 76622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.mCi.changeBarringPassword(facility, oldPwd, 767c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville newPwd, obtainMessage(EVENT_SET_COMPLETE, this)); 768c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 769c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // password mismatch; return error 770c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville handlePasswordError(com.android.internal.R.string.passwordIncorrect); 771c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 772c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 773c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville throw new RuntimeException ("Invalid or Unsupported MMI Code"); 774c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 775c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 77622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (mSc != null && mSc.equals(SC_WAIT)) { 777c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // sia = basic service group 77822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville int serviceClass = siToServiceClass(mSia); 779c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 780c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (isActivate() || isDeactivate()) { 78122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.mCi.setCallWaiting(isActivate(), serviceClass, 782c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville obtainMessage(EVENT_SET_COMPLETE, this)); 783c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (isInterrogate()) { 78422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.mCi.queryCallWaiting(serviceClass, 785c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville obtainMessage(EVENT_QUERY_COMPLETE, this)); 786c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 787c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville throw new RuntimeException ("Invalid or Unsupported MMI Code"); 788c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 7893522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville } else if (isPinPukCommand()) { 7903522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville // TODO: This is the same as the code in CmdaMmiCode.java, 7913522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville // MmiCode should be an abstract or base class and this and 7923522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville // other common variables and code should be promoted. 7933522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville 794c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // sia = old PIN or PUK 795c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // sib = new PIN 796c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // sic = new PIN 79722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville String oldPinOrPuk = mSia; 7983522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville String newPinOrPuk = mSib; 7993522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville int pinLen = newPinOrPuk.length(); 800c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (isRegister()) { 8013522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville if (!newPinOrPuk.equals(mSic)) { 802c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // password mismatch; return error 803c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville handlePasswordError(com.android.internal.R.string.mismatchPin); 804c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (pinLen < 4 || pinLen > 8 ) { 805c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // invalid length 806c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville handlePasswordError(com.android.internal.R.string.invalidPin); 8073522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville } else if (mSc.equals(SC_PIN) 8083522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville && mUiccApplication != null 8093522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville && mUiccApplication.getState() == AppState.APPSTATE_PUK) { 810c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Sim is puk-locked 811c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville handlePasswordError(com.android.internal.R.string.needPuk); 8123522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville } else if (mUiccApplication != null) { 8133522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville Rlog.d(LOG_TAG, "process mmi service code using UiccApp sc=" + mSc); 8143522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville 8153522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville // We have an app and the pre-checks are OK 81622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mSc.equals(SC_PIN)) { 8173522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville mUiccApplication.changeIccLockPassword(oldPinOrPuk, newPinOrPuk, 818c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville obtainMessage(EVENT_SET_COMPLETE, this)); 81922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (mSc.equals(SC_PIN2)) { 8203522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville mUiccApplication.changeIccFdnPassword(oldPinOrPuk, newPinOrPuk, 821c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville obtainMessage(EVENT_SET_COMPLETE, this)); 82222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (mSc.equals(SC_PUK)) { 8233522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville mUiccApplication.supplyPuk(oldPinOrPuk, newPinOrPuk, 824c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville obtainMessage(EVENT_SET_COMPLETE, this)); 82522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (mSc.equals(SC_PUK2)) { 8263522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville mUiccApplication.supplyPuk2(oldPinOrPuk, newPinOrPuk, 827c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville obtainMessage(EVENT_SET_COMPLETE, this)); 8283522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville } else { 8293522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville throw new RuntimeException("uicc unsupported service code=" + mSc); 830c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 8313522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville } else { 8323522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville throw new RuntimeException("No application mUiccApplicaiton is null"); 833c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 834c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 8353522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville throw new RuntimeException ("Ivalid register/action=" + mAction); 836c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 83722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (mPoundString != null) { 83822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sendUssd(mPoundString); 839c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 840c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville throw new RuntimeException ("Invalid or Unsupported MMI Code"); 841c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 842c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } catch (RuntimeException exc) { 84322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.FAILED; 84422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mMessage = mContext.getText(com.android.internal.R.string.mmiError); 84522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.onMMIDone(this); 846c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 847c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 848c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 849c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private void handlePasswordError(int res) { 85022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.FAILED; 851c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville StringBuilder sb = new StringBuilder(getScString()); 852c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sb.append("\n"); 85322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText(res)); 85422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mMessage = sb; 85522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.onMMIDone(this); 856c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 857c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 858c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 859c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Called from GSMPhone 860c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 861c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * An unsolicited USSD NOTIFY or REQUEST has come in matching 862c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * up with this pending USSD request 863c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 864c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Note: If REQUEST, this exchange is complete, but the session remains 865c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * active (ie, the network expects user input). 866c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 867c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville void 868c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville onUssdFinished(String ussdMessage, boolean isUssdRequest) { 86922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mState == State.PENDING) { 870c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ussdMessage == null) { 87122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mMessage = mContext.getText(com.android.internal.R.string.mmiComplete); 872c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 87322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mMessage = ussdMessage; 874c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 87522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mIsUssdRequest = isUssdRequest; 876c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // If it's a request, leave it PENDING so that it's cancelable. 877c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (!isUssdRequest) { 87822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.COMPLETE; 879c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 880c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 88122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.onMMIDone(this); 882c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 883c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 884c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 885c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 886c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Called from GSMPhone 887c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 888c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * The radio has reset, and this is still pending 889c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 890c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 891c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville void 892c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville onUssdFinishedError() { 89322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mState == State.PENDING) { 89422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.FAILED; 89522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mMessage = mContext.getText(com.android.internal.R.string.mmiError); 896c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 89722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.onMMIDone(this); 898c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 899c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 900c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 901c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville void sendUssd(String ussdMessage) { 902c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Treat this as a USSD string 90322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mIsPendingUSSD = true; 904c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 905c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Note that unlike most everything else, the USSD complete 906c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // response does not complete this MMI code...we wait for 907c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // an unsolicited USSD "Notify" or "Request". 908c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // The matching up of this is done in GSMPhone. 909c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 91022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.mCi.sendUSSD(ussdMessage, 911c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville obtainMessage(EVENT_USSD_COMPLETE, this)); 912c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 913c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 914c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** Called from GSMPhone.handleMessage; not a Handler subclass */ 915cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 916c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public void 917c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville handleMessage (Message msg) { 918c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville AsyncResult ar; 919c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 920c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville switch (msg.what) { 921c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_SET_COMPLETE: 922c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ar = (AsyncResult) (msg.obj); 923c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 9243522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville onSetComplete(msg, ar); 925c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 926c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 927c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_SET_CFF_COMPLETE: 928c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ar = (AsyncResult) (msg.obj); 929c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 930c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /* 931c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * msg.arg1 = 1 means to set unconditional voice call forwarding 932c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * msg.arg2 = 1 means to enable voice call forwarding 933c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 934c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if ((ar.exception == null) && (msg.arg1 == 1)) { 935c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville boolean cffEnabled = (msg.arg2 == 1); 936e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mIccRecords != null) { 93731ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled, mDialingNumber); 938bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka } 939c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 940c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 9413522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville onSetComplete(msg, ar); 942c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 943c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 944c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_GET_CLIR_COMPLETE: 945c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ar = (AsyncResult) (msg.obj); 946c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville onGetClirComplete(ar); 947c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 948c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 949c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_QUERY_CF_COMPLETE: 950c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ar = (AsyncResult) (msg.obj); 951c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville onQueryCfComplete(ar); 952c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 953c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 954c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_QUERY_COMPLETE: 955c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ar = (AsyncResult) (msg.obj); 956c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville onQueryComplete(ar); 957c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 958c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 959c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_USSD_COMPLETE: 960c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ar = (AsyncResult) (msg.obj); 961c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 962c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ar.exception != null) { 96322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.FAILED; 96422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mMessage = getErrorMessage(ar); 965c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 96622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.onMMIDone(this); 967c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 968c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 969c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Note that unlike most everything else, the USSD complete 970c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // response does not complete this MMI code...we wait for 971c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // an unsolicited USSD "Notify" or "Request". 972c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // The matching up of this is done in GSMPhone. 973c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 974c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 975c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 976c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_USSD_CANCEL_COMPLETE: 97722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.onMMIDone(this); 978c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 979c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 980c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 981c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville //***** Private instance methods 982c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 983c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private CharSequence getErrorMessage(AsyncResult ar) { 984c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 985c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ar.exception instanceof CommandException) { 986c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville CommandException.Error err = ((CommandException)(ar.exception)).getCommandError(); 987c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (err == CommandException.Error.FDN_CHECK_FAILURE) { 988ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.i(LOG_TAG, "FDN_CHECK_FAILURE"); 98922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mContext.getText(com.android.internal.R.string.mmiFdnError); 990c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 991c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 992c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 99322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mContext.getText(com.android.internal.R.string.mmiError); 994c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 995c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 996c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private CharSequence getScString() { 99722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mSc != null) { 99822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (isServiceCodeCallBarring(mSc)) { 99922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mContext.getText(com.android.internal.R.string.BaMmi); 100022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (isServiceCodeCallForwarding(mSc)) { 100122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mContext.getText(com.android.internal.R.string.CfMmi); 100222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (mSc.equals(SC_CLIP)) { 100322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mContext.getText(com.android.internal.R.string.ClipMmi); 100422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (mSc.equals(SC_CLIR)) { 100522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mContext.getText(com.android.internal.R.string.ClirMmi); 100622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (mSc.equals(SC_PWD)) { 100722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mContext.getText(com.android.internal.R.string.PwdMmi); 100822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (mSc.equals(SC_WAIT)) { 100922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mContext.getText(com.android.internal.R.string.CwMmi); 10103522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville } else if (isPinPukCommand()) { 101122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mContext.getText(com.android.internal.R.string.PinMmi); 1012c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1013c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1014c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1015c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return ""; 1016c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1017c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1018c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private void 10193522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville onSetComplete(Message msg, AsyncResult ar){ 1020c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville StringBuilder sb = new StringBuilder(getScString()); 1021c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sb.append("\n"); 1022c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1023c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ar.exception != null) { 102422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.FAILED; 1025c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ar.exception instanceof CommandException) { 1026c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville CommandException.Error err = ((CommandException)(ar.exception)).getCommandError(); 1027c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (err == CommandException.Error.PASSWORD_INCORRECT) { 10283522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville if (isPinPukCommand()) { 1029c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // look specifically for the PUK commands and adjust 1030c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // the message accordingly. 103122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mSc.equals(SC_PUK) || mSc.equals(SC_PUK2)) { 103222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1033c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.badPuk)); 1034c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 103522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1036c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.badPin)); 1037c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 10383522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville // Get the No. of retries remaining to unlock PUK/PUK2 10393522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville int attemptsRemaining = msg.arg1; 10406d3c836bb8991e9cf7ffb322ebabf48c2446126dWink Saville if (attemptsRemaining <= 0) { 10416d3c836bb8991e9cf7ffb322ebabf48c2446126dWink Saville Rlog.d(LOG_TAG, "onSetComplete: PUK locked," 10426d3c836bb8991e9cf7ffb322ebabf48c2446126dWink Saville + " cancel as lock screen will handle this"); 10436d3c836bb8991e9cf7ffb322ebabf48c2446126dWink Saville mState = State.CANCELLED; 10446d3c836bb8991e9cf7ffb322ebabf48c2446126dWink Saville } else if (attemptsRemaining > 0) { 10456d3c836bb8991e9cf7ffb322ebabf48c2446126dWink Saville Rlog.d(LOG_TAG, "onSetComplete: attemptsRemaining="+attemptsRemaining); 10463522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville sb.append(mContext.getResources().getQuantityString( 10473522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville com.android.internal.R.plurals.pinpuk_attempts, 10483522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville attemptsRemaining, attemptsRemaining)); 10493522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville } 1050c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 105122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1052c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.passwordIncorrect)); 1053c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1054c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (err == CommandException.Error.SIM_PUK2) { 105522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1056c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.badPin)); 1057c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sb.append("\n"); 105822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1059c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.needPuk2)); 10603522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville } else if (err == CommandException.Error.REQUEST_NOT_SUPPORTED) { 10613522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville if (mSc.equals(SC_PIN)) { 10623522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville sb.append(mContext.getText(com.android.internal.R.string.enablePin)); 10633522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville } 1064c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (err == CommandException.Error.FDN_CHECK_FAILURE) { 1065ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.i(LOG_TAG, "FDN_CHECK_FAILURE"); 106622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText(com.android.internal.R.string.mmiFdnError)); 1067c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 106822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1069c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.mmiError)); 1070c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1071c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 107222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1073c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.mmiError)); 1074c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1075c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (isActivate()) { 107622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.COMPLETE; 107722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mIsCallFwdReg) { 107822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 10795f6b9345f8fe5545f576d29fb7ff9f3405d9dc05Bin Li com.android.internal.R.string.serviceRegistered)); 10805f6b9345f8fe5545f576d29fb7ff9f3405d9dc05Bin Li } else { 108122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 10825f6b9345f8fe5545f576d29fb7ff9f3405d9dc05Bin Li com.android.internal.R.string.serviceEnabled)); 10835f6b9345f8fe5545f576d29fb7ff9f3405d9dc05Bin Li } 1084c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Record CLIR setting 108522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mSc.equals(SC_CLIR)) { 108622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.saveClirSetting(CommandsInterface.CLIR_INVOCATION); 1087c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1088c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (isDeactivate()) { 108922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.COMPLETE; 109022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1091c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.serviceDisabled)); 1092c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Record CLIR setting 109322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mSc.equals(SC_CLIR)) { 109422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.saveClirSetting(CommandsInterface.CLIR_SUPPRESSION); 1095c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1096c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (isRegister()) { 109722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.COMPLETE; 109822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1099c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.serviceRegistered)); 1100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (isErasure()) { 110122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.COMPLETE; 110222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1103c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.serviceErased)); 1104c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 110522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.FAILED; 110622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.mmiError)); 1108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 111022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mMessage = sb; 111122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.onMMIDone(this); 1112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private void 1115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville onGetClirComplete(AsyncResult ar) { 1116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville StringBuilder sb = new StringBuilder(getScString()); 1117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sb.append("\n"); 1118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1119c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ar.exception != null) { 112022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.FAILED; 1121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sb.append(getErrorMessage(ar)); 1122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 1123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville int clirArgs[]; 1124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville clirArgs = (int[])ar.result; 1126c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // the 'm' parameter from TS 27.007 7.7 1128c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville switch (clirArgs[1]) { 1129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 0: // CLIR not provisioned 113022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.serviceNotProvisioned)); 113222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.COMPLETE; 1133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 1134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 1: // CLIR provisioned in permanent mode 113622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.CLIRPermanent)); 113822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.COMPLETE; 1139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 1140c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 2: // unknown (e.g. no network, etc.) 114222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.mmiError)); 114422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.FAILED; 1145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 1146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 3: // CLIR temporary mode presentation restricted 1148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // the 'n' parameter from TS 27.007 7.7 1150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville switch (clirArgs[0]) { 1151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville default: 1152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 0: // Default 115322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.CLIRDefaultOnNextCallOn)); 1155c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 1156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 1: // CLIR invocation 115722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1158c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.CLIRDefaultOnNextCallOn)); 1159c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 1160c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 2: // CLIR suppression 116122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.CLIRDefaultOnNextCallOff)); 1163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 1164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 116522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.COMPLETE; 1166c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 1167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 4: // CLIR temporary mode presentation allowed 1169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // the 'n' parameter from TS 27.007 7.7 1170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville switch (clirArgs[0]) { 1171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville default: 1172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 0: // Default 117322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1174c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.CLIRDefaultOffNextCallOff)); 1175c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 1176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 1: // CLIR invocation 117722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1178c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.CLIRDefaultOffNextCallOn)); 1179c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 1180c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case 2: // CLIR suppression 118122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText( 1182c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.CLIRDefaultOffNextCallOff)); 1183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 1184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1185c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 118622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.COMPLETE; 1187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 1188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1189c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 119122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mMessage = sb; 119222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.onMMIDone(this); 1193c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1194c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1195c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 1196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * @param serviceClass 1 bit of the service class bit vectory 1197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * @return String to be used for call forward query MMI response text. 1198c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Returns null if unrecognized 1199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 1200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private CharSequence 1202c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville serviceClassToCFString (int serviceClass) { 1203c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville switch (serviceClass) { 1204c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case SERVICE_CLASS_VOICE: 120522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mContext.getText(com.android.internal.R.string.serviceClassVoice); 1206c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case SERVICE_CLASS_DATA: 120722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mContext.getText(com.android.internal.R.string.serviceClassData); 1208c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case SERVICE_CLASS_FAX: 120922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mContext.getText(com.android.internal.R.string.serviceClassFAX); 1210c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case SERVICE_CLASS_SMS: 121122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mContext.getText(com.android.internal.R.string.serviceClassSMS); 1212c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case SERVICE_CLASS_DATA_SYNC: 121322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mContext.getText(com.android.internal.R.string.serviceClassDataSync); 1214c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case SERVICE_CLASS_DATA_ASYNC: 121522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mContext.getText(com.android.internal.R.string.serviceClassDataAsync); 1216c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case SERVICE_CLASS_PACKET: 121722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mContext.getText(com.android.internal.R.string.serviceClassPacket); 1218c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case SERVICE_CLASS_PAD: 121922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mContext.getText(com.android.internal.R.string.serviceClassPAD); 1220c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville default: 1221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return null; 1222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1223c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1224c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1225c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1226c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** one CallForwardInfo + serviceClassMask -> one line of text */ 1227c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private CharSequence 1228c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville makeCFQueryResultMessage(CallForwardInfo info, int serviceClassMask) { 1229c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville CharSequence template; 1230c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville String sources[] = {"{0}", "{1}", "{2}"}; 1231c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville CharSequence destinations[] = new CharSequence[3]; 1232c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville boolean needTimeTemplate; 1233c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1234c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // CF_REASON_NO_REPLY also has a time value associated with 1235c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // it. All others don't. 1236c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1237c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville needTimeTemplate = 1238c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville (info.reason == CommandsInterface.CF_REASON_NO_REPLY); 1239c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1240c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (info.status == 1) { 1241c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (needTimeTemplate) { 124222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville template = mContext.getText( 1243c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.cfTemplateForwardedTime); 1244c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 124522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville template = mContext.getText( 1246c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.cfTemplateForwarded); 1247c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1248c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (info.status == 0 && isEmptyOrNull(info.number)) { 124922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville template = mContext.getText( 1250c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.cfTemplateNotForwarded); 1251c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { /* (info.status == 0) && !isEmptyOrNull(info.number) */ 1252c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // A call forward record that is not active but contains 1253c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // a phone number is considered "registered" 1254c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1255c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (needTimeTemplate) { 125622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville template = mContext.getText( 1257c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.cfTemplateRegisteredTime); 1258c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 125922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville template = mContext.getText( 1260c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville com.android.internal.R.string.cfTemplateRegistered); 1261c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1262c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1263c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1264c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // In the template (from strings.xmls) 1265c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // {0} is one of "bearerServiceCode*" 1266c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // {1} is dialing number 1267c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // {2} is time in seconds 1268c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1269c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville destinations[0] = serviceClassToCFString(info.serviceClass & serviceClassMask); 12708697e0eb16fd00420efaf626ba4da3d548de3b59Magnus Karlsson destinations[1] = formatLtr( 12718697e0eb16fd00420efaf626ba4da3d548de3b59Magnus Karlsson PhoneNumberUtils.stringFromStringAndTOA(info.number, info.toa)); 1272c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville destinations[2] = Integer.toString(info.timeSeconds); 1273c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1274c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (info.reason == CommandsInterface.CF_REASON_UNCONDITIONAL && 1275c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville (info.serviceClass & serviceClassMask) 1276c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville == CommandsInterface.SERVICE_CLASS_VOICE) { 1277c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville boolean cffEnabled = (info.status == 1); 1278e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mIccRecords != null) { 127931ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled, info.number); 1280bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka } 1281c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1282c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1283c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return TextUtils.replace(template, sources, destinations); 1284c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1285c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 12868697e0eb16fd00420efaf626ba4da3d548de3b59Magnus Karlsson /** 12878697e0eb16fd00420efaf626ba4da3d548de3b59Magnus Karlsson * Used to format a string that should be displayed as LTR even in RTL locales 12888697e0eb16fd00420efaf626ba4da3d548de3b59Magnus Karlsson */ 12898697e0eb16fd00420efaf626ba4da3d548de3b59Magnus Karlsson private String formatLtr(String str) { 12908697e0eb16fd00420efaf626ba4da3d548de3b59Magnus Karlsson BidiFormatter fmt = BidiFormatter.getInstance(); 12918697e0eb16fd00420efaf626ba4da3d548de3b59Magnus Karlsson return str == null ? str : fmt.unicodeWrap(str, TextDirectionHeuristics.LTR, true); 12928697e0eb16fd00420efaf626ba4da3d548de3b59Magnus Karlsson } 1293c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1294c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private void 1295c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville onQueryCfComplete(AsyncResult ar) { 1296c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville StringBuilder sb = new StringBuilder(getScString()); 1297c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sb.append("\n"); 1298c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1299c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ar.exception != null) { 130022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.FAILED; 1301c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sb.append(getErrorMessage(ar)); 1302c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 1303c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville CallForwardInfo infos[]; 1304c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1305c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville infos = (CallForwardInfo[]) ar.result; 1306c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1307c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (infos.length == 0) { 1308c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Assume the default is not active 130922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText(com.android.internal.R.string.serviceDisabled)); 1310c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1311c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Set unconditional CFF in SIM to false 1312e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mIccRecords != null) { 131331ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville mIccRecords.setVoiceCallForwardingFlag(1, false, null); 1314bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka } 1315c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 1316c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1317c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville SpannableStringBuilder tb = new SpannableStringBuilder(); 1318c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1319c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Each bit in the service class gets its own result line 1320c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // The service classes may be split up over multiple 1321c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // CallForwardInfos. So, for each service class, find out 1322c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // which CallForwardInfo represents it and then build 1323c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // the response text based on that 1324c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1325c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville for (int serviceClassMask = 1 1326c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ; serviceClassMask <= SERVICE_CLASS_MAX 1327c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ; serviceClassMask <<= 1 1328c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ) { 1329c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville for (int i = 0, s = infos.length; i < s ; i++) { 1330c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if ((serviceClassMask & infos[i].serviceClass) != 0) { 1331c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville tb.append(makeCFQueryResultMessage(infos[i], 1332c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville serviceClassMask)); 1333c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville tb.append("\n"); 1334c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1335c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1336c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1337c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sb.append(tb); 1338c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1339c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 134022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.COMPLETE; 1341c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1342c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 134322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mMessage = sb; 134422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.onMMIDone(this); 1345c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1346c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1347c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1348c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private void 1349c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville onQueryComplete(AsyncResult ar) { 1350c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville StringBuilder sb = new StringBuilder(getScString()); 1351c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sb.append("\n"); 1352c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1353c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ar.exception != null) { 135422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.FAILED; 1355c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sb.append(getErrorMessage(ar)); 1356c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 1357c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville int[] ints = (int[])ar.result; 1358c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1359c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ints.length != 0) { 1360c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ints[0] == 0) { 136122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText(com.android.internal.R.string.serviceDisabled)); 136222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (mSc.equals(SC_WAIT)) { 1363c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Call Waiting includes additional data in the response. 1364c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sb.append(createQueryCallWaitingResultMessage(ints[1])); 136522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (isServiceCodeCallBarring(mSc)) { 1366c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // ints[0] for Call Barring is a bit vector of services 1367c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sb.append(createQueryCallBarringResultMessage(ints[0])); 1368c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (ints[0] == 1) { 1369c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // for all other services, treat it as a boolean 137022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText(com.android.internal.R.string.serviceEnabled)); 1371c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 137222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText(com.android.internal.R.string.mmiError)); 1373c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1374c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 137522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville sb.append(mContext.getText(com.android.internal.R.string.mmiError)); 1376c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 137722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mState = State.COMPLETE; 1378c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1379c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 138022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mMessage = sb; 138122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mPhone.onMMIDone(this); 1382c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1383c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1384c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private CharSequence 1385c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville createQueryCallWaitingResultMessage(int serviceClass) { 1386c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville StringBuilder sb = 138722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville new StringBuilder(mContext.getText(com.android.internal.R.string.serviceEnabledFor)); 1388c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1389c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville for (int classMask = 1 1390c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ; classMask <= SERVICE_CLASS_MAX 1391c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ; classMask <<= 1 1392c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ) { 1393c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if ((classMask & serviceClass) != 0) { 1394c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sb.append("\n"); 1395c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sb.append(serviceClassToCFString(classMask & serviceClass)); 1396c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1397c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1398c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return sb; 1399c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1400c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private CharSequence 1401c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville createQueryCallBarringResultMessage(int serviceClass) 1402c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville { 140322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville StringBuilder sb = new StringBuilder(mContext.getText(com.android.internal.R.string.serviceEnabledFor)); 1404c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1405c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville for (int classMask = 1 1406c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ; classMask <= SERVICE_CLASS_MAX 1407c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ; classMask <<= 1 1408c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ) { 1409c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if ((classMask & serviceClass) != 0) { 1410c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sb.append("\n"); 1411c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sb.append(serviceClassToCFString(classMask & serviceClass)); 1412c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1413c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1414c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return sb; 1415c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1416c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1417c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /*** 1418c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * TODO: It would be nice to have a method here that can take in a dialstring and 1419c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * figure out if there is an MMI code embedded within it. This code would replace 1420c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * some of the string parsing functionality in the Phone App's 1421c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * SpecialCharSequenceMgr class. 1422c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 1423c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1424c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 1425c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public String toString() { 1426c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville StringBuilder sb = new StringBuilder("GsmMmiCode {"); 1427c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1428c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sb.append("State=" + getState()); 142922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mAction != null) sb.append(" action=" + mAction); 143022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mSc != null) sb.append(" sc=" + mSc); 143122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mSia != null) sb.append(" sia=" + mSia); 143222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mSib != null) sb.append(" sib=" + mSib); 143322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mSic != null) sb.append(" sic=" + mSic); 143422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mPoundString != null) sb.append(" poundString=" + mPoundString); 143522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mDialingNumber != null) sb.append(" dialingNumber=" + mDialingNumber); 143622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mPwd != null) sb.append(" pwd=" + mPwd); 1437c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sb.append("}"); 1438c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return sb.toString(); 1439c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1440c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville} 1441