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);
FindFreeCallIndex()45   int FindFreeCallIndex() const {
46     for (int index = 1; true; index++) {
47       if (active_calls_.find(index) == active_calls_.end()) {
48         return index;
49       }
50     }
51   }
52 
53  private:
54   void InitializeServiceState();
55   std::vector<CommandHandler> InitializeCommandHandlers();
56   void SimulatePendingCallsAnswered();
57   void CallStateUpdate();
58 
59   struct CallStatus {
60     enum CallState {
61       CALL_STATE_ACTIVE = 0,
62       CALL_STATE_HELD,
63       CALL_STATE_DIALING,
64       CALL_STATE_ALERTING,
65       CALL_STATE_INCOMING,
66       CALL_STATE_WAITING,
67       CALL_STATE_HANGUP
68     };
69 
70     // ctors
CallStatusCallStatus71     CallStatus()
72       : call_state(CALL_STATE_ACTIVE),
73         is_mobile_terminated(true),
74         is_international(false),
75         is_voice_mode(true),
76         is_multi_party(false),
77         can_present_number(true) {}
78 
CallStatusCallStatus79     CallStatus(const std::string_view number)
80         : call_state(CALL_STATE_INCOMING),
81           is_mobile_terminated(true),
82           is_international(false),
83           is_voice_mode(true),
84           is_multi_party(false),
85           number(number),
86           can_present_number(true) {}
87 
isCallBackgroundCallStatus88     bool isCallBackground() {
89       return call_state == CALL_STATE_HELD;
90     }
91 
isCallActiveCallStatus92     bool isCallActive() {
93       return call_state == CALL_STATE_ACTIVE;
94     }
95 
isCallDialingCallStatus96     bool isCallDialing() {
97       return call_state == CALL_STATE_DIALING;
98     }
99 
isCallIncomingCallStatus100     bool isCallIncoming() {
101       return call_state == CALL_STATE_INCOMING;
102     }
103 
isCallWaitingCallStatus104     bool isCallWaiting() {
105       return call_state == CALL_STATE_WAITING;
106     }
107 
isCallAlertingCallStatus108     bool isCallAlerting() {
109       return call_state == CALL_STATE_ALERTING;
110     }
111 
SetCallBackgroundCallStatus112     bool SetCallBackground() {
113       if (call_state == CALL_STATE_ACTIVE) {
114         call_state = CALL_STATE_HELD;
115         return true;
116       }
117 
118       return false;
119     }
120 
SetCallActiveCallStatus121     bool SetCallActive() {
122       if (call_state == CALL_STATE_INCOMING || call_state == CALL_STATE_WAITING ||
123           call_state == CALL_STATE_DIALING || call_state == CALL_STATE_HELD) {
124         call_state = CALL_STATE_ACTIVE;
125         return true;
126       }
127 
128       return false;
129     }
130 
131     // date member public
132     CallState call_state;
133     bool is_mobile_terminated;
134     bool is_international;
135     bool is_voice_mode;
136     bool is_multi_party;
137     bool is_remote_call;
138     std::optional<ClientId> remote_client;
139     std::optional<int32_t> timeout_serial;
140     std::string number;
141     bool can_present_number;
142   };
143   using CallToken = std::pair<int, std::string>;
144 
145   void SendCallStatusToRemote(CallStatus& call, CallStatus::CallState state);
146   void TimerWaitingRemoteCallResponse(CallToken token);
147 
148   // private data members
149   SimService* sim_service_;
150   NetworkService* network_service_;
151   std::map<int, CallStatus> active_calls_;
152   bool in_emergency_mode_;
153   bool mute_on_;
154 };
155 
156 }  // namespace
157