blob: 21e28cee4150074faaad315c05325864fb4ab99f [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();
wangqid6b10d52018-04-12 14:44:06 -070066 DialerCall call = CallList.getInstance().getCallById(rttCallScreen.getCallId());
wangqied677ef2018-04-04 12:03:00 -070067 if (call != null) {
68 rttCallScreen.onRestoreRttChat(call.getRttTranscript());
69 }
wangqi153af2f2018-02-15 16:21:49 -080070 }
71
72 @Override
wangqid6b10d52018-04-12 14:44:06 -070073 public void onSaveRttTranscript() {
74 LogUtil.enterBlock("RttCallPresenter.onSaveRttTranscript");
75 DialerCall call = CallList.getInstance().getCallById(rttCallScreen.getCallId());
76 if (call != null) {
77 saveTranscript(call);
78 }
79 }
80
81 @Override
wangqi153af2f2018-02-15 16:21:49 -080082 public void onRttCallScreenUiUnready() {
83 LogUtil.enterBlock("RttCallPresenter.onRttCallScreenUiUnready");
84 InCallPresenter.getInstance().removeListener(this);
85 stopListenOnRemoteMessage();
wangqid6b10d52018-04-12 14:44:06 -070086 onSaveRttTranscript();
wangqied677ef2018-04-04 12:03:00 -070087 }
88
89 private void saveTranscript(DialerCall dialerCall) {
90 LogUtil.enterBlock("RttCallPresenter.saveTranscript");
91 RttTranscript.Builder builder = RttTranscript.newBuilder();
92 builder
wangqid6b10d52018-04-12 14:44:06 -070093 .setId(String.valueOf(dialerCall.getCreationTimeMillis()))
wangqied677ef2018-04-04 12:03:00 -070094 .setTimestamp(dialerCall.getCreationTimeMillis())
95 .setNumber(dialerCall.getNumber())
96 .addAllMessages(rttCallScreen.getRttTranscriptMessageList());
97 dialerCall.setRttTranscript(builder.build());
wangqi153af2f2018-02-15 16:21:49 -080098 }
99
100 @Override
101 public void onStateChange(InCallState oldState, InCallState newState, CallList callList) {
102 LogUtil.enterBlock("RttCallPresenter.onStateChange");
103 if (newState == InCallState.INCALL) {
104 startListenOnRemoteMessage();
105 }
106 }
107
108 private void startListenOnRemoteMessage() {
wangqid6b10d52018-04-12 14:44:06 -0700109 DialerCall call = CallList.getInstance().getCallById(rttCallScreen.getCallId());
wangqi153af2f2018-02-15 16:21:49 -0800110 if (call == null) {
wangqid6b10d52018-04-12 14:44:06 -0700111 LogUtil.i("RttCallPresenter.startListenOnRemoteMessage", "call does not exist");
wangqi153af2f2018-02-15 16:21:49 -0800112 return;
113 }
114 rttCall = call.getRttCall();
115 if (rttCall == null) {
116 LogUtil.i("RttCallPresenter.startListenOnRemoteMessage", "RTT Call is not started yet");
117 return;
118 }
119 if (handlerThread != null && handlerThread.isAlive()) {
120 LogUtil.i("RttCallPresenter.startListenOnRemoteMessage", "already running");
121 return;
122 }
123 handlerThread = new HandlerThread("RttCallRemoteMessageHandler");
124 handlerThread.start();
125 remoteMessageHandler =
126 new RemoteMessageHandler(handlerThread.getLooper(), rttCall, rttCallScreen);
127 remoteMessageHandler.start();
128 }
129
130 private void stopListenOnRemoteMessage() {
131 if (handlerThread != null && handlerThread.isAlive()) {
132 handlerThread.quit();
133 }
134 }
135
136 private static class RemoteMessageHandler extends Handler {
137 private static final int START = 1;
138 private static final int READ_MESSAGE = 2;
139 private static final int WRITE_MESSAGE = 3;
140
141 private final RttCall rttCall;
142 private final RttCallScreen rttCallScreen;
143
144 RemoteMessageHandler(Looper looper, RttCall rttCall, RttCallScreen rttCallScreen) {
145 super(looper);
146 this.rttCall = rttCall;
147 this.rttCallScreen = rttCallScreen;
148 }
149
150 @Override
151 public void handleMessage(android.os.Message msg) {
152 switch (msg.what) {
153 case START:
154 sendEmptyMessage(READ_MESSAGE);
155 break;
156 case READ_MESSAGE:
157 try {
158 final String message = rttCall.readImmediately();
159 if (message != null) {
160 ThreadUtil.postOnUiThread(() -> rttCallScreen.onRemoteMessage(message));
161 }
162 } catch (IOException e) {
163 LogUtil.e("RttCallPresenter.RemoteMessageHandler.handleMessage", "read message", e);
164 }
165 sendEmptyMessageDelayed(READ_MESSAGE, 200);
166 break;
167 case WRITE_MESSAGE:
168 try {
169 rttCall.write((String) msg.obj);
170 } catch (IOException e) {
171 LogUtil.e("RttCallPresenter.RemoteMessageHandler.handleMessage", "write message", e);
172 }
173 break;
174 default: // fall out
175 }
176 }
177
178 void start() {
179 sendEmptyMessage(START);
180 }
181
182 void writeMessage(String message) {
183 sendMessage(obtainMessage(WRITE_MESSAGE, message));
184 }
185 }
wangqi219b8702018-02-13 09:34:41 -0800186}