blob: 63e807374c9564c516c157bdfe326d7658a2fe72 [file] [log] [blame]
// Copyright 2015 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 "ui/base/test/windowed_nsnotification_observer.h"
#import <Cocoa/Cocoa.h>
#include "base/location.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/test/test_timeouts.h"
#include "base/threading/thread_task_runner_handle.h"
@interface WindowedNSNotificationObserver ()
- (void)onNotification:(NSNotification*)notification;
@end
@implementation WindowedNSNotificationObserver
@synthesize notificationCount = _notificationCount;
- (instancetype)initForNotification:(NSString*)name {
return [self initForNotification:name object:nil];
}
- (instancetype)initForNotification:(NSString*)name object:(id)sender {
if ((self = [super init])) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onNotification:)
name:name
object:sender];
}
return self;
}
- (instancetype)initForWorkspaceNotification:(NSString*)name
bundleId:(NSString*)bundleId {
if ((self = [super init])) {
_bundleId.reset([bundleId copy]);
[[[NSWorkspace sharedWorkspace] notificationCenter]
addObserver:self
selector:@selector(onNotification:)
name:name
object:nil];
}
return self;
}
- (void)dealloc {
if (_bundleId)
[[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
else
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
- (void)onNotification:(NSNotification*)notification {
if (_bundleId) {
NSRunningApplication* application =
[notification userInfo][NSWorkspaceApplicationKey];
if (![[application bundleIdentifier] isEqualToString:_bundleId])
return;
}
++_notificationCount;
if (_runLoop)
_runLoop->Quit();
}
- (BOOL)waitForCount:(int)minimumCount {
while (_notificationCount < minimumCount) {
const int oldCount = _notificationCount;
base::RunLoop runLoop;
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, runLoop.QuitClosure(), TestTimeouts::action_timeout());
_runLoop = &runLoop;
runLoop.Run();
_runLoop = nullptr;
// If there was no new notification, it must have been a timeout.
if (_notificationCount == oldCount)
break;
}
return _notificationCount >= minimumCount;
}
- (BOOL)wait {
return [self waitForCount:1];
}
@end