Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

droid: remove the stateful life-cycle manager #2278

Merged
merged 2 commits into from
Mar 1, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 0 additions & 26 deletions xbmc/android/activity/EventLoop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,28 +63,6 @@ void CEventLoop::run(IActivityHandler &activityHandler, IInputHandler &inputHand
}
}

void CEventLoop::activate()
{
if (m_enabled || m_application->window == NULL)
return;

m_enabled = true;
if (m_activityHandler->onActivate() != ActivityOK)
{
CXBMCApp::android_printf("CEventLoop: IActivityHandler::onActivate() failed");
ANativeActivity_finish(m_application->activity);
}
}

void CEventLoop::deactivate()
{
if (!m_enabled)
return;

m_activityHandler->onDeactivate();
m_enabled = false;
}

void CEventLoop::processActivity(int32_t command)
{
switch (command)
Expand All @@ -109,17 +87,14 @@ void CEventLoop::processActivity(int32_t command)
case APP_CMD_TERM_WINDOW:
// The window is being hidden or closed, clean it up.
m_activityHandler->onDestroyWindow();
deactivate();
break;

case APP_CMD_GAINED_FOCUS:
activate();
m_activityHandler->onGainFocus();
break;

case APP_CMD_LOST_FOCUS:
m_activityHandler->onLostFocus();
deactivate();
break;

case APP_CMD_LOW_MEMORY:
Expand All @@ -141,7 +116,6 @@ void CEventLoop::processActivity(int32_t command)

case APP_CMD_PAUSE:
m_activityHandler->onPause();
deactivate();
break;

case APP_CMD_STOP:
Expand Down
2 changes: 0 additions & 2 deletions xbmc/android/activity/IActivityHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ typedef enum
class IActivityHandler
{
public:
virtual ActivityResult onActivate() = 0;
virtual void onDeactivate() = 0;

virtual void onStart() {}
virtual void onResume() {}
Expand Down
228 changes: 75 additions & 153 deletions xbmc/android/activity/XBMCApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,178 +63,138 @@ CXBMCApp::CXBMCApp(ANativeActivity *nativeActivity)
: m_wakeLock(NULL)
{
m_activity = nativeActivity;

m_firstrun = true;
m_exiting=false;
if (m_activity == NULL)
{
android_printf("CXBMCApp: invalid ANativeActivity instance");
exit(1);
return;
}

m_state.appState = Uninitialized;

if (pthread_mutex_init(&m_state.mutex, NULL) != 0)
{
android_printf("CXBMCApp: pthread_mutex_init() failed");
m_state.appState = Error;
exit(1);
return;
}

}

CXBMCApp::~CXBMCApp()
{
stop();

pthread_mutex_destroy(&m_state.mutex);
}

ActivityResult CXBMCApp::onActivate()
void CXBMCApp::onStart()
{
android_printf("%s: %d", __PRETTY_FUNCTION__, m_state.appState);

switch (m_state.appState)
android_printf("%s: ", __PRETTY_FUNCTION__);
if (!m_firstrun)
{
case Uninitialized:
acquireWakeLock();

pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&m_state.thread, &attr, thread_run<CXBMCApp, &CXBMCApp::run>, this);
pthread_attr_destroy(&attr);
break;

case Unfocused:
XBMC_Pause(false);
setAppState(Rendering);
break;

case Paused:
acquireWakeLock();

XBMC_SetupDisplay();
XBMC_Pause(false);
setAppState(Rendering);
break;

case Initialized:
case Rendering:
case Stopping:
case Stopped:
case Error:
default:
break;
android_printf("%s: Already running, ignoring request to start", __PRETTY_FUNCTION__);
return;
}
return ActivityOK;
}

void CXBMCApp::onDeactivate()
{
android_printf("%s: %d", __PRETTY_FUNCTION__, m_state.appState);
// this is called on pause, stop and window destroy which
// require specific (and different) actions
}

void CXBMCApp::onStart()
{
android_printf("%s: %d", __PRETTY_FUNCTION__, m_state.appState);
// wait for onCreateWindow() and onGainFocus()
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&m_thread, &attr, thread_run<CXBMCApp, &CXBMCApp::run>, this);
pthread_attr_destroy(&attr);
}

void CXBMCApp::onResume()
{
android_printf("%s: %d", __PRETTY_FUNCTION__, m_state.appState);
// wait for onCreateWindow() and onGainFocus()
android_printf("%s: ", __PRETTY_FUNCTION__);
}

void CXBMCApp::onPause()
{
android_printf("%s: %d", __PRETTY_FUNCTION__, m_state.appState);
// wait for onDestroyWindow() and/or onLostFocus()
android_printf("%s: ", __PRETTY_FUNCTION__);
}

void CXBMCApp::onStop()
{
android_printf("%s: %d", __PRETTY_FUNCTION__, m_state.appState);
// everything has been handled in onLostFocus() so wait
// if onDestroy() is called
android_printf("%s: ", __PRETTY_FUNCTION__);
}

void CXBMCApp::onDestroy()
{
android_printf("%s: %d", __PRETTY_FUNCTION__, m_state.appState);
stop();
android_printf("%s", __PRETTY_FUNCTION__);

// If android is forcing us to stop, ask XBMC to exit then wait until it's
// been destroyed.
if (!m_exiting)
{
XBMC_Stop();
pthread_join(m_thread, NULL);
android_printf(" => XBMC finished");
}

if (m_wakeLock != NULL && m_activity != NULL)
{
JNIEnv *env = NULL;
m_activity->vm->AttachCurrentThread(&env, NULL);

env->DeleteGlobalRef(m_wakeLock);
DetachCurrentThread();
m_wakeLock = NULL;
}

This comment was marked as spam.

}

void CXBMCApp::onSaveState(void **data, size_t *size)
{
android_printf("%s: %d", __PRETTY_FUNCTION__, m_state.appState);
android_printf("%s: ", __PRETTY_FUNCTION__);
// no need to save anything as XBMC is running in its own thread
}

void CXBMCApp::onConfigurationChanged()
{
android_printf("%s: %d", __PRETTY_FUNCTION__, m_state.appState);
android_printf("%s: ", __PRETTY_FUNCTION__);
// ignore any configuration changes like screen rotation etc
}

void CXBMCApp::onLowMemory()
{
android_printf("%s: %d", __PRETTY_FUNCTION__, m_state.appState);
android_printf("%s: ", __PRETTY_FUNCTION__);
// can't do much as we don't want to close completely
}

void CXBMCApp::onCreateWindow(ANativeWindow* window)
{
android_printf("%s: %d", __PRETTY_FUNCTION__, m_state.appState);
android_printf("%s: ", __PRETTY_FUNCTION__);
if (window == NULL)
{
android_printf(" => invalid ANativeWindow object");
return;
}
m_window = window;
acquireWakeLock();
if(!m_firstrun)
{
XBMC_SetupDisplay();
XBMC_Pause(false);
}
}

void CXBMCApp::onResizeWindow()
{
android_printf("%s: %d", __PRETTY_FUNCTION__, m_state.appState);
android_printf("%s: ", __PRETTY_FUNCTION__);
// no need to do anything because we are fixed in fullscreen landscape mode
}

void CXBMCApp::onDestroyWindow()
{
android_printf("%s: %d", __PRETTY_FUNCTION__, m_state.appState);
android_printf("%s: ", __PRETTY_FUNCTION__);

if (m_state.appState < Paused)
// If we have exited XBMC, it no longer exists.
if (!m_exiting)
{
XBMC_DestroyDisplay();
setAppState(Paused);
releaseWakeLock();
XBMC_Pause(true);
}

releaseWakeLock();
m_window=NULL;
}

void CXBMCApp::onGainFocus()
{
android_printf("%s: %d", __PRETTY_FUNCTION__, m_state.appState);
// everything is handled in onActivate()
android_printf("%s: ", __PRETTY_FUNCTION__);
}

void CXBMCApp::onLostFocus()
{
android_printf("%s: %d", __PRETTY_FUNCTION__, m_state.appState);
switch (m_state.appState)
{
case Initialized:
case Rendering:
XBMC_Pause(true);
setAppState(Unfocused);
break;

default:
break;
}
android_printf("%s: ", __PRETTY_FUNCTION__);
}

bool CXBMCApp::getWakeLock(JNIEnv *env)
Expand Down Expand Up @@ -322,69 +282,31 @@ void CXBMCApp::releaseWakeLock()

void CXBMCApp::run()
{
int status = 0;
setAppState(Initialized);

android_printf(" => running XBMC_Run...");
try
{
setAppState(Rendering);
status = XBMC_Run(true);
android_printf(" => XBMC_Run finished with %d", status);
}
catch(...)
{
android_printf("ERROR: Exception caught on main loop. Exiting");
setAppState(Error);
}

bool finishActivity = false;
pthread_mutex_lock(&m_state.mutex);
finishActivity = m_state.appState != Stopping;
m_state.appState = Stopped;
pthread_mutex_unlock(&m_state.mutex);

if (finishActivity)
{
android_printf(" => calling ANativeActivity_finish()");
ANativeActivity_finish(m_activity);
}
}

void CXBMCApp::stop()
{
android_printf("%s", __PRETTY_FUNCTION__);

pthread_mutex_lock(&m_state.mutex);
if (m_state.appState < Stopped)
int status = 0;

android_printf(" => waiting for a window");
// Hack!
// TODO: Change EGL startup so that we can start headless, then create the
// window once android gives us a surface to play with.
while(!m_window)
usleep(1000);
m_firstrun=false;
android_printf(" => running XBMC_Run...");
try
{
m_state.appState = Stopping;
pthread_mutex_unlock(&m_state.mutex);

android_printf(" => executing XBMC_Stop");
XBMC_Stop();
android_printf(" => waiting for XBMC to finish");
pthread_join(m_state.thread, NULL);
android_printf(" => XBMC finished");
status = XBMC_Run(true);
android_printf(" => XBMC_Run finished with %d", status);
}
else
pthread_mutex_unlock(&m_state.mutex);

if (m_wakeLock != NULL && m_activity != NULL)
catch(...)
{
JNIEnv *env = NULL;
m_activity->vm->AttachCurrentThread(&env, NULL);

env->DeleteGlobalRef(m_wakeLock);
m_wakeLock = NULL;
android_printf("ERROR: Exception caught on main loop. Exiting");
}
}

void CXBMCApp::setAppState(AppState state)
{
pthread_mutex_lock(&m_state.mutex);
m_state.appState = state;
pthread_mutex_unlock(&m_state.mutex);
// If we are have not been force by Android to exit, notify its finish routine.
// This will cause android to run through its teardown events, it calls:
// onPause(), onLostFocus(), onDestroyWindow(), onStop(), onDestroy().
ANativeActivity_finish(m_activity);
m_exiting=true;
}

void CXBMCApp::XBMC_Pause(bool pause)
Expand Down
Loading