Skip to content

Commit

Permalink
Fix activation to create delegate and principal class (#686)
Browse files Browse the repository at this point in the history
* Fix activation to create delegate and principal class

* Fix method call and style fixes

* Change method names and remove unused method

* Remove extra activation function

* Change function names to match convention of UI prefix

* Move definitions to application entry points
  • Loading branch information
aballway authored and Ramu-msft committed Jul 27, 2016
1 parent 68c7e96 commit 1a99852
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 133 deletions.
165 changes: 57 additions & 108 deletions Frameworks/UIKit/StarboardXaml/StarboardXaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,31 +111,29 @@ void App::Connect(int connectionId, Platform::Object^ target) {
}

void App::OnLaunched(LaunchActivatedEventArgs^ args) {
if (EbrApplicationLaunched(args) == true) {
_ApplicationMainLaunch(ActivationTypeNone, nullptr);
}
UIApplicationLaunched(args);
}

void App::OnActivated(IActivatedEventArgs^ args) {
EbrApplicationActivated(args);
UIApplicationActivated(args);
}

bool EbrApplicationLaunched(LaunchActivatedEventArgs^ args) {
if (args->PrelaunchActivated) {
// Opt out of prelaunch for now. MSDN guidance is to check the flag and just return.
return false;
}
void UIApplicationLaunched(LaunchActivatedEventArgs^ args) {
TraceVerbose(TAG, L"OnLaunched event received for %d. Previous app state was %d", args->Kind, args->PreviousExecutionState);

if ((args->PreviousExecutionState == ApplicationExecutionState::Running) ||
(args->PreviousExecutionState == ApplicationExecutionState::Suspended)) {
// Skip re-initializing as the app is being resumed from memory.
return false;
}
// Opt out of prelaunch for now. MSDN guidance is to check the flag and just return.
// Or skip re-initializing as the app is being resumed from memory.
bool initiateAppLaunch = (!(args->PrelaunchActivated)
&& (args->PreviousExecutionState != ApplicationExecutionState::Running)
&& (args->PreviousExecutionState != ApplicationExecutionState::Suspended));

return true;
if (initiateAppLaunch) {
TraceVerbose(TAG, L"Initializing application");
_ApplicationLaunch(ActivationTypeNone, args);
}
}

void EbrApplicationActivated(IActivatedEventArgs^ args) {
void UIApplicationActivated(IActivatedEventArgs^ args) {
TraceVerbose(TAG, L"OnActivated event received for %d. Previous app state was %d", args->Kind, args->PreviousExecutionState);

bool initiateAppLaunch = false;
Expand All @@ -150,7 +148,7 @@ void EbrApplicationActivated(IActivatedEventArgs^ args) {
TraceVerbose(TAG, L"Received toast notification with argument - %s", argsString->Data());

if (initiateAppLaunch) {
_ApplicationMainLaunch(ActivationTypeToast, argsString);
_ApplicationLaunch(ActivationTypeToast, argsString);
}

UIApplicationMainHandleToastNotificationEvent(Strings::WideToNarrow(argsString->Data()).c_str());
Expand All @@ -159,7 +157,7 @@ void EbrApplicationActivated(IActivatedEventArgs^ args) {
TraceVerbose(TAG, L"Received voice command with argument - %s", argResult->Text->Data());

if (initiateAppLaunch) {
_ApplicationMainLaunch(ActivationTypeVoiceCommand, argResult);
_ApplicationLaunch(ActivationTypeVoiceCommand, argResult);
}

UIApplicationMainHandleVoiceCommandEvent(reinterpret_cast<IInspectable*>(argResult));
Expand All @@ -170,27 +168,21 @@ void EbrApplicationActivated(IActivatedEventArgs^ args) {
TraceVerbose(TAG, L"Received protocol with uri- %s from %s", argUri->ToString()->Data(), caller);

if (initiateAppLaunch) {
_ApplicationMainLaunch(ActivationTypeProtocol, argUri);
_ApplicationLaunch(ActivationTypeProtocol, argUri);
}

UIApplicationMainHandleProtocolEvent(reinterpret_cast<IInspectable*>(argUri), caller);
} else {
TraceVerbose(TAG, L"Received unhandled activation kind - %d", args->Kind);

if (initiateAppLaunch) {
_ApplicationMainLaunch(ActivationTypeNone, nullptr);
_ApplicationLaunch(ActivationTypeNone, nullptr);
}
}
}

void _ApplicationMainLaunch(ActivationType activationType, Platform::Object^ activationArg) {
_ApplicationLaunch(activationType, activationArg);

_appEvents = ref new AppEventListener();
_appEvents->_RegisterEventHandlers();
}

extern "C" void _ApplicationLaunch(ActivationType activationType, Platform::Object^ activationArg) {
void _ApplicationLaunch(ActivationType activationType, Platform::Object^ activationArg) {
auto uiElem = ref new Xaml::Controls::Grid();
auto rootFrame = ref new Xaml::Controls::Frame();
rootFrame->Content = uiElem;
Expand All @@ -202,100 +194,57 @@ extern "C" void _ApplicationLaunch(ActivationType activationType, Platform::Obje

auto startupRect = Xaml::Window::Current->Bounds;
RunApplicationMain(g_principalClassName, g_delegateClassName, startupRect.Width, startupRect.Height, activationType, activationArg);
}

extern "C" void _ApplicationActivate(Platform::Object^ arguments) {
IActivatedEventArgs^ args = static_cast<IActivatedEventArgs^>(arguments);
TraceVerbose(TAG, L"OnActivated event received for %d. Previous app state was %d", args->Kind, args->PreviousExecutionState);
bool initiateAppLaunch = false;
if ((args->PreviousExecutionState != ApplicationExecutionState::Running) &&
(args->PreviousExecutionState != ApplicationExecutionState::Suspended)) {
TraceVerbose(TAG, L"Initializing application");
initiateAppLaunch = true;
}

if (args->Kind == ActivationKind::ToastNotification) {
Platform::String^ argsString = safe_cast<ToastNotificationActivatedEventArgs^>(args)->Argument;
TraceVerbose(TAG, L"Received toast notification with argument - %ls", argsString->Data());

if (initiateAppLaunch) {
_ApplicationLaunch(ActivationTypeToast, argsString);
}

UIApplicationMainHandleToastNotificationEvent(Strings::WideToNarrow(argsString->Data()).c_str());
} else if (args->Kind == ActivationKind::VoiceCommand) {
Windows::Media::SpeechRecognition::SpeechRecognitionResult^ argResult = safe_cast<VoiceCommandActivatedEventArgs^>(args)->Result;
TraceVerbose(TAG, L"Received voice command with argument - %ls", argResult->Text->Data());

if (initiateAppLaunch) {
_ApplicationLaunch(ActivationTypeVoiceCommand, argResult);
}

UIApplicationMainHandleVoiceCommandEvent(reinterpret_cast<IInspectable*>(argResult));
} else if (args->Kind == ActivationKind::Protocol) {
ProtocolActivatedEventArgs^ protocolArgs = safe_cast<ProtocolActivatedEventArgs^>(args);
Windows::Foundation::Uri^ argUri = protocolArgs->Uri;
const wchar_t* caller = protocolArgs->CallerPackageFamilyName->Data();
TraceVerbose(TAG, L"Received protocol with uri- %ls from %ls", argUri->ToString()->Data(), caller);

if (initiateAppLaunch) {
_ApplicationLaunch(ActivationTypeProtocol, argUri);
}

UIApplicationMainHandleProtocolEvent(reinterpret_cast<IInspectable*>(argUri), caller);
} else {
TraceVerbose(TAG, L"Received unhandled activation kind - %d", args->Kind);

if (initiateAppLaunch) {
_ApplicationLaunch(ActivationTypeNone, nullptr);
}
}
_appEvents = ref new AppEventListener();
_appEvents->_RegisterEventHandlers();
}


// This is the actual entry point from the app into our framework.
// Note: principalClassName and delegateClassName are actually NSString*s.
UIKIT_EXPORT
int UIApplicationMain(int argc, char* argv[], void* principalClassName, void* delegateClassName) {
// Initialize COM on this thread
::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
// Make method only run once
static int once = [principalClassName, delegateClassName] () -> int {

// Register tracelogging
TraceRegister();
// Initialize COM on this thread
::CoInitializeEx(nullptr, COINIT_MULTITHREADED);

// Copy the principal and delegate class names into our globals
if (principalClassName) {
auto rawString = _RawBufferFromNSString(principalClassName);
g_principalClassName = reinterpret_cast<Platform::String^>(Strings::NarrowToWide<HSTRING>(rawString).Detach());
}
// Register tracelogging
TraceRegister();

if (delegateClassName) {
auto rawString = _RawBufferFromNSString(delegateClassName);
g_delegateClassName = reinterpret_cast<Platform::String^>(Strings::NarrowToWide<HSTRING>(rawString).Detach());
}
// Copy the principal and delegate class names into our globals
if (principalClassName) {
auto rawString = _RawBufferFromNSString(principalClassName);
g_principalClassName = reinterpret_cast<Platform::String^>(Strings::NarrowToWide<HSTRING>(rawString).Detach());
}

Microsoft::WRL::ComPtr<ABI::Windows::UI::Xaml::IApplicationStatics> appStatics = nullptr;
Microsoft::WRL::ComPtr<ABI::Windows::UI::Xaml::IApplication> currentApplication = nullptr;
HRESULT hr = RoGetActivationFactory(Platform::StringReference(RuntimeClass_Windows_UI_Xaml_Application).GetHSTRING(),
ABI::Windows::UI::Xaml::IID_IApplicationStatics,
reinterpret_cast<void **>(appStatics.GetAddressOf()));
if (delegateClassName) {
auto rawString = _RawBufferFromNSString(delegateClassName);
g_delegateClassName = reinterpret_cast<Platform::String^>(Strings::NarrowToWide<HSTRING>(rawString).Detach());
}

if (hr == S_OK && appStatics) {
appStatics->get_Current(currentApplication.GetAddressOf());
}
Microsoft::WRL::ComPtr<ABI::Windows::UI::Xaml::IApplicationStatics> appStatics = nullptr;
Microsoft::WRL::ComPtr<ABI::Windows::UI::Xaml::IApplication> currentApplication = nullptr;
HRESULT hr = RoGetActivationFactory(Platform::StringReference(RuntimeClass_Windows_UI_Xaml_Application).GetHSTRING(),
ABI::Windows::UI::Xaml::IID_IApplicationStatics,
reinterpret_cast<void **>(appStatics.GetAddressOf()));

if (currentApplication == nullptr) {
// Start our application
Xaml::Application::Start(
ref new Xaml::ApplicationInitializationCallback([](Xaml::ApplicationInitializationCallbackParams^ p) {
// Simply creating the app will kick off the rest of the launch sequence
auto app = ref new App();
}));
}
else {
_ApplicationMainLaunch(ActivationTypeNone, nullptr);
}
if (hr == S_OK && appStatics) {
appStatics->get_Current(currentApplication.GetAddressOf());
}

return 0;
if (currentApplication == nullptr) {
// Start our application
Xaml::Application::Start(
ref new Xaml::ApplicationInitializationCallback([](Xaml::ApplicationInitializationCallbackParams^ p) {
// Simply creating the app will kick off the rest of the launch sequence
auto app = ref new App();
}));
}
return 0;
}();
return once;
}

// This is the initialization function for non-Islandwood apps that intend to call into Islandwood:
Expand Down Expand Up @@ -339,7 +288,7 @@ void UIApplicationActivationTest(IInspectable* activationArgs, void* delegateCla
g_delegateClassName = ref new Platform::String();
}

_ApplicationActivate(reinterpret_cast<Platform::Object^>(activationArgs));
UIApplicationActivated(static_cast<IActivatedEventArgs^>(reinterpret_cast<Platform::Object^>(activationArgs)));
}

// clang-format on
7 changes: 3 additions & 4 deletions Frameworks/UIKit/StarboardXaml/StarboardXaml.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,9 @@ ref class AppEventListener
void _OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ args);
};

extern "C" void _ApplicationLaunch(ActivationType activationType, Platform::Object^ activationArg);
extern "C" void EbrApplicationActivated(Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
extern "C" bool EbrApplicationLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ args);
void _ApplicationMainLaunch(ActivationType activationType, Platform::Object^ activationArg);
extern "C" void UIApplicationActivated(Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
extern "C" void UIApplicationLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ args);
void _ApplicationLaunch(ActivationType activationType, Platform::Object^ activationArg);

#endif

Expand Down
4 changes: 2 additions & 2 deletions build/UIKit/dll/UIKit.def
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ LIBRARY UIKit
UIApplicationMain
UIApplicationInitialize
UIApplicationActivationTest
UIApplicationActivated
UIApplicationLaunched

; NSAttributedString
NSFontAttributeName DATA
Expand Down Expand Up @@ -1164,6 +1166,4 @@ LIBRARY UIKit
UIRequestTransactionProcessing
UIOrientationFromString
UIApplicationDidChangeDisplayModeNofication
EbrApplicationActivated
EbrApplicationLaunched

31 changes: 12 additions & 19 deletions msvc/vsimporter-templates/WinStore10-App/App.xaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,33 +25,28 @@ using namespace Windows::UI::Xaml::Navigation;
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
App::App()
{
App::App() {
InitializeComponent();
Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending);
}

extern "C" int main(int argc, char* argv[]);
extern "C" int __cdecl EbrDefaultXamlMain();
extern "C" void EbrApplicationActivated(Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
extern "C" bool EbrApplicationLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ args);
extern "C" void UIApplicationActivated(Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
extern "C" void UIApplicationLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ args);

/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e)
{
if (EbrApplicationLaunched(e)) {
// Jump default "C" main
main(0, NULL);
}
void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) {
main(0, NULL);
UIApplicationLaunched(e);
}

void App::OnActivated(Windows::ApplicationModel::Activation::IActivatedEventArgs^ e)
{
EbrApplicationActivated(e);
void App::OnActivated(Windows::ApplicationModel::Activation::IActivatedEventArgs^ e) {
main(0, NULL);
UIApplicationActivated(e);
}

/// <summary>
Expand All @@ -61,8 +56,7 @@ void App::OnActivated(Windows::ApplicationModel::Activation::IActivatedEventArgs
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
void App::OnSuspending(Object^ /*sender*/, SuspendingEventArgs^ /*e*/)
{
void App::OnSuspending(Object^ /*sender*/, SuspendingEventArgs^ /*e*/) {
// TODO: Save application state and stop any background activity
}

Expand All @@ -71,7 +65,6 @@ void App::OnSuspending(Object^ /*sender*/, SuspendingEventArgs^ /*e*/)
/// </summary>
/// <param name="sender">The Frame which failed navigation</param>
/// <param name="e">Details about the navigation failure</param>
void App::OnNavigationFailed(Platform::Object^ sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs^ e)
{
void App::OnNavigationFailed(Platform::Object^ sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs^ e) {
throw ref new FailureException("Failed to load Page " + e->SourcePageType.Name);
}
}

0 comments on commit 1a99852

Please sign in to comment.