blob: 211469147a586bf1b06861041298d0e91f04e4db [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
wangqie00bbae2018-04-17 14:48:03 -070093
wangqid6b10d52018-04-12 14:44:06 -070094 .setId(String.valueOf(dialerCall.getCreationTimeMillis()))
wangqie00bbae2018-04-17 14:48:03 -070095
wangqied677ef2018-04-04 12:03:00 -070096 .setTimestamp(dialerCall.getCreationTimeMillis())
97 .setNumber(dialerCall.getNumber())
98 .addAllMessages(rttCallScreen.getRttTranscriptMessageList());
99 dialerCall.setRttTranscript(builder.build());
wangqi153af2f2018-02-15 16:21:49 -0800100 }
101
102 @Override
103 public void onStateChange(InCallState oldState, InCallState newState, CallList callList) {
104 LogUtil.enterBlock("RttCallPresenter.onStateChange");
105 if (newState == InCallState.INCALL) {
106 startListenOnRemoteMessage();
107 }
108 }
109
110 private void startListenOnRemoteMessage() {
wangqid6b10d52018-04-12 14:44:06 -0700111 DialerCall call = CallList.getInstance().getCallById(rttCallScreen.getCallId());
wangqi153af2f2018-02-15 16:21:49 -0800112 if (call == null) {
wangqid6b10d52018-04-12 14:44:06 -0700113 LogUtil.i("RttCallPresenter.startListenOnRemoteMessage", "call does not exist");
wangqi153af2f2018-02-15 16:21:49 -0800114 return;
115 }
116 rttCall = call.getRttCall();
117 if (rttCall == null) {
118 LogUtil.i("RttCallPresenter.startListenOnRemoteMessage", "RTT Call is not started yet");
119 return;
120 }
121 if (handlerThread != null && handlerThread.isAlive()) {
122 LogUtil.i("RttCallPresenter.startListenOnRemoteMessage", "already running");
123 return;
124 }
125 handlerThread = new HandlerThread("RttCallRemoteMessageHandler");
126 handlerThread.start();
127 remoteMessageHandler =
128 new RemoteMessageHandler(handlerThread.getLooper(), rttCall, rttCallScreen);
129 remoteMessageHandler.start();
130 }
131
132 private void stopListenOnRemoteMessage() {
133 if (handlerThread != null && handlerThread.isAlive()) {
134 handlerThread.quit();
135 }
136 }
137
138 private static class RemoteMessageHandler extends Handler {
139 private static final int START = 1;
140 private static final int READ_MESSAGE = 2;
141 private static final int WRITE_MESSAGE = 3;
142
143 private final RttCall rttCall;
144 private final RttCallScreen rttCallScreen;
145
146 RemoteMessageHandler(Looper looper, RttCall rttCall, RttCallScreen rttCallScreen) {
147 super(looper);
148 this.rttCall = rttCall;
149 this.rttCallScreen = rttCallScreen;
150 }
151
152 @Override
153 public void handleMessage(android.os.Message msg) {
154 switch (msg.what) {
155 case START:
156 sendEmptyMessage(READ_MESSAGE);
157 break;
158 case READ_MESSAGE:
159 try {
160 final String message = rttCall.readImmediately();
161 if (message != null) {
162 ThreadUtil.postOnUiThread(() -> rttCallScreen.onRemoteMessage(message));
163 }
164 } catch (IOException e) {
165 LogUtil.e("RttCallPresenter.RemoteMessageHandler.handleMessage", "read message", e);
166 }
167 sendEmptyMessageDelayed(READ_MESSAGE, 200);
168 break;
169 case WRITE_MESSAGE:
170 try {
171 rttCall.write((String) msg.obj);
172 } catch (IOException e) {
173 LogUtil.e("RttCallPresenter.RemoteMessageHandler.handleMessage", "write message", e);
174 }
175 break;
176 default: // fall out
177 }
178 }
179
180 void start() {
181 sendEmptyMessage(START);
182 }
183
184 void writeMessage(String message) {
185 sendMessage(obtainMessage(WRITE_MESSAGE, message));
186 }
187 }
wangqi219b8702018-02-13 09:34:41 -0800188}