1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program Tester Core 3e5c31af7Sopenharmony_ci * ---------------------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief iOS App Wrapper. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "tcuIOSApp.h" 25e5c31af7Sopenharmony_ci#include "tcuIOSPlatform.hh" 26e5c31af7Sopenharmony_ci#include "tcuApp.hpp" 27e5c31af7Sopenharmony_ci#include "tcuCommandLine.hpp" 28e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp" 29e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 30e5c31af7Sopenharmony_ci#include "tcuResource.hpp" 31e5c31af7Sopenharmony_ci#include "deThread.hpp" 32e5c31af7Sopenharmony_ci#include "deMutex.hpp" 33e5c31af7Sopenharmony_ci#include "xsExecutionServer.hpp" 34e5c31af7Sopenharmony_ci#include "xsTestProcess.hpp" 35e5c31af7Sopenharmony_ci#include "xsPosixFileReader.hpp" 36e5c31af7Sopenharmony_ci#include "deFilePath.hpp" 37e5c31af7Sopenharmony_ci#include "deClock.h" 38e5c31af7Sopenharmony_ci#include "deMemory.h" 39e5c31af7Sopenharmony_ci 40e5c31af7Sopenharmony_ci#include <string> 41e5c31af7Sopenharmony_ci 42e5c31af7Sopenharmony_ci#import <Foundation/NSObject.h> 43e5c31af7Sopenharmony_ci#import <Foundation/NSString.h> 44e5c31af7Sopenharmony_ci#import <Foundation/NSBundle.h> 45e5c31af7Sopenharmony_ci#import <Foundation/NSPathUtilities.h> 46e5c31af7Sopenharmony_ci 47e5c31af7Sopenharmony_ciusing std::string; 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_cinamespace 50e5c31af7Sopenharmony_ci{ 51e5c31af7Sopenharmony_ci 52e5c31af7Sopenharmony_ciclass TestThreadState 53e5c31af7Sopenharmony_ci{ 54e5c31af7Sopenharmony_cipublic: 55e5c31af7Sopenharmony_ci enum State 56e5c31af7Sopenharmony_ci { 57e5c31af7Sopenharmony_ci STATE_NOT_RUNNING = 0, 58e5c31af7Sopenharmony_ci STATE_RUNNING, 59e5c31af7Sopenharmony_ci STATE_STOP_REQUESTED, 60e5c31af7Sopenharmony_ci 61e5c31af7Sopenharmony_ci STATE_LAST 62e5c31af7Sopenharmony_ci }; 63e5c31af7Sopenharmony_ci 64e5c31af7Sopenharmony_ci TestThreadState (void); 65e5c31af7Sopenharmony_ci ~TestThreadState (void); 66e5c31af7Sopenharmony_ci 67e5c31af7Sopenharmony_ci void requestStart (const char* cmdLine); 68e5c31af7Sopenharmony_ci void requestStop (void); 69e5c31af7Sopenharmony_ci State getState (void); 70e5c31af7Sopenharmony_ci 71e5c31af7Sopenharmony_ci void testExecFinished (void); 72e5c31af7Sopenharmony_ci 73e5c31af7Sopenharmony_ci const char* getCommandLine (void) const { return m_cmdLine.c_str(); } 74e5c31af7Sopenharmony_ci 75e5c31af7Sopenharmony_ciprivate: 76e5c31af7Sopenharmony_ci de::Mutex m_lock; 77e5c31af7Sopenharmony_ci 78e5c31af7Sopenharmony_ci State m_state; 79e5c31af7Sopenharmony_ci std::string m_cmdLine; 80e5c31af7Sopenharmony_ci}; 81e5c31af7Sopenharmony_ci 82e5c31af7Sopenharmony_ciTestThreadState::TestThreadState (void) 83e5c31af7Sopenharmony_ci : m_state(STATE_NOT_RUNNING) 84e5c31af7Sopenharmony_ci{ 85e5c31af7Sopenharmony_ci} 86e5c31af7Sopenharmony_ci 87e5c31af7Sopenharmony_ciTestThreadState::~TestThreadState (void) 88e5c31af7Sopenharmony_ci{ 89e5c31af7Sopenharmony_ci} 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_civoid TestThreadState::requestStart (const char* cmdLine) 92e5c31af7Sopenharmony_ci{ 93e5c31af7Sopenharmony_ci de::ScopedLock stateLock(m_lock); 94e5c31af7Sopenharmony_ci 95e5c31af7Sopenharmony_ci TCU_CHECK(m_state == STATE_NOT_RUNNING); 96e5c31af7Sopenharmony_ci 97e5c31af7Sopenharmony_ci m_cmdLine = cmdLine; 98e5c31af7Sopenharmony_ci m_state = STATE_RUNNING; 99e5c31af7Sopenharmony_ci} 100e5c31af7Sopenharmony_ci 101e5c31af7Sopenharmony_civoid TestThreadState::requestStop (void) 102e5c31af7Sopenharmony_ci{ 103e5c31af7Sopenharmony_ci de::ScopedLock stateLock(m_lock); 104e5c31af7Sopenharmony_ci 105e5c31af7Sopenharmony_ci if (m_state != STATE_NOT_RUNNING) 106e5c31af7Sopenharmony_ci m_state = STATE_STOP_REQUESTED; 107e5c31af7Sopenharmony_ci} 108e5c31af7Sopenharmony_ci 109e5c31af7Sopenharmony_civoid TestThreadState::testExecFinished (void) 110e5c31af7Sopenharmony_ci{ 111e5c31af7Sopenharmony_ci de::ScopedLock stateLock(m_lock); 112e5c31af7Sopenharmony_ci m_state = STATE_NOT_RUNNING; 113e5c31af7Sopenharmony_ci} 114e5c31af7Sopenharmony_ci 115e5c31af7Sopenharmony_ciTestThreadState::State TestThreadState::getState (void) 116e5c31af7Sopenharmony_ci{ 117e5c31af7Sopenharmony_ci de::ScopedLock stateLock(m_lock); 118e5c31af7Sopenharmony_ci return m_state; 119e5c31af7Sopenharmony_ci} 120e5c31af7Sopenharmony_ci 121e5c31af7Sopenharmony_ciclass LocalTestProcess : public xs::TestProcess 122e5c31af7Sopenharmony_ci{ 123e5c31af7Sopenharmony_cipublic: 124e5c31af7Sopenharmony_ci LocalTestProcess (TestThreadState& state, const char* logFileName); 125e5c31af7Sopenharmony_ci ~LocalTestProcess (void); 126e5c31af7Sopenharmony_ci 127e5c31af7Sopenharmony_ci void start (const char* name, const char* params, const char* workingDir, const char* caseList); 128e5c31af7Sopenharmony_ci void terminate (void); 129e5c31af7Sopenharmony_ci void cleanup (void); 130e5c31af7Sopenharmony_ci 131e5c31af7Sopenharmony_ci bool isRunning (void); 132e5c31af7Sopenharmony_ci int getExitCode (void) const { return 0; /* not available */ } 133e5c31af7Sopenharmony_ci 134e5c31af7Sopenharmony_ci int readInfoLog (deUint8* dst, int numBytes) { DE_UNREF(dst && numBytes); return 0; /* not supported */ } 135e5c31af7Sopenharmony_ci int readTestLog (deUint8* dst, int numBytes); 136e5c31af7Sopenharmony_ci 137e5c31af7Sopenharmony_ci const char* getLogFileName (void) const { return m_logFileName.c_str(); } 138e5c31af7Sopenharmony_ci 139e5c31af7Sopenharmony_ciprivate: 140e5c31af7Sopenharmony_ci TestThreadState& m_state; 141e5c31af7Sopenharmony_ci string m_logFileName; 142e5c31af7Sopenharmony_ci xs::posix::FileReader m_logReader; 143e5c31af7Sopenharmony_ci deUint64 m_processStartTime; 144e5c31af7Sopenharmony_ci}; 145e5c31af7Sopenharmony_ci 146e5c31af7Sopenharmony_ciLocalTestProcess::LocalTestProcess (TestThreadState& state, const char* logFileName) 147e5c31af7Sopenharmony_ci : m_state (state) 148e5c31af7Sopenharmony_ci , m_logFileName (logFileName) 149e5c31af7Sopenharmony_ci , m_logReader (xs::LOG_BUFFER_BLOCK_SIZE, xs::LOG_BUFFER_NUM_BLOCKS) 150e5c31af7Sopenharmony_ci , m_processStartTime (0) 151e5c31af7Sopenharmony_ci{ 152e5c31af7Sopenharmony_ci} 153e5c31af7Sopenharmony_ci 154e5c31af7Sopenharmony_ciLocalTestProcess::~LocalTestProcess (void) 155e5c31af7Sopenharmony_ci{ 156e5c31af7Sopenharmony_ci} 157e5c31af7Sopenharmony_ci 158e5c31af7Sopenharmony_civoid LocalTestProcess::start (const char* name, const char* params, const char* workingDir, const char* caseList) 159e5c31af7Sopenharmony_ci{ 160e5c31af7Sopenharmony_ci DE_UNREF(name && workingDir); 161e5c31af7Sopenharmony_ci 162e5c31af7Sopenharmony_ci // Delete old log file. 163e5c31af7Sopenharmony_ci if (deFileExists(m_logFileName.c_str())) 164e5c31af7Sopenharmony_ci TCU_CHECK(deDeleteFile(m_logFileName.c_str())); 165e5c31af7Sopenharmony_ci 166e5c31af7Sopenharmony_ci string cmdLine = string("deqp"); 167e5c31af7Sopenharmony_ci if (caseList && strlen(caseList) > 0) 168e5c31af7Sopenharmony_ci cmdLine += string(" --deqp-caselist=") + caseList; 169e5c31af7Sopenharmony_ci 170e5c31af7Sopenharmony_ci if (params && strlen(params) > 0) 171e5c31af7Sopenharmony_ci cmdLine += string(" ") + params; 172e5c31af7Sopenharmony_ci 173e5c31af7Sopenharmony_ci m_state.requestStart(cmdLine.c_str()); 174e5c31af7Sopenharmony_ci m_processStartTime = deGetMicroseconds(); 175e5c31af7Sopenharmony_ci} 176e5c31af7Sopenharmony_ci 177e5c31af7Sopenharmony_civoid LocalTestProcess::terminate (void) 178e5c31af7Sopenharmony_ci{ 179e5c31af7Sopenharmony_ci m_state.requestStop(); 180e5c31af7Sopenharmony_ci} 181e5c31af7Sopenharmony_ci 182e5c31af7Sopenharmony_civoid LocalTestProcess::cleanup (void) 183e5c31af7Sopenharmony_ci{ 184e5c31af7Sopenharmony_ci if (isRunning()) 185e5c31af7Sopenharmony_ci { 186e5c31af7Sopenharmony_ci m_state.requestStop(); 187e5c31af7Sopenharmony_ci 188e5c31af7Sopenharmony_ci // Wait until stopped. 189e5c31af7Sopenharmony_ci while (isRunning()) 190e5c31af7Sopenharmony_ci deSleep(50); 191e5c31af7Sopenharmony_ci } 192e5c31af7Sopenharmony_ci 193e5c31af7Sopenharmony_ci m_logReader.stop(); 194e5c31af7Sopenharmony_ci} 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_cibool LocalTestProcess::isRunning (void) 197e5c31af7Sopenharmony_ci{ 198e5c31af7Sopenharmony_ci return m_state.getState() != TestThreadState::STATE_NOT_RUNNING; 199e5c31af7Sopenharmony_ci} 200e5c31af7Sopenharmony_ci 201e5c31af7Sopenharmony_ciint LocalTestProcess::readTestLog (deUint8* dst, int numBytes) 202e5c31af7Sopenharmony_ci{ 203e5c31af7Sopenharmony_ci if (!m_logReader.isRunning()) 204e5c31af7Sopenharmony_ci { 205e5c31af7Sopenharmony_ci if (deGetMicroseconds() - m_processStartTime > xs::LOG_FILE_TIMEOUT*1000) 206e5c31af7Sopenharmony_ci { 207e5c31af7Sopenharmony_ci // Timeout, kill execution. 208e5c31af7Sopenharmony_ci terminate(); 209e5c31af7Sopenharmony_ci return 0; // \todo [2013-08-13 pyry] Throw exception? 210e5c31af7Sopenharmony_ci } 211e5c31af7Sopenharmony_ci 212e5c31af7Sopenharmony_ci if (!deFileExists(m_logFileName.c_str())) 213e5c31af7Sopenharmony_ci return 0; 214e5c31af7Sopenharmony_ci 215e5c31af7Sopenharmony_ci // Start reader. 216e5c31af7Sopenharmony_ci m_logReader.start(m_logFileName.c_str()); 217e5c31af7Sopenharmony_ci } 218e5c31af7Sopenharmony_ci 219e5c31af7Sopenharmony_ci DE_ASSERT(m_logReader.isRunning()); 220e5c31af7Sopenharmony_ci return m_logReader.read(dst, numBytes); 221e5c31af7Sopenharmony_ci} 222e5c31af7Sopenharmony_ci 223e5c31af7Sopenharmony_ciclass ServerThread : public de::Thread 224e5c31af7Sopenharmony_ci{ 225e5c31af7Sopenharmony_cipublic: 226e5c31af7Sopenharmony_ci ServerThread (xs::TestProcess* testProcess, int port); 227e5c31af7Sopenharmony_ci ~ServerThread (void); 228e5c31af7Sopenharmony_ci 229e5c31af7Sopenharmony_ci void run (void); 230e5c31af7Sopenharmony_ci void stop (void); 231e5c31af7Sopenharmony_ci 232e5c31af7Sopenharmony_ciprivate: 233e5c31af7Sopenharmony_ci xs::ExecutionServer m_server; 234e5c31af7Sopenharmony_ci bool m_isRunning; 235e5c31af7Sopenharmony_ci}; 236e5c31af7Sopenharmony_ci 237e5c31af7Sopenharmony_ciServerThread::ServerThread (xs::TestProcess* testProcess, int port) 238e5c31af7Sopenharmony_ci : m_server (testProcess, DE_SOCKETFAMILY_INET4, port, xs::ExecutionServer::RUNMODE_FOREVER) 239e5c31af7Sopenharmony_ci , m_isRunning (false) 240e5c31af7Sopenharmony_ci{ 241e5c31af7Sopenharmony_ci} 242e5c31af7Sopenharmony_ci 243e5c31af7Sopenharmony_ciServerThread::~ServerThread (void) 244e5c31af7Sopenharmony_ci{ 245e5c31af7Sopenharmony_ci stop(); 246e5c31af7Sopenharmony_ci} 247e5c31af7Sopenharmony_ci 248e5c31af7Sopenharmony_civoid ServerThread::run (void) 249e5c31af7Sopenharmony_ci{ 250e5c31af7Sopenharmony_ci m_isRunning = true; 251e5c31af7Sopenharmony_ci m_server.runServer(); 252e5c31af7Sopenharmony_ci} 253e5c31af7Sopenharmony_ci 254e5c31af7Sopenharmony_civoid ServerThread::stop (void) 255e5c31af7Sopenharmony_ci{ 256e5c31af7Sopenharmony_ci if (m_isRunning) 257e5c31af7Sopenharmony_ci { 258e5c31af7Sopenharmony_ci m_server.stopServer(); 259e5c31af7Sopenharmony_ci join(); 260e5c31af7Sopenharmony_ci m_isRunning = false; 261e5c31af7Sopenharmony_ci } 262e5c31af7Sopenharmony_ci} 263e5c31af7Sopenharmony_ci 264e5c31af7Sopenharmony_cistring getAppBundleDir (void) 265e5c31af7Sopenharmony_ci{ 266e5c31af7Sopenharmony_ci NSString* dataPath = [[NSBundle mainBundle] bundlePath]; 267e5c31af7Sopenharmony_ci const char* utf8Str = [dataPath UTF8String]; 268e5c31af7Sopenharmony_ci 269e5c31af7Sopenharmony_ci return string(utf8Str); 270e5c31af7Sopenharmony_ci} 271e5c31af7Sopenharmony_ci 272e5c31af7Sopenharmony_cistring getAppDocumentsDir (void) 273e5c31af7Sopenharmony_ci{ 274e5c31af7Sopenharmony_ci NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 275e5c31af7Sopenharmony_ci NSString* docPath = [paths objectAtIndex:0]; 276e5c31af7Sopenharmony_ci const char* utf8Str = [docPath UTF8String]; 277e5c31af7Sopenharmony_ci 278e5c31af7Sopenharmony_ci return string(utf8Str); 279e5c31af7Sopenharmony_ci} 280e5c31af7Sopenharmony_ci 281e5c31af7Sopenharmony_ci} // anonymous 282e5c31af7Sopenharmony_ci 283e5c31af7Sopenharmony_cistruct tcuIOSApp_s 284e5c31af7Sopenharmony_ci{ 285e5c31af7Sopenharmony_cipublic: 286e5c31af7Sopenharmony_ci tcuIOSApp_s (void* view); 287e5c31af7Sopenharmony_ci ~tcuIOSApp_s (void); 288e5c31af7Sopenharmony_ci 289e5c31af7Sopenharmony_ci void iterate (void); 290e5c31af7Sopenharmony_ci 291e5c31af7Sopenharmony_ciprotected: 292e5c31af7Sopenharmony_ci void createTestApp (void); 293e5c31af7Sopenharmony_ci void destroyTestApp (void); 294e5c31af7Sopenharmony_ci 295e5c31af7Sopenharmony_ci TestThreadState m_state; 296e5c31af7Sopenharmony_ci LocalTestProcess m_testProcess; 297e5c31af7Sopenharmony_ci ServerThread m_server; 298e5c31af7Sopenharmony_ci 299e5c31af7Sopenharmony_ci tcu::DirArchive m_archive; 300e5c31af7Sopenharmony_ci tcu::ios::ScreenManager m_screenManager; 301e5c31af7Sopenharmony_ci tcu::ios::Platform m_platform; 302e5c31af7Sopenharmony_ci 303e5c31af7Sopenharmony_ci tcu::TestLog* m_log; 304e5c31af7Sopenharmony_ci tcu::CommandLine* m_cmdLine; 305e5c31af7Sopenharmony_ci tcu::App* m_app; 306e5c31af7Sopenharmony_ci}; 307e5c31af7Sopenharmony_ci 308e5c31af7Sopenharmony_citcuIOSApp_s::tcuIOSApp_s (void* view) 309e5c31af7Sopenharmony_ci : m_testProcess (m_state, de::FilePath::join(getAppDocumentsDir(), "TestResults.qpa").getPath()) 310e5c31af7Sopenharmony_ci , m_server (&m_testProcess, 50016) 311e5c31af7Sopenharmony_ci , m_archive (getAppBundleDir().c_str()) 312e5c31af7Sopenharmony_ci , m_screenManager ((tcuEAGLView*)view) 313e5c31af7Sopenharmony_ci , m_platform (&m_screenManager) 314e5c31af7Sopenharmony_ci , m_log (DE_NULL) 315e5c31af7Sopenharmony_ci , m_cmdLine (DE_NULL) 316e5c31af7Sopenharmony_ci , m_app (DE_NULL) 317e5c31af7Sopenharmony_ci{ 318e5c31af7Sopenharmony_ci // Start server. 319e5c31af7Sopenharmony_ci m_server.start(); 320e5c31af7Sopenharmony_ci} 321e5c31af7Sopenharmony_ci 322e5c31af7Sopenharmony_citcuIOSApp_s::~tcuIOSApp_s (void) 323e5c31af7Sopenharmony_ci{ 324e5c31af7Sopenharmony_ci m_server.stop(); 325e5c31af7Sopenharmony_ci destroyTestApp(); 326e5c31af7Sopenharmony_ci} 327e5c31af7Sopenharmony_ci 328e5c31af7Sopenharmony_civoid tcuIOSApp::createTestApp (void) 329e5c31af7Sopenharmony_ci{ 330e5c31af7Sopenharmony_ci DE_ASSERT(!m_app && !m_log && !m_cmdLine && !m_platform); 331e5c31af7Sopenharmony_ci 332e5c31af7Sopenharmony_ci try 333e5c31af7Sopenharmony_ci { 334e5c31af7Sopenharmony_ci m_log = new tcu::TestLog(m_testProcess.getLogFileName()); 335e5c31af7Sopenharmony_ci m_cmdLine = new tcu::CommandLine(m_state.getCommandLine()); 336e5c31af7Sopenharmony_ci m_app = new tcu::App(m_platform, m_archive, *m_log, *m_cmdLine); 337e5c31af7Sopenharmony_ci } 338e5c31af7Sopenharmony_ci catch (const std::exception& e) 339e5c31af7Sopenharmony_ci { 340e5c31af7Sopenharmony_ci destroyTestApp(); 341e5c31af7Sopenharmony_ci tcu::die("%s", e.what()); 342e5c31af7Sopenharmony_ci } 343e5c31af7Sopenharmony_ci} 344e5c31af7Sopenharmony_ci 345e5c31af7Sopenharmony_civoid tcuIOSApp::destroyTestApp (void) 346e5c31af7Sopenharmony_ci{ 347e5c31af7Sopenharmony_ci delete m_app; 348e5c31af7Sopenharmony_ci delete m_cmdLine; 349e5c31af7Sopenharmony_ci delete m_log; 350e5c31af7Sopenharmony_ci m_app = DE_NULL; 351e5c31af7Sopenharmony_ci m_cmdLine = DE_NULL; 352e5c31af7Sopenharmony_ci m_log = DE_NULL; 353e5c31af7Sopenharmony_ci} 354e5c31af7Sopenharmony_ci 355e5c31af7Sopenharmony_civoid tcuIOSApp::iterate (void) 356e5c31af7Sopenharmony_ci{ 357e5c31af7Sopenharmony_ci TestThreadState::State curState = m_state.getState(); 358e5c31af7Sopenharmony_ci 359e5c31af7Sopenharmony_ci if (curState == TestThreadState::STATE_RUNNING) 360e5c31af7Sopenharmony_ci { 361e5c31af7Sopenharmony_ci if (!m_app) 362e5c31af7Sopenharmony_ci createTestApp(); 363e5c31af7Sopenharmony_ci 364e5c31af7Sopenharmony_ci TCU_CHECK(m_app); 365e5c31af7Sopenharmony_ci 366e5c31af7Sopenharmony_ci if (!m_app->iterate()) 367e5c31af7Sopenharmony_ci { 368e5c31af7Sopenharmony_ci destroyTestApp(); 369e5c31af7Sopenharmony_ci m_state.testExecFinished(); 370e5c31af7Sopenharmony_ci } 371e5c31af7Sopenharmony_ci } 372e5c31af7Sopenharmony_ci else if (curState == TestThreadState::STATE_STOP_REQUESTED) 373e5c31af7Sopenharmony_ci { 374e5c31af7Sopenharmony_ci destroyTestApp(); 375e5c31af7Sopenharmony_ci m_state.testExecFinished(); 376e5c31af7Sopenharmony_ci } 377e5c31af7Sopenharmony_ci // else wait until state has changed? 378e5c31af7Sopenharmony_ci} 379e5c31af7Sopenharmony_ci 380e5c31af7Sopenharmony_citcuIOSApp* tcuIOSApp_create (void* view) 381e5c31af7Sopenharmony_ci{ 382e5c31af7Sopenharmony_ci try 383e5c31af7Sopenharmony_ci { 384e5c31af7Sopenharmony_ci return new tcuIOSApp(view); 385e5c31af7Sopenharmony_ci } 386e5c31af7Sopenharmony_ci catch (const std::exception& e) 387e5c31af7Sopenharmony_ci { 388e5c31af7Sopenharmony_ci tcu::die("FATAL ERROR: %s", e.what()); 389e5c31af7Sopenharmony_ci return DE_NULL; 390e5c31af7Sopenharmony_ci } 391e5c31af7Sopenharmony_ci} 392e5c31af7Sopenharmony_ci 393e5c31af7Sopenharmony_civoid tcuIOSApp_destroy (tcuIOSApp* app) 394e5c31af7Sopenharmony_ci{ 395e5c31af7Sopenharmony_ci delete app; 396e5c31af7Sopenharmony_ci} 397e5c31af7Sopenharmony_ci 398e5c31af7Sopenharmony_cideBool tcuIOSApp_iterate (tcuIOSApp* app) 399e5c31af7Sopenharmony_ci{ 400e5c31af7Sopenharmony_ci try 401e5c31af7Sopenharmony_ci { 402e5c31af7Sopenharmony_ci app->iterate(); 403e5c31af7Sopenharmony_ci return DE_TRUE; 404e5c31af7Sopenharmony_ci } 405e5c31af7Sopenharmony_ci catch (const std::exception& e) 406e5c31af7Sopenharmony_ci { 407e5c31af7Sopenharmony_ci tcu::print("FATAL ERROR: %s\n", e.what()); 408e5c31af7Sopenharmony_ci return DE_FALSE; 409e5c31af7Sopenharmony_ci } 410e5c31af7Sopenharmony_ci} 411