summaryrefslogtreecommitdiffstats
path: root/testapps
diff options
context:
space:
mode:
authorHall Liu <hallliu@google.com>2017-02-22 19:05:07 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-02-22 19:05:07 +0000
commit86f417aa84995ffba44ea98b32d5ba4ee338aa6f (patch)
tree208bd848391e2ba05f658861be0c1f23684f51e8 /testapps
parent6dc6e969f2179e21402ad7ac1b453ea7273415aa (diff)
parent1d36154ab9ace2609131eb86a242513c20dc53d8 (diff)
downloadandroid_packages_services_Telecomm-86f417aa84995ffba44ea98b32d5ba4ee338aa6f.tar.gz
android_packages_services_Telecomm-86f417aa84995ffba44ea98b32d5ba4ee338aa6f.tar.bz2
android_packages_services_Telecomm-86f417aa84995ffba44ea98b32d5ba4ee338aa6f.zip
Add support for RTT calls (part 1) am: dd68bc36a3 am: 399f7e50b0
am: 1d36154ab9 Change-Id: Id768015a354c9a3428b4c817507d058df6ea15f7
Diffstat (limited to 'testapps')
-rw-r--r--testapps/AndroidManifest.xml15
-rw-r--r--testapps/res/layout/incall_screen.xml13
-rw-r--r--testapps/res/layout/rtt_incall_screen.xml57
-rw-r--r--testapps/res/layout/testdialer_main.xml5
-rw-r--r--testapps/res/values/donottranslate_strings.xml26
-rw-r--r--testapps/src/com/android/server/telecom/testapps/CallListAdapter.java3
-rw-r--r--testapps/src/com/android/server/telecom/testapps/CallNotificationReceiver.java21
-rw-r--r--testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java2
-rw-r--r--testapps/src/com/android/server/telecom/testapps/RttChatbot.java134
-rw-r--r--testapps/src/com/android/server/telecom/testapps/TestCallActivity.java6
-rw-r--r--testapps/src/com/android/server/telecom/testapps/TestCallList.java17
-rw-r--r--testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java1
-rw-r--r--testapps/src/com/android/server/telecom/testapps/TestConnectionService.java29
-rw-r--r--testapps/src/com/android/server/telecom/testapps/TestDialerActivity.java18
-rw-r--r--testapps/src/com/android/server/telecom/testapps/TestInCallUI.java22
-rw-r--r--testapps/src/com/android/server/telecom/testapps/TestRttActivity.java229
16 files changed, 578 insertions, 20 deletions
diff --git a/testapps/AndroidManifest.xml b/testapps/AndroidManifest.xml
index 6c7202b9..2cdfc554 100644
--- a/testapps/AndroidManifest.xml
+++ b/testapps/AndroidManifest.xml
@@ -81,6 +81,16 @@
</intent-filter>
</activity>
+ <activity android:name="com.android.server.telecom.testapps.TestRttActivity"
+ android:process="com.android.server.telecom.testapps.TestInCallService"
+ android:label="@string/rttUiLabel"
+ android:launchMode="singleInstance">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
<activity android:name="com.android.server.telecom.testapps.TestCallActivity"
android:theme="@android:style/Theme.NoDisplay"
android:label="@string/testCallActivityLabel">
@@ -105,6 +115,11 @@
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="int" />
</intent-filter>
+ <intent-filter>
+ <action android:name="android.telecom.testapps.ACTION_RTT_CALL" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:scheme="tel" />
+ </intent-filter>
</activity>
<receiver android:name="com.android.server.telecom.testapps.CallNotificationReceiver"
diff --git a/testapps/res/layout/incall_screen.xml b/testapps/res/layout/incall_screen.xml
index 6a891e7f..3ca87814 100644
--- a/testapps/res/layout/incall_screen.xml
+++ b/testapps/res/layout/incall_screen.xml
@@ -44,7 +44,16 @@
android:id="@+id/hold_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/holdButton" >
- </Button>
+ android:text="@string/holdButton"/>
+ <Button
+ android:id="@+id/rtt_iface_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/rttIfaceButton"/>
+ <Button
+ android:id="@+id/answer_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/answerCallButton"/>
</LinearLayout>
</LinearLayout>
diff --git a/testapps/res/layout/rtt_incall_screen.xml b/testapps/res/layout/rtt_incall_screen.xml
new file mode 100644
index 00000000..e7cbac4a
--- /dev/null
+++ b/testapps/res/layout/rtt_incall_screen.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2017 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ android:id="@+id/received_messages_text"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="> "
+ android:lines="7" />
+ <TextView
+ android:id="@+id/sent_messages_text"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="> "
+ android:lines="7" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <Button
+ android:id="@+id/end_rtt_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/endRttButton" />
+ <Spinner
+ android:id="@+id/rtt_mode_selection_spinner"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ </LinearLayout>
+
+ <EditText
+ android:id="@+id/rtt_typing_box"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:lines="1"
+ android:hint="Type here" />
+</LinearLayout> \ No newline at end of file
diff --git a/testapps/res/layout/testdialer_main.xml b/testapps/res/layout/testdialer_main.xml
index 2c3e5e48..e6c56b74 100644
--- a/testapps/res/layout/testdialer_main.xml
+++ b/testapps/res/layout/testdialer_main.xml
@@ -44,4 +44,9 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cancelMissedButton" />
+ <CheckBox
+ android:id="@+id/call_with_rtt_checkbox"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/startCallWithRtt"/>
</LinearLayout>
diff --git a/testapps/res/values/donottranslate_strings.xml b/testapps/res/values/donottranslate_strings.xml
index 74a3fd40..f24625e5 100644
--- a/testapps/res/values/donottranslate_strings.xml
+++ b/testapps/res/values/donottranslate_strings.xml
@@ -40,6 +40,14 @@
<string name="endCallButton">End Call</string>
+ <string name="answerCallButton">Answer</string>
+
+ <string name="startCallWithRtt">Start call with RTT</string>
+
+ <string name="rttIfaceButton">RTT</string>
+
+ <string name="endRttButton">End RTT</string>
+
<string name="muteButton">Mute</string>
<string name="holdButton">Hold</string>
@@ -62,4 +70,22 @@
<string name="incomingCallNotPermitted">Incoming call not permitted.</string>
<string name="incomingCallNotPermittedCS">Incoming call not permitted (CS Reported).</string>
+
+ <string name="rttUiLabel">Test RTT UI</string>
+
+ <string-array name="rtt_mode_array">
+ <item>Full</item>
+ <item>HCO</item>
+ <item>VCO</item>
+ </string-array>
+
+ <string-array name="rtt_reply_one_liners">
+ <item>To RTT or not to RTT, that is the question...</item>
+ <item>Making TTY great again!</item>
+ <item>I would be more comfortable with real "Thyme" chatting. I don\'t know how to end
+ this pun</item>
+ <item>お疲れ様でした</item>
+ <item>The FCC has mandated that I respond... I will do so begrudgingly</item>
+ <item>😂😂😂💯</item>
+ </string-array>
</resources>
diff --git a/testapps/src/com/android/server/telecom/testapps/CallListAdapter.java b/testapps/src/com/android/server/telecom/testapps/CallListAdapter.java
index bea0e63e..85785d58 100644
--- a/testapps/src/com/android/server/telecom/testapps/CallListAdapter.java
+++ b/testapps/src/com/android/server/telecom/testapps/CallListAdapter.java
@@ -103,7 +103,8 @@ public class CallListAdapter extends BaseAdapter {
state.setText(getStateString(call));
- Log.i(TAG, "Call found: " + handle.getSchemeSpecificPart() + ", " + durationMs);
+ Log.i(TAG, "Call found: " + ((handle == null) ? "null" : handle.getSchemeSpecificPart())
+ + ", " + durationMs);
return convertView;
}
diff --git a/testapps/src/com/android/server/telecom/testapps/CallNotificationReceiver.java b/testapps/src/com/android/server/telecom/testapps/CallNotificationReceiver.java
index aee55148..8fd23780 100644
--- a/testapps/src/com/android/server/telecom/testapps/CallNotificationReceiver.java
+++ b/testapps/src/com/android/server/telecom/testapps/CallNotificationReceiver.java
@@ -51,6 +51,8 @@ public class CallNotificationReceiver extends BroadcastReceiver {
"com.android.server.telecom.testapps.ACTION_TWO_WAY_VIDEO_CALL";
static final String ACTION_AUDIO_CALL =
"com.android.server.telecom.testapps.ACTION_AUDIO_CALL";
+ static final String ACTION_RTT_CALL =
+ "com.android.server.telecom.testapps.ACTION_RTT_CALL";
/** {@inheritDoc} */
@Override
@@ -66,6 +68,8 @@ public class CallNotificationReceiver extends BroadcastReceiver {
sendIncomingCallIntent(context, null, VideoProfile.STATE_RX_ENABLED);
} else if (ACTION_TWO_WAY_VIDEO_CALL.equals(action)) {
sendIncomingCallIntent(context, null, VideoProfile.STATE_BIDIRECTIONAL);
+ } else if (ACTION_RTT_CALL.equals(action)) {
+ sendIncomingRttCallIntent(context, null, VideoProfile.STATE_AUDIO_ONLY);
} else if (ACTION_AUDIO_CALL.equals(action)) {
sendIncomingCallIntent(context, null, VideoProfile.STATE_AUDIO_ONLY);
}
@@ -93,6 +97,23 @@ public class CallNotificationReceiver extends BroadcastReceiver {
TelecomManager.from(context).addNewIncomingCall(phoneAccount, extras);
}
+ public static void sendIncomingRttCallIntent(Context context, Uri handle, int videoState) {
+ PhoneAccountHandle phoneAccount = new PhoneAccountHandle(
+ new ComponentName(context, TestConnectionService.class),
+ CallServiceNotifier.SIM_SUBSCRIPTION_ID);
+
+ // For the purposes of testing, indicate whether the incoming call is a video call by
+ // stashing an indicator in the EXTRA_INCOMING_CALL_EXTRAS.
+ Bundle extras = new Bundle();
+ extras.putInt(TestConnectionService.EXTRA_START_VIDEO_STATE, videoState);
+ if (handle != null) {
+ extras.putParcelable(TestConnectionService.EXTRA_HANDLE, handle);
+ }
+ extras.putBoolean(TelecomManager.EXTRA_START_CALL_WITH_RTT, true);
+
+ TelecomManager.from(context).addNewIncomingCall(phoneAccount, extras);
+ }
+
public static void addNewUnknownCall(Context context, Uri handle, Bundle extras) {
Log.i(TAG, "Adding new unknown call with handle " + handle);
PhoneAccountHandle phoneAccount = new PhoneAccountHandle(
diff --git a/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java b/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java
index 9292273e..ba586553 100644
--- a/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java
+++ b/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java
@@ -119,6 +119,7 @@ public class CallServiceNotifier {
.setSubscriptionAddress(Uri.parse("tel:555-TEST"))
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
PhoneAccount.CAPABILITY_VIDEO_CALLING |
+ PhoneAccount.CAPABILITY_RTT |
PhoneAccount.CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE)
.setIcon(Icon.createWithResource(
context.getResources(), R.drawable.stat_sys_phone_call))
@@ -139,6 +140,7 @@ public class CallServiceNotifier {
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
PhoneAccount.CAPABILITY_VIDEO_CALLING |
+ PhoneAccount.CAPABILITY_RTT |
PhoneAccount.CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE)
.setIcon(Icon.createWithResource(
context.getResources(), R.drawable.stat_sys_phone_call))
diff --git a/testapps/src/com/android/server/telecom/testapps/RttChatbot.java b/testapps/src/com/android/server/telecom/testapps/RttChatbot.java
new file mode 100644
index 00000000..3b16bd44
--- /dev/null
+++ b/testapps/src/com/android/server/telecom/testapps/RttChatbot.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.telecom.testapps;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.telecom.Connection;
+import android.telecom.Log;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.util.Random;
+
+public class RttChatbot {
+ private static final String LOG_TAG = RttChatbot.class.getSimpleName();
+ private static final long PER_CHARACTER_DELAY_MS = 100;
+ private static final long MSG_WAIT_DELAY_MS = 3999;
+ private static final double ONE_LINER_FREQUENCY = 0.1;
+ private static final String REPLY_PREFIX = "You said: ";
+
+ private static final int BEGIN_SEND_REPLY_MESSAGE = 1;
+ private static final int SEND_CHARACTER = 2;
+ private static final int APPEND_TO_INPUT_BUFFER = 3;
+
+ private final Connection.RttTextStream mRttTextStream;
+ private final Random mRandom = new Random();
+ private final String[] mOneLiners;
+ private Handler mHandler;
+
+ private final class ReplyHandler extends Handler {
+ private StringBuilder mInputSoFar;
+
+ public ReplyHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case BEGIN_SEND_REPLY_MESSAGE:
+ removeMessages(SEND_CHARACTER);
+ sendReplyMessage();
+ break;
+ case SEND_CHARACTER:
+ try {
+ mRttTextStream.write((String) msg.obj);
+ } catch (IOException e) {
+ }
+ break;
+ case APPEND_TO_INPUT_BUFFER:
+ removeMessages(BEGIN_SEND_REPLY_MESSAGE);
+ sendEmptyMessageDelayed(BEGIN_SEND_REPLY_MESSAGE, MSG_WAIT_DELAY_MS);
+ String toAppend = (String) msg.obj;
+ if (mInputSoFar == null) {
+ mInputSoFar = new StringBuilder(toAppend);
+ } else {
+ mInputSoFar.append(toAppend);
+ }
+ Log.d(LOG_TAG, "Got %s to append, total text now %s",
+ toAppend, mInputSoFar.toString());
+ break;
+ }
+ }
+
+ private void sendReplyMessage() {
+ String messageToSend;
+ if (mRandom.nextDouble() < ONE_LINER_FREQUENCY) {
+ messageToSend = mOneLiners[mRandom.nextInt(mOneLiners.length)];
+ } else {
+ messageToSend = REPLY_PREFIX + mInputSoFar.toString();
+ }
+ mInputSoFar = null;
+ Log.i(LOG_TAG, "Begin send reply message: %s", messageToSend);
+ int[] charsToSend = messageToSend.codePoints().toArray();
+ for (int i = 0; i < charsToSend.length; i++) {
+ Message msg = obtainMessage(SEND_CHARACTER,
+ new String(new int[] {charsToSend[i]}, 0, 1));
+ sendMessageDelayed(msg, PER_CHARACTER_DELAY_MS * i);
+ }
+ }
+ }
+
+ public RttChatbot(Context context, Connection.RttTextStream textStream) {
+ mOneLiners = context.getResources().getStringArray(R.array.rtt_reply_one_liners);
+ mRttTextStream = textStream;
+ }
+
+ public void start() {
+ Log.i(LOG_TAG, "Starting RTT chatbot.");
+ HandlerThread ht = new HandlerThread("RttChatbotSender");
+ ht.start();
+ mHandler = new ReplyHandler(ht.getLooper());
+ Thread receiveThread = new Thread(() -> {
+ while (true) {
+ String charsReceived = mRttTextStream.read();
+ if (charsReceived == null) {
+ if (Thread.currentThread().isInterrupted()) {
+ Log.w(LOG_TAG, "Thread interrupted");
+ break;
+ }
+ Log.w(LOG_TAG, "Stream closed");
+ break;
+ }
+ if (charsReceived.length() == 0) {
+ continue;
+ }
+ mHandler.obtainMessage(APPEND_TO_INPUT_BUFFER, charsReceived)
+ .sendToTarget();
+ }
+ }, "RttChatbotReceiver");
+ receiveThread.start();
+ }
+}
diff --git a/testapps/src/com/android/server/telecom/testapps/TestCallActivity.java b/testapps/src/com/android/server/telecom/testapps/TestCallActivity.java
index 862ccf76..76f2058c 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestCallActivity.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestCallActivity.java
@@ -52,6 +52,9 @@ public class TestCallActivity extends Activity {
public static final String ACTION_SEND_UPGRADE_REQUEST =
"android.telecom.testapps.ACTION_SEND_UPGRADE_REQUEST";
+ static final String ACTION_RTT_CALL =
+ "android.telecom.testapps.ACTION_RTT_CALL";
+
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -65,6 +68,9 @@ public class TestCallActivity extends Activity {
CallNotificationReceiver.addNewUnknownCall(this, data, intent.getExtras());
} else if (ACTION_HANGUP_CALLS.equals(action)) {
CallNotificationReceiver.hangupCalls(this);
+ } else if (ACTION_RTT_CALL.equals(action)) {
+ CallNotificationReceiver.sendIncomingRttCallIntent(
+ this, data, VideoProfile.STATE_AUDIO_ONLY);
} else if (ACTION_SEND_UPGRADE_REQUEST.equals(action)) {
CallNotificationReceiver.sendUpgradeRequest(this, data);
} else {
diff --git a/testapps/src/com/android/server/telecom/testapps/TestCallList.java b/testapps/src/com/android/server/telecom/testapps/TestCallList.java
index 391a5886..4419b17d 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestCallList.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestCallList.java
@@ -32,7 +32,7 @@ import java.util.Set;
/**
* Maintains a list of calls received via the {@link TestInCallServiceImpl}.
*/
-public class TestCallList extends Call.Listener {
+public class TestCallList extends Call.Callback {
public static abstract class Listener {
public void onCallAdded(Call call) {}
@@ -126,7 +126,7 @@ public class TestCallList extends Call.Listener {
}
Log.i(TAG, "addCall: " + call + " " + System.identityHashCode(this));
mCalls.add(call);
- call.addListener(this);
+ call.registerCallback(this);
for (Listener l : mListeners) {
l.onCallAdded(call);
@@ -140,7 +140,7 @@ public class TestCallList extends Call.Listener {
}
Log.i(TAG, "removeCall: " + call);
mCalls.remove(call);
- call.removeListener(this);
+ call.unregisterCallback(this);
for (Listener l : mListeners) {
l.onCallRemoved(call);
@@ -214,4 +214,15 @@ public class TestCallList extends Call.Listener {
}
}
}
+
+ @Override
+ public void onRttStatusChanged(Call call, boolean enabled, Call.RttCall rttCall) {
+ Log.v(TAG, "onRttStatusChanged: call = " + call + " " + System.identityHashCode(this));
+
+ if (call != null) {
+ // Did you have another call? Well too bad, this class isn't gonna handle it.
+ mCalls.clear();
+ mCalls.add(call);
+ }
+ }
}
diff --git a/testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java b/testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java
index 5b0cf637..c2d8852a 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java
@@ -135,6 +135,7 @@ public class TestConnectionManager extends ConnectionService {
mRemote.registerCallback(mRemoteCallback);
setState(mRemote.getState());
setVideoState(mRemote.getVideoState());
+ setConnectionProperties(remote.getConnectionProperties());
}
@Override
diff --git a/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java b/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java
index 0150dbe5..6c070739 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java
@@ -25,6 +25,7 @@ import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
+import android.os.ParcelFileDescriptor;
import android.support.v4.content.LocalBroadcastManager;
import android.telecom.Conference;
import android.telecom.Connection;
@@ -35,7 +36,7 @@ import android.telecom.ConnectionService;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
-import android.util.Log;
+import android.telecom.Log;
import android.widget.Toast;
import com.android.server.telecom.testapps.R;
@@ -57,6 +58,7 @@ public class TestConnectionService extends ConnectionService {
public static final String EXTRA_HANDLE = "extra_handle";
+ private static final String LOG_TAG = TestConnectionService.class.getSimpleName();
/**
* Random number generator used to generate phone numbers.
*/
@@ -271,6 +273,8 @@ public class TestConnectionService extends ConnectionService {
/** Used to play an audio tone during a call. */
private MediaPlayer mMediaPlayer;
+ // Used to provide text reply in an RTT call
+ private RttChatbot mRttChatbot;
@Override
public boolean onUnbind(Intent intent) {
@@ -309,11 +313,22 @@ public class TestConnectionService extends ConnectionService {
Toast.LENGTH_SHORT).show();
}
+ if (originalRequest.isRequestingRtt()) {
+ Log.i(LOG_TAG, "Is RTT call. Starting chatbot service.");
+ mRttChatbot = new RttChatbot(getApplicationContext(),
+ originalRequest.getRttTextStream());
+ mRttChatbot.start();
+ }
+
log("gateway package [" + gatewayPackage + "], original handle [" +
originalHandle + "]");
final TestConnection connection = new TestConnection(false /* isIncoming */);
setAddress(connection, handle);
+ if (originalRequest.isRequestingRtt()) {
+ connection.setConnectionProperties(
+ connection.getConnectionProperties() | Connection.PROPERTY_IS_RTT);
+ }
// If the number starts with 555, then we handle it ourselves. If not, then we
// use a remote connection service.
@@ -377,6 +392,13 @@ public class TestConnectionService extends ConnectionService {
connectionExtras.putString(Connection.EXTRA_CALL_SUBJECT,
"This is a test of call subject lines.");
}
+
+ if (request.isRequestingRtt()) {
+ Log.i(LOG_TAG, "Is RTT call. Starting chatbot service.");
+ mRttChatbot = new RttChatbot(getApplicationContext(), request.getRttTextStream());
+ mRttChatbot.start();
+ }
+
connection.putExtras(connectionExtras);
setAddress(connection, address);
@@ -385,11 +407,6 @@ public class TestConnectionService extends ConnectionService {
addCall(connection);
- ConnectionRequest newRequest = new ConnectionRequest(
- request.getAccountHandle(),
- address,
- request.getExtras(),
- videoState);
connection.setVideoState(videoState);
return connection;
} else {
diff --git a/testapps/src/com/android/server/telecom/testapps/TestDialerActivity.java b/testapps/src/com/android/server/telecom/testapps/TestDialerActivity.java
index 596d18d4..c7eccf72 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestDialerActivity.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestDialerActivity.java
@@ -12,15 +12,15 @@ import android.telecom.TelecomManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
+import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
-import com.android.server.telecom.testapps.R;
-
public class TestDialerActivity extends Activity {
private static final int REQUEST_CODE_SET_DEFAULT_DIALER = 1;
private EditText mNumberView;
+ private CheckBox mRttCheckbox;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -55,7 +55,8 @@ public class TestDialerActivity extends Activity {
});
mNumberView = (EditText) findViewById(R.id.number);
- updateEditTextWithNumber();
+ mRttCheckbox = (CheckBox) findViewById(R.id.call_with_rtt_checkbox);
+ updateMutableUi();
}
@Override
@@ -72,13 +73,15 @@ public class TestDialerActivity extends Activity {
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
- updateEditTextWithNumber();
+ updateMutableUi();
}
- private void updateEditTextWithNumber() {
+ private void updateMutableUi() {
Intent intent = getIntent();
if (intent != null) {
mNumberView.setText(intent.getDataString());
+ mRttCheckbox.setChecked(
+ intent.getBooleanExtra(TelecomManager.EXTRA_START_CALL_WITH_RTT, false));
}
}
@@ -127,7 +130,10 @@ public class TestDialerActivity extends Activity {
private Bundle createCallIntentExtras() {
Bundle extras = new Bundle();
- extras.putString("com.android.server.telecom.testapps.CALL_EXTRAS", "Yorke was here");
+ extras.putString("com.android.server.telecom.testapps.CALL_EXTRAS", "Hall was here");
+ if (mRttCheckbox.isChecked()) {
+ extras.putBoolean(TelecomManager.EXTRA_START_CALL_WITH_RTT, true);
+ }
Bundle intentExtras = new Bundle();
intentExtras.putBundle(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, extras);
diff --git a/testapps/src/com/android/server/telecom/testapps/TestInCallUI.java b/testapps/src/com/android/server/telecom/testapps/TestInCallUI.java
index ce53709d..809036c8 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestInCallUI.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestInCallUI.java
@@ -17,9 +17,10 @@
package com.android.server.telecom.testapps;
import android.app.Activity;
-import android.graphics.Color;
+import android.content.Intent;
import android.os.Bundle;
import android.telecom.Call;
+import android.telecom.VideoProfile;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
@@ -46,7 +47,7 @@ public class TestInCallUI extends Activity {
@Override
public void onCallRemoved(Call call) {
if (mCallList.size() == 0) {
- Log.i("Santos", "Ending the incall UI");
+ Log.i(TestInCallUI.class.getSimpleName(), "Ending the incall UI");
finish();
}
}
@@ -55,6 +56,8 @@ public class TestInCallUI extends Activity {
View endCallButton = findViewById(R.id.end_call_button);
View holdButton = findViewById(R.id.hold_button);
View muteButton = findViewById(R.id.mute_button);
+ View rttIfaceButton = findViewById(R.id.rtt_iface_button);
+ View answerButton = findViewById(R.id.answer_button);
endCallButton.setOnClickListener(new OnClickListener() {
@Override
@@ -83,9 +86,24 @@ public class TestInCallUI extends Activity {
public void onClick(View view) {
Call call = mCallList.getCall(0);
if (call != null) {
+
}
}
});
+ rttIfaceButton.setOnClickListener((view) -> {
+ Call call = mCallList.getCall(0);
+ if (call.isRttActive()) {
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClass(this, TestRttActivity.class);
+ startActivity(intent);
+ }
+ });
+ answerButton.setOnClickListener(view -> {
+ Call call = mCallList.getCall(0);
+ if (call.getState() == Call.STATE_RINGING) {
+ call.answer(VideoProfile.STATE_AUDIO_ONLY);
+ }
+ });
}
/** ${inheritDoc} */
diff --git a/testapps/src/com/android/server/telecom/testapps/TestRttActivity.java b/testapps/src/com/android/server/telecom/testapps/TestRttActivity.java
new file mode 100644
index 00000000..ce962b47
--- /dev/null
+++ b/testapps/src/com/android/server/telecom/testapps/TestRttActivity.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.telecom.testapps;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.telecom.Call;
+import android.telecom.Log;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+
+public class TestRttActivity extends Activity {
+ private static final String LOG_TAG = TestRttActivity.class.getSimpleName();
+ private static final long NEWLINE_DELAY_MILLIS = 3000;
+
+ private static final int UPDATE_RECEIVED_TEXT = 1;
+ private static final int UPDATE_SENT_TEXT = 2;
+ private static final int RECEIVED_MESSAGE_GAP = 3;
+ private static final int SENT_MESSAGE_GAP = 4;
+
+ private TextView mReceivedText;
+ private TextView mSentText;
+ private EditText mTypingBox;
+
+ private TestCallList mCallList;
+
+ private Handler mTextDisplayHandler = new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ String text;
+ switch (msg.what) {
+ case UPDATE_RECEIVED_TEXT:
+ text = (String) msg.obj;
+ mReceivedText.append(text);
+ break;
+ case UPDATE_SENT_TEXT:
+ text = (String) msg.obj;
+ mSentText.append(text);
+ break;
+ case RECEIVED_MESSAGE_GAP:
+ mReceivedText.append("\n> ");
+ break;
+ case SENT_MESSAGE_GAP:
+ mSentText.append("\n> ");
+ mTypingBox.setText("");
+ break;
+ default:
+ Log.w(LOG_TAG, "Invalid message %d", msg.what);
+ }
+ }
+ };
+
+ private Thread mReceiveReader = new Thread() {
+ @Override
+ public void run() {
+ // outer loop
+ while (true) {
+ begin :
+ // sleep and wait if there are no calls
+ while (mCallList.size() > 0) {
+ Call.RttCall rttCall = mCallList.getCall(0).getRttCall();
+ if (rttCall == null) {
+ break;
+ }
+ // inner read loop
+ while (true) {
+ String receivedText = rttCall.read();
+ if (receivedText == null) {
+ if (Thread.currentThread().isInterrupted()) {
+ break begin;
+ }
+ break;
+ }
+ Log.d(LOG_TAG, "Received %s", receivedText);
+ mTextDisplayHandler.removeMessages(RECEIVED_MESSAGE_GAP);
+ mTextDisplayHandler.sendEmptyMessageDelayed(RECEIVED_MESSAGE_GAP,
+ NEWLINE_DELAY_MILLIS);
+ mTextDisplayHandler.obtainMessage(UPDATE_RECEIVED_TEXT, receivedText)
+ .sendToTarget();
+ }
+ }
+ if (Thread.currentThread().isInterrupted()) {
+ break;
+ }
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ break;
+ }
+ }
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.rtt_incall_screen);
+
+ mReceivedText = (TextView) findViewById(R.id.received_messages_text);
+ mSentText = (TextView) findViewById(R.id.sent_messages_text);
+ mTypingBox = (EditText) findViewById(R.id.rtt_typing_box);
+
+ Button endRttButton = (Button) findViewById(R.id.end_rtt_button);
+ Spinner rttModeSelector = (Spinner) findViewById(R.id.rtt_mode_selection_spinner);
+
+ ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
+ R.array.rtt_mode_array, android.R.layout.simple_spinner_item);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ rttModeSelector.setAdapter(adapter);
+
+ mCallList = TestCallList.getInstance();
+ mCallList.addListener(new TestCallList.Listener() {
+ @Override
+ public void onCallRemoved(Call call) {
+ if (mCallList.size() == 0) {
+ Log.i(LOG_TAG, "Ending the RTT UI");
+ finish();
+ }
+ }
+ });
+
+ endRttButton.setOnClickListener((view) -> {
+ Call call = mCallList.getCall(0);
+ call.stopRtt();
+ });
+
+ rttModeSelector.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ CharSequence selection = (CharSequence) parent.getItemAtPosition(position);
+ Call.RttCall call = mCallList.getCall(0).getRttCall();
+ switch (selection.toString()) {
+ case "Full":
+ call.setRttMode(Call.RttCall.RTT_MODE_FULL);
+ break;
+ case "HCO":
+ call.setRttMode(Call.RttCall.RTT_MODE_HCO);
+ break;
+ case "VCO":
+ call.setRttMode(Call.RttCall.RTT_MODE_VCO);
+ break;
+ default:
+ Log.w(LOG_TAG, "Bad name for rtt mode: %s", selection.toString());
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ }
+ });
+
+ mTypingBox.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ if (count == 0 || count < before) {
+ // ignore deletions and clears
+ return;
+ }
+ // Only appending at the end is supported.
+ int numCharsInserted = count - before;
+ String toAppend =
+ s.subSequence(s.length() - numCharsInserted, s.length()).toString();
+
+ if (toAppend.isEmpty()) {
+ return;
+ }
+ try {
+ mCallList.getCall(0).getRttCall().write(toAppend);
+ } catch (IOException e) {
+ Log.w(LOG_TAG, "Exception sending text %s: %s", toAppend, e);
+ }
+ mTextDisplayHandler.removeMessages(SENT_MESSAGE_GAP);
+ mTextDisplayHandler.sendEmptyMessageDelayed(SENT_MESSAGE_GAP, NEWLINE_DELAY_MILLIS);
+ mTextDisplayHandler.obtainMessage(UPDATE_SENT_TEXT, toAppend).sendToTarget();
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ }
+ });
+
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ mReceiveReader.start();
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ mReceiveReader.interrupt();
+ }
+
+}