diff options
author | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-01 23:56:17 +0000 |
---|---|---|
committer | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-01 23:56:17 +0000 |
commit | d47af217ea470077b039d9f4d49f529dd0eda6bd (patch) | |
tree | f55006b328a59a6f702a8921f0e74f8ef3d82be4 /base | |
parent | 7f2c27ac648a224202f59da047e73e9821328f5d (diff) | |
download | chromium_src-d47af217ea470077b039d9f4d49f529dd0eda6bd.zip chromium_src-d47af217ea470077b039d9f4d49f529dd0eda6bd.tar.gz chromium_src-d47af217ea470077b039d9f4d49f529dd0eda6bd.tar.bz2 |
[Mac] Move ScopedSendingEvent from content/common/mac to base/mac.
Also merge content/ MockCrControlApp into base/ MockCrApp.
Also use MockCrApp in test_shell_tests, and slight tweak to autorelease pool in test_shell's initialization.
BUG=102224
Review URL: http://codereview.chromium.org/8724004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112578 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/base.gyp | 1 | ||||
-rw-r--r-- | base/base.gypi | 2 | ||||
-rw-r--r-- | base/mac/scoped_sending_event.h | 49 | ||||
-rw-r--r-- | base/mac/scoped_sending_event.mm | 24 | ||||
-rw-r--r-- | base/mac/scoped_sending_event_unittest.mm | 38 | ||||
-rw-r--r-- | base/test/mock_chrome_application_mac.h | 16 | ||||
-rw-r--r-- | base/test/mock_chrome_application_mac.mm | 28 |
7 files changed, 147 insertions, 11 deletions
diff --git a/base/base.gyp b/base/base.gyp index 3579c2d..c75544b 100644 --- a/base/base.gyp +++ b/base/base.gyp @@ -160,6 +160,7 @@ 'mac/foundation_util_unittest.mm', 'mac/mac_util_unittest.mm', 'mac/objc_property_releaser_unittest.mm', + 'mac/scoped_sending_event_unittest.mm', 'md5_unittest.cc', 'memory/linked_ptr_unittest.cc', 'memory/mru_cache_unittest.cc', diff --git a/base/base.gypi b/base/base.gypi index 8c483b3..52fef77 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -158,6 +158,8 @@ 'mac/scoped_nsautorelease_pool.mm', 'mac/scoped_nsexception_enabler.h', 'mac/scoped_nsexception_enabler.mm', + 'mac/scoped_sending_event.h', + 'mac/scoped_sending_event.mm', 'mach_ipc_mac.h', 'mach_ipc_mac.mm', 'memory/linked_ptr.h', diff --git a/base/mac/scoped_sending_event.h b/base/mac/scoped_sending_event.h new file mode 100644 index 0000000..fcc984f --- /dev/null +++ b/base/mac/scoped_sending_event.h @@ -0,0 +1,49 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_MAC_SCOPED_SENDING_EVENT_H_ +#define BASE_MAC_SCOPED_SENDING_EVENT_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/memory/scoped_nsobject.h" +#include "base/message_pump_mac.h" + +// Nested event loops can pump IPC messages, including +// script-initiated tab closes, which could release objects that the +// nested event loop might message. CrAppProtocol defines how to ask +// the embedding NSApplication subclass if an event is currently being +// handled, in which case such closes are deferred to the top-level +// event loop. +// +// ScopedSendingEvent allows script-initiated event loops to work like +// a nested event loop, as such events do not arrive via -sendEvent:. +// CrAppControlProtocol lets ScopedSendingEvent tell the embedding +// NSApplication what to return from -handlingSendEvent. + +@protocol CrAppControlProtocol<CrAppProtocol> +- (void)setHandlingSendEvent:(BOOL)handlingSendEvent; +@end + +namespace base { +namespace mac { + +class ScopedSendingEvent { + public: + ScopedSendingEvent(); + ~ScopedSendingEvent(); + + private: + // The NSApp in control at the time the constructor was run, to be + // sure the |handling_| setting is restored appropriately. + NSObject<CrAppControlProtocol>* app_; + BOOL handling_; // Value of -[app_ handlingSendEvent] at construction. + + DISALLOW_COPY_AND_ASSIGN(ScopedSendingEvent); +}; + +} // namespace mac +} // namespace base + +#endif // BASE_MAC_SCOPED_SENDING_EVENT_H_ diff --git a/base/mac/scoped_sending_event.mm b/base/mac/scoped_sending_event.mm new file mode 100644 index 0000000..c3813d8 --- /dev/null +++ b/base/mac/scoped_sending_event.mm @@ -0,0 +1,24 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "base/mac/scoped_sending_event.h" + +#include "base/logging.h" + +namespace base { +namespace mac { + +ScopedSendingEvent::ScopedSendingEvent() + : app_(static_cast<NSObject<CrAppControlProtocol>*>(NSApp)) { + DCHECK([app_ conformsToProtocol:@protocol(CrAppControlProtocol)]); + handling_ = [app_ isHandlingSendEvent]; + [app_ setHandlingSendEvent:YES]; +} + +ScopedSendingEvent::~ScopedSendingEvent() { + [app_ setHandlingSendEvent:handling_]; +} + +} // namespace mac +} // namespace base diff --git a/base/mac/scoped_sending_event_unittest.mm b/base/mac/scoped_sending_event_unittest.mm new file mode 100644 index 0000000..9ae9985 --- /dev/null +++ b/base/mac/scoped_sending_event_unittest.mm @@ -0,0 +1,38 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "base/mac/scoped_sending_event.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +// Sets the flag within scope, resets when leaving scope. +TEST(ScopedSendingEventTest, SetHandlingSendEvent) { + id<CrAppProtocol> app = NSApp; + EXPECT_FALSE([app isHandlingSendEvent]); + { + base::mac::ScopedSendingEvent is_handling_send_event; + EXPECT_TRUE([app isHandlingSendEvent]); + } + EXPECT_FALSE([app isHandlingSendEvent]); +} + +// Nested call restores previous value rather than resetting flag. +TEST(ScopedSendingEventTest, NestedSetHandlingSendEvent) { + id<CrAppProtocol> app = NSApp; + EXPECT_FALSE([app isHandlingSendEvent]); + { + base::mac::ScopedSendingEvent is_handling_send_event; + EXPECT_TRUE([app isHandlingSendEvent]); + { + base::mac::ScopedSendingEvent nested_is_handling_send_event; + EXPECT_TRUE([app isHandlingSendEvent]); + } + EXPECT_TRUE([app isHandlingSendEvent]); + } + EXPECT_FALSE([app isHandlingSendEvent]); +} + +} // namespace diff --git a/base/test/mock_chrome_application_mac.h b/base/test/mock_chrome_application_mac.h index e7e2c67..325c637 100644 --- a/base/test/mock_chrome_application_mac.h +++ b/base/test/mock_chrome_application_mac.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -10,12 +10,18 @@ #import <AppKit/AppKit.h> +#include "base/mac/scoped_sending_event.h" #include "base/message_pump_mac.h" -// A mock implementation of CrAppProtocol that claims that -sendEvent: is never -// on the stack. This can be used in tests that need an NSApplication and use a -// runloop, but don't run nested message loops. -@interface MockCrApp : NSApplication<CrAppProtocol> +// A basic implementation of CrAppProtocol and +// CrAppControlProtocol. This can be used in tests that need an +// NSApplication and use a runloop, or which need a ScopedSendingEvent +// when handling a nested event loop. +@interface MockCrApp : NSApplication<CrAppProtocol, + CrAppControlProtocol> { + @private + BOOL handlingSendEvent_; +} @end #endif diff --git a/base/test/mock_chrome_application_mac.mm b/base/test/mock_chrome_application_mac.mm index 48db419..b0b8617 100644 --- a/base/test/mock_chrome_application_mac.mm +++ b/base/test/mock_chrome_application_mac.mm @@ -4,22 +4,38 @@ #include "base/test/mock_chrome_application_mac.h" +#include "base/auto_reset.h" #include "base/logging.h" @implementation MockCrApp + ++ (NSApplication*)sharedApplication { + NSApplication* app = [super sharedApplication]; + DCHECK([app conformsToProtocol:@protocol(CrAppControlProtocol)]) + << "Existing NSApp (class " << [[app className] UTF8String] + << ") does not conform to required protocol."; + return app; +} + +- (void)sendEvent:(NSEvent*)event { + AutoReset<BOOL> scoper(&handlingSendEvent_, YES); + [super sendEvent:event]; +} + +- (void)setHandlingSendEvent:(BOOL)handlingSendEvent { + handlingSendEvent_ = handlingSendEvent; +} + - (BOOL)isHandlingSendEvent { - return NO; + return handlingSendEvent_; } + @end namespace mock_cr_app { void RegisterMockCrApp() { - NSApplication* app = [MockCrApp sharedApplication]; - - // Would prefer ASSERT_TRUE() to provide better test failures, but - // this class is used by remoting/ for a non-test use. - DCHECK([app conformsToProtocol:@protocol(CrAppProtocol)]); + [MockCrApp sharedApplication]; } } // namespace mock_cr_app |