1 //
2 // Copyright (C) 2020 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 #pragma once
17 
18 #include "host/commands/modem_simulator/modem_service.h"
19 #include "host/commands/modem_simulator/network_service.h"
20 #include "host/commands/modem_simulator/sim_service.h"
21 
22 namespace cuttlefish {
23 
24 class CallService : public ModemService, public std::enable_shared_from_this<CallService>  {
25  public:
26   CallService(int32_t service_id, ChannelMonitor* channel_monitor,
27               ThreadLooper* thread_looper);
28   ~CallService() = default;
29 
30   CallService(const CallService &) = delete;
31   CallService &operator=(const CallService &) = delete;
32 
33   void SetupDependency(SimService* sim, NetworkService* net);
34 
35   void HandleDial(const Client& client, const std::string& command);
36   void HandleAcceptCall(const Client& client);
37   void HandleRejectCall(const Client& client);
38   void HandleCurrentCalls(const Client& client);
39   void HandleHangup(const Client& client, const std::string& command);
40   void HandleMute(const Client& client, const std::string& command);
41   void HandleSendDtmf(const Client& client, const std::string& command);
42   void HandleCancelUssd(const Client& client, const std::string& command);
43   void HandleEmergencyMode(const Client& client, const std::string& command);
44   void HandleRemoteCall(const Client& client, const std::string& command);
45 
46  private:
47   void InitializeServiceState();
48   std::vector<CommandHandler> InitializeCommandHandlers();
49   void SimulatePendingCallsAnswered();
50   void CallStateUpdate();
51 
52   struct CallStatus {
53     enum CallState {
54       CALL_STATE_ACTIVE = 0,
55       CALL_STATE_HELD,
56       CALL_STATE_DIALING,
57       CALL_STATE_ALERTING,
58       CALL_STATE_INCOMING,
59       CALL_STATE_WAITING,
60       CALL_STATE_HANGUP
61     };
62 
63     // ctors
CallStatusCallStatus64     CallStatus()
65       : call_state(CALL_STATE_ACTIVE),
66         is_mobile_terminated(true),
67         is_international(false),
68         is_voice_mode(true),
69         is_multi_party(false),
70         can_present_number(true) {}
71 
CallStatusCallStatus72     CallStatus(const std::string_view number)
73         : call_state(CALL_STATE_INCOMING),
74           is_mobile_terminated(true),
75           is_international(false),
76           is_voice_mode(true),
77           is_multi_party(false),
78           number(number),
79           can_present_number(true) {}
80 
isCallBackgroundCallStatus81     bool isCallBackground() {
82       return call_state == CALL_STATE_HELD;
83     }
84 
isCallActiveCallStatus85     bool isCallActive() {
86       return call_state == CALL_STATE_ACTIVE;
87     }
88 
isCallDialingCallStatus89     bool isCallDialing() {
90       return call_state == CALL_STATE_DIALING;
91     }
92 
isCallIncomingCallStatus93     bool isCallIncoming() {
94       return call_state == CALL_STATE_INCOMING;
95     }
96 
isCallWaitingCallStatus97     bool isCallWaiting() {
98       return call_state == CALL_STATE_WAITING;
99     }
100 
isCallAlertingCallStatus101     bool isCallAlerting() {
102       return call_state == CALL_STATE_ALERTING;
103     }
104 
SetCallBackgroundCallStatus105     bool SetCallBackground() {
106       if (call_state == CALL_STATE_ACTIVE) {
107         call_state = CALL_STATE_HELD;
108         return true;
109       }
110 
111       return false;
112     }
113 
SetCallActiveCallStatus114     bool SetCallActive() {
115       if (call_state == CALL_STATE_INCOMING || call_state == CALL_STATE_WAITING ||
116           call_state == CALL_STATE_DIALING || call_state == CALL_STATE_HELD) {
117         call_state = CALL_STATE_ACTIVE;
118         return true;
119       }
120 
121       return false;
122     }
123 
124     // date member public
125     CallState call_state;
126     bool is_mobile_terminated;
127     bool is_international;
128     bool is_voice_mode;
129     bool is_multi_party;
130     bool is_remote_call;
131     std::optional<cuttlefish::SharedFD> remote_client;
132     std::optional<int32_t> timeout_serial;
133     std::string number;
134     bool can_present_number;
135   };
136   using CallToken = std::pair<int, std::string>;
137 
138   void SendCallStatusToRemote(CallStatus& call, CallStatus::CallState state);
139   void TimerWaitingRemoteCallResponse(CallToken token);
140 
141   // private data members
142   SimService* sim_service_;
143   NetworkService* network_service_;
144   int32_t last_active_call_index_;
145   std::map<int, CallStatus> active_calls_;
146   bool in_emergency_mode_;
147   bool mute_on_;
148 };
149 
150 }  // namespace
151