chromium/ios/chrome/browser/voice/model/text_to_speech_listener.mm

// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "ios/chrome/browser/voice/model/text_to_speech_listener.h"

#import <memory>

#import "base/check_op.h"
#import "ios/chrome/browser/voice/model/text_to_speech_parser.h"
#import "ios/chrome/browser/voice/model/voice_search_url_rewriter.h"
#import "ios/web/public/navigation/navigation_manager.h"
#import "ios/web/public/web_state.h"
#import "ios/web/public/web_state_observer.h"
#import "ios/web/public/web_state_observer_bridge.h"
#import "url/gurl.h"

#pragma mark - TextToSpeechListener Private Interface

@interface TextToSpeechListener () <CRWWebStateObserver>

// The TextToSpeechListenerDelegate passed on initialization.
@property(weak, nonatomic, readonly) id<TextToSpeechListenerDelegate> delegate;

@end

#pragma mark - TextToSpeechListener

@implementation TextToSpeechListener {
  // The WebStateObserverBridge that listens for WebState events.
  std::unique_ptr<web::WebStateObserverBridge> _webStateObserver;
}

@synthesize webState = _webState;
@synthesize delegate = _delegate;

- (instancetype)initWithWebState:(web::WebState*)webState
                        delegate:(id<TextToSpeechListenerDelegate>)delegate {
  if ((self = [super init])) {
    DCHECK(webState);
    DCHECK(delegate);
    _webState = webState;
    _delegate = delegate;

    _webStateObserver = std::make_unique<web::WebStateObserverBridge>(self);
    _webState->AddObserver(_webStateObserver.get());
    _webState->GetNavigationManager()->AddTransientURLRewriter(
        &VoiceSearchURLRewriter);
  }
  return self;
}

- (void)dealloc {
  if (_webState) {
    _webState->RemoveObserver(_webStateObserver.get());
    _webStateObserver.reset();
    _webState = nullptr;
  }
}

#pragma mark - CRWWebStateObserver

- (void)webState:(web::WebState*)webState didLoadPageWithSuccess:(BOOL)success {
  DCHECK_EQ(_webState, webState);
  const GURL& URL = webState->GetLastCommittedURL();
  if ([_delegate shouldTextToSpeechListener:self parseDataFromURL:URL]) {
    __weak TextToSpeechListener* weakSelf = self;
    ExtractVoiceSearchAudioDataFromWebState(webState, ^(NSData* audioData) {
      [weakSelf.delegate textToSpeechListener:weakSelf
                             didReceiveResult:audioData];
    });
  } else {
    [self.delegate textToSpeechListener:self didReceiveResult:nil];
  }
}

- (void)webStateDestroyed:(web::WebState*)webState {
  DCHECK_EQ(_webState, webState);
  if (_webState) {
    _webState->RemoveObserver(_webStateObserver.get());
    _webStateObserver.reset();
    _webState = nullptr;
  }
  [self.delegate textToSpeechListenerWebStateWasDestroyed:self];
}

@end