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