• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.compat.annotation.UnsupportedAppUsage;
20 import android.os.Build;
21 
22 import com.android.ims.internal.ConferenceParticipant;
23 import com.android.telephony.Rlog;
24 
25 import java.util.ArrayList;
26 import java.util.List;
27 
28 /**
29  * {@hide}
30  */
31 public abstract class Call {
32     protected final String LOG_TAG = "Call";
33 
34     @UnsupportedAppUsage
Call()35     public Call() {
36     }
37 
38     /* Enums */
39     @UnsupportedAppUsage(implicitMember = "values()[Lcom/android/internal/telephony/Call$State;")
40     public enum State {
41         @UnsupportedAppUsage IDLE,
42         ACTIVE,
43         @UnsupportedAppUsage HOLDING,
44         @UnsupportedAppUsage DIALING,
45         @UnsupportedAppUsage ALERTING,
46         @UnsupportedAppUsage INCOMING,
47         @UnsupportedAppUsage WAITING,
48         @UnsupportedAppUsage DISCONNECTED,
49         @UnsupportedAppUsage DISCONNECTING;
50 
51         @UnsupportedAppUsage
isAlive()52         public boolean isAlive() {
53             return !(this == IDLE || this == DISCONNECTED || this == DISCONNECTING);
54         }
55 
56         @UnsupportedAppUsage
isRinging()57         public boolean isRinging() {
58             return this == INCOMING || this == WAITING;
59         }
60 
isDialing()61         public boolean isDialing() {
62             return this == DIALING || this == ALERTING;
63         }
64     }
65 
66     public static State
stateFromDCState(DriverCall.State dcState)67     stateFromDCState (DriverCall.State dcState) {
68         switch (dcState) {
69             case ACTIVE:        return State.ACTIVE;
70             case HOLDING:       return State.HOLDING;
71             case DIALING:       return State.DIALING;
72             case ALERTING:      return State.ALERTING;
73             case INCOMING:      return State.INCOMING;
74             case WAITING:       return State.WAITING;
75             default:            throw new RuntimeException ("illegal call state:" + dcState);
76         }
77     }
78 
79     public enum SrvccState {
80         NONE, STARTED, COMPLETED, FAILED, CANCELED;
81     }
82 
83     /* Instance Variables */
84 
85     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
86     public State mState = State.IDLE;
87 
88     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
89     public ArrayList<Connection> mConnections = new ArrayList<>();
90 
91     private Object mLock = new Object();
92 
93     /* Instance Methods */
94 
95     /** Do not modify the List result!!! This list is not yours to keep
96      *  It will change across event loop iterations            top
97      */
98 
99     @UnsupportedAppUsage
getConnections()100     public ArrayList<Connection> getConnections() {
101         synchronized (mLock) {
102             return (ArrayList<Connection>) mConnections.clone();
103         }
104     }
105 
106     /**
107      * Get mConnections field from another Call instance.
108      * @param other
109      */
copyConnectionFrom(Call other)110     public void copyConnectionFrom(Call other) {
111         mConnections = other.getConnections();
112     }
113 
114     /**
115      * Get connections count of this instance.
116      * @return the count to return
117      */
getConnectionsCount()118     public int getConnectionsCount() {
119         synchronized (mLock) {
120             return mConnections.size();
121         }
122     }
123 
124     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getPhone()125     public abstract Phone getPhone();
126     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
isMultiparty()127     public abstract boolean isMultiparty();
128     @UnsupportedAppUsage
hangup()129     public abstract void hangup() throws CallStateException;
130 
hangup(@ndroid.telecom.Call.RejectReason int rejectReason)131     public abstract void hangup(@android.telecom.Call.RejectReason int rejectReason)
132             throws CallStateException;
133 
134     /**
135      * hasConnection
136      *
137      * @param c a Connection object
138      * @return true if the call contains the connection object passed in
139      */
hasConnection(Connection c)140     public boolean hasConnection(Connection c) {
141         return c.getCall() == this;
142     }
143 
144     /**
145      * hasConnections
146      * @return true if the call contains one or more connections
147      */
hasConnections()148     public boolean hasConnections() {
149         List<Connection> connections = getConnections();
150 
151         if (connections == null) {
152             return false;
153         }
154 
155         return connections.size() > 0;
156     }
157 
158     /**
159      * removeConnection
160      *
161      * @param conn the connection to be removed
162      */
removeConnection(Connection conn)163     public void removeConnection(Connection conn) {
164         synchronized (mLock) {
165             mConnections.remove(conn);
166         }
167     }
168 
169     /**
170      * addConnection
171      *
172      * @param conn the connection to be added
173      */
addConnection(Connection conn)174     public void addConnection(Connection conn) {
175         synchronized (mLock) {
176             mConnections.add(conn);
177         }
178     }
179 
180     /**
181      * clearConnection
182      */
clearConnections()183     public void clearConnections() {
184         synchronized (mLock) {
185             mConnections.clear();
186         }
187     }
188 
189     /**
190      * getState
191      * @return state of class call
192      */
193     @UnsupportedAppUsage
getState()194     public State getState() {
195         return mState;
196     }
197 
198     /**
199      * getConferenceParticipants
200      * @return List of conference participants.
201      */
getConferenceParticipants()202     public List<ConferenceParticipant> getConferenceParticipants() {
203         return null;
204     }
205 
206     /**
207      * isIdle
208      *
209      * FIXME rename
210      * @return true if the call contains only disconnected connections (if any)
211      */
212     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
isIdle()213     public boolean isIdle() {
214         return !getState().isAlive();
215     }
216 
217     /**
218      * Returns the Connection associated with this Call that was created
219      * first, or null if there are no Connections in this Call
220      */
221     @UnsupportedAppUsage
222     public Connection
getEarliestConnection()223     getEarliestConnection() {
224         List<Connection> l;
225         long time = Long.MAX_VALUE;
226         Connection c;
227         Connection earliest = null;
228 
229         l = getConnections();
230 
231         if (l.size() == 0) {
232             return null;
233         }
234 
235         for (int i = 0, s = l.size() ; i < s ; i++) {
236             c = l.get(i);
237             long t;
238 
239             t = c.getCreateTime();
240 
241             if (t < time) {
242                 earliest = c;
243                 time = t;
244             }
245         }
246 
247         return earliest;
248     }
249 
250     public long
getEarliestCreateTime()251     getEarliestCreateTime() {
252         List<Connection> l;
253         long time = Long.MAX_VALUE;
254 
255         l = getConnections();
256 
257         if (l.size() == 0) {
258             return 0;
259         }
260 
261         for (int i = 0, s = l.size() ; i < s ; i++) {
262             Connection c = l.get(i);
263             long t;
264 
265             t = c.getCreateTime();
266 
267             time = t < time ? t : time;
268         }
269 
270         return time;
271     }
272 
273     public long
274     getEarliestConnectTime() {
275         long time = Long.MAX_VALUE;
276         List<Connection> l = getConnections();
277 
278         if (l.size() == 0) {
279             return 0;
280         }
281 
282         for (int i = 0, s = l.size() ; i < s ; i++) {
283             Connection c = l.get(i);
284             long t;
285 
286             t = c.getConnectTime();
287 
288             time = t < time ? t : time;
289         }
290 
291         return time;
292     }
293 
294 
295     public boolean
296     isDialingOrAlerting() {
297         return getState().isDialing();
298     }
299 
300     public boolean
301     isRinging() {
302         return getState().isRinging();
303     }
304 
305     /**
306      * Returns the Connection associated with this Call that was created
307      * last, or null if there are no Connections in this Call
308      */
309     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
310     public Connection
311     getLatestConnection() {
312         List<Connection> l = getConnections();
313         if (l.size() == 0) {
314             return null;
315         }
316 
317         long time = 0;
318         Connection latest = null;
319         for (int i = 0, s = l.size() ; i < s ; i++) {
320             Connection c = l.get(i);
321             long t = c.getCreateTime();
322 
323             if (t > time) {
324                 latest = c;
325                 time = t;
326             }
327         }
328 
329         return latest;
330     }
331 
332     /**
333      * Hangup call if it is alive
334      */
335     public void hangupIfAlive() {
336         if (getState().isAlive()) {
337             try {
338                 hangup();
339             } catch (CallStateException ex) {
340                 Rlog.w(LOG_TAG, " hangupIfActive: caught " + ex);
341             }
342         }
343     }
344 
345     /**
346      * Called when it's time to clean up disconnected Connection objects
347      */
348     public void clearDisconnected() {
349         for (Connection conn : getConnections()) {
350             if (conn.getState() == State.DISCONNECTED) {
351                 removeConnection(conn);
352             }
353         }
354 
355         if (getConnectionsCount() == 0) {
356             setState(State.IDLE);
357         }
358     }
359 
360     protected void setState(State newState) {
361         mState = newState;
362     }
363 }
364