62
62
import static io .wazo .callkeep .RNCallKeepModule .ACTION_ONGOING_CALL ;
63
63
import static io .wazo .callkeep .RNCallKeepModule .ACTION_UNHOLD_CALL ;
64
64
import static io .wazo .callkeep .RNCallKeepModule .ACTION_UNMUTE_CALL ;
65
+ import static io .wazo .callkeep .RNCallKeepModule .ACTION_CHECK_REACHABILITY ;
65
66
import static io .wazo .callkeep .RNCallKeepModule .EXTRA_CALLER_NAME ;
66
67
import static io .wazo .callkeep .RNCallKeepModule .EXTRA_CALL_NUMBER ;
67
68
import static io .wazo .callkeep .RNCallKeepModule .EXTRA_CALL_UUID ;
70
71
// @see https://github.com/kbagchiGWC/voice-quickstart-android/blob/9a2aff7fbe0d0a5ae9457b48e9ad408740dfb968/exampleConnectionService/src/main/java/com/twilio/voice/examples/connectionservice/VoiceConnectionService.java
71
72
@ TargetApi (Build .VERSION_CODES .M )
72
73
public class VoiceConnectionService extends ConnectionService {
73
- private static Boolean isAvailable = false ;
74
+ private static Boolean isAvailable ;
75
+ private static Boolean isInitialized ;
76
+ private static Boolean isReachable ;
77
+ private static String notReachableCallUuid ;
78
+ private static ConnectionRequest currentConnectionRequest ;
74
79
private static String TAG = "RNCK:VoiceConnectionService" ;
75
80
public static Map <String , VoiceConnection > currentConnections = new HashMap <>();
76
81
public static Boolean hasOutgoingCall = false ;
82
+ public static VoiceConnectionService currentConnectionService = null ;
77
83
78
84
public static Connection getConnection (String connectionId ) {
79
85
if (currentConnections .containsKey (connectionId )) {
@@ -85,12 +91,27 @@ public static Connection getConnection(String connectionId) {
85
91
public VoiceConnectionService () {
86
92
super ();
87
93
Log .e (TAG , "Constructor" );
94
+ isReachable = false ;
95
+ isInitialized = false ;
96
+ isAvailable = false ;
97
+ currentConnectionRequest = null ;
98
+ currentConnectionService = this ;
88
99
}
89
100
90
101
public static void setAvailable (Boolean value ) {
102
+ Log .d (TAG , "setAvailable: " + (value ? "true" : "false" ));
103
+ if (value ) {
104
+ isInitialized = true ;
105
+ }
106
+
91
107
isAvailable = value ;
92
108
}
93
109
110
+ public static void setReachable () {
111
+ Log .d (TAG , "setReachable" );
112
+ isReachable = true ;
113
+ VoiceConnectionService .currentConnectionRequest = null ;
114
+ }
94
115
95
116
public static void deinitConnection (String connectionId ) {
96
117
Log .d (TAG , "deinitConnection:" + connectionId );
@@ -116,44 +137,44 @@ public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManage
116
137
@ Override
117
138
public Connection onCreateOutgoingConnection (PhoneAccountHandle connectionManagerPhoneAccount , ConnectionRequest request ) {
118
139
VoiceConnectionService .hasOutgoingCall = true ;
140
+ String uuid = UUID .randomUUID ().toString ();
141
+
142
+ if (!isInitialized && !isReachable ) {
143
+ this .notReachableCallUuid = uuid ;
144
+ this .currentConnectionRequest = request ;
145
+ this .checkReachability ();
146
+ }
147
+
148
+ return this .makeOutgoingCall (request , uuid , false );
149
+ }
119
150
151
+ private Connection makeOutgoingCall (ConnectionRequest request , String uuid , Boolean forceWakeUp ) {
120
152
Bundle extras = request .getExtras ();
121
153
Connection outgoingCallConnection = null ;
122
154
String number = request .getAddress ().getSchemeSpecificPart ();
123
155
String extrasNumber = extras .getString (EXTRA_CALL_NUMBER );
124
156
String displayName = extras .getString (EXTRA_CALLER_NAME );
125
- String uuid = UUID . randomUUID (). toString ( );
157
+ Boolean isForeground = VoiceConnectionService . isRunning ( this . getApplicationContext () );
126
158
127
- Log .d (TAG , "onCreateOutgoingConnection :" + uuid + ", number: " + number );
159
+ Log .d (TAG , "makeOutgoingCall :" + uuid + ", number: " + number + ", displayName:" + displayName );
128
160
129
161
// Wakeup application if needed
130
- if (!VoiceConnectionService . isRunning ( this . getApplicationContext ()) ) {
162
+ if (!isForeground || forceWakeUp ) {
131
163
Log .d (TAG , "onCreateOutgoingConnection: Waking up application" );
132
- Intent headlessIntent = new Intent (
133
- this .getApplicationContext (),
134
- RNCallKeepBackgroundMessagingService .class
135
- );
136
- headlessIntent .putExtra ("callUUID" , uuid );
137
- headlessIntent .putExtra ("name" , displayName );
138
- headlessIntent .putExtra ("handle" , number );
139
- ComponentName name = this .getApplicationContext ().startService (headlessIntent );
140
- if (name != null ) {
141
- HeadlessJsTaskService .acquireWakeLockNow (this .getApplicationContext ());
142
- }
143
- } else if (!this .canMakeOutgoingCall ()) {
164
+ this .wakeUpApplication (uuid , number , displayName );
165
+ } else if (!this .canMakeOutgoingCall () && isReachable ) {
166
+ Log .d (TAG , "onCreateOutgoingConnection: not available" );
144
167
return Connection .createFailedConnection (new DisconnectCause (DisconnectCause .LOCAL ));
145
168
}
146
169
147
170
// TODO: Hold all other calls
148
- if (extrasNumber != null && extrasNumber .equals (number )) {
149
- outgoingCallConnection = createConnection (request );
150
- } else {
171
+ if (extrasNumber == null || !extrasNumber .equals (number )) {
151
172
extras .putString (EXTRA_CALL_UUID , uuid );
152
173
extras .putString (EXTRA_CALLER_NAME , displayName );
153
174
extras .putString (EXTRA_CALL_NUMBER , number );
154
- outgoingCallConnection = createConnection (request );
155
175
}
156
176
177
+ outgoingCallConnection = createConnection (request );
157
178
outgoingCallConnection .setDialing ();
158
179
outgoingCallConnection .setAudioModeIsVoip (true );
159
180
outgoingCallConnection .setCallerDisplayName (displayName , TelecomManager .PRESENTATION_ALLOWED );
@@ -164,15 +185,59 @@ public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManage
164
185
sendCallRequestToActivity (ACTION_ONGOING_CALL , extrasMap );
165
186
sendCallRequestToActivity (ACTION_AUDIO_SESSION , null );
166
187
188
+ Log .d (TAG , "onCreateOutgoingConnection: calling" );
189
+
167
190
return outgoingCallConnection ;
168
191
}
169
192
193
+ private void wakeUpApplication (String uuid , String number , String displayName ) {
194
+ Intent headlessIntent = new Intent (
195
+ this .getApplicationContext (),
196
+ RNCallKeepBackgroundMessagingService .class
197
+ );
198
+ headlessIntent .putExtra ("callUUID" , uuid );
199
+ headlessIntent .putExtra ("name" , displayName );
200
+ headlessIntent .putExtra ("handle" , number );
201
+ Log .d (TAG , "wakeUpApplication: " + uuid + ", number : " + number + ", displayName:" + displayName );
202
+
203
+ ComponentName name = this .getApplicationContext ().startService (headlessIntent );
204
+ if (name != null ) {
205
+ HeadlessJsTaskService .acquireWakeLockNow (this .getApplicationContext ());
206
+ }
207
+ }
208
+
209
+ private void wakeUpAfterReachabilityTimeout (ConnectionRequest request ) {
210
+ if (this .currentConnectionRequest == null ) {
211
+ return ;
212
+ }
213
+ Log .d (TAG , "checkReachability timeout, force wakeup" );
214
+ Bundle extras = request .getExtras ();
215
+ String number = request .getAddress ().getSchemeSpecificPart ();
216
+ String displayName = extras .getString (EXTRA_CALLER_NAME );
217
+ wakeUpApplication (this .notReachableCallUuid , number , displayName );
218
+
219
+ VoiceConnectionService .currentConnectionRequest = null ;
220
+ }
221
+
222
+ private void checkReachability () {
223
+ Log .d (TAG , "checkReachability" );
224
+
225
+ final VoiceConnectionService instance = this ;
226
+ sendCallRequestToActivity (ACTION_CHECK_REACHABILITY , null );
227
+
228
+ new android .os .Handler ().postDelayed (
229
+ new Runnable () {
230
+ public void run () {
231
+ instance .wakeUpAfterReachabilityTimeout (instance .currentConnectionRequest );
232
+ }
233
+ }, 2000 );
234
+ }
235
+
170
236
private Boolean canMakeOutgoingCall () {
171
237
return isAvailable ;
172
238
}
173
239
174
240
private Connection createConnection (ConnectionRequest request ) {
175
-
176
241
Bundle extras = request .getExtras ();
177
242
HashMap <String , String > extrasMap = this .bundleToMap (extras );
178
243
extrasMap .put (EXTRA_CALL_NUMBER , request .getAddress ().toString ());
0 commit comments