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;
18
19import android.telecom.ConferenceParticipant;
20
21import java.util.ArrayList;
22import java.util.List;
23
24import android.telephony.Rlog;
25
26/**
27 * {@hide}
28 */
29public abstract class Call {
30    protected final String LOG_TAG = "Call";
31
32    /* Enums */
33
34    public enum State {
35        IDLE, ACTIVE, HOLDING, DIALING, ALERTING, INCOMING, WAITING, DISCONNECTED, DISCONNECTING;
36
37        public boolean isAlive() {
38            return !(this == IDLE || this == DISCONNECTED || this == DISCONNECTING);
39        }
40
41        public boolean isRinging() {
42            return this == INCOMING || this == WAITING;
43        }
44
45        public boolean isDialing() {
46            return this == DIALING || this == ALERTING;
47        }
48    }
49
50    public static State
51    stateFromDCState (DriverCall.State dcState) {
52        switch (dcState) {
53            case ACTIVE:        return State.ACTIVE;
54            case HOLDING:       return State.HOLDING;
55            case DIALING:       return State.DIALING;
56            case ALERTING:      return State.ALERTING;
57            case INCOMING:      return State.INCOMING;
58            case WAITING:       return State.WAITING;
59            default:            throw new RuntimeException ("illegal call state:" + dcState);
60        }
61    }
62
63    public enum SrvccState {
64        NONE, STARTED, COMPLETED, FAILED, CANCELED;
65    }
66
67    /* Instance Variables */
68
69    public State mState = State.IDLE;
70
71    public ArrayList<Connection> mConnections = new ArrayList<Connection>();
72
73    /* Instance Methods */
74
75    /** Do not modify the List result!!! This list is not yours to keep
76     *  It will change across event loop iterations            top
77     */
78
79    public abstract List<Connection> getConnections();
80    public abstract Phone getPhone();
81    public abstract boolean isMultiparty();
82    public abstract void hangup() throws CallStateException;
83
84
85    /**
86     * hasConnection
87     *
88     * @param c a Connection object
89     * @return true if the call contains the connection object passed in
90     */
91    public boolean hasConnection(Connection c) {
92        return c.getCall() == this;
93    }
94
95    /**
96     * hasConnections
97     * @return true if the call contains one or more connections
98     */
99    public boolean hasConnections() {
100        List<Connection> connections = getConnections();
101
102        if (connections == null) {
103            return false;
104        }
105
106        return connections.size() > 0;
107    }
108
109    /**
110     * getState
111     * @return state of class call
112     */
113    public State getState() {
114        return mState;
115    }
116
117    /**
118     * getConferenceParticipants
119     * @return List of conference participants.
120     */
121    public List<ConferenceParticipant> getConferenceParticipants() {
122        return null;
123    }
124
125    /**
126     * isIdle
127     *
128     * FIXME rename
129     * @return true if the call contains only disconnected connections (if any)
130     */
131    public boolean isIdle() {
132        return !getState().isAlive();
133    }
134
135    /**
136     * Returns the Connection associated with this Call that was created
137     * first, or null if there are no Connections in this Call
138     */
139    public Connection
140    getEarliestConnection() {
141        List<Connection> l;
142        long time = Long.MAX_VALUE;
143        Connection c;
144        Connection earliest = null;
145
146        l = getConnections();
147
148        if (l.size() == 0) {
149            return null;
150        }
151
152        for (int i = 0, s = l.size() ; i < s ; i++) {
153            c = l.get(i);
154            long t;
155
156            t = c.getCreateTime();
157
158            if (t < time) {
159                earliest = c;
160                time = t;
161            }
162        }
163
164        return earliest;
165    }
166
167    public long
168    getEarliestCreateTime() {
169        List<Connection> l;
170        long time = Long.MAX_VALUE;
171
172        l = getConnections();
173
174        if (l.size() == 0) {
175            return 0;
176        }
177
178        for (int i = 0, s = l.size() ; i < s ; i++) {
179            Connection c = l.get(i);
180            long t;
181
182            t = c.getCreateTime();
183
184            time = t < time ? t : time;
185        }
186
187        return time;
188    }
189
190    public long
191    getEarliestConnectTime() {
192        long time = Long.MAX_VALUE;
193        List<Connection> l = getConnections();
194
195        if (l.size() == 0) {
196            return 0;
197        }
198
199        for (int i = 0, s = l.size() ; i < s ; i++) {
200            Connection c = l.get(i);
201            long t;
202
203            t = c.getConnectTime();
204
205            time = t < time ? t : time;
206        }
207
208        return time;
209    }
210
211
212    public boolean
213    isDialingOrAlerting() {
214        return getState().isDialing();
215    }
216
217    public boolean
218    isRinging() {
219        return getState().isRinging();
220    }
221
222    /**
223     * Returns the Connection associated with this Call that was created
224     * last, or null if there are no Connections in this Call
225     */
226    public Connection
227    getLatestConnection() {
228        List<Connection> l = getConnections();
229        if (l.size() == 0) {
230            return null;
231        }
232
233        long time = 0;
234        Connection latest = null;
235        for (int i = 0, s = l.size() ; i < s ; i++) {
236            Connection c = l.get(i);
237            long t = c.getCreateTime();
238
239            if (t > time) {
240                latest = c;
241                time = t;
242            }
243        }
244
245        return latest;
246    }
247
248    /**
249     * Hangup call if it is alive
250     */
251    public void hangupIfAlive() {
252        if (getState().isAlive()) {
253            try {
254                hangup();
255            } catch (CallStateException ex) {
256                Rlog.w(LOG_TAG, " hangupIfActive: caught " + ex);
257            }
258        }
259    }
260
261    /**
262     * Called when it's time to clean up disconnected Connection objects
263     */
264    public void clearDisconnected() {
265        for (int i = mConnections.size() - 1 ; i >= 0 ; i--) {
266            Connection c = mConnections.get(i);
267            if (c.getState() == State.DISCONNECTED) {
268                mConnections.remove(i);
269            }
270        }
271
272        if (mConnections.size() == 0) {
273            setState(State.IDLE);
274        }
275    }
276
277    protected void setState(State newState) {
278        mState = newState;
279    }
280}
281