Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
FlutterAppLifecycleDelegate.mm
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterAppLifecycleDelegate.h"
6#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterAppLifecycleDelegate_Internal.h"
7
8#include <AppKit/AppKit.h>
9#include <AppKit/NSApplication.h>
10#include <Foundation/Foundation.h>
11#include <objc/message.h>
12
13#include "flutter/fml/logging.h"
14#include "flutter/fml/paths.h"
15
16@implementation FlutterAppLifecycleRegistrar {
17 NSMutableArray* _notificationUnsubscribers;
18}
19
20- (void)addObserverFor:(NSString*)name selector:(SEL)selector {
21 [[NSNotificationCenter defaultCenter] addObserver:self selector:selector name:name object:nil];
22 __block NSObject* blockSelf = self;
23 dispatch_block_t unsubscribe = ^{
24 [[NSNotificationCenter defaultCenter] removeObserver:blockSelf name:name object:nil];
25 };
26 [_notificationUnsubscribers addObject:[unsubscribe copy]];
27}
28
29- (instancetype)init {
30 if (self = [super init]) {
31 _notificationUnsubscribers = [[NSMutableArray alloc] init];
32
33// Using a macro to avoid errors where the notification doesn't match the
34// selector.
35#ifdef OBSERVE_NOTIFICATION
36#error OBSERVE_NOTIFICATION ALREADY DEFINED!
37#else
38#define OBSERVE_NOTIFICATION(SELECTOR) \
39 [self addObserverFor:NSApplication##SELECTOR##Notification selector:@selector(handle##SELECTOR:)]
40#endif
41
42 OBSERVE_NOTIFICATION(WillFinishLaunching);
43 OBSERVE_NOTIFICATION(DidFinishLaunching);
44 OBSERVE_NOTIFICATION(WillBecomeActive);
45 OBSERVE_NOTIFICATION(DidBecomeActive);
46 OBSERVE_NOTIFICATION(WillResignActive);
47 OBSERVE_NOTIFICATION(DidResignActive);
48 OBSERVE_NOTIFICATION(WillTerminate);
49 OBSERVE_NOTIFICATION(WillHide);
50 OBSERVE_NOTIFICATION(DidHide);
51 OBSERVE_NOTIFICATION(WillUnhide);
52 OBSERVE_NOTIFICATION(DidUnhide);
53 OBSERVE_NOTIFICATION(DidChangeScreenParameters);
54 OBSERVE_NOTIFICATION(DidChangeOcclusionState);
55
56#undef OBSERVE_NOTIFICATION
57
58 _delegates = [NSPointerArray weakObjectsPointerArray];
59 }
60 return self;
61}
62
63- (void)dealloc {
64 for (dispatch_block_t unsubscribe in _notificationUnsubscribers) {
65 unsubscribe();
66 }
67 [_notificationUnsubscribers removeAllObjects];
68 _delegates = nil;
69 _notificationUnsubscribers = nil;
70}
71
72static BOOL IsPowerOfTwo(NSUInteger x) {
73 return x != 0 && (x & (x - 1)) == 0;
74}
75
76- (void)addDelegate:(NSObject<FlutterAppLifecycleDelegate>*)delegate {
77 [_delegates addPointer:(__bridge void*)delegate];
78 if (IsPowerOfTwo([_delegates count])) {
79 [_delegates compact];
80 }
81}
82
83- (void)removeDelegate:(NSObject<FlutterAppLifecycleDelegate>*)delegate {
84 NSUInteger index = [[_delegates allObjects] indexOfObject:delegate];
85 if (index != NSNotFound) {
86 [_delegates removePointerAtIndex:index];
87 }
88}
89
90// This isn't done via performSelector because that can cause leaks due to the
91// selector not being known. Using a macro to avoid mismatch errors between the
92// notification and the selector.
93#ifdef DISTRIBUTE_NOTIFICATION
94#error DISTRIBUTE_NOTIFICATION ALREADY DEFINED!
95#else
96#define DISTRIBUTE_NOTIFICATION(SELECTOR) \
97 -(void)handle##SELECTOR : (NSNotification*)notification { \
98 for (NSObject<FlutterAppLifecycleDelegate> * delegate in _delegates) { \
99 if ([delegate respondsToSelector:@selector(handle##SELECTOR:)]) { \
100 [delegate handle##SELECTOR:notification]; \
101 } \
102 } \
103 }
104#endif
105
106DISTRIBUTE_NOTIFICATION(WillFinishLaunching)
107DISTRIBUTE_NOTIFICATION(DidFinishLaunching)
108DISTRIBUTE_NOTIFICATION(WillBecomeActive)
109DISTRIBUTE_NOTIFICATION(DidBecomeActive)
110DISTRIBUTE_NOTIFICATION(WillResignActive)
111DISTRIBUTE_NOTIFICATION(DidResignActive)
112DISTRIBUTE_NOTIFICATION(WillTerminate)
114DISTRIBUTE_NOTIFICATION(WillUnhide)
117DISTRIBUTE_NOTIFICATION(DidChangeScreenParameters)
118DISTRIBUTE_NOTIFICATION(DidChangeOcclusionState)
119
120#undef DISTRIBUTE_NOTIFICATION
121
122@end
#define DISTRIBUTE_NOTIFICATION(SELECTOR)
#define OBSERVE_NOTIFICATION(SELECTOR)
NSPointerArray * _delegates
int count
double x
init(device_serial, adb_binary)
Definition _adb_path.py:12
int BOOL