1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#import "MenuController.h" 18 19#import "UIAlertView+Extensions.h" 20#import "WALTLogger.h" 21#import "WALTAppDelegate.h" 22#import "WALTClient.h" 23 24@implementation MenuController { 25 WALTClient *_client; 26 UIActivityIndicatorView *_spinner; 27} 28 29- (void)viewDidLoad { 30 [super viewDidLoad]; 31 32 _spinner = 33 [[UIActivityIndicatorView alloc] 34 initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 35 36 _client = ((WALTAppDelegate *)[UIApplication sharedApplication].delegate).client; 37} 38 39- (void)viewDidAppear:(BOOL)animated { 40 [super viewDidAppear:animated]; 41 42 [_client addObserver:self 43 forKeyPath:@"connected" 44 options:NSKeyValueObservingOptionInitial 45 context:NULL]; 46} 47 48- (void)dealloc { 49 [_client removeObserver:self forKeyPath:@"connected"]; 50} 51 52- (void)observeValueForKeyPath:(NSString *)keyPath 53 ofObject:(id)object 54 change:(NSDictionary *)change 55 context:(void *)context { 56 if (_client.isConnected) { 57 [_spinner stopAnimating]; 58 self.syncCell.accessoryView = nil; // Display a checkmark. 59 [[WALTLogger sessionLogger] appendString:@"WALT\tCONNECTED\n"]; 60 [[WALTLogger sessionLogger] appendFormat:@"SYNC\t%lld\t%lld\n", 61 _client.minError, _client.maxError]; 62 } else { 63 self.syncCell.accessoryView = _spinner; 64 [_spinner startAnimating]; 65 [[WALTLogger sessionLogger] appendString:@"WALT\tDISCONNECTED\n"]; 66 67 // Return to this view controller. 68 UINavigationController *navigationController = self.navigationController; 69 if (navigationController.visibleViewController != self) { 70 [navigationController popToRootViewControllerAnimated:YES]; 71 72 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"WALT Connection Error" 73 message:@"WALT disconnected." 74 delegate:nil 75 cancelButtonTitle:@"Dismiss" 76 otherButtonTitles:nil]; 77 [alert show]; 78 } 79 } 80 81 [self.tableView reloadData]; // Update accessory types. 82} 83 84- (void)shareLog:(id)sender { 85 NSFileManager *fileManager = [NSFileManager defaultManager]; 86 NSArray *urls = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]; 87 88 if (urls.count > 0) { 89 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 90 formatter.dateFormat = @"yyyy-MM-dd'T'HH-mm-ss"; 91 92 // Save the log to a file (which also allows it to be retrieved in iTunes/Xcode). 93 NSString *logName = [NSString stringWithFormat:@"walt_%@.log", 94 [formatter stringFromDate:[NSDate date]]]; 95 NSURL *logURL = [urls.firstObject URLByAppendingPathComponent:logName]; 96 97 WALTLogger *logger = [WALTLogger sessionLogger]; 98 NSError *error = nil; 99 if ([logger writeToURL:logURL error:&error]) { 100 // Open a share sheet for the URL. 101 UIActivityViewController *activityController = 102 [[UIActivityViewController alloc] initWithActivityItems:@[logURL] 103 applicationActivities:nil]; 104 [self presentViewController:activityController animated:YES completion:NULL]; 105 } else { 106 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Log Write Error" 107 error:error]; 108 [alert show]; 109 } 110 } else { 111 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Log Write Error" 112 message:@"Could not locate document directory." 113 delegate:nil 114 cancelButtonTitle:@"Dismiss" 115 otherButtonTitles:nil]; 116 [alert show]; 117 } 118} 119 120#pragma mark - UITableView Delegate 121 122- (void)tableView:(UITableView *)tableView 123 willDisplayCell:(UITableViewCell *)cell 124forRowAtIndexPath:(NSIndexPath *)indexPath { 125 if (indexPath.section == 1) { 126 // Show/hide the disclosure indicator on the "Measure Latency" cells. 127 cell.accessoryType = (_client.isConnected ? 128 UITableViewCellAccessoryDisclosureIndicator : 129 UITableViewCellAccessoryNone); 130 } 131} 132 133- (NSIndexPath *)tableView:(UITableView *)tableView 134 willSelectRowAtIndexPath:(NSIndexPath *)indexPath { 135 if (indexPath.section == 0 && indexPath.row == 0) { 136 // "Clock Sync" 137 NSError *error = nil; 138 if (![_client checkConnectionWithError:&error] || 139 ![_client syncClocksWithError:&error]) { 140 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"WALT Connection Error" 141 error:error]; 142 [alert show]; 143 } 144 [[WALTLogger sessionLogger] appendFormat:@"SYNC\t%lld\t%lld\n", 145 _client.minError, _client.maxError]; 146 return nil; 147 } else if (indexPath.section == 1 && !_client.isConnected) { 148 // "Measure Latency" 149 return nil; 150 } 151 152 return indexPath; 153} 154@end 155