19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17767a662ecde33c3979bf02b793d392aca0403162Wink Savillepackage com.android.internal.telephony.cdma;
18105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
19767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.*;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
21767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.os.AsyncResult;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Looper;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message;
25767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.os.PowerManager;
26767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.os.Registrant;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock;
2822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Savilleimport android.os.SystemProperties;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Config;
30767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.util.Log;
3122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Savilleimport android.text.TextUtils;
3222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.telephony.PhoneNumberUtils;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.telephony.ServiceState;
3522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Savilleimport com.android.internal.telephony.TelephonyProperties;
36767a662ecde33c3979bf02b793d392aca0403162Wink Saville
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide}
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
40767a662ecde33c3979bf02b793d392aca0403162Wink Savillepublic class CdmaConnection extends Connection {
41767a662ecde33c3979bf02b793d392aca0403162Wink Saville    static final String LOG_TAG = "CDMA";
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Instance Variables
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
45767a662ecde33c3979bf02b793d392aca0403162Wink Saville    CdmaCallTracker owner;
46767a662ecde33c3979bf02b793d392aca0403162Wink Saville    CdmaCall parent;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
48767a662ecde33c3979bf02b793d392aca0403162Wink Saville
49767a662ecde33c3979bf02b793d392aca0403162Wink Saville    String address;             // MAY BE NULL!!!
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String dialString;          // outgoing calls only
51767a662ecde33c3979bf02b793d392aca0403162Wink Saville    String postDialString;      // outgoing calls only
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean isIncoming;
53767a662ecde33c3979bf02b793d392aca0403162Wink Saville    boolean disconnected;
54dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    String cnapName;
55767a662ecde33c3979bf02b793d392aca0403162Wink Saville    int index;          // index in CdmaCallTracker.connections[], -1 if unassigned
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * These time/timespan values are based on System.currentTimeMillis(),
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * i.e., "wall clock" time.
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long createTime;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long connectTime;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long disconnectTime;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * These time/timespan values are based on SystemClock.elapsedRealTime(),
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * i.e., time since boot.  They are appropriate for comparison and
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * calculating deltas.
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long connectTimeReal;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long duration;
72767a662ecde33c3979bf02b793d392aca0403162Wink Saville    long holdingStartTime;  // The time when the Connection last transitioned
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // into HOLDING
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int nextPostDialChar;       // index into postDialString
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DisconnectCause cause = DisconnectCause.NOT_DISCONNECTED;
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PostDialState postDialState = PostDialState.NOT_STARTED;
79105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    int numberPresentation = Connection.PRESENTATION_ALLOWED;
80dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    int cnapNamePresentation  = Connection.PRESENTATION_ALLOWED;
81dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Handler h;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private PowerManager.WakeLock mPartialWakeLock;
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Event Constants
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int EVENT_DTMF_DONE = 1;
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int EVENT_PAUSE_DONE = 2;
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int EVENT_NEXT_POST_DIAL = 3;
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int EVENT_WAKE_LOCK_TIMEOUT = 4;
92e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Constants
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int WAKE_LOCK_TIMEOUT_MILLIS = 60*1000;
95dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    static final int PAUSE_DELAY_MILLIS = 2 * 1000;
9622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Inner Classes
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    class MyHandler extends Handler {
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MyHandler(Looper l) {super(l);}
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void
103767a662ecde33c3979bf02b793d392aca0403162Wink Saville        handleMessage(Message msg) {
104767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (msg.what) {
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case EVENT_NEXT_POST_DIAL:
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case EVENT_DTMF_DONE:
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case EVENT_PAUSE_DONE:
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    processNextPostDialChar();
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case EVENT_WAKE_LOCK_TIMEOUT:
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    releaseWakeLock();
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Constructors
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** This is probably an MT call that we first saw in a CLCC response */
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package*/
122767a662ecde33c3979bf02b793d392aca0403162Wink Saville    CdmaConnection (Context context, DriverCall dc, CdmaCallTracker ct, int index) {
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        createWakeLock(context);
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        acquireWakeLock();
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        owner = ct;
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        h = new MyHandler(owner.getLooper());
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        address = dc.number;
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        isIncoming = dc.isMT;
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        createTime = System.currentTimeMillis();
133dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        cnapName = dc.name;
134dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        cnapNamePresentation = dc.namePresentation;
135105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        numberPresentation = dc.numberPresentation;
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this.index = index;
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parent = parentFromDCState (dc.state);
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parent.attach(this, dc);
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    /** This is an MO call/three way call, created when dialing */
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package*/
14522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    CdmaConnection(Context context, String dialString, CdmaCallTracker ct, CdmaCall parent) {
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        createWakeLock(context);
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        acquireWakeLock();
148e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        owner = ct;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        h = new MyHandler(owner.getLooper());
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this.dialString = dialString;
153dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        Log.d(LOG_TAG, "[CDMAConn] CdmaConnection: dialString=" + dialString);
154dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        dialString = formatDialString(dialString);
155dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        Log.d(LOG_TAG, "[CDMAConn] CdmaConnection:formated dialString=" + dialString);
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1579e534153264138cfee383c626db92b934fafc1afTammo Spalink        this.address = PhoneNumberUtils.extractNetworkPortionAlt(dialString);
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this.postDialString = PhoneNumberUtils.extractPostDialPortion(dialString);
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        index = -1;
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        isIncoming = false;
163dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        cnapName = null;
1645e9760c16b0b0dca96b59fdb2fd3c875ecfd33ebJinghui Guo        cnapNamePresentation = Connection.PRESENTATION_ALLOWED;
1655e9760c16b0b0dca96b59fdb2fd3c875ecfd33ebJinghui Guo        numberPresentation = Connection.PRESENTATION_ALLOWED;
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        createTime = System.currentTimeMillis();
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
168dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        if (parent != null) {
169dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            this.parent = parent;
17022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
17122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            //for the three way call case, not change parent state
17222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            if (parent.state == CdmaCall.State.ACTIVE) {
17322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                parent.attachFake(this, CdmaCall.State.ACTIVE);
17422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            } else {
17522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                parent.attachFake(this, CdmaCall.State.DIALING);
17622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            }
177dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        }
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
179767a662ecde33c3979bf02b793d392aca0403162Wink Saville
18022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    /** This is a Call waiting call*/
18122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    CdmaConnection(Context context, CdmaCallWaitingNotification cw, CdmaCallTracker ct,
18222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            CdmaCall parent) {
18322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        createWakeLock(context);
18422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        acquireWakeLock();
18522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
18622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        owner = ct;
18722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        h = new MyHandler(owner.getLooper());
18822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        address = cw.number;
18922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        numberPresentation = cw.numberPresentation;
19022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        cnapName = cw.name;
19122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        cnapNamePresentation = cw.namePresentation;
19222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        index = -1;
19322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        isIncoming = true;
19422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        createTime = System.currentTimeMillis();
19522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        connectTime = 0;
19622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        this.parent = parent;
19722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        parent.attachFake(this, CdmaCall.State.WAITING);
19822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    }
19922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
200767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public void dispose() {
201767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
202767a662ecde33c3979bf02b793d392aca0403162Wink Saville
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static boolean
204767a662ecde33c3979bf02b793d392aca0403162Wink Saville    equalsHandlesNulls (Object a, Object b) {
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return (a == null) ? (b == null) : a.equals (b);
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package*/ boolean
209767a662ecde33c3979bf02b793d392aca0403162Wink Saville    compareTo(DriverCall c) {
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // On mobile originated (MO) calls, the phone number may have changed
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // due to a SIM Toolkit call control modification.
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // We assume we know when MO calls are created (since we created them)
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // and therefore don't need to compare the phone number anyway.
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (! (isIncoming || c.isMT)) return true;
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // ... but we can compare phone numbers on MT calls, and we have
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // no control over when they begin, so we might as well
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String cAddress = PhoneNumberUtils.stringFromStringAndTOA(c.number, c.TOA);
221767a662ecde33c3979bf02b793d392aca0403162Wink Saville        return isIncoming == c.isMT && equalsHandlesNulls(address, cAddress);
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
225dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    public String getOrigDialString(){
226dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        return dialString;
227dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    }
228dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
229767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public String getAddress() {
230767a662ecde33c3979bf02b793d392aca0403162Wink Saville        return address;
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
233dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    public String getCnapName() {
234dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        return cnapName;
235dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    }
236dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
237dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    public int getCnapNamePresentation() {
238dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        return cnapNamePresentation;
239dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    }
240dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
241767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public CdmaCall getCall() {
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return parent;
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
245767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public long getCreateTime() {
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return createTime;
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
249767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public long getConnectTime() {
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return connectTime;
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
253767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public long getDisconnectTime() {
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return disconnectTime;
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
257767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public long getDurationMillis() {
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (connectTimeReal == 0) {
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (duration == 0) {
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return SystemClock.elapsedRealtime() - connectTimeReal;
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return duration;
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
267767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public long getHoldDurationMillis() {
268767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (getState() != CdmaCall.State.HOLDING) {
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If not holding, return 0
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return SystemClock.elapsedRealtime() - holdingStartTime;
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
276767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public DisconnectCause getDisconnectCause() {
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return cause;
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
280767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public boolean isIncoming() {
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return isIncoming;
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
284767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public CdmaCall.State getState() {
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (disconnected) {
286767a662ecde33c3979bf02b793d392aca0403162Wink Saville            return CdmaCall.State.DISCONNECTED;
287767a662ecde33c3979bf02b793d392aca0403162Wink Saville        } else {
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return super.getState();
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
292767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public void hangup() throws CallStateException {
293767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (!disconnected) {
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            owner.hangup(this);
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new CallStateException ("disconnected");
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
300767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public void separate() throws CallStateException {
301767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (!disconnected) {
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            owner.separate(this);
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new CallStateException ("disconnected");
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
308767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public PostDialState getPostDialState() {
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return postDialState;
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
312767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public void proceedAfterWaitChar() {
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (postDialState != PostDialState.WAIT) {
314767a662ecde33c3979bf02b793d392aca0403162Wink Saville            Log.w(LOG_TAG, "CdmaConnection.proceedAfterWaitChar(): Expected "
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + "getPostDialState() to be WAIT but was " + postDialState);
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setPostDialState(PostDialState.STARTED);
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        processNextPostDialChar();
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
323767a662ecde33c3979bf02b793d392aca0403162Wink Saville
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void proceedAfterWildChar(String str) {
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (postDialState != PostDialState.WILD) {
326767a662ecde33c3979bf02b793d392aca0403162Wink Saville            Log.w(LOG_TAG, "CdmaConnection.proceedAfterWaitChar(): Expected "
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + "getPostDialState() to be WILD but was " + postDialState);
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setPostDialState(PostDialState.STARTED);
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (false) {
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean playedTone = false;
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int len = (str != null ? str.length() : 0);
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i=0; i<len; i++) {
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                char c = str.charAt(i);
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Message msg = null;
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (i == len-1) {
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    msg = h.obtainMessage(EVENT_DTMF_DONE);
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (PhoneNumberUtils.is12Key(c)) {
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    owner.cm.sendDtmf(c, msg);
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    playedTone = true;
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!playedTone) {
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                processNextPostDialChar();
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // make a new postDialString, with the wild char replacement string
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // at the beginning, followed by the remaining postDialString.
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            StringBuilder buf = new StringBuilder(str);
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            buf.append(postDialString.substring(nextPostDialChar));
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            postDialString = buf.toString();
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            nextPostDialChar = 0;
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (Phone.DEBUG_PHONE) {
363767a662ecde33c3979bf02b793d392aca0403162Wink Saville                log("proceedAfterWildChar: new postDialString is " +
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        postDialString);
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            processNextPostDialChar();
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
370767a662ecde33c3979bf02b793d392aca0403162Wink Saville
371767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public void cancelPostDial() {
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setPostDialState(PostDialState.CANCELLED);
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
375767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /**
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when this Connection is being hung up locally (eg, user pressed "end")
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Note that at this point, the hangup request has been dispatched to the radio
378767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * but no response has yet been received so update() has not yet been called
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void
381767a662ecde33c3979bf02b793d392aca0403162Wink Saville    onHangupLocal() {
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cause = DisconnectCause.LOCAL;
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DisconnectCause
386767a662ecde33c3979bf02b793d392aca0403162Wink Saville    disconnectCauseFromCode(int causeCode) {
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * See 22.001 Annex F.4 for mapping of cause codes
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * to local tones
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
391767a662ecde33c3979bf02b793d392aca0403162Wink Saville
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (causeCode) {
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case CallFailCause.USER_BUSY:
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return DisconnectCause.BUSY;
395e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            case CallFailCause.NO_CIRCUIT_AVAIL:
396e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                return DisconnectCause.CONGESTION;
397e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            case CallFailCause.ACM_LIMIT_EXCEEDED:
398e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                return DisconnectCause.LIMIT_EXCEEDED;
399e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            case CallFailCause.CALL_BARRED:
400e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                return DisconnectCause.CALL_BARRED;
401e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            case CallFailCause.FDN_BLOCKED:
402e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                return DisconnectCause.FDN_BLOCKED;
403e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            case CallFailCause.CDMA_LOCKED_UNTIL_POWER_CYCLE:
404e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                return DisconnectCause.CDMA_LOCKED_UNTIL_POWER_CYCLE;
405e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            case CallFailCause.CDMA_DROP:
40622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                return DisconnectCause.CDMA_DROP;
407e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            case CallFailCause.CDMA_INTERCEPT:
408e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                return DisconnectCause.CDMA_INTERCEPT;
409e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            case CallFailCause.CDMA_REORDER:
410e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                return DisconnectCause.CDMA_REORDER;
411e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            case CallFailCause.CDMA_SO_REJECT:
412e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                return DisconnectCause.CDMA_SO_REJECT;
413e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            case CallFailCause.CDMA_RETRY_ORDER:
414e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                return DisconnectCause.CDMA_RETRY_ORDER;
415e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            case CallFailCause.CDMA_ACCESS_FAILURE:
416e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                return DisconnectCause.CDMA_ACCESS_FAILURE;
417e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            case CallFailCause.CDMA_PREEMPTED:
418e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                return DisconnectCause.CDMA_PREEMPTED;
419e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            case CallFailCause.CDMA_NOT_EMERGENCY:
420e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                return DisconnectCause.CDMA_NOT_EMERGENCY;
42127d074e0efbdabd40f00eca41169ea225c05fcbeNaveen Kalla            case CallFailCause.CDMA_ACCESS_BLOCKED:
42227d074e0efbdabd40f00eca41169ea225c05fcbeNaveen Kalla                return DisconnectCause.CDMA_ACCESS_BLOCKED;
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case CallFailCause.ERROR_UNSPECIFIED:
424767a662ecde33c3979bf02b793d392aca0403162Wink Saville            case CallFailCause.NORMAL_CLEARING:
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            default:
426767a662ecde33c3979bf02b793d392aca0403162Wink Saville                CDMAPhone phone = owner.phone;
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int serviceState = phone.getServiceState().getState();
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (serviceState == ServiceState.STATE_POWER_OFF) {
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return DisconnectCause.POWER_OFF;
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE
431e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                        || serviceState == ServiceState.STATE_EMERGENCY_ONLY) {
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return DisconnectCause.OUT_OF_SERVICE;
433767a662ecde33c3979bf02b793d392aca0403162Wink Saville                } else if (phone.mCM.getRadioState() != CommandsInterface.RadioState.NV_READY
434767a662ecde33c3979bf02b793d392aca0403162Wink Saville                        && phone.getIccCard().getState() != RuimCard.State.READY) {
435767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    return DisconnectCause.ICC_ERROR;
436eafe72a0db89b5867ccd4b8170377309827785a2Satish.Kulkarni                } else if (causeCode==CallFailCause.NORMAL_CLEARING) {
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return DisconnectCause.NORMAL;
438eafe72a0db89b5867ccd4b8170377309827785a2Satish.Kulkarni                } else {
439eafe72a0db89b5867ccd4b8170377309827785a2Satish.Kulkarni                    return DisconnectCause.ERROR_UNSPECIFIED;
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package*/ void
445767a662ecde33c3979bf02b793d392aca0403162Wink Saville    onRemoteDisconnect(int causeCode) {
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        onDisconnect(disconnectCauseFromCode(causeCode));
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Called when the radio indicates the connection has been disconnected */
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package*/ void
451767a662ecde33c3979bf02b793d392aca0403162Wink Saville    onDisconnect(DisconnectCause cause) {
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this.cause = cause;
453767a662ecde33c3979bf02b793d392aca0403162Wink Saville
454767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (!disconnected) {
4558a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause            doDisconnect();
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (Config.LOGD) Log.d(LOG_TAG,
457767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    "[CDMAConn] onDisconnect: cause=" + cause);
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            owner.phone.notifyDisconnect(this);
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (parent != null) {
462767a662ecde33c3979bf02b793d392aca0403162Wink Saville                parent.connectionDisconnected(this);
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        releaseWakeLock();
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4688a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause    /** Called when the call waiting connection has been hung up */
4698a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause    /*package*/ void
4708a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause    onLocalDisconnect() {
4718a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause        if (!disconnected) {
4728a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause            doDisconnect();
4738a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause            if (Config.LOGD) Log.d(LOG_TAG,
4748a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause                    "[CDMAConn] onLoalDisconnect" );
4758a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause
4768a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause            if (parent != null) {
4778a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause                parent.detach(this);
4788a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause            }
4798a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause        }
4808a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause        releaseWakeLock();
4818a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause    }
4828a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Returns true if state has changed, false if nothing changed
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package*/ boolean
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    update (DriverCall dc) {
486767a662ecde33c3979bf02b793d392aca0403162Wink Saville        CdmaCall newParent;
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean changed = false;
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean wasConnectingInOrOut = isConnectingInOrOut();
489767a662ecde33c3979bf02b793d392aca0403162Wink Saville        boolean wasHolding = (getState() == CdmaCall.State.HOLDING);
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        newParent = parentFromDCState(dc.state);
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
493963558b0f36b0a3cc143ebb04688d074e69a08b3Libin Tang        if (Phone.DEBUG_PHONE) log("parent= " +parent +", newParent= " + newParent);
494963558b0f36b0a3cc143ebb04688d074e69a08b3Libin Tang
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!equalsHandlesNulls(address, dc.number)) {
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (Phone.DEBUG_PHONE) log("update: phone # changed!");
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            address = dc.number;
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            changed = true;
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
501dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        // A null cnapName should be the same as ""
5024be0d4378c3d9c79a094e99ce429907f1e9eda5fWink Saville        if (TextUtils.isEmpty(dc.name)) {
5034be0d4378c3d9c79a094e99ce429907f1e9eda5fWink Saville            if (!TextUtils.isEmpty(cnapName)) {
5044be0d4378c3d9c79a094e99ce429907f1e9eda5fWink Saville                changed = true;
5054be0d4378c3d9c79a094e99ce429907f1e9eda5fWink Saville                cnapName = "";
5064be0d4378c3d9c79a094e99ce429907f1e9eda5fWink Saville            }
5074be0d4378c3d9c79a094e99ce429907f1e9eda5fWink Saville        } else if (!dc.name.equals(cnapName)) {
50822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            changed = true;
50922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            cnapName = dc.name;
510dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        }
51122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
512963558b0f36b0a3cc143ebb04688d074e69a08b3Libin Tang        if (Phone.DEBUG_PHONE) log("--dssds----"+cnapName);
513dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        cnapNamePresentation = dc.namePresentation;
514dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        numberPresentation = dc.numberPresentation;
515dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newParent != parent) {
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (parent != null) {
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                parent.detach(this);
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            newParent.attach(this, dc);
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            parent = newParent;
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            changed = true;
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean parentStateChange;
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            parentStateChange = parent.update (this, dc);
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            changed = changed || parentStateChange;
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /** Some state-transition events */
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (Phone.DEBUG_PHONE) log(
532963558b0f36b0a3cc143ebb04688d074e69a08b3Libin Tang                "Update, wasConnectingInOrOut=" + wasConnectingInOrOut +
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ", wasHolding=" + wasHolding +
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ", isConnectingInOrOut=" + isConnectingInOrOut() +
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ", changed=" + changed);
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (wasConnectingInOrOut && !isConnectingInOrOut()) {
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onConnectedInOrOut();
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
542767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (changed && !wasHolding && (getState() == CdmaCall.State.HOLDING)) {
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // We've transitioned into HOLDING
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onStartedHolding();
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return changed;
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when this Connection is in the foregroundCall
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when a dial is initiated.
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * We know we're ACTIVE, and we know we're going to end up
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * HOLDING in the backgroundCall
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void
557767a662ecde33c3979bf02b793d392aca0403162Wink Saville    fakeHoldBeforeDial() {
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (parent != null) {
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            parent.detach(this);
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parent = owner.backgroundCall;
563767a662ecde33c3979bf02b793d392aca0403162Wink Saville        parent.attachFake(this, CdmaCall.State.HOLDING);
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        onStartedHolding();
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package*/ int
569767a662ecde33c3979bf02b793d392aca0403162Wink Saville    getCDMAIndex() throws CallStateException {
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (index >= 0) {
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return index + 1;
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
573767a662ecde33c3979bf02b793d392aca0403162Wink Saville            throw new CallStateException ("CDMA connection index not assigned");
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * An incoming or outgoing call has connected
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    onConnectedInOrOut() {
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        connectTime = System.currentTimeMillis();
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        connectTimeReal = SystemClock.elapsedRealtime();
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        duration = 0;
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // bug #678474: incoming call interpreted as missed call, even though
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // it sounds like the user has picked up the call.
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (Phone.DEBUG_PHONE) {
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            log("onConnectedInOrOut: connectTime=" + connectTime);
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isIncoming) {
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // outgoing calls only
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            processNextPostDialChar();
59582c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville        } else {
59682c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville            // Only release wake lock for incoming calls, for outgoing calls the wake lock
59782c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville            // will be released after any pause-dial is completed
59882c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville            releaseWakeLock();
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void
6038a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause    doDisconnect() {
6048a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause       index = -1;
6058a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause       disconnectTime = System.currentTimeMillis();
6068a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause       duration = SystemClock.elapsedRealtime() - connectTimeReal;
6078a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause       disconnected = true;
6088a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause    }
6098a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause
6108a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause    private void
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    onStartedHolding() {
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        holdingStartTime = SystemClock.elapsedRealtime();
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Performs the appropriate action for a post-dial char, but does not
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * notify application. returns false if the character is invalid and
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * should be ignored
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean
620767a662ecde33c3979bf02b793d392aca0403162Wink Saville    processPostDialChar(char c) {
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (PhoneNumberUtils.is12Key(c)) {
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            owner.cm.sendDtmf(c, h.obtainMessage(EVENT_DTMF_DONE));
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (c == PhoneNumberUtils.PAUSE) {
624dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            setPostDialState(PostDialState.PAUSE);
625dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
626dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            // Upon occurrences of the separator, the UE shall
627dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            // pause again for 2 seconds before sending any
628dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            // further DTMF digits.
629dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            h.sendMessageDelayed(h.obtainMessage(EVENT_PAUSE_DONE),
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            PAUSE_DELAY_MILLIS);
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (c == PhoneNumberUtils.WAIT) {
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setPostDialState(PostDialState.WAIT);
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (c == PhoneNumberUtils.WILD) {
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setPostDialState(PostDialState.WILD);
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
642dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    public String getRemainingPostDialString() {
643767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (postDialState == PostDialState.CANCELLED
644dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                || postDialState == PostDialState.COMPLETE
645dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                || postDialString == null
646dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                || postDialString.length() <= nextPostDialChar) {
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "";
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
650dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        String subStr = postDialString.substring(nextPostDialChar);
651dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        if (subStr != null) {
652dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            int wIndex = subStr.indexOf(PhoneNumberUtils.WAIT);
653dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            int pIndex = subStr.indexOf(PhoneNumberUtils.PAUSE);
654dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
65522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            if (wIndex > 0 && (wIndex < pIndex || pIndex <= 0)) {
656dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                subStr = subStr.substring(0, wIndex);
657dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            } else if (pIndex > 0) {
658dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                subStr = subStr.substring(0, pIndex);
659dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            }
660dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        }
661dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        return subStr;
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
663e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
66422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    public void updateParent(CdmaCall oldParent, CdmaCall newParent){
66522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        if (newParent != oldParent) {
66622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            if (oldParent != null) {
66722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                oldParent.detach(this);
66822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            }
66922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            newParent.attachFake(this, CdmaCall.State.ACTIVE);
67022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            parent = newParent;
67122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        }
67222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    }
67322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void finalize()
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * It is understood that This finializer is not guaranteed
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * to be called and the release lock call is here just in
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * case there is some path that doesn't call onDisconnect
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * and or onConnectedInOrOut.
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mPartialWakeLock.isHeld()) {
684767a662ecde33c3979bf02b793d392aca0403162Wink Saville            Log.e(LOG_TAG, "[CdmaConn] UNEXPECTED; mPartialWakeLock is held when finalizing.");
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        releaseWakeLock();
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
689dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    void processNextPostDialChar() {
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char c = 0;
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Registrant postDialHandler;
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (postDialState == PostDialState.CANCELLED) {
69482c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville            releaseWakeLock();
695767a662ecde33c3979bf02b793d392aca0403162Wink Saville            //Log.v("CDMA", "##### processNextPostDialChar: postDialState == CANCELLED, bail");
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (postDialString == null ||
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                postDialString.length() <= nextPostDialChar) {
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setPostDialState(PostDialState.COMPLETE);
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
70382c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville            // We were holding a wake lock until pause-dial was complete, so give it up now
70482c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville            releaseWakeLock();
70582c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // notifyMessage.arg1 is 0 on complete
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c = 0;
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean isValid;
710e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setPostDialState(PostDialState.STARTED);
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c = postDialString.charAt(nextPostDialChar++);
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            isValid = processPostDialChar(c);
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!isValid) {
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Will call processNextPostDialChar
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                h.obtainMessage(EVENT_NEXT_POST_DIAL).sendToTarget();
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Don't notify application
721767a662ecde33c3979bf02b793d392aca0403162Wink Saville                Log.e("CDMA", "processNextPostDialChar: c=" + c + " isn't valid!");
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        postDialHandler = owner.phone.mPostDialHandler;
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Message notifyMessage;
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
730767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (postDialHandler != null &&
731767a662ecde33c3979bf02b793d392aca0403162Wink Saville                (notifyMessage = postDialHandler.messageForRegistrant()) != null) {
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // The AsyncResult.result is the Connection object
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            PostDialState state = postDialState;
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            AsyncResult ar = AsyncResult.forMessage(notifyMessage);
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ar.result = this;
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ar.userObj = state;
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // arg1 is the character that was/is being processed
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyMessage.arg1 = c;
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyMessage.sendToTarget();
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** "connecting" means "has never been ACTIVE" for both incoming
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  and outgoing calls
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean
750767a662ecde33c3979bf02b793d392aca0403162Wink Saville    isConnectingInOrOut() {
751767a662ecde33c3979bf02b793d392aca0403162Wink Saville        return parent == null || parent == owner.ringingCall
752767a662ecde33c3979bf02b793d392aca0403162Wink Saville            || parent.state == CdmaCall.State.DIALING
753767a662ecde33c3979bf02b793d392aca0403162Wink Saville            || parent.state == CdmaCall.State.ALERTING;
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
756767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private CdmaCall
757767a662ecde33c3979bf02b793d392aca0403162Wink Saville    parentFromDCState (DriverCall.State state) {
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (state) {
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case ACTIVE:
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DIALING:
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case ALERTING:
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return owner.foregroundCall;
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //break;
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case HOLDING:
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return owner.backgroundCall;
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //break;
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case INCOMING:
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case WAITING:
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return owner.ringingCall;
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //break;
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            default:
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new RuntimeException("illegal call state: " + state);
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
78082c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville     * Set post dial state and acquire wake lock while switching to "started" or "wait"
78182c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville     * state, the wake lock will be released if state switches out of "started" or "wait"
782e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville     * state or after WAKE_LOCK_TIMEOUT_MILLIS.
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param s new PostDialState
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void setPostDialState(PostDialState s) {
78682c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville        if (s == PostDialState.STARTED ||
78782c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville                s == PostDialState.PAUSE) {
78882c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville            synchronized (mPartialWakeLock) {
78982c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville                if (mPartialWakeLock.isHeld()) {
79082c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville                    h.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
79182c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville                } else {
79282c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville                    acquireWakeLock();
79382c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville                }
79482c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville                Message msg = h.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT);
79582c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville                h.sendMessageDelayed(msg, WAKE_LOCK_TIMEOUT_MILLIS);
79682c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville            }
79782c08459789e139aa94e8484e3e105b4f54f22a4Wink Saville        } else {
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            h.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            releaseWakeLock();
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        postDialState = s;
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
803e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
804dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    private void createWakeLock(Context context) {
805dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
808e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
809dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    private void acquireWakeLock() {
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        log("acquireWakeLock");
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPartialWakeLock.acquire();
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
814dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    private void releaseWakeLock() {
815dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        synchronized (mPartialWakeLock) {
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mPartialWakeLock.isHeld()) {
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                log("releaseWakeLock");
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mPartialWakeLock.release();
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
822e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
823dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    private static boolean isPause(char c) {
82422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        return c == PhoneNumberUtils.PAUSE;
825dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    }
826dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
827dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    private static boolean isWait(char c) {
82822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        return c == PhoneNumberUtils.WAIT;
82922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    }
83022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
83122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    // This function is to find the next PAUSE character index if
83222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    // multiple pauses in a row. Otherwise it finds the next non PAUSE or
83322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    // non WAIT character index.
8342563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville    private static int
83522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    findNextPCharOrNonPOrNonWCharIndex(String phoneNumber, int currIndex) {
83618e7b98c1c7e3cf340e39e93be67b777e7036cc4Tang@Motorola.com        boolean wMatched = isWait(phoneNumber.charAt(currIndex));
83722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        int index = currIndex + 1;
83822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        int length = phoneNumber.length();
83922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        while (index < length) {
84022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            char cNext = phoneNumber.charAt(index);
84122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // if there is any W inside P/W sequence,mark it
84222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            if (isWait(cNext)) {
84322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                wMatched = true;
84422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            }
84522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // if any characters other than P/W chars after P/W sequence
84622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // we break out the loop and append the correct
84722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            if (!isWait(cNext) && !isPause(cNext)) {
84822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                break;
84922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            }
85022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            index++;
85122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        }
85222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
85322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // It means the PAUSE character(s) is in the middle of dial string
85422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // and it needs to be handled one by one.
85522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        if ((index < length) && (index > (currIndex + 1))  &&
85622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            ((wMatched == false) && isPause(phoneNumber.charAt(currIndex)))) {
85722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            return (currIndex + 1);
85822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        }
85922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        return index;
86022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    }
86122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
86222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    // This function returns either PAUSE or WAIT character to append.
86322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    // It is based on the next non PAUSE/WAIT character in the phoneNumber and the
86422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    // index for the current PAUSE/WAIT character
8652563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville    private static char
86622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    findPOrWCharToAppend(String phoneNumber, int currPwIndex, int nextNonPwCharIndex) {
86722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        char c = phoneNumber.charAt(currPwIndex);
86822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        char ret;
86922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
87022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // Append the PW char
87122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        ret = (isPause(c)) ? PhoneNumberUtils.PAUSE : PhoneNumberUtils.WAIT;
87222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
873963558b0f36b0a3cc143ebb04688d074e69a08b3Libin Tang        // If the nextNonPwCharIndex is greater than currPwIndex + 1,
874963558b0f36b0a3cc143ebb04688d074e69a08b3Libin Tang        // it means the PW sequence contains not only P characters.
875963558b0f36b0a3cc143ebb04688d074e69a08b3Libin Tang        // Since for the sequence that only contains P character,
876963558b0f36b0a3cc143ebb04688d074e69a08b3Libin Tang        // the P character is handled one by one, the nextNonPwCharIndex
877963558b0f36b0a3cc143ebb04688d074e69a08b3Libin Tang        // equals to currPwIndex + 1.
878963558b0f36b0a3cc143ebb04688d074e69a08b3Libin Tang        // In this case, skip P, append W.
879963558b0f36b0a3cc143ebb04688d074e69a08b3Libin Tang        if (nextNonPwCharIndex > (currPwIndex + 1)) {
88022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            ret = PhoneNumberUtils.WAIT;
881dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        }
88222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        return ret;
883dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    }
884dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
885dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    /**
88618e7b98c1c7e3cf340e39e93be67b777e7036cc4Tang@Motorola.com     * format original dial string
88722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville     * 1) convert international dialing prefix "+" to
88822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville     *    string specified per region
88922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville     *
89022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville     * 2) handle corner cases for PAUSE/WAIT dialing:
89122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville     *
89222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville     *    If PAUSE/WAIT sequence at the end, ignore them.
89322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville     *
89422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville     *    If consecutive PAUSE/WAIT sequence in the middle of the string,
89522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville     *    and if there is any WAIT in PAUSE/WAIT sequence, treat them like WAIT.
896dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville     */
89722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    public static String formatDialString(String phoneNumber) {
898963558b0f36b0a3cc143ebb04688d074e69a08b3Libin Tang        /**
899963558b0f36b0a3cc143ebb04688d074e69a08b3Libin Tang         * TODO(cleanup): This function should move to PhoneNumberUtils, and
900963558b0f36b0a3cc143ebb04688d074e69a08b3Libin Tang         * tests should be added.
901963558b0f36b0a3cc143ebb04688d074e69a08b3Libin Tang         */
902963558b0f36b0a3cc143ebb04688d074e69a08b3Libin Tang
903dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        if (phoneNumber == null) {
904dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            return null;
905dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        }
906dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        int length = phoneNumber.length();
907dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        StringBuilder ret = new StringBuilder();
90822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        char c;
90922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        int currIndex = 0;
91018e7b98c1c7e3cf340e39e93be67b777e7036cc4Tang@Motorola.com
91122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        while (currIndex < length) {
91222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            c = phoneNumber.charAt(currIndex);
91318e7b98c1c7e3cf340e39e93be67b777e7036cc4Tang@Motorola.com            if (isPause(c) || isWait(c)) {
91422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                if (currIndex < length - 1) {
91522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    // if PW not at the end
91622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    int nextIndex = findNextPCharOrNonPOrNonWCharIndex(phoneNumber, currIndex);
91722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    // If there is non PW char following PW sequence
91822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    if (nextIndex < length) {
91922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                        char pC = findPOrWCharToAppend(phoneNumber, currIndex, nextIndex);
92022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                        ret.append(pC);
92118e7b98c1c7e3cf340e39e93be67b777e7036cc4Tang@Motorola.com                        // If PW char sequence has more than 2 PW characters,
922963558b0f36b0a3cc143ebb04688d074e69a08b3Libin Tang                        // skip to the last PW character since the sequence already be
92318e7b98c1c7e3cf340e39e93be67b777e7036cc4Tang@Motorola.com                        // converted to WAIT character
924963558b0f36b0a3cc143ebb04688d074e69a08b3Libin Tang                        if (nextIndex > (currIndex + 1)) {
92522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                            currIndex = nextIndex - 1;
926dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                        }
92722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    } else if (nextIndex == length) {
92822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                        // It means PW characters at the end, ignore
92922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                        currIndex = length - 1;
930dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                    }
931dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                }
93222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            } else {
933dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                ret.append(c);
934dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            }
93522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            currIndex++;
936dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        }
93718e7b98c1c7e3cf340e39e93be67b777e7036cc4Tang@Motorola.com        return PhoneNumberUtils.cdmaCheckAndProcessPlusCode(ret.toString());
938dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    }
939dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void log(String msg) {
941767a662ecde33c3979bf02b793d392aca0403162Wink Saville        Log.d(LOG_TAG, "[CDMAConn] " + msg);
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
943105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
944105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    @Override
945105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    public int getNumberPresentation() {
946105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        return numberPresentation;
947105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
949