From 1356a8d0ce57cbc8185d8f8d32e91b164b73f68e Mon Sep 17 00:00:00 2001 From: Pankaj Garg Date: Fri, 12 Feb 2021 12:12:14 -0800 Subject: [PATCH 1/3] Add a device selector view in CHIPTool iOS app --- .../CHIPTool.xcodeproj/project.pbxproj | 6 + .../Framework Helpers/DefaultsUtils.h | 1 + .../Framework Helpers/DefaultsUtils.m | 12 ++ .../View Controllers/DeviceSelector.h | 28 ++++ .../View Controllers/DeviceSelector.m | 136 ++++++++++++++++++ .../MultiAdmin/MultiAdminViewController.m | 45 +++--- .../OnOffCluster/OnOffViewController.m | 31 +++- 7 files changed, 226 insertions(+), 33 deletions(-) create mode 100644 src/darwin/CHIPTool/CHIPTool/View Controllers/DeviceSelector.h create mode 100644 src/darwin/CHIPTool/CHIPTool/View Controllers/DeviceSelector.m diff --git a/src/darwin/CHIPTool/CHIPTool.xcodeproj/project.pbxproj b/src/darwin/CHIPTool/CHIPTool.xcodeproj/project.pbxproj index c90f15c2f01bed..2f18be7523e836 100644 --- a/src/darwin/CHIPTool/CHIPTool.xcodeproj/project.pbxproj +++ b/src/darwin/CHIPTool/CHIPTool.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 0CA0E0CF248599BB009087B9 /* OnOffViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CA0E0CE248599BB009087B9 /* OnOffViewController.m */; }; 2C21071525D1A8F200DDA4AD /* MultiAdminViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C21071325D1A8F200DDA4AD /* MultiAdminViewController.m */; }; + 2C460C2425D7594B000512D6 /* DeviceSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C460C2325D7594B000512D6 /* DeviceSelector.m */; }; 991DC091247747F500C13860 /* EchoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 991DC090247747F500C13860 /* EchoViewController.m */; }; 997A639C253F93F7005C64E6 /* CHIP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 997A639B253F93F7005C64E6 /* CHIP.framework */; }; 997A639D253F93F7005C64E6 /* CHIP.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 997A639B253F93F7005C64E6 /* CHIP.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -55,6 +56,8 @@ 0CA0E0CE248599BB009087B9 /* OnOffViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OnOffViewController.m; sourceTree = ""; }; 2C21071325D1A8F200DDA4AD /* MultiAdminViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MultiAdminViewController.m; sourceTree = ""; }; 2C21071425D1A8F200DDA4AD /* MultiAdminViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MultiAdminViewController.h; sourceTree = ""; }; + 2C460C2225D7594B000512D6 /* DeviceSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceSelector.h; sourceTree = ""; }; + 2C460C2325D7594B000512D6 /* DeviceSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DeviceSelector.m; sourceTree = ""; }; 991DC08F247747F500C13860 /* EchoViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EchoViewController.h; sourceTree = ""; }; 991DC090247747F500C13860 /* EchoViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EchoViewController.m; sourceTree = ""; }; 997A639B253F93F7005C64E6 /* CHIP.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CHIP.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -203,6 +206,8 @@ B232D8BF251A0EC500792CB4 /* View Controllers */ = { isa = PBXGroup; children = ( + 2C460C2225D7594B000512D6 /* DeviceSelector.h */, + 2C460C2325D7594B000512D6 /* DeviceSelector.m */, 2C21071225D1A8F200DDA4AD /* MultiAdmin */, B204A61F244E1D0600C7C0E1 /* AppDelegate.h */, B204A620244E1D0600C7C0E1 /* AppDelegate.m */, @@ -356,6 +361,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2C460C2425D7594B000512D6 /* DeviceSelector.m in Sources */, 2C21071525D1A8F200DDA4AD /* MultiAdminViewController.m in Sources */, B204A627244E1D0600C7C0E1 /* QRCodeViewController.m in Sources */, B232D8BA2514BD0800792CB4 /* CHIPUIViewUtils.m in Sources */, diff --git a/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.h b/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.h index 63e4a5df0dba76..0087ebd5de6e78 100644 --- a/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.h +++ b/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.h @@ -28,6 +28,7 @@ void CHIPRemoveDomainValueForKey(NSString * domain, NSString * key); uint64_t CHIPGetNextAvailableDeviceID(void); void CHIPSetNextAvailableDeviceID(uint64_t id); CHIPDevice * GetPairedDevice(void); +CHIPDevice * GetPairedDeviceWithID(uint64_t id); @interface CHIPToolPersistentStorageDelegate : NSObject diff --git a/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m b/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m index cc6526649d0664..f351620ebe9e9d 100644 --- a/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m +++ b/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m @@ -82,6 +82,18 @@ void CHIPSetNextAvailableDeviceID(uint64_t id) return device; } +CHIPDevice * GetPairedDeviceWithID(uint64_t deviceId) +{ + CHIPToolPersistentStorageDelegate * storage = [[CHIPToolPersistentStorageDelegate alloc] init]; + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.persistentstorage.callback", DISPATCH_QUEUE_SERIAL); + + CHIPDeviceController * controller = [CHIPDeviceController sharedController]; + [controller setPersistentStorageDelegate:storage queue:callbackQueue]; + + NSError * error; + return [controller getPairedDevice:deviceId error:&error]; +} + @implementation CHIPToolPersistentStorageDelegate // MARK: CHIPPersistentStorageDelegate diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/DeviceSelector.h b/src/darwin/CHIPTool/CHIPTool/View Controllers/DeviceSelector.h new file mode 100644 index 00000000000000..44bb67e6d83ddd --- /dev/null +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/DeviceSelector.h @@ -0,0 +1,28 @@ +/** + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface DeviceSelector : UITextField +- (instancetype)init; +- (CHIPDevice *)selectedDevice; +@end + +NS_ASSUME_NONNULL_END diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/DeviceSelector.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/DeviceSelector.m new file mode 100644 index 00000000000000..fd79af6b83df23 --- /dev/null +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/DeviceSelector.m @@ -0,0 +1,136 @@ +/** + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "DeviceSelector.h" + +#import "CHIPUIViewUtils.h" +#import "DefaultsUtils.h" + +@interface DeviceSelector () +@property (readwrite) CHIPDevice * chipDevice; +@property (readwrite) uint64_t nextDeviceID; +@end + +@implementation DeviceSelector { + NSMutableArray * _deviceList; + UIPickerView * _devicePicker; + NSUInteger _selectedDeviceIndex; +} + +- (id)init +{ + if (self = [super init]) { + _nextDeviceID = CHIPGetNextAvailableDeviceID(); + _selectedDeviceIndex = self.nextDeviceID + 1; + [self refreshDeviceList]; + [self setupView]; + } + return self; +} + +- (void)refreshDeviceList +{ + _deviceList = [NSMutableArray new]; + for (uint64_t i = 0; i < _nextDeviceID; i++) { + if (GetPairedDeviceWithID(i) != nil) { + [_deviceList addObject:[@(i) stringValue]]; + } + } + _selectedDeviceIndex = 0; +} + +- (void)selectDevice +{ + uint64_t deviceID = [_deviceList[_selectedDeviceIndex] intValue]; + _chipDevice = GetPairedDeviceWithID(deviceID); +} + +- (CHIPDevice *)selectedDevice +{ + return _chipDevice; +} + +- (void)setupView +{ + self.text = [_deviceList objectAtIndex:_selectedDeviceIndex]; + _devicePicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 100, 0, 0)]; + self.inputView = _devicePicker; + [_devicePicker setDataSource:self]; + [_devicePicker setDelegate:self]; + self.delegate = self; + + UIToolbar * deviceSelectButtonView = [[UIToolbar alloc] init]; + [deviceSelectButtonView sizeToFit]; + UIBarButtonItem * deviceSelectButton = [[UIBarButtonItem alloc] initWithTitle:@"Select Device" + style:UIBarButtonItemStylePlain + target:self + action:@selector(deviceSelectClicked:)]; + UIBarButtonItem * flexible = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace + target:self + action:nil]; + [deviceSelectButtonView setItems:[NSArray arrayWithObjects:flexible, deviceSelectButton, nil]]; + self.inputAccessoryView = deviceSelectButtonView; + + [self selectDevice]; +} + +// MARK: UIPickerView + +- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component +{ + NSLog(@"%@", [_deviceList objectAtIndex:row]); + self.text = [NSString stringWithFormat:@"%@", [_deviceList objectAtIndex:row]]; +} + +- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component +{ + return [_deviceList count]; +} + +- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView +{ + return 1; +} + +- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component +{ + return [_deviceList objectAtIndex:row]; +} + +- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component +{ + return 200; +} + +- (IBAction)deviceSelectClicked:(id)sender +{ + _selectedDeviceIndex = [_deviceList indexOfObject:self.text]; + [self resignFirstResponder]; + [self selectDevice]; +} + +// MARK: CHIPDeviceControllerDelegate +- (void)deviceControllerOnConnected +{ + NSLog(@"Status: Device connected"); +} + +- (void)deviceControllerOnError:(nonnull NSError *)error +{ +} + +@end diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/MultiAdmin/MultiAdminViewController.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/MultiAdmin/MultiAdminViewController.m index b18bad14fd81f6..8cfd2fdf0128f1 100644 --- a/src/darwin/CHIPTool/CHIPTool/View Controllers/MultiAdmin/MultiAdminViewController.m +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/MultiAdmin/MultiAdminViewController.m @@ -19,6 +19,7 @@ #import "CHIPUIViewUtils.h" #import "DefaultsUtils.h" +#import "DeviceSelector.h" static NSString * const DEFAULT_TIMEOUT = @"900"; static NSString * const DEFAULT_DISCRIMINATOR = @"3840"; @@ -33,10 +34,7 @@ @interface MultiAdminViewController () @property (nonatomic, strong) UILabel * resultLabel; @property (nonatomic, strong) UIStackView * stackView; -@property (readwrite) CHIPDevice * chipDevice; - -@property (readonly) CHIPToolPersistentStorageDelegate * persistentStorage; - +@property (nonatomic, strong) DeviceSelector * deviceSelector; @end @implementation MultiAdminViewController @@ -51,14 +49,13 @@ - (void)viewDidLoad // listen for taps to dismiss the keyboard UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)]; [self.view addGestureRecognizer:tap]; - - self.chipDevice = GetPairedDevice(); } - (void)dismissKeyboard { [self.discriminatorField resignFirstResponder]; [self.timeoutField resignFirstResponder]; + [self.deviceSelector resignFirstResponder]; } // MARK: UI Setup @@ -83,6 +80,18 @@ - (void)setupUIElements [stackView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:30].active = YES; [stackView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-30].active = YES; + // Device List and selector + UILabel * deviceIDLabel = [UILabel new]; + deviceIDLabel.text = @"Device ID:"; + _deviceSelector = [DeviceSelector new]; + + UIView * deviceIDView = [CHIPUIViewUtils viewWithLabel:deviceIDLabel textField:_deviceSelector]; + deviceIDLabel.font = [UIFont systemFontOfSize:17 weight:UIFontWeightSemibold]; + + [stackView addArrangedSubview:deviceIDView]; + deviceIDView.translatesAutoresizingMaskIntoConstraints = false; + [deviceIDView.trailingAnchor constraintEqualToAnchor:stackView.trailingAnchor].active = true; + // Open Pairing Window UILabel * useOnboardingToken = [UILabel new]; useOnboardingToken.text = @"Use Onboarding Token"; @@ -170,7 +179,8 @@ - (IBAction)overrideControls:(id)sender - (IBAction)openPairingWindow:(id)sender { // send message - if ([self.chipDevice isActive]) { + CHIPDevice * chipDevice = [self.deviceSelector selectedDevice]; + if (chipDevice != nil && [chipDevice isActive]) { NSString * timeoutStr = [self.timeoutField text]; if (timeoutStr.length == 0) { timeoutStr = [self.timeoutField placeholder]; @@ -186,7 +196,7 @@ - (IBAction)openPairingWindow:(id)sender } NSInteger discriminator = [discriminatorStr intValue]; - output = [self.chipDevice openPairingWindowWithPIN:timeout discriminator:discriminator error:&error]; + output = [chipDevice openPairingWindowWithPIN:timeout discriminator:discriminator error:&error]; if (output != nil) { NSString * result = [@"Use Manual Code: " stringByAppendingString:output]; @@ -195,7 +205,7 @@ - (IBAction)openPairingWindow:(id)sender [self updateResult:@"Failed in opening the pairing window"]; } } else { - BOOL didSend = [self.chipDevice openPairingWindow:timeout error:&error]; + BOOL didSend = [chipDevice openPairingWindow:timeout error:&error]; if (didSend) { [self updateResult:@"Scan the QR code on the device"]; } else { @@ -208,21 +218,4 @@ - (IBAction)openPairingWindow:(id)sender } } -// MARK: CHIPDeviceControllerDelegate -- (void)deviceControllerOnConnected -{ - NSLog(@"Status: Device connected"); -} - -- (void)deviceControllerOnError:(nonnull NSError *)error -{ - NSLog(@"Status: Device Controller error %@", [error description]); - if (error) { - NSString * stringError = [@"Error: " stringByAppendingString:error.description]; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5.0), dispatch_get_main_queue(), ^{ - [self updateResult:stringError]; - }); - } -} - @end diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/OnOffCluster/OnOffViewController.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/OnOffCluster/OnOffViewController.m index b11ce4ab026437..360d59bff27cb1 100644 --- a/src/darwin/CHIPTool/CHIPTool/View Controllers/OnOffCluster/OnOffViewController.m +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/OnOffCluster/OnOffViewController.m @@ -18,6 +18,7 @@ #import "OnOffViewController.h" #import "CHIPUIViewUtils.h" #import "DefaultsUtils.h" +#import "DeviceSelector.h" #import NSString * const kCHIPNumLightOnOffCluster = @"OnOffViewController_NumLights"; @@ -29,7 +30,7 @@ @interface OnOffViewController () @property (nonatomic, strong) UILabel * titleLabel; @property (nonatomic, strong) UIStackView * stackView; -@property (readwrite) CHIPDevice * chipDevice; +@property (nonatomic, strong) DeviceSelector * deviceSelector; @end @@ -48,13 +49,12 @@ - (void)viewDidLoad [self.view addGestureRecognizer:tap]; [self setupUIElements]; - - self.chipDevice = GetPairedDevice(); } - (void)dismissKeyboard { [_numLightsTextField resignFirstResponder]; + [_deviceSelector resignFirstResponder]; } // MARK: UI Setup @@ -85,6 +85,18 @@ - (void)setupStackView [stackView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:30].active = YES; [stackView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-30].active = YES; + // Device List and picker + UILabel * deviceIDLabel = [UILabel new]; + deviceIDLabel.text = @"Device ID:"; + _deviceSelector = [DeviceSelector new]; + + UIView * deviceIDView = [CHIPUIViewUtils viewWithLabel:deviceIDLabel textField:_deviceSelector]; + deviceIDLabel.font = [UIFont systemFontOfSize:17 weight:UIFontWeightSemibold]; + + [stackView addArrangedSubview:deviceIDView]; + deviceIDView.translatesAutoresizingMaskIntoConstraints = false; + [deviceIDView.trailingAnchor constraintEqualToAnchor:stackView.trailingAnchor].active = true; + // Num lights to show UILabel * numLightsLabel = [UILabel new]; numLightsLabel.text = @"# of light endpoints:"; @@ -174,7 +186,6 @@ - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComp { NSLog(@"%@", [_numLightsOptions objectAtIndex:row]); _numLightsTextField.text = [NSString stringWithFormat:@"%@", [_numLightsOptions objectAtIndex:row]]; - ; } - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component @@ -222,11 +233,13 @@ - (int)numLightClustersToShow - (IBAction)onButtonTapped:(id)sender { + CHIPDevice * chipDevice = [self.deviceSelector selectedDevice]; + UIButton * button = (UIButton *) sender; NSInteger endpoint = button.tag; [self updateResult:[NSString stringWithFormat:@"On command sent on endpoint %@", @(endpoint)]]; - CHIPOnOff * onOff = [[CHIPOnOff alloc] initWithDevice:self.chipDevice endpoint:endpoint queue:dispatch_get_main_queue()]; + CHIPOnOff * onOff = [[CHIPOnOff alloc] initWithDevice:chipDevice endpoint:endpoint queue:dispatch_get_main_queue()]; [onOff on:^(NSError * error, NSDictionary * values) { NSString * resultString = (error != nil) ? [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code] : @"On command success"; @@ -236,11 +249,13 @@ - (IBAction)onButtonTapped:(id)sender - (IBAction)offButtonTapped:(id)sender { + CHIPDevice * chipDevice = [self.deviceSelector selectedDevice]; + UIButton * button = (UIButton *) sender; NSInteger endpoint = button.tag; [self updateResult:[NSString stringWithFormat:@"Off command sent on endpoint %@", @(endpoint)]]; - CHIPOnOff * onOff = [[CHIPOnOff alloc] initWithDevice:self.chipDevice endpoint:endpoint queue:dispatch_get_main_queue()]; + CHIPOnOff * onOff = [[CHIPOnOff alloc] initWithDevice:chipDevice endpoint:endpoint queue:dispatch_get_main_queue()]; [onOff off:^(NSError * error, NSDictionary * values) { NSString * resultString = (error != nil) ? [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code] : @"Off command success"; @@ -250,11 +265,13 @@ - (IBAction)offButtonTapped:(id)sender - (IBAction)toggleButtonTapped:(id)sender { + CHIPDevice * chipDevice = [self.deviceSelector selectedDevice]; + UIButton * button = (UIButton *) sender; NSInteger endpoint = button.tag; [self updateResult:[NSString stringWithFormat:@"Toggle command sent on endpoint %@", @(endpoint)]]; - CHIPOnOff * onOff = [[CHIPOnOff alloc] initWithDevice:self.chipDevice endpoint:endpoint queue:dispatch_get_main_queue()]; + CHIPOnOff * onOff = [[CHIPOnOff alloc] initWithDevice:chipDevice endpoint:endpoint queue:dispatch_get_main_queue()]; [onOff toggle:^(NSError * error, NSDictionary * values) { NSString * resultString = (error != nil) ? [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code] : @"Toggle command success"; From 4368420bc1f26bbfc3833a2bd34ea7c982c293bf Mon Sep 17 00:00:00 2001 From: Pankaj Garg Date: Mon, 15 Feb 2021 09:12:37 -0800 Subject: [PATCH 2/3] add a TODO to remove repeated calls to set persistent storage delegate --- src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m b/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m index f351620ebe9e9d..d706304bc2e89c 100644 --- a/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m +++ b/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m @@ -88,6 +88,8 @@ void CHIPSetNextAvailableDeviceID(uint64_t id) dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.persistentstorage.callback", DISPATCH_QUEUE_SERIAL); CHIPDeviceController * controller = [CHIPDeviceController sharedController]; + // TODO: setting persistent storage delegate repeatedly is wasteful. This is being done here, and in + // GetPairedDevice() on every call. The delegate should be set once at the controller init time. [controller setPersistentStorageDelegate:storage queue:callbackQueue]; NSError * error; From fc6ad11d12b1421a8af4dfde7645e7e3c88798be Mon Sep 17 00:00:00 2001 From: Pankaj Garg Date: Mon, 15 Feb 2021 10:24:38 -0800 Subject: [PATCH 3/3] address TODO, and review comments --- .../Framework Helpers/DefaultsUtils.h | 4 +-- .../Framework Helpers/DefaultsUtils.m | 31 +++++++++++-------- .../Bindings/BindingsViewController.m | 2 +- .../View Controllers/DeviceSelector.m | 12 ++++--- .../Echo client/EchoViewController.m | 2 +- .../OnOffCluster/OnOffViewController.m | 12 +++++++ .../TemperatureSensorViewController.m | 4 ++- 7 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.h b/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.h index 0087ebd5de6e78..e21b34755e83b0 100644 --- a/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.h +++ b/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.h @@ -27,8 +27,8 @@ void CHIPSetDomainValueForKey(NSString * domain, NSString * key, id value); void CHIPRemoveDomainValueForKey(NSString * domain, NSString * key); uint64_t CHIPGetNextAvailableDeviceID(void); void CHIPSetNextAvailableDeviceID(uint64_t id); -CHIPDevice * GetPairedDevice(void); -CHIPDevice * GetPairedDeviceWithID(uint64_t id); +CHIPDevice * CHIPGetPairedDevice(void); +CHIPDevice * CHIPGetPairedDeviceWithID(uint64_t id); @interface CHIPToolPersistentStorageDelegate : NSObject diff --git a/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m b/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m index d706304bc2e89c..628c1013961a70 100644 --- a/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m +++ b/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m @@ -62,13 +62,24 @@ void CHIPSetNextAvailableDeviceID(uint64_t id) CHIPSetDomainValueForKey(kCHIPToolDefaultsDomain, kCHIPNextAvailableDeviceIDKey, [NSNumber numberWithUnsignedLongLong:id]); } -CHIPDevice * GetPairedDevice(void) +CHIPDeviceController * InitializeCHIP(void) { - CHIPToolPersistentStorageDelegate * storage = [[CHIPToolPersistentStorageDelegate alloc] init]; - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.persistentstorage.callback", DISPATCH_QUEUE_SERIAL); - + static dispatch_queue_t callbackQueue; + static CHIPToolPersistentStorageDelegate * storage = nil; + static dispatch_once_t onceToken; CHIPDeviceController * controller = [CHIPDeviceController sharedController]; - [controller setPersistentStorageDelegate:storage queue:callbackQueue]; + dispatch_once(&onceToken, ^{ + storage = [[CHIPToolPersistentStorageDelegate alloc] init]; + callbackQueue = dispatch_queue_create("com.chip.persistentstorage.callback", DISPATCH_QUEUE_SERIAL); + [controller setPersistentStorageDelegate:storage queue:callbackQueue]; + }); + + return controller; +} + +CHIPDevice * CHIPGetPairedDevice(void) +{ + CHIPDeviceController * controller = InitializeCHIP(); CHIPDevice * device = nil; uint64_t deviceId = CHIPGetNextAvailableDeviceID(); @@ -82,15 +93,9 @@ void CHIPSetNextAvailableDeviceID(uint64_t id) return device; } -CHIPDevice * GetPairedDeviceWithID(uint64_t deviceId) +CHIPDevice * CHIPGetPairedDeviceWithID(uint64_t deviceId) { - CHIPToolPersistentStorageDelegate * storage = [[CHIPToolPersistentStorageDelegate alloc] init]; - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.persistentstorage.callback", DISPATCH_QUEUE_SERIAL); - - CHIPDeviceController * controller = [CHIPDeviceController sharedController]; - // TODO: setting persistent storage delegate repeatedly is wasteful. This is being done here, and in - // GetPairedDevice() on every call. The delegate should be set once at the controller init time. - [controller setPersistentStorageDelegate:storage queue:callbackQueue]; + CHIPDeviceController * controller = InitializeCHIP(); NSError * error; return [controller getPairedDevice:deviceId error:&error]; diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/Bindings/BindingsViewController.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/Bindings/BindingsViewController.m index 543a99bdc2714e..d974220356d0bc 100644 --- a/src/darwin/CHIPTool/CHIPTool/View Controllers/Bindings/BindingsViewController.m +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/Bindings/BindingsViewController.m @@ -38,7 +38,7 @@ - (void)viewDidLoad UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)]; [self.view addGestureRecognizer:tap]; - self.cluster = [[CHIPBinding alloc] initWithDevice:GetPairedDevice() endpoint:1 queue:dispatch_get_main_queue()]; + self.cluster = [[CHIPBinding alloc] initWithDevice:CHIPGetPairedDevice() endpoint:1 queue:dispatch_get_main_queue()]; } - (void)dismissKeyboard diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/DeviceSelector.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/DeviceSelector.m index fd79af6b83df23..6b51973918c42d 100644 --- a/src/darwin/CHIPTool/CHIPTool/View Controllers/DeviceSelector.m +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/DeviceSelector.m @@ -46,7 +46,7 @@ - (void)refreshDeviceList { _deviceList = [NSMutableArray new]; for (uint64_t i = 0; i < _nextDeviceID; i++) { - if (GetPairedDeviceWithID(i) != nil) { + if (CHIPGetPairedDeviceWithID(i) != nil) { [_deviceList addObject:[@(i) stringValue]]; } } @@ -55,8 +55,10 @@ - (void)refreshDeviceList - (void)selectDevice { - uint64_t deviceID = [_deviceList[_selectedDeviceIndex] intValue]; - _chipDevice = GetPairedDeviceWithID(deviceID); + if ([_deviceList count] > 0) { + uint64_t deviceID = [_deviceList[_selectedDeviceIndex] intValue]; + _chipDevice = CHIPGetPairedDeviceWithID(deviceID); + } } - (CHIPDevice *)selectedDevice @@ -66,7 +68,9 @@ - (CHIPDevice *)selectedDevice - (void)setupView { - self.text = [_deviceList objectAtIndex:_selectedDeviceIndex]; + if ([_deviceList count] > 0) { + self.text = [_deviceList objectAtIndex:_selectedDeviceIndex]; + } _devicePicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 100, 0, 0)]; self.inputView = _devicePicker; [_devicePicker setDataSource:self]; diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/Echo client/EchoViewController.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/Echo client/EchoViewController.m index c91d591ecb7c8c..156d0833b7f9a7 100644 --- a/src/darwin/CHIPTool/CHIPTool/View Controllers/Echo client/EchoViewController.m +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/Echo client/EchoViewController.m @@ -45,7 +45,7 @@ - (void)viewDidLoad UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)]; [self.view addGestureRecognizer:tap]; - self.cluster = [[CHIPBasic alloc] initWithDevice:GetPairedDevice() endpoint:1 queue:dispatch_get_main_queue()]; + self.cluster = [[CHIPBasic alloc] initWithDevice:CHIPGetPairedDevice() endpoint:1 queue:dispatch_get_main_queue()]; } - (void)dismissKeyboard diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/OnOffCluster/OnOffViewController.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/OnOffCluster/OnOffViewController.m index 360d59bff27cb1..e030bced9ed7c7 100644 --- a/src/darwin/CHIPTool/CHIPTool/View Controllers/OnOffCluster/OnOffViewController.m +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/OnOffCluster/OnOffViewController.m @@ -234,6 +234,10 @@ - (int)numLightClustersToShow - (IBAction)onButtonTapped:(id)sender { CHIPDevice * chipDevice = [self.deviceSelector selectedDevice]; + if (chipDevice == nil) { + [self updateResult:[NSString stringWithFormat:@"No device has been selected"]]; + return; + } UIButton * button = (UIButton *) sender; NSInteger endpoint = button.tag; @@ -250,6 +254,10 @@ - (IBAction)onButtonTapped:(id)sender - (IBAction)offButtonTapped:(id)sender { CHIPDevice * chipDevice = [self.deviceSelector selectedDevice]; + if (chipDevice == nil) { + [self updateResult:[NSString stringWithFormat:@"No device has been selected"]]; + return; + } UIButton * button = (UIButton *) sender; NSInteger endpoint = button.tag; @@ -266,6 +274,10 @@ - (IBAction)offButtonTapped:(id)sender - (IBAction)toggleButtonTapped:(id)sender { CHIPDevice * chipDevice = [self.deviceSelector selectedDevice]; + if (chipDevice == nil) { + [self updateResult:[NSString stringWithFormat:@"No device has been selected"]]; + return; + } UIButton * button = (UIButton *) sender; NSInteger endpoint = button.tag; diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/Temperature Sensor/TemperatureSensorViewController.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/Temperature Sensor/TemperatureSensorViewController.m index d8b4125f00451a..aec38cc68fa640 100644 --- a/src/darwin/CHIPTool/CHIPTool/View Controllers/Temperature Sensor/TemperatureSensorViewController.m +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/Temperature Sensor/TemperatureSensorViewController.m @@ -32,7 +32,9 @@ - (void)viewDidLoad UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)]; [self.view addGestureRecognizer:tap]; - self.cluster = [[CHIPTemperatureMeasurement alloc] initWithDevice:GetPairedDevice() endpoint:1 queue:dispatch_get_main_queue()]; + self.cluster = [[CHIPTemperatureMeasurement alloc] initWithDevice:CHIPGetPairedDevice() + endpoint:1 + queue:dispatch_get_main_queue()]; [self readCurrentTemperature]; }