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        return owner.phone;
79    }
80
81    public boolean isMultiparty() {
82        return connections.size() > 1;
83    }
84
85    /** Please note: if this is the foreground call and a
86     *  background call exists, the background call will be resumed
87     *  because an AT+CHLD=1 will be sent
88     */
89    public void
90    hangup() throws CallStateException {
91        owner.hangup(this);
92    }
93
94    public String
95    toString() {
96        return state.toString();
97    }
98
99    //***** Called from CdmaConnection
100
101    /*package*/ void
102    attach(Connection conn, DriverCall dc) {
103        connections.add(conn);
104
105        state = stateFromDCState (dc.state);
106    }
107
108    /*package*/ void
109    attachFake(Connection conn, State state) {
110        connections.add(conn);
111
112        this.state = state;
113    }
114
115    /**
116     * Called by CdmaConnection when it has disconnected
117     */
118    void
119    connectionDisconnected(CdmaConnection conn) {
120        if (state != State.DISCONNECTED) {
121            /* If only disconnected connections remain, we are disconnected*/
122
123            boolean hasOnlyDisconnectedConnections = true;
124
125            for (int i = 0, s = connections.size()  ; i < s; i ++) {
126                if (connections.get(i).getState()
127                    != State.DISCONNECTED
128                ) {
129                    hasOnlyDisconnectedConnections = false;
130                    break;
131                }
132            }
133
134            if (hasOnlyDisconnectedConnections) {
135                state = State.DISCONNECTED;
136            }
137        }
138    }
139
140
141    /*package*/ void
142    detach(CdmaConnection conn) {
143        connections.remove(conn);
144
145        if (connections.size() == 0) {
146            state = State.IDLE;
147        }
148    }
149
150    /*package*/ boolean
151    update (CdmaConnection conn, DriverCall dc) {
152        State newState;
153        boolean changed = false;
154
155        newState = stateFromDCState(dc.state);
156
157        if (newState != state) {
158            state = newState;
159            changed = true;
160        }
161
162        return changed;
163    }
164
165    /**
166     * @return true if there's no space in this call for additional
167     * connections to be added via "conference"
168     */
169    /*package*/ boolean
170    isFull() {
171        return connections.size() == CdmaCallTracker.MAX_CONNECTIONS_PER_CALL;
172    }
173
174    //***** Called from CdmaCallTracker
175
176
177    /**
178     * Called when this Call is being hung up locally (eg, user pressed "end")
179     * Note that at this point, the hangup request has been dispatched to the radio
180     * but no response has yet been received so update() has not yet been called
181     */
182    void
183    onHangupLocal() {
184        for (int i = 0, s = connections.size(); i < s; i++) {
185            CdmaConnection cn = (CdmaConnection)connections.get(i);
186
187            cn.onHangupLocal();
188        }
189        state = State.DISCONNECTING;
190    }
191
192    /**
193     * Called when it's time to clean up disconnected Connection objects
194     */
195   void clearDisconnected() {
196        for (int i = connections.size() - 1 ; i >= 0 ; i--) {
197        CdmaConnection cn = (CdmaConnection)connections.get(i);
198
199            if (cn.getState() == State.DISCONNECTED) {
200                connections.remove(i);
201            }
202        }
203
204        if (connections.size() == 0) {
205            state = State.IDLE;
206        }
207    }
208}
209