Skip to content

Commit 1ddaac1

Browse files
committed
Add the ability to wake up the application on outgoing native call
1 parent f95cae6 commit 1ddaac1

File tree

4 files changed

+122
-11
lines changed

4 files changed

+122
-11
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright (c) 2016-2019 The CallKeep Authors (see the AUTHORS file)
3+
* SPDX-License-Identifier: ISC, MIT
4+
*
5+
* Permission to use, copy, modify, and distribute this software for any
6+
* purpose with or without fee is hereby granted, provided that the above
7+
* copyright notice and this permission notice appear in all copies.
8+
*
9+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16+
*/
17+
18+
package io.wazo.callkeep;
19+
20+
import android.content.Intent;
21+
import android.os.Bundle;
22+
import android.util.Log;
23+
24+
import com.facebook.react.HeadlessJsTaskService;
25+
import com.facebook.react.bridge.WritableMap;
26+
import com.facebook.react.bridge.Arguments;
27+
import com.facebook.react.jstasks.HeadlessJsTaskConfig;
28+
29+
import static io.wazo.callkeep.RNCallKeepModule.EXTRA_CALLER_NAME;
30+
import static io.wazo.callkeep.RNCallKeepModule.EXTRA_CALL_NUMBER;
31+
import static io.wazo.callkeep.RNCallKeepModule.EXTRA_CALL_UUID;
32+
33+
import javax.annotation.Nullable;
34+
35+
public class RNCallKeepBackgroundMessagingService extends HeadlessJsTaskService {
36+
@Override
37+
protected @Nullable
38+
HeadlessJsTaskConfig getTaskConfig(Intent intent) {
39+
Bundle extras = intent.getExtras();
40+
41+
return new HeadlessJsTaskConfig(
42+
"RNCallKeepBackgroundMessage",
43+
Arguments.fromBundle(extras),
44+
60000,
45+
false
46+
);
47+
}
48+
}

android/src/main/java/io/wazo/callkeep/VoiceConnection.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ public void run() {
204204
Bundle extras = new Bundle();
205205
extras.putSerializable("attributeMap", attributeMap);
206206
intent.putExtras(extras);
207-
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
208207
}
208+
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
209209
}
210210
});
211211
}

android/src/main/java/io/wazo/callkeep/VoiceConnectionService.java

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
import android.annotation.TargetApi;
2121
import android.content.Intent;
22+
import android.content.Context;
23+
import android.content.ComponentName;
2224
import android.net.Uri;
2325
import android.os.Build;
2426
import android.os.Bundle;
@@ -35,6 +37,13 @@
3537
import android.telecom.TelecomManager;
3638
import android.util.Log;
3739

40+
import android.app.ActivityManager;
41+
import android.app.ActivityManager.RunningTaskInfo;
42+
43+
import com.facebook.react.HeadlessJsTaskService;
44+
import com.facebook.react.bridge.ReactContext;
45+
import com.facebook.react.common.LifecycleState;
46+
3847
import java.util.ArrayList;
3948
import java.util.HashMap;
4049
import java.util.Iterator;
@@ -103,29 +112,46 @@ public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManage
103112

104113
@Override
105114
public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
106-
if (!this.canMakeOutgoingCall()) {
107-
return Connection.createFailedConnection(new DisconnectCause(DisconnectCause.LOCAL));
108-
}
109-
// TODO: Hold all other calls
110-
111115
Bundle extras = request.getExtras();
112116
Connection outgoingCallConnection = null;
113117
String number = request.getAddress().getSchemeSpecificPart();
114118
String extrasNumber = extras.getString(EXTRA_CALL_NUMBER);
115-
String name = extras.getString(EXTRA_CALLER_NAME);
119+
String displayName = extras.getString(EXTRA_CALLER_NAME);
120+
String uuid = UUID.randomUUID().toString();
121+
122+
Log.d(TAG, "onCreateOutgoingConnection:" + uuid + ", number: " + number);
123+
124+
// Wakeup application if needed
125+
if (!VoiceConnectionService.isRunning(this.getApplicationContext())) {
126+
Log.d(TAG, "onCreateOutgoingConnection: Waking up application");
127+
Intent headlessIntent = new Intent(
128+
this.getApplicationContext(),
129+
RNCallKeepBackgroundMessagingService.class
130+
);
131+
headlessIntent.putExtra("callUUID", uuid);
132+
headlessIntent.putExtra("name", displayName);
133+
headlessIntent.putExtra("handle", number);
134+
ComponentName name = this.getApplicationContext().startService(headlessIntent);
135+
if (name != null) {
136+
HeadlessJsTaskService.acquireWakeLockNow(this.getApplicationContext());
137+
}
138+
} else if (!this.canMakeOutgoingCall()) {
139+
return Connection.createFailedConnection(new DisconnectCause(DisconnectCause.LOCAL));
140+
}
116141

142+
// TODO: Hold all other calls
117143
if (extrasNumber != null && extrasNumber.equals(number)) {
118144
outgoingCallConnection = createConnection(request);
119145
} else {
120-
String uuid = UUID.randomUUID().toString();
121146
extras.putString(EXTRA_CALL_UUID, uuid);
122-
extras.putString(EXTRA_CALLER_NAME, name);
147+
extras.putString(EXTRA_CALLER_NAME, displayName);
123148
extras.putString(EXTRA_CALL_NUMBER, number);
124149
outgoingCallConnection = createConnection(request);
125150
}
151+
126152
outgoingCallConnection.setDialing();
127153
outgoingCallConnection.setAudioModeIsVoip(true);
128-
outgoingCallConnection.setCallerDisplayName(name, TelecomManager.PRESENTATION_ALLOWED);
154+
outgoingCallConnection.setCallerDisplayName(displayName, TelecomManager.PRESENTATION_ALLOWED);
129155
outgoingCallConnection.setInitialized();
130156

131157
HashMap<String, String> extrasMap = this.bundleToMap(extras);
@@ -197,8 +223,8 @@ public void run() {
197223
Bundle extras = new Bundle();
198224
extras.putSerializable("attributeMap", attributeMap);
199225
intent.putExtras(extras);
200-
LocalBroadcastManager.getInstance(instance).sendBroadcast(intent);
201226
}
227+
LocalBroadcastManager.getInstance(instance).sendBroadcast(intent);
202228
}
203229
});
204230
}
@@ -216,4 +242,22 @@ private HashMap<String, String> bundleToMap(Bundle extras) {
216242
}
217243
return extrasMap;
218244
}
245+
246+
/**
247+
* https://stackoverflow.com/questions/5446565/android-how-do-i-check-if-activity-is-running
248+
*
249+
* @param context Context
250+
* @return boolean
251+
*/
252+
public static boolean isRunning(Context context) {
253+
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
254+
List<RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
255+
256+
for (RunningTaskInfo task : tasks) {
257+
if (context.getPackageName().equalsIgnoreCase(task.baseActivity.getPackageName()))
258+
return true;
259+
}
260+
261+
return false;
262+
}
219263
}

docs/android-installation.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,22 @@ public class MainActivity extends ReactActivity {
7979
// ....
8080
</application>
8181
```
82+
83+
2. To be able to wake up your killed application when making an outgoing call form the native Phone application:
84+
85+
Add this in the `application` node of `android/app/src/main/AndroidManifest.xml` :
86+
87+
```xml
88+
<service android:name="io.wazo.callkeep.RNCallKeepBackgroundMessagingService" />
89+
```
90+
91+
92+
In your `index.android.js` file :
93+
94+
```js
95+
AppRegistry.registerHeadlessTask('RNCallKeepBackgroundMessage', () => ({ name, callUUID, handle }) => {
96+
// Make your call here
97+
98+
return Promise.resolve();
99+
});
100+
```

0 commit comments

Comments
 (0)