summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorshess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-01 23:56:17 +0000
committershess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-01 23:56:17 +0000
commitd47af217ea470077b039d9f4d49f529dd0eda6bd (patch)
treef55006b328a59a6f702a8921f0e74f8ef3d82be4 /base
parent7f2c27ac648a224202f59da047e73e9821328f5d (diff)
downloadchromium_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.gyp1
-rw-r--r--base/base.gypi2
-rw-r--r--base/mac/scoped_sending_event.h49
-rw-r--r--base/mac/scoped_sending_event.mm24
-rw-r--r--base/mac/scoped_sending_event_unittest.mm38
-rw-r--r--base/test/mock_chrome_application_mac.h16
-rw-r--r--base/test/mock_chrome_application_mac.mm28
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