InCall.xaml.cs 9.03 KB
Newer Older
1 2
using Linphone.Core;
using Linphone.Model;
3
using Linphone.Resources;
4
using System;
5
using System.ComponentModel;
6
using System.Diagnostics;
7
using System.Threading;
8
using System.Windows;
9
using System.Windows.Controls;
10
using System.Windows.Media.Imaging;
11
using System.Windows.Navigation;
12 13 14

namespace Linphone.Views
{
15 16 17
    /// <summary>
    /// InCall page, displayed for both incoming and outgoing calls.
    /// </summary>
18
    public partial class InCall : BasePage, MuteChangedListener, PauseChangedListener
19 20 21 22 23 24 25 26
    {
        private const string speakerOn = "/Assets/AppBar/speaker.png";
        private const string speakerOff = "/Assets/AppBar/speaker.png";
        private const string micOn = "/Assets/AppBar/mic.png";
        private const string micOff = "/Assets/AppBar/mic.png";
        private const string pauseOn = "/Assets/AppBar/play.png";
        private const string pauseOff = "/Assets/AppBar/pause.png";

27
        private Timer timer;
28
        private DateTimeOffset startTime;
29

30 31 32
        /// <summary>
        /// Public constructor.
        /// </summary>
33 34 35
        public InCall()
        {
            InitializeComponent();
36 37 38 39 40 41

            var call = LinphoneManager.Instance.LinphoneCore.GetCurrentCall();
            if (call != null && call.GetState() == Core.LinphoneCallState.StreamsRunning)
            {
                PauseStateChanged(false);
            }
42 43
        }

44 45 46 47
        /// <summary>
        /// Method called when the page is displayed.
        /// Searches for a matching contact using the current call address or number and display information if found.
        /// </summary>
48
        protected override void OnNavigatedTo(NavigationEventArgs nee)
49
        {
50
            // Create LinphoneCore if not created yet, otherwise do nothing
Sylvain Berfini's avatar
Sylvain Berfini committed
51
            LinphoneManager.Instance.InitLinphoneCore();
52

53 54 55
            base.OnNavigatedTo(nee);
            this.ViewModel.MuteListener = this;
            this.ViewModel.PauseListener = this;
56

57 58
            if (NavigationContext.QueryString.ContainsKey("sip"))
            {
59
                String calledNumber = NavigationContext.QueryString["sip"];
60 61 62 63
                if (calledNumber.StartsWith("sip:"))
                {
                    calledNumber = calledNumber.Substring(4);
                }
64
                // While we dunno if the number matches a contact one, we consider it won't and we display the phone number as username
65
                Contact.Text = calledNumber;
66

67 68 69 70 71 72
                if (calledNumber != null && calledNumber.Length > 0)
                {
                    ContactManager cm = ContactManager.Instance;
                    cm.ContactFound += cm_ContactFound;
                    cm.FindContact(calledNumber);
                }
73 74 75
            }
        }

76 77 78 79 80
        /// <summary>
        /// Method called when the page is leaved.
        /// </summary>
        protected override void OnNavigatedFrom(NavigationEventArgs nee)
        {
81 82 83 84 85
            if (timer != null)
            {
                timer.Dispose();
            }

86 87 88 89 90
            base.OnNavigatedFrom(nee);
            this.ViewModel.MuteListener = null;
            this.ViewModel.PauseListener = null;
        }

91 92 93
        /// <summary>
        /// Callback called when the search on a phone number for a contact has a match
        /// </summary>
94 95 96 97 98 99 100 101 102 103
        private void cm_ContactFound(object sender, ContactFoundEventArgs e)
        {
            Contact.Text = e.ContactFound.DisplayName;
            if (e.PhoneLabel != null)
            {
                Number.Text = e.PhoneLabel + " : " + e.PhoneNumber;
            }
            else
            {
                Number.Text = e.PhoneNumber;
104 105 106 107 108
            }
        }

        private void hangUp_Click(object sender, RoutedEventArgs e)
        {
109 110 111 112
            if (timer != null)
            {
                timer.Dispose();
            }
113
            LinphoneManager.Instance.EndCurrentCall();
114 115 116 117 118 119
        }

        private void speaker_Click_1(object sender, RoutedEventArgs e)
        {
            bool isSpeakerToggled = (bool)speaker.IsChecked;
            speakerImg.Source = new BitmapImage(new Uri(isSpeakerToggled ? speakerOn : speakerOff, UriKind.RelativeOrAbsolute));
Ghislain MARY's avatar
Ghislain MARY committed
120
            LinphoneManager.Instance.EnableSpeaker(isSpeakerToggled);
121 122 123 124 125
        }

        private void microphone_Click_1(object sender, RoutedEventArgs e)
        {
            bool isMicToggled = (bool)microphone.IsChecked;
126
            LinphoneManager.Instance.MuteMic(isMicToggled);
127 128 129 130 131

            if (isMicToggled)
                LinphoneManager.Instance.CallController.NotifyMuted();
            else
                LinphoneManager.Instance.CallController.NotifyUnmuted();
132 133
        }

134 135 136 137 138 139 140
        private void stats_Click_1(object sender, RoutedEventArgs e)
        {
            bool areStatsVisible = (bool)stats.IsChecked;
            emptyPanel.Visibility = areStatsVisible ? Visibility.Collapsed : Visibility.Visible;
            statsPanel.Visibility = areStatsVisible ? Visibility.Visible : Visibility.Collapsed;
        }

141 142 143 144 145
        /// <summary>
        /// Called when the mute status of the microphone changes.
        /// </summary>
        public void MuteStateChanged(Boolean isMicMuted)
        {
146
            microphone.IsChecked = isMicMuted;
147 148 149
            microImg.Source = new BitmapImage(new Uri(isMicMuted ? micOn : micOff, UriKind.RelativeOrAbsolute));
        }

150 151 152
        private void pause_Click_1(object sender, RoutedEventArgs e)
        {
            bool isPauseToggled = (bool)pause.IsChecked;
153 154 155 156
            if (isPauseToggled)
                LinphoneManager.Instance.PauseCurrentCall();
            else
                LinphoneManager.Instance.ResumeCurrentCall();
157 158
        }

159 160 161 162 163
        /// <summary>
        /// Called when the call changes its state to paused or resumed.
        /// </summary>
        public void PauseStateChanged(bool isCallPaused)
        {
164
            pause.IsChecked = isCallPaused;
165
            pauseImg.Source = new BitmapImage(new Uri(isCallPaused ? pauseOn : pauseOff, UriKind.RelativeOrAbsolute));
166

167
            if (!isCallPaused)
168 169 170
            {
                timer = new Timer(new TimerCallback(timerTick), null, 0, 1000);
            }
171
            else if (timer != null)
172
            {
173
                timer.Dispose();
174 175 176 177 178
            }
        }

        private void timerTick(Object state)
        {
179
            try
180
            {
181 182 183 184 185 186 187 188 189 190 191 192 193 194
                LinphoneCall call = LinphoneManager.Instance.LinphoneCore.GetCurrentCall();
                if (call == null)
                {
                    timer.Dispose();
                    return;
                }
                startTime = (DateTimeOffset)call.GetCallStartTimeFromContext();
                DateTimeOffset now = DateTimeOffset.Now;
                TimeSpan elapsed = now.Subtract(startTime);
                var ss = elapsed.Seconds;
                var mm = elapsed.Minutes;
                Status.Dispatcher.BeginInvoke(delegate()
                {
                    Status.Text = mm.ToString("00") + ":" + ss.ToString("00");
195 196 197 198 199 200 201 202 203 204 205 206 207 208

                    LinphoneCallStats stats = call.GetAudioStats();
                    if (stats != null)
                    {
                        DownBw.Text = String.Format(AppResources.StatDownloadBW + ": {0} kbit/s", stats.GetDownloadBandwidth());
                        UpBw.Text = String.Format(AppResources.StatUploadBW + ": {0} kbit/s", stats.GetUploadBandwidth());
                    }

                    LinphoneCallParams param = call.GetCurrentParamsCopy();
                    PayloadType pt = param.GetUsedAudioCodec();
                    if (pt != null) 
                    {
                        PType.Text = AppResources.StatAudioPayload + ": " + pt.GetMimeType() + "/" + pt.GetClockRate();
                    }
209 210 211 212
                });
            } catch {
                timer.Dispose();
            }
213 214
        }

215 216 217 218 219 220 221
        private void dialpad_Click_1(object sender, RoutedEventArgs e)
        {
            bool isDialpadVisible = (bool)dialpad.IsChecked;
            pause.Visibility = isDialpadVisible ? Visibility.Collapsed : Visibility.Visible;
            speaker.Visibility = isDialpadVisible ? Visibility.Collapsed : Visibility.Visible;
            microphone.Visibility = isDialpadVisible ? Visibility.Collapsed : Visibility.Visible;
            numpad.Visibility = isDialpadVisible ? Visibility.Visible : Visibility.Collapsed;
222
            stats.Visibility = isDialpadVisible ? Visibility.Collapsed : Visibility.Visible;
223 224 225 226
        }

        private void Numpad_Click_1(object sender, RoutedEventArgs e)
        {
227 228 229
            Button button = sender as Button;
            String tag = button.Tag as String;
            LinphoneManager.Instance.LinphoneCore.SendDTMF(Convert.ToChar(tag));
230
        }
231 232 233 234 235 236 237 238

        /// <summary>
        /// Do not allow user to leave the incall page while call is active
        /// </summary>
        protected override void OnBackKeyPress(CancelEventArgs e)
        {
            e.Cancel = true;
        }
239 240
    }
}