blob: 96ab01177c130593040a24d5aa538726c998307b [file] [log] [blame]
Nicolas Jager998fbd72016-08-08 11:41:28 -04001/**************************************************************************
2* Copyright (C) 2016 by Savoir-faire Linux *
3* Author: Jäger Nicolas <nicolas.jager@savoirfairelinux.com> *
4* *
5* This program is free software; you can redistribute it and/or modify *
6* it under the terms of the GNU General Public License as published by *
7* the Free Software Foundation; either version 3 of the License, or *
8* (at your option) any later version. *
9* *
10* This program is distributed in the hope that it will be useful, *
11* but WITHOUT ANY WARRANTY; without even the implied warranty of *
12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13* GNU General Public License for more details. *
14* *
15* You should have received a copy of the GNU General Public License *
16* along with this program. If not, see <http://www.gnu.org/licenses/>. *
17**************************************************************************/
18#include "pch.h"
19
Nicolas Jager8a85e1f2016-08-15 15:11:06 -040020#include "ContactsViewModel.h"
21#include "MessageTextPage.xaml.h"
Nicolas Jager998fbd72016-08-08 11:41:28 -040022#include "SmartPanel.xaml.h"
23#include "RingConsolePanel.xaml.h"
Nicolas Jagere069c412016-08-15 15:00:17 -040024#include "VideoPage.xaml.h"
Nicolas Jager998fbd72016-08-08 11:41:28 -040025#include "WelcomePage.xaml.h"
26
27#include "MainPage.xaml.h"
28
29using namespace RingClientUWP;
30using namespace RingClientUWP::Views;
Nicolas Jager8a85e1f2016-08-15 15:11:06 -040031using namespace RingClientUWP::ViewModel;
Nicolas Jager998fbd72016-08-08 11:41:28 -040032
33using namespace Platform;
Nicolas Jager15861202016-08-12 11:13:05 -040034using namespace Windows::ApplicationModel::Core;
Nicolas Jager998fbd72016-08-08 11:41:28 -040035using namespace Windows::Foundation;
36using namespace Windows::Foundation::Collections;
37using namespace Windows::UI::ViewManagement;
38using namespace Windows::UI::Xaml;
39using namespace Windows::UI::Xaml::Controls;
40using namespace Windows::UI::Xaml::Controls::Primitives;
41using namespace Windows::UI::Core;
42using namespace Windows::UI::Xaml::Data;
43using namespace Windows::UI::Xaml::Input;
44using namespace Windows::UI::Xaml::Interop;
Nicolas Jager998fbd72016-08-08 11:41:28 -040045using namespace Windows::UI::Xaml::Navigation;
46using namespace Windows::ApplicationModel::Activation;
47using namespace Windows::Graphics::Display;
48using namespace Windows::System;
49
50MainPage::MainPage()
51{
52 InitializeComponent();
53
atraczyk1ddcb5a2016-09-07 16:18:30 -040054 Window::Current->SizeChanged += ref new WindowSizeChangedEventHandler(this, &MainPage::OnResize);
55
Nicolas Jager998fbd72016-08-08 11:41:28 -040056 _welcomeFrame_->Navigate(TypeName(RingClientUWP::Views::WelcomePage::typeid));
57 _smartPanel_->Navigate(TypeName(RingClientUWP::Views::SmartPanel::typeid));
58 _consolePanel_->Navigate(TypeName(RingClientUWP::Views::RingConsolePanel::typeid));
Nicolas Jagere069c412016-08-15 15:00:17 -040059 _videoFrame_->Navigate(TypeName(RingClientUWP::Views::VideoPage::typeid));
Nicolas Jager8a85e1f2016-08-15 15:11:06 -040060 _messageTextFrame_->Navigate(TypeName(RingClientUWP::Views::MessageTextPage::typeid));
61
62 /* connect to delegates */
Nicolas Jagerc551c362016-10-01 19:24:50 -040063 RingD::instance->stateChange += ref new RingClientUWP::StateChange(this, &RingClientUWP::MainPage::OnstateChange);
64 auto smartPanel = dynamic_cast<SmartPanel^>(_smartPanel_->Content);
65 smartPanel->summonMessageTextPage += ref new RingClientUWP::SummonMessageTextPage(this, &RingClientUWP::MainPage::OnsummonMessageTextPage);
66 smartPanel->summonWelcomePage += ref new RingClientUWP::SummonWelcomePage(this, &RingClientUWP::MainPage::OnsummonWelcomePage);
67 smartPanel->summonVideoPage += ref new RingClientUWP::SummonVideoPage(this, &RingClientUWP::MainPage::OnsummonVideoPage);
68 auto videoPage = dynamic_cast<VideoPage^>(_videoFrame_->Content);
69 videoPage->pressHangUpCall += ref new RingClientUWP::PressHangUpCall(this, &RingClientUWP::MainPage::OnpressHangUpCall);
atraczyk1ddcb5a2016-09-07 16:18:30 -040070
71 DisplayInformation^ displayInformation = DisplayInformation::GetForCurrentView();
72 dpiChangedtoken = (displayInformation->DpiChanged += ref new TypedEventHandler<DisplayInformation^,
Nicolas Jager7bef1492016-09-14 11:23:29 -040073 Platform::Object^>(this, &MainPage::DisplayProperties_DpiChanged));
atraczyk6290cc32016-10-07 08:47:15 -040074
75 visibilityChangedEventToken = Window::Current->VisibilityChanged +=
76 ref new WindowVisibilityChangedEventHandler(this, &MainPage::Application_VisibilityChanged);
77 applicationSuspendingEventToken = Application::Current->Suspending +=
78 ref new SuspendingEventHandler(this, &MainPage::Application_Suspending);
79 applicationResumingEventToken = Application::Current->Resuming +=
80 ref new EventHandler<Object^>(this, &MainPage::Application_Resuming);
Nicolas Jager998fbd72016-08-08 11:41:28 -040081}
82
83void
84MainPage::OnKeyDown(KeyRoutedEventArgs^ e)
85{
86 if (e->Key == VirtualKey::F5) {
87 _outerSplitView_->OpenPaneLength = Window::Current->Bounds.Width;
88 _outerSplitView_->IsPaneOpen = !_outerSplitView_->IsPaneOpen;
89 }
Nicolas Jager15861202016-08-12 11:13:05 -040090}
91
92void RingClientUWP::MainPage::_toggleSmartBoxButton__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
93{
94 _innerSplitView_->IsPaneOpen = !_innerSplitView_->IsPaneOpen;
atraczyk0cf42d72016-09-06 11:16:37 -040095 if (_innerSplitView_->IsPaneOpen) {
96 dynamic_cast<SmartPanel^>(_smartPanel_->Content)->setMode(Views::SmartPanel::Mode::Normal);
97 _hamburgerButtonBar_->Width = 320;
98 }
99 else {
100 dynamic_cast<SmartPanel^>(_smartPanel_->Content)->setMode(Views::SmartPanel::Mode::Minimized);
101 _hamburgerButtonBar_->Width = 60;
102 }
Nicolas Jager15861202016-08-12 11:13:05 -0400103}
Nicolas Jager8a85e1f2016-08-15 15:11:06 -0400104
105void
106RingClientUWP::MainPage::showFrame(Windows::UI::Xaml::Controls::Frame^ frame)
107{
108 _navGrid_->SetRow(_welcomeFrame_, 0);
109 _navGrid_->SetRow(_messageTextFrame_, 0);
110 _navGrid_->SetRow(_videoFrame_, 0);
111
112 if (frame == _welcomeFrame_) {
113 _navGrid_->SetRow(_welcomeFrame_, 1);
114 } else if (frame == _videoFrame_) {
115 _navGrid_->SetRow(_videoFrame_, 1);
116 } else if (frame == _messageTextFrame_) {
117 _navGrid_->SetRow(_messageTextFrame_, 1);
Nicolas Jager8a85e1f2016-08-15 15:11:06 -0400118 }
119}
atraczyk61b28422016-08-24 09:25:59 -0400120
121void
122RingClientUWP::MainPage::OnNavigatedTo(NavigationEventArgs ^ e)
123{
124 RingD::instance->startDaemon();
atraczyk1ddcb5a2016-09-07 16:18:30 -0400125 showLoadingOverlay(true, false);
126}
127
128void
129RingClientUWP::MainPage::showLoadingOverlay(bool load, bool modal)
130{
131 if (!isLoading && load) {
132 isLoading = true;
133 _loadingOverlay_->Visibility = Windows::UI::Xaml::Visibility::Visible;
134 if (modal) {
135 _fadeInModalStoryboard_->Begin();
136 auto blackBrush = ref new Windows::UI::Xaml::Media::SolidColorBrush(Windows::UI::Colors::Black);
137 _loadingOverlayRect_->Fill = blackBrush;
138 }
139 else {
140 auto whiteBrush = ref new Windows::UI::Xaml::Media::SolidColorBrush(Windows::UI::Colors::White);
141 _loadingOverlayRect_->Fill = whiteBrush;
142 _loadingOverlayRect_->Opacity = 1.0;
143 }
144 OnResize(nullptr, nullptr);
145 }
146 else if (!load) {
147 isLoading = false;
148 _fadeOutStoryboard_->Begin();
149 }
150}
151
152void
153RingClientUWP::MainPage::PositionImage()
154{
155 bounds = ApplicationView::GetForCurrentView()->VisibleBounds;
156
157 auto img = ref new Image();
158 auto bitmapImage = ref new Windows::UI::Xaml::Media::Imaging::BitmapImage();
159 Windows::Foundation::Uri^ uri;
160
161 if (bounds.Width < 1200)
162 uri = ref new Windows::Foundation::Uri("ms-appx:///Assets/TESTS/logo-ring.scale-200.png");
163 else
164 uri = ref new Windows::Foundation::Uri("ms-appx:///Assets/TESTS/logo-ring.scale-150.png");
165
166 bitmapImage->UriSource = uri;
167 img->Source = bitmapImage;
168 _loadingImage_->Source = img->Source;
169
170 _loadingImage_->SetValue(Canvas::LeftProperty, bounds.Width * 0.5 - _loadingImage_->Width * 0.5);
171 _loadingImage_->SetValue(Canvas::TopProperty, bounds.Height * 0.5 - _loadingImage_->Height * 0.5);
172}
173
174void
175RingClientUWP::MainPage::PositionRing()
176{
177 double left;
178 double top;
179 if (bounds.Width < 1200) {
180 _splashProgressRing_->Width = 118;
181 _splashProgressRing_->Height = 118;
182 left = bounds.Width * 0.5 - _loadingImage_->Width * 0.5 - 145;
183 top = bounds.Height * 0.5 - _loadingImage_->Height * 0.5 - 60;
184 }
185 else {
186 _splashProgressRing_->Width = 162;
187 _splashProgressRing_->Height = 162;
188 left = bounds.Width * 0.5 - _loadingImage_->Width * 0.5 - 195;
189 top = bounds.Height * 0.5 - _loadingImage_->Height * 0.5 - 84;
190 }
191 _splashProgressRing_->SetValue(Canvas::LeftProperty, left + _loadingImage_->Width * 0.5);
192 _splashProgressRing_->SetValue(Canvas::TopProperty, top + _loadingImage_->Height * 0.5);
193}
194
195void
196RingClientUWP::MainPage::OnResize(Platform::Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e)
197{
198 PositionImage();
199 PositionRing();
200}
201
202void
203RingClientUWP::MainPage::DisplayProperties_DpiChanged(DisplayInformation^ sender, Platform::Object^ args)
204{
205 OnResize(nullptr, nullptr);
206}
207
208void
209RingClientUWP::MainPage::hideLoadingOverlay()
210{
211 _loadingOverlay_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
Nicolas Jagerc551c362016-10-01 19:24:50 -0400212}
213
214void RingClientUWP::MainPage::OnsummonMessageTextPage()
215{
216 auto messageTextPage = dynamic_cast<MessageTextPage^>(_messageTextFrame_->Content);
217 messageTextPage->updatePageContent();
218 showFrame(_messageTextFrame_);
219
220}
221
222
223void RingClientUWP::MainPage::OnsummonWelcomePage()
224{
225 showFrame(_welcomeFrame_);
226}
227
228
229void RingClientUWP::MainPage::OnsummonVideoPage()
230{
231 auto videoPage = dynamic_cast<VideoPage^>(_videoFrame_->Content);
232 videoPage->updatePageContent();
233 showFrame(_videoFrame_);
234}
235
236
237void RingClientUWP::MainPage::OnpressHangUpCall()
238{
239 OnsummonMessageTextPage();
240}
241
242
243
244void RingClientUWP::MainPage::OnstateChange(Platform::String ^callId, RingClientUWP::CallStatus state, int code)
245{
246 auto item = SmartPanelItemsViewModel::instance->_selectedItem;
247
248 switch (state) {
249 /* send the user to the peer's message text page */
250 case CallStatus::ENDED:
251 {
252 if (item)
253 OnsummonMessageTextPage();
254 break;
255 }
Nicolas Jagerc551c362016-10-01 19:24:50 -0400256 default:
257 break;
258 }
259
260}
atraczyk6290cc32016-10-07 08:47:15 -0400261#include <dring.h>
262#include "callmanager_interface.h"
atraczyk14ba30c2016-09-22 18:31:59 -0400263void
264MainPage::Application_Suspending(Object^, Windows::ApplicationModel::SuspendingEventArgs^ e)
265{
266 WriteLine("Application_Suspending");
267 if (Frame->CurrentSourcePageType.Name ==
atraczyk6290cc32016-10-07 08:47:15 -0400268 Interop::TypeName(MainPage::typeid).Name) {
atraczyk14ba30c2016-09-22 18:31:59 -0400269 auto deferral = e->SuspendingOperation->GetDeferral();
atraczyk6290cc32016-10-07 08:47:15 -0400270 BeginExtendedExecution()
271 .then([=](task<void> previousTask) {
272 try {
273 previousTask.get();
274 }
275 catch (Exception^ e) {
276 WriteLine("Exception: Extended Execution Begin");
277 }
278 })
279 .then([this, deferral](task<void> previousTask) {
280 try {
281 previousTask.get();
282 WriteLine("deferral->Complete()");
283 deferral->Complete();
284 }
285 catch (Exception^ e) {
286 WriteLine("Exception: Extended Execution");
287 deferral->Complete();
288 }
atraczyk14ba30c2016-09-22 18:31:59 -0400289 });
290 }
291}
292
293void
294MainPage::Application_VisibilityChanged(Object^ sender, VisibilityChangedEventArgs^ e)
295{
atraczyk6290cc32016-10-07 08:47:15 -0400296 if (e->Visible) {
atraczyk14ba30c2016-09-22 18:31:59 -0400297 WriteLine("->Visible");
atraczykc8f949a2016-10-07 11:34:03 -0400298 auto isPreviewing = Video::VideoManager::instance->captureManager()->isPreviewing;
299 bool isInCall = false;
300 for (auto item : SmartPanelItemsViewModel::instance->itemsList) {
301 if (item->_callId && item->_callStatus == CallStatus::IN_PROGRESS) {
302 isInCall = true;
303 break;
304 }
305 }
306 if (isInCall) {
307 /*if (RingD::instance->currentCallId)
308 RingD::instance->unPauseCall(RingD::instance->currentCallId);*/
309 Video::VideoManager::instance->captureManager()->InitializeCameraAsync();
310 Video::VideoManager::instance->captureManager()->videoFrameCopyInvoker->Start();
311 }
atraczyk14ba30c2016-09-22 18:31:59 -0400312 }
atraczyk6290cc32016-10-07 08:47:15 -0400313 else {
atraczyk14ba30c2016-09-22 18:31:59 -0400314 WriteLine("->Invisible");
atraczykc8f949a2016-10-07 11:34:03 -0400315 auto isPreviewing = Video::VideoManager::instance->captureManager()->isPreviewing;
316 bool isInCall = false;
317 for (auto item : SmartPanelItemsViewModel::instance->itemsList) {
318 if (item->_callId && item->_callStatus == CallStatus::IN_PROGRESS) {
319 isInCall = true;
320 RingD::instance->currentCallId = item->_callId;
321 break;
322 }
323 }
324 if (isInCall) {
325 /*if (RingD::instance->currentCallId) {
326 WriteLine("Pausing call: " + RingD::instance->currentCallId);
327 RingD::instance->pauseCall(RingD::instance->currentCallId);
328 }*/
329 if (isPreviewing) {
330 Video::VideoManager::instance->captureManager()->StopPreviewAsync();
331 if (Video::VideoManager::instance->captureManager()->captureTaskTokenSource)
332 Video::VideoManager::instance->captureManager()->captureTaskTokenSource->cancel();
333 Video::VideoManager::instance->captureManager()->videoFrameCopyInvoker->Stop();
334 }
335 }
atraczyk14ba30c2016-09-22 18:31:59 -0400336 }
Nicolas Jager083b3ae2016-10-04 08:46:19 -0400337}
338
atraczyk6290cc32016-10-07 08:47:15 -0400339void MainPage::Application_Resuming(Object^, Object^)
340{
341 WriteLine("Application_Resuming");
342}
343
344void
345MainPage::SessionRevoked(Object^ sender, ExtendedExecutionRevokedEventArgs^ args)
346{
347 Dispatcher->RunAsync(CoreDispatcherPriority::High, ref new DispatchedHandler([=]() {
348 ClearExtendedExecution();
349 }));
350}
351
352void
353MainPage::ClearExtendedExecution()
354{
355 if (session != nullptr) {
356 WriteLine("End Extended Execution");
357 session->Revoked -= sessionRevokedToken;
358 }
359}
360
361task<void>
362MainPage::BeginExtendedExecution()
363{
364 ClearExtendedExecution();
365
366 auto newSession = ref new ExtendedExecutionSession();
367 newSession->Reason = ExtendedExecutionReason::SavingData;
368 newSession->Description = "Extended Execution";
369 sessionRevokedToken = (newSession->Revoked += ref new TypedEventHandler<Object^,
370 ExtendedExecutionRevokedEventArgs^>(this, &MainPage::SessionRevoked));
371 return create_task(newSession->RequestExtensionAsync())
372 .then([=](ExtendedExecutionResult result){
373 try {
374 switch (result)
375 {
376 case ExtendedExecutionResult::Allowed:
377 session = newSession;
378 WriteLine("Request Extended Execution Allowed");
379 WriteLine("Clean up camera...");
380 Video::VideoManager::instance->captureManager()->CleanupCameraAsync()
381 .then([](){
382 WriteLine("Hang up calls...");
atraczykc8f949a2016-10-07 11:34:03 -0400383 DRing::fini();
atraczyk6290cc32016-10-07 08:47:15 -0400384 });
385 break;
386
387 default:
388 case ExtendedExecutionResult::Denied:
389 WriteLine("Request Extended Execution Denied");
390 break;
391 }
392 }
393 catch (Exception^ e) {
394 WriteLine("Exception: Extended Execution Request");
395 }
396 });
397}