From 497fb4fda9d99d3b8db36d90e9d6657b072498e3 Mon Sep 17 00:00:00 2001 From: "phoglund@webrtc.org" Date: Thu, 26 Apr 2012 12:58:02 +0000 Subject: [PATCH] Fixed vie_auto_test on mac so it will exit when the test completes instead of hanging like it used to. Also applied an old patch I had which rewrites the window handling to do ui stuff on the main thread instead of the worker thread, which as far as I know is a very bad idea. BUG= TEST= Review URL: https://webrtc-codereview.appspot.com/502001 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2126 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../interface/vie_autotest_mac_cocoa.h | 49 +++-- .../auto_test/interface/vie_autotest_main.h | 4 +- .../source/vie_autotest_cocoa_mac.mm | 167 ++++++++++++------ .../auto_test/source/vie_autotest_main.cc | 7 +- 4 files changed, 160 insertions(+), 67 deletions(-) diff --git a/src/video_engine/test/auto_test/interface/vie_autotest_mac_cocoa.h b/src/video_engine/test/auto_test/interface/vie_autotest_mac_cocoa.h index 745431d5a9..dc1a6cd3ce 100644 --- a/src/video_engine/test/auto_test/interface/vie_autotest_mac_cocoa.h +++ b/src/video_engine/test/auto_test/interface/vie_autotest_mac_cocoa.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -16,16 +16,43 @@ #define WEBRTC_VIDEO_ENGINE_MAIN_TEST_AUTOTEST_INTERFACE_VIE_AUTOTEST_MAC_COCOA_H_ #include "vie_autotest_window_manager_interface.h" -#define MAC_COCOA_USE_NSRUNLOOP 1 @class CocoaRenderView; #import +@interface TestCocoaUi : NSObject { + CocoaRenderView* cocoaRenderView1_; + CocoaRenderView* cocoaRenderView2_; + NSWindow* window1_; + NSWindow* window2_; + + AutoTestRect window1Size_; + AutoTestRect window2Size_; + void* window1Title_; + void* window2Title_; +} + +// Must be called as a selector in the main thread. +- (void)createWindows:(NSObject*)ignored; + +// Used to transfer parameters from background thread. +- (void)prepareToCreateWindowsWithSize:(AutoTestRect)window1Size + andSize:(AutoTestRect)window2Size + withTitle:(void*)window1Title + andTitle:(void*)window2Title; + +- (NSWindow*)window1; +- (NSWindow*)window2; +- (CocoaRenderView*)cocoaRenderView1; +- (CocoaRenderView*)cocoaRenderView2; + +@end + class ViEAutoTestWindowManager: public ViEAutoTestWindowManagerInterface { public: ViEAutoTestWindowManager(); - virtual ~ViEAutoTestWindowManager() {} + virtual ~ViEAutoTestWindowManager(); virtual void* GetWindow1(); virtual void* GetWindow2(); virtual int CreateWindows(AutoTestRect window1Size, @@ -36,21 +63,21 @@ class ViEAutoTestWindowManager: public ViEAutoTestWindowManagerInterface { virtual bool SetTopmostWindow(); private: - CocoaRenderView* _cocoaRenderView1; - CocoaRenderView* _cocoaRenderView2; - NSWindow* outWindow1_; - NSWindow* outWindow2_; + TestCocoaUi* cocoa_ui_; }; -@interface AutoTestClass : NSObject { +@interface AutoTestInWorkerThread : NSObject { int argc_; char** argv_; int result_; + bool done_; } --(void)setArgc:(int)argc argv:(char**)argv; --(int) result; --(void)autoTestWithArg:(NSObject*)ignored; +- (void)setDone:(bool)done; +- (bool)done; +- (void)setArgc:(int)argc argv:(char**)argv; +- (int) result; +- (void)autoTestWithArg:(NSObject*)ignored; @end diff --git a/src/video_engine/test/auto_test/interface/vie_autotest_main.h b/src/video_engine/test/auto_test/interface/vie_autotest_main.h index d24de5c171..68d0079f39 100644 --- a/src/video_engine/test/auto_test/interface/vie_autotest_main.h +++ b/src/video_engine/test/auto_test/interface/vie_autotest_main.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -29,7 +29,7 @@ class ViEAutoTestMain { static const int kInvalidChoice = -1; // Starts interactive mode. - bool RunInteractiveMode(); + int RunInteractiveMode(); // Prompts the user for a specific test method in the provided test case. // Returns 0 on success, nonzero otherwise. int RunSpecificTestCaseIn(const std::string test_case_name); diff --git a/src/video_engine/test/auto_test/source/vie_autotest_cocoa_mac.mm b/src/video_engine/test/auto_test/source/vie_autotest_cocoa_mac.mm index 3f9ef6bccb..38b813c02f 100644 --- a/src/video_engine/test/auto_test/source/vie_autotest_cocoa_mac.mm +++ b/src/video_engine/test/auto_test/source/vie_autotest_cocoa_mac.mm @@ -17,61 +17,114 @@ #include "vie_autotest.h" #include "vie_autotest_main.h" -ViEAutoTestWindowManager::ViEAutoTestWindowManager() - : _cocoaRenderView1(nil), _cocoaRenderView2(nil) { +@implementation TestCocoaUi + +// TODO(phoglund): This file probably leaks memory like crazy. Find someone +// who understands objective-c memory management and fix it. + +- (void)prepareToCreateWindowsWithSize:(AutoTestRect)window1Size + andSize:(AutoTestRect)window2Size + withTitle:(void*)window1_title + andTitle:(void*)window2_title { + window1Size_ = window1Size; + window2Size_ = window2Size; + window1Title_ = window1_title; + window2Title_ = window2_title; +} + +- (void)createWindows:(NSObject*)ignored { + NSRect window1Frame = NSMakeRect( + window1Size_.origin.x, window1Size_.origin.y, + window1Size_.size.width, window1Size_.size.height); + + window1_ = [[NSWindow alloc] + initWithContentRect:window1Frame + styleMask:NSTitledWindowMask + backing:NSBackingStoreBuffered + defer:NO]; + [window1_ orderOut:nil]; + + NSRect render_view1_frame = NSMakeRect( + 0, 0, window1Size_.size.width, window1Size_.size.height); + cocoaRenderView1_ = + [[CocoaRenderView alloc] initWithFrame:render_view1_frame]; + + [[window1_ contentView] addSubview:(NSView*)cocoaRenderView1_]; + [window1_ setTitle:[NSString stringWithFormat:@"%s", window1Title_]]; + [window1_ makeKeyAndOrderFront:NSApp]; + + NSRect window2_frame = NSMakeRect( + window2Size_.origin.x, window2Size_.origin.y, + window2Size_.size.width, window2Size_.size.height); + + window2_ = [[NSWindow alloc] + initWithContentRect:window2_frame + styleMask:NSTitledWindowMask + backing:NSBackingStoreBuffered + defer:NO]; + [window2_ orderOut:nil]; + + NSRect render_view2_frame = NSMakeRect( + 0, 0, window1Size_.size.width, window1Size_.size.height); + cocoaRenderView2_ = + [[CocoaRenderView alloc] initWithFrame:render_view2_frame]; + [[window2_ contentView] addSubview:(NSView*)cocoaRenderView2_]; + [window2_ setTitle:[NSString stringWithFormat:@"%s", window2Title_]]; + [window2_ makeKeyAndOrderFront:NSApp]; +} + +- (NSWindow*)window1 { + return window1_; +} + +- (NSWindow*)window2 { + return window2_; +} + +- (CocoaRenderView*)cocoaRenderView1 { + return cocoaRenderView1_; +} + +- (CocoaRenderView*)cocoaRenderView2 { + return cocoaRenderView2_; +} + +@end + +ViEAutoTestWindowManager::ViEAutoTestWindowManager() { + cocoa_ui_ = [[TestCocoaUi alloc] init]; +} + +ViEAutoTestWindowManager::~ViEAutoTestWindowManager() { + [cocoa_ui_ release]; } int ViEAutoTestWindowManager::CreateWindows(AutoTestRect window1Size, AutoTestRect window2Size, - void* window1Title, - void* window2Title) { - NSRect outWindow1Frame = NSMakeRect(window1Size.origin.x, - window1Size.origin.y, - window1Size.size.width, - window1Size.size.height); - outWindow1_ = [[NSWindow alloc] initWithContentRect:outWindow1Frame - styleMask:NSTitledWindowMask - backing:NSBackingStoreBuffered defer:NO]; - [outWindow1_ orderOut:nil]; - NSRect cocoaRenderView1Frame = NSMakeRect(0, 0, window1Size.size.width, - window1Size.size.height); - _cocoaRenderView1 = [[CocoaRenderView alloc] - initWithFrame:cocoaRenderView1Frame]; - [[outWindow1_ contentView] addSubview:(NSView*)_cocoaRenderView1]; - [outWindow1_ setTitle:[NSString stringWithFormat:@"%s", window1Title]]; - [outWindow1_ makeKeyAndOrderFront:NSApp]; - - NSRect outWindow2Frame = NSMakeRect(window2Size.origin.x, - window2Size.origin.y, - window2Size.size.width, - window2Size.size.height); - outWindow2_ = [[NSWindow alloc] initWithContentRect:outWindow2Frame - styleMask:NSTitledWindowMask - backing:NSBackingStoreBuffered defer:NO]; - [outWindow2_ orderOut:nil]; - NSRect cocoaRenderView2Frame = NSMakeRect(0, 0, window2Size.size.width, - window2Size.size.height); - _cocoaRenderView2 = [[CocoaRenderView alloc] - initWithFrame:cocoaRenderView2Frame]; - [[outWindow2_ contentView] addSubview:(NSView*)_cocoaRenderView2]; - [outWindow2_ setTitle:[NSString stringWithFormat:@"%s", window2Title]]; - [outWindow2_ makeKeyAndOrderFront:NSApp]; - + void* window1_title, + void* window2_title) { + [cocoa_ui_ prepareToCreateWindowsWithSize:window1Size + andSize:window2Size + withTitle:window1_title + andTitle:window2_title]; + [cocoa_ui_ performSelectorOnMainThread:@selector(createWindows:) + withObject:nil + waitUntilDone:YES]; return 0; } int ViEAutoTestWindowManager::TerminateWindows() { - [outWindow1_ close]; - [outWindow2_ close]; + [[cocoa_ui_ window1] close]; + [[cocoa_ui_ window2] close]; return 0; } void* ViEAutoTestWindowManager::GetWindow1() { - return _cocoaRenderView1; + return [cocoa_ui_ cocoaRenderView1]; } void* ViEAutoTestWindowManager::GetWindow2() { - return _cocoaRenderView2; + return [cocoa_ui_ cocoaRenderView2]; } bool ViEAutoTestWindowManager::SetTopmostWindow() { @@ -84,27 +137,38 @@ int main(int argc, char * argv[]) { [NSApplication sharedApplication]; int result = 0; -#if defined(MAC_COCOA_USE_NSRUNLOOP) - AutoTestClass* tests = [[AutoTestClass alloc] init]; + AutoTestInWorkerThread* tests = [[AutoTestInWorkerThread alloc] init]; [tests setArgc:argc argv:argv]; + [tests setDone:false]; [NSThread detachNewThreadSelector:@selector(autoTestWithArg:) - toTarget:tests withObject:nil]; - // Process OS events. Blocking call. - [[NSRunLoop mainRunLoop]run]; + toTarget:tests + withObject:nil]; + + NSRunLoop* main_run_loop = [NSRunLoop mainRunLoop]; + NSDate *loop_until = [NSDate dateWithTimeIntervalSinceNow:0.1]; + bool runloop_ok = true; + while (![tests done] && runloop_ok) { + runloop_ok = [main_run_loop runMode:NSDefaultRunLoopMode + beforeDate:loop_until]; + loop_until = [NSDate dateWithTimeIntervalSinceNow:0.1]; + } result = [tests result]; -#else - ViEAutoTestMain autoTest; - result = autoTest.RunTests(argc, argv); - -#endif [pool release]; return result; } -@implementation AutoTestClass +@implementation AutoTestInWorkerThread + +- (void)setDone:(bool)done { + done_ = done; +} + +- (bool)done { + return done_; +} - (void)setArgc:(int)argc argv:(char**)argv { argc_ = argc; @@ -117,6 +181,7 @@ int main(int argc, char * argv[]) { ViEAutoTestMain auto_test; result_ = auto_test.RunTests(argc_, argv_); + done_ = true; [pool release]; return; diff --git a/src/video_engine/test/auto_test/source/vie_autotest_main.cc b/src/video_engine/test/auto_test/source/vie_autotest_main.cc index b9f69582c9..a2c6451f22 100644 --- a/src/video_engine/test/auto_test/source/vie_autotest_main.cc +++ b/src/video_engine/test/auto_test/source/vie_autotest_main.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -139,7 +139,7 @@ int ViEAutoTestMain::RunSpecialTestCase(int choice) { return errors; } -bool ViEAutoTestMain::RunInteractiveMode() { +int ViEAutoTestMain::RunInteractiveMode() { ViETest::Log(" ============================== "); ViETest::Log(" WebRTC ViE 3.x Autotest "); ViETest::Log(" ============================== \n"); @@ -179,10 +179,11 @@ bool ViEAutoTestMain::RunInteractiveMode() { if (errors) { ViETest::Log("Test done with errors, see ViEAutotestLog.txt for test " "result.\n"); + return 1; } else { ViETest::Log("Test done without errors, see ViEAutotestLog.txt for " "test result.\n"); + return 0; } - return true; }