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