Chromium Code Reviews| Index: ios/chrome/browser/physical_web/physical_web_initial_state_recorder.mm |
| diff --git a/ios/chrome/browser/physical_web/physical_web_initial_state_recorder.mm b/ios/chrome/browser/physical_web/physical_web_initial_state_recorder.mm |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..2ba4df5ce99e7a5955d785eea6d3c6ab2574c5d9 |
| --- /dev/null |
| +++ b/ios/chrome/browser/physical_web/physical_web_initial_state_recorder.mm |
| @@ -0,0 +1,131 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#import "ios/chrome/browser/physical_web/physical_web_initial_state_recorder.h" |
| + |
| +#include "base/mac/scoped_nsobject.h" |
| +#include "base/metrics/histogram.h" |
| +#include "ios/chrome/browser/physical_web/physical_web_constants.h" |
| + |
| +namespace { |
| + |
| +// Initial state of settings relevant to the Physical Web feature. These are |
| +// ordered so that bits 2:0 encode the Bluetooth enabled state, the Location |
| +// Services enabled state, and whether Chrome has been granted the Location app |
| +// permission. Bits 4:3 encode the Physical Web preference tristate. |
|
rohitrao (ping after 24h)
2016/10/31 19:41:08
This feels very brittle. There is no better way t
mattreynolds
2016/11/01 17:17:17
We could record the state separately, but combinin
|
| +enum PhysicalWebInitialStateIosChrome { |
| + OPTOUT_BTOFF_LOCOFF_UNAUTH, |
| + OPTOUT_BTOFF_LOCOFF_AUTH, |
| + OPTOUT_BTOFF_LOCON_UNAUTH, |
| + OPTOUT_BTOFF_LOCON_AUTH, |
| + OPTOUT_BTON_LOCOFF_UNAUTH, |
| + OPTOUT_BTON_LOCOFF_AUTH, |
| + OPTOUT_BTON_LOCON_UNAUTH, |
| + OPTOUT_BTON_LOCON_AUTH, |
| + OPTIN_BTOFF_LOCOFF_UNAUTH, |
| + OPTIN_BTOFF_LOCOFF_AUTH, |
| + OPTIN_BTOFF_LOCON_UNAUTH, |
| + OPTIN_BTOFF_LOCON_AUTH, |
| + OPTIN_BTON_LOCOFF_UNAUTH, |
| + OPTIN_BTON_LOCOFF_AUTH, |
| + OPTIN_BTON_LOCON_UNAUTH, |
| + OPTIN_BTON_LOCON_AUTH, |
| + ONBOARDING_BTOFF_LOCOFF_UNAUTH, |
| + ONBOARDING_BTOFF_LOCOFF_AUTH, |
| + ONBOARDING_BTOFF_LOCON_UNAUTH, |
| + ONBOARDING_BTOFF_LOCON_AUTH, |
| + ONBOARDING_BTON_LOCOFF_UNAUTH, |
| + ONBOARDING_BTON_LOCOFF_AUTH, |
| + ONBOARDING_BTON_LOCON_UNAUTH, |
| + ONBOARDING_BTON_LOCON_AUTH, |
| + PHYSICAL_WEB_INITIAL_STATE_COUNT, |
| + |
| + // Helper flag values |
| + LOCATION_AUTHORIZED_FLAG = 1 << 0, |
| + LOCATION_SERVICES_FLAG = 1 << 1, |
| + BLUETOOTH_FLAG = 1 << 2, |
| + OPTIN_FLAG = 1 << 3, |
| + ONBOARDING_FLAG = 1 << 4, |
| +}; |
| +} // namespace |
| + |
| +@implementation PhysicalWebInitialStateRecorder { |
| + int preferenceState_; |
| + BOOL locationServicesEnabled_; |
| + BOOL locationAuthorized_; |
| + BOOL bluetoothEnabled_; |
| + base::scoped_nsobject<CBCentralManager> centralManager_; |
| +} |
| + |
| +- (instancetype)initWithPreferenceState:(int)preferenceState |
| + locationServicesEnabled:(BOOL)locationServicesEnabled |
| + locationAuthorized:(BOOL)locationAuthorized { |
| + self = [super init]; |
| + if (self) { |
| + preferenceState_ = preferenceState; |
| + locationServicesEnabled_ = locationServicesEnabled; |
| + locationAuthorized_ = locationAuthorized; |
| + centralManager_.reset([[CBCentralManager alloc] |
| + initWithDelegate:self |
| + queue:dispatch_get_main_queue() |
| + options:@{ |
| + CBCentralManagerOptionShowPowerAlertKey : @NO |
| + }]); |
| + |
| + // Make sure we aren't released before the central manager reports back. |
| + [self retain]; |
| + } |
| + return self; |
| +} |
| + |
| +- (instancetype)init { |
| + NOTREACHED(); |
| + return nil; |
| +} |
| + |
| +- (void)dealloc { |
| + [centralManager_ setDelegate:nil]; |
| + centralManager_.reset(); |
| + [super dealloc]; |
| +} |
| + |
| +- (BOOL)bluetoothEnabled { |
| +// TODO(crbug.com/619982): The CBManager base class appears to still be in |
| +// flux. Unwind this #ifdef once the APIs settle. |
|
rohitrao (ping after 24h)
2016/10/31 19:41:08
Have the APIs settled now that iOS10 is out for re
mattreynolds
2016/11/01 17:17:16
Yeah, I think we can remove the #ifdef now.
|
| +#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 |
| + return [centralManager_ state] == CBManagerStatePoweredOn; |
| +#else |
| + return [centralManager_ state] == CBCentralManagerStatePoweredOn; |
| +#endif |
| +} |
| + |
| +- (void)centralManagerDidUpdateState:(CBCentralManager*)central { |
| + [self recordInitialStateAndFinish]; |
| +} |
| + |
| +- (void)recordInitialStateAndFinish { |
| + int state = 0; |
| + if (preferenceState_ == physical_web::kPhysicalWebOn) { |
| + state |= OPTIN_FLAG; |
| + } else if (preferenceState_ == physical_web::kPhysicalWebOnboarding) { |
| + state |= ONBOARDING_FLAG; |
| + } |
| + if (locationServicesEnabled_) { |
| + state |= LOCATION_SERVICES_FLAG; |
| + } |
| + if (locationAuthorized_) { |
| + state |= LOCATION_AUTHORIZED_FLAG; |
| + } |
| + if ([self bluetoothEnabled]) { |
| + state |= BLUETOOTH_FLAG; |
| + } |
| + |
| + DCHECK(state < PHYSICAL_WEB_INITIAL_STATE_COUNT); |
| + UMA_HISTOGRAM_ENUMERATION("PhysicalWeb.InitialState.IosChrome", state, |
| + PHYSICAL_WEB_INITIAL_STATE_COUNT); |
| + |
| + [self release]; |
| +} |
| + |
| +@end |