blob: 939c9d00be77e6b6b71f484863b5910b0bc24e9d [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;
26import com.android.incallui.InCallPresenter.InCallState;
27import com.android.incallui.InCallPresenter.InCallStateListener;
28import com.android.incallui.call.CallList;
29import com.android.incallui.call.DialerCall;
wangqi219b8702018-02-13 09:34:41 -080030import com.android.incallui.rtt.protocol.RttCallScreen;
31import com.android.incallui.rtt.protocol.RttCallScreenDelegate;
wangqi153af2f2018-02-15 16:21:49 -080032import java.io.IOException;
wangqi219b8702018-02-13 09:34:41 -080033
34/**
35 * Logic related to the {@link RttCallScreen} and for managing changes to the RTT calling surfaces
36 * based on other user interface events and incoming events.
37 */
wangqi153af2f2018-02-15 16:21:49 -080038@TargetApi(28)
39public class RttCallPresenter implements RttCallScreenDelegate, InCallStateListener {
wangqi219b8702018-02-13 09:34:41 -080040
wangqi219b8702018-02-13 09:34:41 -080041 private RttCallScreen rttCallScreen;
wangqi153af2f2018-02-15 16:21:49 -080042 private RttCall rttCall;
43 private HandlerThread handlerThread;
44 private RemoteMessageHandler remoteMessageHandler;
wangqi219b8702018-02-13 09:34:41 -080045
46 @Override
wangqi153af2f2018-02-15 16:21:49 -080047 public void initRttCallScreenDelegate(RttCallScreen rttCallScreen) {
wangqi219b8702018-02-13 09:34:41 -080048 this.rttCallScreen = rttCallScreen;
49 }
50
51 @Override
wangqi153af2f2018-02-15 16:21:49 -080052 public void onLocalMessage(String message) {
53 if (rttCall == null) {
54 LogUtil.w("RttCallPresenter.onLocalMessage", "Rtt Call is not started yet");
55 return;
56 }
57 remoteMessageHandler.writeMessage(message);
58 }
wangqi219b8702018-02-13 09:34:41 -080059
60 @Override
wangqi153af2f2018-02-15 16:21:49 -080061 public void onRttCallScreenUiReady() {
62 LogUtil.enterBlock("RttCallPresenter.onRttCallScreenUiReady");
63 InCallPresenter.getInstance().addListener(this);
64 startListenOnRemoteMessage();
65 }
66
67 @Override
68 public void onRttCallScreenUiUnready() {
69 LogUtil.enterBlock("RttCallPresenter.onRttCallScreenUiUnready");
70 InCallPresenter.getInstance().removeListener(this);
71 stopListenOnRemoteMessage();
72 }
73
74 @Override
75 public void onStateChange(InCallState oldState, InCallState newState, CallList callList) {
76 LogUtil.enterBlock("RttCallPresenter.onStateChange");
77 if (newState == InCallState.INCALL) {
78 startListenOnRemoteMessage();
79 }
80 }
81
82 private void startListenOnRemoteMessage() {
83 DialerCall call = CallList.getInstance().getActiveCall();
84 if (call == null) {
85 LogUtil.i("RttCallPresenter.startListenOnRemoteMessage", "call is active yet");
86 return;
87 }
88 rttCall = call.getRttCall();
89 if (rttCall == null) {
90 LogUtil.i("RttCallPresenter.startListenOnRemoteMessage", "RTT Call is not started yet");
91 return;
92 }
93 if (handlerThread != null && handlerThread.isAlive()) {
94 LogUtil.i("RttCallPresenter.startListenOnRemoteMessage", "already running");
95 return;
96 }
97 handlerThread = new HandlerThread("RttCallRemoteMessageHandler");
98 handlerThread.start();
99 remoteMessageHandler =
100 new RemoteMessageHandler(handlerThread.getLooper(), rttCall, rttCallScreen);
101 remoteMessageHandler.start();
102 }
103
104 private void stopListenOnRemoteMessage() {
105 if (handlerThread != null && handlerThread.isAlive()) {
106 handlerThread.quit();
107 }
108 }
109
110 private static class RemoteMessageHandler extends Handler {
111 private static final int START = 1;
112 private static final int READ_MESSAGE = 2;
113 private static final int WRITE_MESSAGE = 3;
114
115 private final RttCall rttCall;
116 private final RttCallScreen rttCallScreen;
117
118 RemoteMessageHandler(Looper looper, RttCall rttCall, RttCallScreen rttCallScreen) {
119 super(looper);
120 this.rttCall = rttCall;
121 this.rttCallScreen = rttCallScreen;
122 }
123
124 @Override
125 public void handleMessage(android.os.Message msg) {
126 switch (msg.what) {
127 case START:
128 sendEmptyMessage(READ_MESSAGE);
129 break;
130 case READ_MESSAGE:
131 try {
132 final String message = rttCall.readImmediately();
133 if (message != null) {
134 ThreadUtil.postOnUiThread(() -> rttCallScreen.onRemoteMessage(message));
135 }
136 } catch (IOException e) {
137 LogUtil.e("RttCallPresenter.RemoteMessageHandler.handleMessage", "read message", e);
138 }
139 sendEmptyMessageDelayed(READ_MESSAGE, 200);
140 break;
141 case WRITE_MESSAGE:
142 try {
143 rttCall.write((String) msg.obj);
144 } catch (IOException e) {
145 LogUtil.e("RttCallPresenter.RemoteMessageHandler.handleMessage", "write message", e);
146 }
147 break;
148 default: // fall out
149 }
150 }
151
152 void start() {
153 sendEmptyMessage(START);
154 }
155
156 void writeMessage(String message) {
157 sendMessage(obtainMessage(WRITE_MESSAGE, message));
158 }
159 }
wangqi219b8702018-02-13 09:34:41 -0800160}