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