blob: 5e8390793e72ca13a144b7b54332b748749547b0 [file] [log] [blame]
wangqi219b8702018-02-13 09:34:41 -08001/*
2 * Copyright (C) 2018 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
17package com.android.incallui;
18
wangqi153af2f2018-02-15 16:21:49 -080019import android.annotation.TargetApi;
20import android.os.Handler;
21import android.os.HandlerThread;
22import android.os.Looper;
23import android.telecom.Call.RttCall;
24import com.android.dialer.common.LogUtil;
25import com.android.dialer.common.concurrent.ThreadUtil;
wangqied677ef2018-04-04 12:03:00 -070026import com.android.dialer.rtt.RttTranscript;
wangqi153af2f2018-02-15 16:21:49 -080027import com.android.incallui.InCallPresenter.InCallState;
28import com.android.incallui.InCallPresenter.InCallStateListener;
29import com.android.incallui.call.CallList;
30import com.android.incallui.call.DialerCall;
wangqi219b8702018-02-13 09:34:41 -080031import com.android.incallui.rtt.protocol.RttCallScreen;
32import com.android.incallui.rtt.protocol.RttCallScreenDelegate;
wangqi153af2f2018-02-15 16:21:49 -080033import java.io.IOException;
wangqi219b8702018-02-13 09:34:41 -080034
35/**
36 * Logic related to the {@link RttCallScreen} and for managing changes to the RTT calling surfaces
37 * based on other user interface events and incoming events.
38 */
wangqi153af2f2018-02-15 16:21:49 -080039@TargetApi(28)
40public class RttCallPresenter implements RttCallScreenDelegate, InCallStateListener {
wangqi219b8702018-02-13 09:34:41 -080041
wangqi219b8702018-02-13 09:34:41 -080042 private RttCallScreen rttCallScreen;
wangqi153af2f2018-02-15 16:21:49 -080043 private RttCall rttCall;
44 private HandlerThread handlerThread;
45 private RemoteMessageHandler remoteMessageHandler;
wangqi219b8702018-02-13 09:34:41 -080046
47 @Override
wangqi153af2f2018-02-15 16:21:49 -080048 public void initRttCallScreenDelegate(RttCallScreen rttCallScreen) {
wangqi219b8702018-02-13 09:34:41 -080049 this.rttCallScreen = rttCallScreen;
50 }
51
52 @Override
wangqi153af2f2018-02-15 16:21:49 -080053 public void onLocalMessage(String message) {
54 if (rttCall == null) {
55 LogUtil.w("RttCallPresenter.onLocalMessage", "Rtt Call is not started yet");
56 return;
57 }
58 remoteMessageHandler.writeMessage(message);
59 }
wangqi219b8702018-02-13 09:34:41 -080060
61 @Override
wangqi153af2f2018-02-15 16:21:49 -080062 public void onRttCallScreenUiReady() {
63 LogUtil.enterBlock("RttCallPresenter.onRttCallScreenUiReady");
64 InCallPresenter.getInstance().addListener(this);
65 startListenOnRemoteMessage();
wangqied677ef2018-04-04 12:03:00 -070066 DialerCall call = CallList.getInstance().getActiveCall();
67 if (call != null) {
68 rttCallScreen.onRestoreRttChat(call.getRttTranscript());
69 }
wangqi153af2f2018-02-15 16:21:49 -080070 }
71
72 @Override
73 public void onRttCallScreenUiUnready() {
74 LogUtil.enterBlock("RttCallPresenter.onRttCallScreenUiUnready");
75 InCallPresenter.getInstance().removeListener(this);
76 stopListenOnRemoteMessage();
wangqied677ef2018-04-04 12:03:00 -070077 DialerCall call = CallList.getInstance().getActiveCall();
78 if (call != null) {
79 saveTranscript(call);
80 }
81 }
82
83 private void saveTranscript(DialerCall dialerCall) {
84 LogUtil.enterBlock("RttCallPresenter.saveTranscript");
85 RttTranscript.Builder builder = RttTranscript.newBuilder();
86 builder
87 .setId(dialerCall.getNumber() + dialerCall.getCreationTimeMillis())
88 .setTimestamp(dialerCall.getCreationTimeMillis())
89 .setNumber(dialerCall.getNumber())
90 .addAllMessages(rttCallScreen.getRttTranscriptMessageList());
91 dialerCall.setRttTranscript(builder.build());
wangqi153af2f2018-02-15 16:21:49 -080092 }
93
94 @Override
95 public void onStateChange(InCallState oldState, InCallState newState, CallList callList) {
96 LogUtil.enterBlock("RttCallPresenter.onStateChange");
97 if (newState == InCallState.INCALL) {
98 startListenOnRemoteMessage();
99 }
100 }
101
102 private void startListenOnRemoteMessage() {
103 DialerCall call = CallList.getInstance().getActiveCall();
104 if (call == null) {
wangqied677ef2018-04-04 12:03:00 -0700105 LogUtil.i("RttCallPresenter.startListenOnRemoteMessage", "call is not active yet");
wangqi153af2f2018-02-15 16:21:49 -0800106 return;
107 }
108 rttCall = call.getRttCall();
109 if (rttCall == null) {
110 LogUtil.i("RttCallPresenter.startListenOnRemoteMessage", "RTT Call is not started yet");
111 return;
112 }
113 if (handlerThread != null && handlerThread.isAlive()) {
114 LogUtil.i("RttCallPresenter.startListenOnRemoteMessage", "already running");
115 return;
116 }
117 handlerThread = new HandlerThread("RttCallRemoteMessageHandler");
118 handlerThread.start();
119 remoteMessageHandler =
120 new RemoteMessageHandler(handlerThread.getLooper(), rttCall, rttCallScreen);
121 remoteMessageHandler.start();
122 }
123
124 private void stopListenOnRemoteMessage() {
125 if (handlerThread != null && handlerThread.isAlive()) {
126 handlerThread.quit();
127 }
128 }
129
130 private static class RemoteMessageHandler extends Handler {
131 private static final int START = 1;
132 private static final int READ_MESSAGE = 2;
133 private static final int WRITE_MESSAGE = 3;
134
135 private final RttCall rttCall;
136 private final RttCallScreen rttCallScreen;
137
138 RemoteMessageHandler(Looper looper, RttCall rttCall, RttCallScreen rttCallScreen) {
139 super(looper);
140 this.rttCall = rttCall;
141 this.rttCallScreen = rttCallScreen;
142 }
143
144 @Override
145 public void handleMessage(android.os.Message msg) {
146 switch (msg.what) {
147 case START:
148 sendEmptyMessage(READ_MESSAGE);
149 break;
150 case READ_MESSAGE:
151 try {
152 final String message = rttCall.readImmediately();
153 if (message != null) {
154 ThreadUtil.postOnUiThread(() -> rttCallScreen.onRemoteMessage(message));
155 }
156 } catch (IOException e) {
157 LogUtil.e("RttCallPresenter.RemoteMessageHandler.handleMessage", "read message", e);
158 }
159 sendEmptyMessageDelayed(READ_MESSAGE, 200);
160 break;
161 case WRITE_MESSAGE:
162 try {
163 rttCall.write((String) msg.obj);
164 } catch (IOException e) {
165 LogUtil.e("RttCallPresenter.RemoteMessageHandler.handleMessage", "write message", e);
166 }
167 break;
168 default: // fall out
169 }
170 }
171
172 void start() {
173 sendEmptyMessage(START);
174 }
175
176 void writeMessage(String message) {
177 sendMessage(obtainMessage(WRITE_MESSAGE, message));
178 }
179 }
wangqi219b8702018-02-13 09:34:41 -0800180}