1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.telephony.cdma;
18
19import java.util.ArrayList;
20import java.util.List;
21
22import com.android.internal.telephony.Call;
23import com.android.internal.telephony.CallStateException;
24import com.android.internal.telephony.Connection;
25import com.android.internal.telephony.DriverCall;
26import com.android.internal.telephony.Phone;
27import com.android.internal.telephony.Call.State;
28
29/**
30 * {@hide}
31 */
32public final class CdmaCall extends Call {
33    /*************************** Instance Variables **************************/
34
35    /*package*/ ArrayList<Connection> connections = new ArrayList<Connection>();
36    /*package*/ State state = State.IDLE;
37    /*package*/ CdmaCallTracker owner;
38
39    /***************************** Class Methods *****************************/
40
41    static State
42    stateFromDCState (DriverCall.State dcState) {
43        switch (dcState) {
44            case ACTIVE:        return State.ACTIVE;
45            case HOLDING:       return State.HOLDING;
46            case DIALING:       return State.DIALING;
47            case ALERTING:      return State.ALERTING;
48            case INCOMING:      return State.INCOMING;
49            case WAITING:       return State.WAITING;
50            default:            throw new RuntimeException ("illegal call state:" + dcState);
51        }
52    }
53
54
55    /****************************** Constructors *****************************/
56    /*package*/
57    CdmaCall (CdmaCallTracker owner) {
58        this.owner = owner;
59    }
60
61    public void dispose() {
62    }
63
64    /************************** Overridden from Call *************************/
65    public List<Connection>
66    getConnections() {
67        // FIXME should return Collections.unmodifiableList();
68        return connections;
69    }
70
71    public State
72    getState() {
73        return state;
74    }
75
76    public Phone
77    getPhone() {
78        //TODO, see GsmCall
79        return null;
80    }
81
82    public boolean isMultiparty() {
83        return connections.size() > 1;
84    }
85
86    /** Please note: if this is the foreground call and a
87     *  background call exists, the background call will be resumed
88     *  because an AT+CHLD=1 will be sent
89     */
90    public void
91    hangup() throws CallStateException {
92        owner.hangup(this);
93    }
94
95    public String
96    toString() {
97        return state.toString();
98    }
99
100    //***** Called from CdmaConnection
101
102    /*package*/ void
103    attach(Connection conn, DriverCall dc) {
104        connections.add(conn);
105
106        state = stateFromDCState (dc.state);
107    }
108
109    /*package*/ void
110    attachFake(Connection conn, State state) {
111        connections.add(conn);
112
113        this.state = state;
114    }
115
116    /**
117     * Called by CdmaConnection when it has disconnected
118     */
119    void
120    connectionDisconnected(CdmaConnection conn) {
121        if (state != State.DISCONNECTED) {
122            /* If only disconnected connections remain, we are disconnected*/
123
124            boolean hasOnlyDisconnectedConnections = true;
125
126            for (int i = 0, s = connections.size()  ; i < s; i ++) {
127                if (connections.get(i).getState()
128                    != State.DISCONNECTED
129                ) {
130                    hasOnlyDisconnectedConnections = false;
131                    break;
132                }
133            }
134
135            if (hasOnlyDisconnectedConnections) {
136                state = State.DISCONNECTED;
137            }
138        }
139    }
140
141
142    /*package*/ void
143    detach(CdmaConnection conn) {
144        connections.remove(conn);
145
146        if (connections.size() == 0) {
147            state = State.IDLE;
148        }
149    }
150
151    /*package*/ boolean
152    update (CdmaConnection conn, DriverCall dc) {
153        State newState;
154        boolean changed = false;
155
156        newState = stateFromDCState(dc.state);
157
158        if (newState != state) {
159            state = newState;
160            changed = true;
161        }
162
163        return changed;
164    }
165
166    /**
167     * @return true if there's no space in this call for additional
168     * connections to be added via "conference"
169     */
170    /*package*/ boolean
171    isFull() {
172        return connections.size() == CdmaCallTracker.MAX_CONNECTIONS_PER_CALL;
173    }
174
175    //***** Called from CdmaCallTracker
176
177
178    /**
179     * Called when this Call is being hung up locally (eg, user pressed "end")
180     * Note that at this point, the hangup request has been dispatched to the radio
181     * but no response has yet been received so update() has not yet been called
182     */
183    void
184    onHangupLocal() {
185        for (int i = 0, s = connections.size(); i < s; i++) {
186            CdmaConnection cn = (CdmaConnection)connections.get(i);
187
188            cn.onHangupLocal();
189        }
190        state = State.DISCONNECTING;
191    }
192
193    /**
194     * Called when it's time to clean up disconnected Connection objects
195     */
196   void clearDisconnected() {
197        for (int i = connections.size() - 1 ; i >= 0 ; i--) {
198        CdmaConnection cn = (CdmaConnection)connections.get(i);
199
200            if (cn.getState() == State.DISCONNECTED) {
201                connections.remove(i);
202            }
203        }
204
205        if (connections.size() == 0) {
206            state = State.IDLE;
207        }
208    }
209}
210