• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.incallui;
18 
19 import android.annotation.TargetApi;
20 import android.os.Handler;
21 import android.os.HandlerThread;
22 import android.os.Looper;
23 import android.telecom.Call.RttCall;
24 import com.android.dialer.common.LogUtil;
25 import com.android.dialer.common.concurrent.ThreadUtil;
26 import com.android.incallui.InCallPresenter.InCallState;
27 import com.android.incallui.InCallPresenter.InCallStateListener;
28 import com.android.incallui.call.CallList;
29 import com.android.incallui.call.DialerCall;
30 import com.android.incallui.rtt.protocol.RttCallScreen;
31 import com.android.incallui.rtt.protocol.RttCallScreenDelegate;
32 import java.io.IOException;
33 
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  */
38 @TargetApi(28)
39 public class RttCallPresenter implements RttCallScreenDelegate, InCallStateListener {
40 
41   private RttCallScreen rttCallScreen;
42   private RttCall rttCall;
43   private HandlerThread handlerThread;
44   private RemoteMessageHandler remoteMessageHandler;
45 
46   @Override
initRttCallScreenDelegate(RttCallScreen rttCallScreen)47   public void initRttCallScreenDelegate(RttCallScreen rttCallScreen) {
48     this.rttCallScreen = rttCallScreen;
49   }
50 
51   @Override
onLocalMessage(String message)52   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   }
59 
60   @Override
onRttCallScreenUiReady()61   public void onRttCallScreenUiReady() {
62     LogUtil.enterBlock("RttCallPresenter.onRttCallScreenUiReady");
63     InCallPresenter.getInstance().addListener(this);
64     startListenOnRemoteMessage();
65   }
66 
67   @Override
onRttCallScreenUiUnready()68   public void onRttCallScreenUiUnready() {
69     LogUtil.enterBlock("RttCallPresenter.onRttCallScreenUiUnready");
70     InCallPresenter.getInstance().removeListener(this);
71     stopListenOnRemoteMessage();
72   }
73 
74   @Override
onStateChange(InCallState oldState, InCallState newState, CallList callList)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 
startListenOnRemoteMessage()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 
stopListenOnRemoteMessage()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 
RemoteMessageHandler(Looper looper, RttCall rttCall, RttCallScreen rttCallScreen)118     RemoteMessageHandler(Looper looper, RttCall rttCall, RttCallScreen rttCallScreen) {
119       super(looper);
120       this.rttCall = rttCall;
121       this.rttCallScreen = rttCallScreen;
122     }
123 
124     @Override
handleMessage(android.os.Message msg)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 
start()152     void start() {
153       sendEmptyMessage(START);
154     }
155 
writeMessage(String message)156     void writeMessage(String message) {
157       sendMessage(obtainMessage(WRITE_MESSAGE, message));
158     }
159   }
160 }
161