Home | History | Annotate | Download | only in impl
      1 /*
      2  * Copyright (C) 2017 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.dialer.simulator.impl;
     18 
     19 import android.annotation.TargetApi;
     20 import android.content.Context;
     21 import android.support.annotation.NonNull;
     22 import android.support.v4.os.BuildCompat;
     23 import android.telecom.Connection;
     24 import android.telecom.Connection.RttTextStream;
     25 import android.telecom.ConnectionRequest;
     26 import android.telecom.VideoProfile;
     27 import com.android.dialer.common.Assert;
     28 import com.android.dialer.common.LogUtil;
     29 import com.android.dialer.simulator.Simulator;
     30 import com.android.dialer.simulator.Simulator.Event;
     31 import com.android.dialer.simulator.SimulatorComponent;
     32 import com.android.dialer.simulator.SimulatorConnectionsBank;
     33 import java.util.ArrayList;
     34 import java.util.List;
     35 
     36 /** Represents a single phone call on the device. */
     37 @TargetApi(28)
     38 public final class SimulatorConnection extends Connection {
     39   private final List<Listener> listeners = new ArrayList<>();
     40   private final List<Event> events = new ArrayList<>();
     41   private final SimulatorConnectionsBank simulatorConnectionsBank;
     42   private int currentState = STATE_NEW;
     43   private RttTextStream rttTextStream;
     44   private RttChatBot rttChatBot;
     45 
     46   SimulatorConnection(@NonNull Context context, @NonNull ConnectionRequest request) {
     47     Assert.isNotNull(context);
     48     Assert.isNotNull(request);
     49     putExtras(request.getExtras());
     50     setConnectionCapabilities(
     51         CAPABILITY_MUTE
     52             | CAPABILITY_SUPPORT_HOLD
     53             | CAPABILITY_HOLD
     54             | CAPABILITY_CAN_UPGRADE_TO_VIDEO
     55             | CAPABILITY_DISCONNECT_FROM_CONFERENCE);
     56 
     57     if (request.getExtras() != null) {
     58       if (!request.getExtras().getBoolean(Simulator.IS_VOLTE)) {
     59         setConnectionCapabilities(
     60             getConnectionCapabilities() | CAPABILITY_SEPARATE_FROM_CONFERENCE);
     61       }
     62     }
     63     if (BuildCompat.isAtLeastP()) {
     64       rttTextStream = request.getRttTextStream();
     65     }
     66     setVideoProvider(new SimulatorVideoProvider(context, this));
     67     simulatorConnectionsBank = SimulatorComponent.get(context).getSimulatorConnectionsBank();
     68   }
     69 
     70   public void addListener(@NonNull Listener listener) {
     71     listeners.add(Assert.isNotNull(listener));
     72   }
     73 
     74   public void removeListener(@NonNull Listener listener) {
     75     listeners.remove(Assert.isNotNull(listener));
     76   }
     77 
     78   RttTextStream getRttTextStream() {
     79     return rttTextStream;
     80   }
     81 
     82   @NonNull
     83   public List<Event> getEvents() {
     84     return events;
     85   }
     86 
     87   @Override
     88   public void onAnswer(int videoState) {
     89     LogUtil.enterBlock("SimulatorConnection.onAnswer");
     90     onEvent(new Event(Event.ANSWER, Integer.toString(videoState), null));
     91   }
     92 
     93   @Override
     94   public void onReject() {
     95     LogUtil.enterBlock("SimulatorConnection.onReject");
     96     simulatorConnectionsBank.remove(this);
     97     onEvent(new Event(Event.REJECT));
     98   }
     99 
    100   @Override
    101   public void onHold() {
    102     LogUtil.enterBlock("SimulatorConnection.onHold");
    103     onEvent(new Event(Event.HOLD));
    104   }
    105 
    106   @Override
    107   public void onUnhold() {
    108     LogUtil.enterBlock("SimulatorConnection.onUnhold");
    109     onEvent(new Event(Event.UNHOLD));
    110   }
    111 
    112   @Override
    113   public void onDisconnect() {
    114     LogUtil.enterBlock("SimulatorConnection.onDisconnect");
    115     simulatorConnectionsBank.remove(this);
    116     onEvent(new Event(Event.DISCONNECT));
    117     rttTextStream = null;
    118     if (rttChatBot != null) {
    119       rttChatBot.stop();
    120       rttChatBot = null;
    121     }
    122   }
    123 
    124   @Override
    125   public void onStateChanged(int newState) {
    126     LogUtil.i(
    127         "SimulatorConnection.onStateChanged",
    128         "%s -> %s",
    129         stateToString(currentState),
    130         stateToString(newState));
    131     int oldState = currentState;
    132     currentState = newState;
    133     onEvent(new Event(Event.STATE_CHANGE, stateToString(oldState), stateToString(newState)));
    134   }
    135 
    136   @Override
    137   public void onPlayDtmfTone(char c) {
    138     LogUtil.enterBlock("SimulatorConnection.onPlayDtmfTone");
    139     onEvent(new Event(Event.DTMF, Character.toString(c), null));
    140   }
    141 
    142   @Override
    143   public void onStartRtt(@NonNull RttTextStream rttTextStream) {
    144     LogUtil.enterBlock("SimulatorConnection.onStartRtt");
    145     if (this.rttTextStream != null || rttChatBot != null) {
    146       LogUtil.e("SimulatorConnection.onStartRtt", "rttTextStream or rttChatBot is not null!");
    147     }
    148     this.rttTextStream = rttTextStream;
    149     rttChatBot = new RttChatBot(rttTextStream);
    150     rttChatBot.start();
    151     onEvent(new Event(Event.START_RTT));
    152   }
    153 
    154   @Override
    155   public void onStopRtt() {
    156     LogUtil.enterBlock("SimulatorConnection.onStopRtt");
    157     rttChatBot.stop();
    158     rttChatBot = null;
    159     rttTextStream = null;
    160     onEvent(new Event(Event.STOP_RTT));
    161   }
    162 
    163   @Override
    164   public void handleRttUpgradeResponse(RttTextStream rttTextStream) {
    165     LogUtil.enterBlock("SimulatorConnection.handleRttUpgradeResponse");
    166     onEvent(new Event(Event.HANDLE_RTT_UPGRADE_RESPONSE));
    167   }
    168 
    169   void onEvent(@NonNull Event event) {
    170     events.add(Assert.isNotNull(event));
    171     for (Listener listener : new ArrayList<>(listeners)) {
    172       listener.onEvent(this, event);
    173     }
    174   }
    175 
    176   void handleSessionModifyRequest(@NonNull Event event) {
    177     VideoProfile fromProfile = new VideoProfile(Integer.parseInt(event.data1));
    178     VideoProfile toProfile = new VideoProfile(Integer.parseInt(event.data2));
    179     setVideoState(toProfile.getVideoState());
    180     getVideoProvider()
    181         .receiveSessionModifyResponse(
    182             Connection.VideoProvider.SESSION_MODIFY_REQUEST_SUCCESS, fromProfile, toProfile);
    183   }
    184 
    185   /** Callback for when a new event arrives. */
    186   public interface Listener {
    187     void onEvent(@NonNull SimulatorConnection connection, @NonNull Event event);
    188   }
    189 }
    190