1 /*
2  * Copyright (C) 2015 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.internal.annotations.VisibleForTesting;
23 
24 /**
25  * {@hide}
26  */
27 public class GsmCdmaCall extends Call {
28     /*************************** Instance Variables **************************/
29 
30     /*package*/ GsmCdmaCallTracker mOwner;
31 
32     /****************************** Constructors *****************************/
33     /*package*/
GsmCdmaCall(GsmCdmaCallTracker owner)34     public GsmCdmaCall (GsmCdmaCallTracker owner) {
35         mOwner = owner;
36     }
37 
38     /************************** Overridden from Call *************************/
39 
40     @Override
getPhone()41     public Phone getPhone() {
42         return mOwner.getPhone();
43     }
44 
45     @Override
isMultiparty()46     public boolean isMultiparty() {
47         return getConnectionsCount() > 1;
48     }
49 
50     /** Please note: if this is the foreground call and a
51      *  background call exists, the background call will be resumed
52      *  because an AT+CHLD=1 will be sent
53      */
54     @Override
hangup()55     public void hangup() throws CallStateException {
56         mOwner.hangup(this);
57     }
58 
59     /**
60      * Hangup the ringing call with a specified reason; reason is not supported on GSM/CDMA.
61      * @param rejectReason
62      */
63     @Override
hangup(@ndroid.telecom.Call.RejectReason int rejectReason)64     public void hangup(@android.telecom.Call.RejectReason int rejectReason)
65             throws CallStateException {
66         mOwner.hangup(this);
67     }
68 
69     @Override
toString()70     public String toString() {
71         return mState.toString();
72     }
73 
74     //***** Called from GsmCdmaConnection
75 
attach(Connection conn, DriverCall dc)76     public void attach(Connection conn, DriverCall dc) {
77         addConnection(conn);
78 
79         mState = stateFromDCState (dc.state);
80     }
81 
82     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
attachFake(Connection conn, State state)83     public void attachFake(Connection conn, State state) {
84         addConnection(conn);
85 
86         mState = state;
87     }
88 
89     /**
90      * Called by GsmCdmaConnection when it has disconnected
91      */
connectionDisconnected(GsmCdmaConnection conn)92     public boolean connectionDisconnected(GsmCdmaConnection conn) {
93         if (mState != State.DISCONNECTED) {
94             /* If only disconnected connections remain, we are disconnected*/
95 
96             boolean hasOnlyDisconnectedConnections = true;
97 
98             for (Connection c : getConnections()) {
99                 if (c.getState() != State.DISCONNECTED) {
100                     hasOnlyDisconnectedConnections = false;
101                     break;
102                 }
103             }
104 
105             if (hasOnlyDisconnectedConnections) {
106                 mState = State.DISCONNECTED;
107                 return true;
108             }
109         }
110 
111         return false;
112     }
113 
detach(GsmCdmaConnection conn)114     public void detach(GsmCdmaConnection conn) {
115         removeConnection(conn);
116 
117         if (getConnectionsCount() == 0) {
118             mState = State.IDLE;
119         }
120     }
121 
update(GsmCdmaConnection conn, DriverCall dc)122     /*package*/ boolean update (GsmCdmaConnection conn, DriverCall dc) {
123         State newState;
124         boolean changed = false;
125 
126         newState = stateFromDCState(dc.state);
127 
128         if (newState != mState) {
129             mState = newState;
130             changed = true;
131         }
132 
133         return changed;
134     }
135 
136     /**
137      * @return true if there's no space in this call for additional
138      * connections to be added via "conference"
139      */
isFull()140     /*package*/ boolean isFull() {
141         return getConnectionsCount() == mOwner.getMaxConnectionsPerCall();
142     }
143 
144     //***** Called from GsmCdmaCallTracker
145 
146 
147     /**
148      * Called when this Call is being hung up locally (eg, user pressed "end")
149      * Note that at this point, the hangup request has been dispatched to the radio
150      * but no response has yet been received so update() has not yet been called
151      */
152     @VisibleForTesting
onHangupLocal()153     public void onHangupLocal() {
154         if (!mState.isAlive()) {
155             return;
156         }
157         for (Connection conn : getConnections()) {
158             ((GsmCdmaConnection) conn).onHangupLocal();
159         }
160         mState = State.DISCONNECTING;
161     }
162 }