| OLD | NEW |
| (Empty) |
| 1 // Copyright 2017 The Chromium 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 #if !defined(__has_feature) || !__has_feature(objc_arc) | |
| 6 #error "This file requires ARC support." | |
| 7 #endif | |
| 8 | |
| 9 #import "remoting/client/ios/app/remoting_settings_view_controller.h" | |
| 10 | |
| 11 #import "ios/third_party/material_components_ios/src/components/AppBar/src/Mater
ialAppBar.h" | |
| 12 #import "ios/third_party/material_components_ios/src/components/Buttons/src/Mate
rialButtons.h" | |
| 13 #import "remoting/client/ios/facade/remoting_authentication.h" | |
| 14 #import "remoting/client/ios/facade/remoting_service.h" | |
| 15 | |
| 16 #include "base/strings/stringprintf.h" | |
| 17 #include "google_apis/google_api_keys.h" | |
| 18 #include "net/base/escape.h" | |
| 19 | |
| 20 // TODO(nicholss): This should be generated from a remoting/base class: | |
| 21 | |
| 22 static NSString* const kReusableIdentifierItem = | |
| 23 @"remotingSettingsViewControllerItem"; | |
| 24 static UIColor* kBackgroundColor = | |
| 25 [UIColor colorWithRed:0.f green:0.67f blue:0.55f alpha:1.f]; | |
| 26 | |
| 27 namespace { | |
| 28 const char kChromotingAuthScopeValues[] = | |
| 29 "https://www.googleapis.com/auth/chromoting " | |
| 30 "https://www.googleapis.com/auth/googletalk " | |
| 31 "https://www.googleapis.com/auth/userinfo.email"; | |
| 32 | |
| 33 std::string GetAuthorizationCodeUri() { | |
| 34 // Replace space characters with a '+' sign when formatting. | |
| 35 bool use_plus = true; | |
| 36 return base::StringPrintf( | |
| 37 "https://accounts.google.com/o/oauth2/auth" | |
| 38 "?scope=%s" | |
| 39 "&redirect_uri=https://chromoting-oauth.talkgadget.google.com/" | |
| 40 "talkgadget/oauth/chrome-remote-desktop/dev" | |
| 41 "&response_type=code" | |
| 42 "&client_id=%s" | |
| 43 "&access_type=offline" | |
| 44 "&approval_prompt=force", | |
| 45 net::EscapeUrlEncodedData(kChromotingAuthScopeValues, use_plus).c_str(), | |
| 46 net::EscapeUrlEncodedData( | |
| 47 google_apis::GetOAuth2ClientID(google_apis::CLIENT_REMOTING), | |
| 48 use_plus) | |
| 49 .c_str()); | |
| 50 } | |
| 51 | |
| 52 } // namespace | |
| 53 | |
| 54 @interface RemotingSettingsViewController () { | |
| 55 MDCAppBar* _appBar; | |
| 56 NSMutableArray* _content; | |
| 57 } | |
| 58 @end | |
| 59 | |
| 60 // This is the chromium version of the settings view controller. This will | |
| 61 // launch a web view to login and collect an oauth token to be able to login to | |
| 62 // the app without the standard google login flow. | |
| 63 // | |
| 64 // This class is majority boiler plate code to get a collection view. | |
| 65 // It will be replaced with a sidebar-like view in the future, but in | |
| 66 // chromium this is how we get an oauth token to login to the app. | |
| 67 // | |
| 68 // Note: this class is not localized, it will not be shipped to production. | |
| 69 // | |
| 70 // TODO(nicholss): This class needs to be split into a shareable view | |
| 71 // for chromium and prod to share. | |
| 72 // | |
| 73 @implementation RemotingSettingsViewController | |
| 74 | |
| 75 - (id)init { | |
| 76 self = [super init]; | |
| 77 if (self) { | |
| 78 self.title = @"Settings"; | |
| 79 | |
| 80 _appBar = [[MDCAppBar alloc] init]; | |
| 81 [self addChildViewController:_appBar.headerViewController]; | |
| 82 | |
| 83 _appBar.headerViewController.headerView.backgroundColor = kBackgroundColor; | |
| 84 _appBar.navigationBar.tintColor = [UIColor whiteColor]; | |
| 85 _appBar.navigationBar.titleTextAttributes = | |
| 86 @{NSForegroundColorAttributeName : [UIColor whiteColor]}; | |
| 87 } | |
| 88 return self; | |
| 89 } | |
| 90 | |
| 91 #pragma mark - UIViewController | |
| 92 | |
| 93 - (void)viewDidLoad { | |
| 94 [super viewDidLoad]; | |
| 95 | |
| 96 _appBar.headerViewController.headerView.trackingScrollView = | |
| 97 self.collectionView; | |
| 98 [_appBar addSubviewsToParent]; | |
| 99 | |
| 100 UIBarButtonItem* backButton = | |
| 101 [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Back"] | |
| 102 style:UIBarButtonItemStyleDone | |
| 103 target:self | |
| 104 action:@selector(didTapBack:)]; | |
| 105 self.navigationItem.leftBarButtonItem = backButton; | |
| 106 self.navigationItem.rightBarButtonItem = nil; | |
| 107 | |
| 108 [self.collectionView registerClass:[MDCCollectionViewTextCell class] | |
| 109 forCellWithReuseIdentifier:kReusableIdentifierItem]; | |
| 110 | |
| 111 [self.collectionView registerClass:[MDCCollectionViewTextCell class] | |
| 112 forSupplementaryViewOfKind:UICollectionElementKindSectionHeader | |
| 113 withReuseIdentifier:UICollectionElementKindSectionHeader]; | |
| 114 | |
| 115 self.styler.cellStyle = MDCCollectionViewCellStyleCard; | |
| 116 | |
| 117 _content = [NSMutableArray array]; | |
| 118 [_content addObject:@[ @"Login", @"Logout" ]]; | |
| 119 } | |
| 120 | |
| 121 #pragma mark - UICollectionViewDataSource | |
| 122 | |
| 123 - (NSInteger)numberOfSectionsInCollectionView: | |
| 124 (UICollectionView*)collectionView { | |
| 125 return (NSInteger)[_content count]; | |
| 126 } | |
| 127 | |
| 128 - (NSInteger)collectionView:(UICollectionView*)collectionView | |
| 129 numberOfItemsInSection:(NSInteger)section { | |
| 130 return (NSInteger)[_content[(NSUInteger)section] count]; | |
| 131 } | |
| 132 | |
| 133 - (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView | |
| 134 cellForItemAtIndexPath:(NSIndexPath*)indexPath { | |
| 135 MDCCollectionViewTextCell* cell = [collectionView | |
| 136 dequeueReusableCellWithReuseIdentifier:kReusableIdentifierItem | |
| 137 forIndexPath:indexPath]; | |
| 138 cell.textLabel.text = | |
| 139 _content[(NSUInteger)indexPath.section][(NSUInteger)indexPath.item]; | |
| 140 | |
| 141 if (indexPath.section == 0 && indexPath.item == 0) { | |
| 142 MDCRaisedButton* accessCodeButton = [[MDCRaisedButton alloc] init]; | |
| 143 [accessCodeButton setTitle:@"Get Access Code" | |
| 144 forState:UIControlStateNormal]; | |
| 145 [accessCodeButton sizeToFit]; | |
| 146 [accessCodeButton addTarget:self | |
| 147 action:@selector(didTapGetAccessCode:) | |
| 148 forControlEvents:UIControlEventTouchUpInside]; | |
| 149 accessCodeButton.translatesAutoresizingMaskIntoConstraints = NO; | |
| 150 cell.accessoryView = accessCodeButton; | |
| 151 } else if (indexPath.section == 0 && indexPath.item == 1) { | |
| 152 MDCRaisedButton* logoutButton = [[MDCRaisedButton alloc] init]; | |
| 153 [logoutButton setTitle:@"Logout" forState:UIControlStateNormal]; | |
| 154 [logoutButton sizeToFit]; | |
| 155 [logoutButton addTarget:self | |
| 156 action:@selector(didTapLogout:) | |
| 157 forControlEvents:UIControlEventTouchUpInside]; | |
| 158 logoutButton.translatesAutoresizingMaskIntoConstraints = NO; | |
| 159 cell.accessoryView = logoutButton; | |
| 160 } | |
| 161 | |
| 162 return cell; | |
| 163 } | |
| 164 | |
| 165 - (UICollectionReusableView*)collectionView:(UICollectionView*)collectionView | |
| 166 viewForSupplementaryElementOfKind:(NSString*)kind | |
| 167 atIndexPath:(NSIndexPath*)indexPath { | |
| 168 MDCCollectionViewTextCell* supplementaryView = | |
| 169 [collectionView dequeueReusableSupplementaryViewOfKind:kind | |
| 170 withReuseIdentifier:kind | |
| 171 forIndexPath:indexPath]; | |
| 172 if ([kind isEqualToString:UICollectionElementKindSectionHeader]) { | |
| 173 if (indexPath.section == 0) { | |
| 174 supplementaryView.textLabel.text = @"Account"; | |
| 175 } | |
| 176 supplementaryView.textLabel.textColor = kBackgroundColor; | |
| 177 } | |
| 178 return supplementaryView; | |
| 179 } | |
| 180 | |
| 181 #pragma mark - <UICollectionViewDelegateFlowLayout> | |
| 182 | |
| 183 - (CGSize)collectionView:(UICollectionView*)collectionView | |
| 184 layout: | |
| 185 (UICollectionViewLayout*)collectionViewLayout | |
| 186 referenceSizeForHeaderInSection:(NSInteger)section { | |
| 187 return CGSizeMake(collectionView.bounds.size.width, | |
| 188 MDCCellDefaultOneLineHeight); | |
| 189 } | |
| 190 | |
| 191 #pragma mark - Private | |
| 192 | |
| 193 - (void)didTapBack:(id)button { | |
| 194 [self dismissViewControllerAnimated:YES completion:nil]; | |
| 195 } | |
| 196 | |
| 197 - (void)didTapGetAccessCode:(id)sender { | |
| 198 NSString* authUri = | |
| 199 [NSString stringWithCString:GetAuthorizationCodeUri().c_str() | |
| 200 encoding:[NSString defaultCStringEncoding]]; | |
| 201 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:authUri]]; | |
| 202 } | |
| 203 | |
| 204 - (void)didTapLogout:(id)sender { | |
| 205 [[RemotingService SharedInstance].authentication logout]; | |
| 206 } | |
| 207 | |
| 208 @end | |
| OLD | NEW |