summaryrefslogtreecommitdiffstats
path: root/ui/base/test/windowed_nsnotification_observer.mm
blob: f5c1e667a6f00cf9950eed7d9ce9d6cec79a5d4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// 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/run_loop.h"
#include "base/test/test_timeouts.h"

@interface WindowedNSNotificationObserver ()
- (void)onNotification:(NSNotification*)notification;
@end

@implementation WindowedNSNotificationObserver

@synthesize notificationCount = notificationCount_;

- (id)initForNotification:(NSString*)name {
  return [self initForNotification:name object:nil];
}

- (id)initForNotification:(NSString*)name object:(id)sender {
  if ((self = [super init])) {
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(onNotification:)
                                                 name:name
                                               object:sender];
  }
  return self;
}

- (id)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] objectForKey: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::MessageLoop::current()->task_runner()->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