Commit 824cd870 authored by Robbie Gibson's avatar Robbie Gibson Committed by Commit Bot

[iOS] Factor search-by-image parameter construction into separate class

This CL moves constructing the WebLoadParams for search by image out
into their own separate class. This will be used in an upcoming CL to
immediately load the search-by-image search on startup from the search
widget.

Bug: 952939
Change-Id: I755dbd8190fe9d9cd08bbc9a4572afc9f2225a17
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1574058
Commit-Queue: Robbie Gibson <rkgibson@google.com>
Reviewed-by: default avatarRohit Rao <rohitrao@chromium.org>
Cr-Commit-Position: refs/heads/master@{#654542}
parent 8aa59c52
...@@ -166,6 +166,7 @@ ...@@ -166,6 +166,7 @@
#import "ios/chrome/browser/ui/voice/text_to_speech_playback_controller.h" #import "ios/chrome/browser/ui/voice/text_to_speech_playback_controller.h"
#import "ios/chrome/browser/ui/voice/text_to_speech_playback_controller_factory.h" #import "ios/chrome/browser/ui/voice/text_to_speech_playback_controller_factory.h"
#include "ios/chrome/browser/upgrade/upgrade_center.h" #include "ios/chrome/browser/upgrade/upgrade_center.h"
#import "ios/chrome/browser/url_loading/image_search_param_generator.h"
#import "ios/chrome/browser/url_loading/url_loading_notifier.h" #import "ios/chrome/browser/url_loading/url_loading_notifier.h"
#import "ios/chrome/browser/url_loading/url_loading_notifier_factory.h" #import "ios/chrome/browser/url_loading/url_loading_notifier_factory.h"
#import "ios/chrome/browser/url_loading/url_loading_observer_bridge.h" #import "ios/chrome/browser/url_loading/url_loading_observer_bridge.h"
...@@ -218,7 +219,6 @@ ...@@ -218,7 +219,6 @@
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/l10n_util_mac.h" #include "ui/base/l10n/l10n_util_mac.h"
#include "ui/base/page_transition_types.h" #include "ui/base/page_transition_types.h"
#import "ui/gfx/image/image_util.h"
#include "url/gurl.h" #include "url/gurl.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
...@@ -3338,61 +3338,26 @@ NSString* const kBrowserViewControllerSnackbarCategory = ...@@ -3338,61 +3338,26 @@ NSString* const kBrowserViewControllerSnackbarCategory =
// Performs a search using |data| and |imageURL| as inputs. Opens the results in // Performs a search using |data| and |imageURL| as inputs. Opens the results in
// a new tab based on |inNewTab|. // a new tab based on |inNewTab|.
- (void)searchByImageData:(NSData*)data atURL:(const GURL&)imageURL { - (void)searchByImageData:(NSData*)data atURL:(const GURL&)imageURL {
NSData* imageData = data; web::NavigationManager::WebLoadParams loadParams =
UIImage* image = [UIImage imageWithData:data]; ImageSearchParamGenerator::LoadParamsForImageData(
gfx::Image gfxImage(image); data, imageURL,
// Converting to gfx::Image creates an empty image if UIImage is nil. However, ios::TemplateURLServiceFactory::GetForBrowserState(_browserState));
// we still want to do the image search with nil data because that gives [self searchByImageWithWebLoadParams:loadParams inNewTab:YES];
// the user the best error experience.
if (gfxImage.IsEmpty()) {
[self searchByResizedImageData:imageData atURL:&imageURL inNewTab:YES];
return;
}
UIImage* resizedImage =
gfx::ResizedImageForSearchByImage(gfxImage).ToUIImage();
if (![image isEqual:resizedImage]) {
imageData = UIImageJPEGRepresentation(resizedImage, 1.0);
}
[self searchByResizedImageData:imageData atURL:&imageURL inNewTab:YES];
} }
// Performs a search with the given image data. The data should alread have // Performs a search with the given image data. The data should alread have
// been scaled down in |ResizedImageForSearchByImage|. // been scaled down in |ResizedImageForSearchByImage|.
- (void)searchByResizedImageData:(NSData*)data - (void)searchByImageWithWebLoadParams:
atURL:(const GURL*)imageURL (web::NavigationManager::WebLoadParams)webParams
inNewTab:(BOOL)inNewTab { inNewTab:(BOOL)inNewTab {
char const* bytes = reinterpret_cast<const char*>([data bytes]);
std::string byteString(bytes, [data length]);
TemplateURLService* templateUrlService =
ios::TemplateURLServiceFactory::GetForBrowserState(_browserState);
const TemplateURL* defaultURL =
templateUrlService->GetDefaultSearchProvider();
DCHECK(!defaultURL->image_url().empty());
DCHECK(defaultURL->image_url_ref().IsValid(
templateUrlService->search_terms_data()));
TemplateURLRef::SearchTermsArgs search_args(base::ASCIIToUTF16(""));
if (imageURL) {
search_args.image_url = *imageURL;
}
search_args.image_thumbnail_content = byteString;
// Generate the URL and populate |post_content| with the content type and
// HTTP body for the request.
TemplateURLRef::PostContent postContent;
GURL result(defaultURL->image_url_ref().ReplaceSearchTerms(
search_args, templateUrlService->search_terms_data(), &postContent));
web::NavigationManager::WebLoadParams loadParams =
web_navigation_util::CreateWebLoadParams(
result, ui::PAGE_TRANSITION_TYPED, &postContent);
if (inNewTab) { if (inNewTab) {
UrlLoadParams params = UrlLoadParams::InNewTab(loadParams); UrlLoadParams params = UrlLoadParams::InNewTab(webParams);
params.in_incognito = self.isOffTheRecord; params.in_incognito = self.isOffTheRecord;
UrlLoadingServiceFactory::GetForBrowserState(self.browserState) UrlLoadingServiceFactory::GetForBrowserState(self.browserState)
->Load(params); ->Load(params);
} else { } else {
UrlLoadingServiceFactory::GetForBrowserState(self.browserState) UrlLoadingServiceFactory::GetForBrowserState(self.browserState)
->Load(UrlLoadParams::InCurrentTab(loadParams)); ->Load(UrlLoadParams::InCurrentTab(webParams));
} }
} }
...@@ -4297,11 +4262,11 @@ NSString* const kBrowserViewControllerSnackbarCategory = ...@@ -4297,11 +4262,11 @@ NSString* const kBrowserViewControllerSnackbarCategory =
} }
- (void)searchByImage:(UIImage*)image { - (void)searchByImage:(UIImage*)image {
gfx::Image gfxImage(image); [self searchByImageWithWebLoadParams:
UIImage* resizedImage = ImageSearchParamGenerator::LoadParamsForImage(
gfx::ResizedImageForSearchByImage(gfxImage).ToUIImage(); image, ios::TemplateURLServiceFactory::GetForBrowserState(
NSData* data = UIImageJPEGRepresentation(resizedImage, 1.0); _browserState))
[self searchByResizedImageData:data atURL:nil inNewTab:NO]; inNewTab:NO];
} }
#pragma mark - FindInPageResponseDelegate #pragma mark - FindInPageResponseDelegate
......
...@@ -7,6 +7,8 @@ source_set("url_loading") { ...@@ -7,6 +7,8 @@ source_set("url_loading") {
sources = [ sources = [
"app_url_loading_service.h", "app_url_loading_service.h",
"app_url_loading_service.mm", "app_url_loading_service.mm",
"image_search_param_generator.h",
"image_search_param_generator.mm",
"test_app_url_loading_service.h", "test_app_url_loading_service.h",
"test_app_url_loading_service.mm", "test_app_url_loading_service.mm",
"test_url_loading_service.h", "test_url_loading_service.h",
...@@ -29,6 +31,7 @@ source_set("url_loading") { ...@@ -29,6 +31,7 @@ source_set("url_loading") {
deps = [ deps = [
"//base", "//base",
"//components/keyed_service/ios", "//components/keyed_service/ios",
"//components/search_engines",
"//components/sessions", "//components/sessions",
"//ios/chrome/app:mode", "//ios/chrome/app:mode",
"//ios/chrome/browser", "//ios/chrome/browser",
...@@ -53,6 +56,7 @@ source_set("unit_tests") { ...@@ -53,6 +56,7 @@ source_set("unit_tests") {
configs += [ "//build/config/compiler:enable_arc" ] configs += [ "//build/config/compiler:enable_arc" ]
testonly = true testonly = true
sources = [ sources = [
"image_search_param_generator_unittest.mm",
"url_loading_service_unittest.mm", "url_loading_service_unittest.mm",
] ]
deps = [ deps = [
...@@ -63,6 +67,7 @@ source_set("unit_tests") { ...@@ -63,6 +67,7 @@ source_set("unit_tests") {
"//ios/chrome/browser/browser_state", "//ios/chrome/browser/browser_state",
"//ios/chrome/browser/browser_state:test_support", "//ios/chrome/browser/browser_state:test_support",
"//ios/chrome/browser/main:test_support", "//ios/chrome/browser/main:test_support",
"//ios/chrome/browser/search_engines",
"//ios/chrome/browser/tabs", "//ios/chrome/browser/tabs",
"//ios/chrome/browser/web", "//ios/chrome/browser/web",
"//ios/chrome/browser/web:web_internal", "//ios/chrome/browser/web:web_internal",
......
// Copyright 2019 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.
#ifndef IOS_CHROME_BROWSER_URL_LOADING_IMAGE_SEARCH_PARAM_GENERATOR_H_
#define IOS_CHROME_BROWSER_URL_LOADING_IMAGE_SEARCH_PARAM_GENERATOR_H_
#import <UIKit/UIKit.h>
#import "ios/chrome/browser/web/web_navigation_util.h"
class GURL;
class TemplateURLService;
class ImageSearchParamGenerator {
public:
// Create loading parameters using the given |data|, which should represent
// an image and |url|, the web url the image came from. This can be useful to
// avoid having to convert from UIImage back to NSData, which can be slow. If
// the image data didn't come from a url, use an empty GURL to indicate that.
static web::NavigationManager::WebLoadParams LoadParamsForImageData(
NSData* data,
const GURL& url,
TemplateURLService* template_url_service);
// Create loading parameters using the given |image|.
static web::NavigationManager::WebLoadParams LoadParamsForImage(
UIImage* image,
TemplateURLService* template_url_service);
private:
static web::NavigationManager::WebLoadParams LoadParamsForResizedImageData(
NSData* data,
const GURL& url,
TemplateURLService* template_url_service);
};
#endif // IOS_CHROME_BROWSER_URL_LOADING_IMAGE_SEARCH_PARAM_GENERATOR_H_
// Copyright 2019 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/url_loading/image_search_param_generator.h"
#include "base/strings/utf_string_conversions.h"
#include "components/search_engines/template_url_service.h"
#import "ui/gfx/image/image.h"
#import "ui/gfx/image/image_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
web::NavigationManager::WebLoadParams
ImageSearchParamGenerator::LoadParamsForImageData(
NSData* data,
const GURL& url,
TemplateURLService* template_url_service) {
NSData* image_data = data;
UIImage* image = [UIImage imageWithData:image_data];
gfx::Image gfx_image(image);
// Converting to gfx::Image creates an empty image if UIImage is nil. However,
// we still want to do the image search with nil data because that gives
// the user the best error experience.
if (gfx_image.IsEmpty()) {
return LoadParamsForResizedImageData(image_data, url, template_url_service);
}
UIImage* resized_image =
gfx::ResizedImageForSearchByImage(gfx_image).ToUIImage();
if (![image isEqual:resized_image]) {
image_data = UIImageJPEGRepresentation(resized_image, 1.0);
}
return LoadParamsForResizedImageData(image_data, url, template_url_service);
}
web::NavigationManager::WebLoadParams
ImageSearchParamGenerator::LoadParamsForImage(
UIImage* image,
TemplateURLService* template_url_service) {
gfx::Image gfx_image(image);
// Converting to gfx::Image creates an empty image if UIImage is nil. However,
// we still want to do the image search with nil data because that gives
// the user the best error experience.
if (gfx_image.IsEmpty()) {
return LoadParamsForResizedImageData(nil, GURL(), template_url_service);
}
UIImage* resized_image =
gfx::ResizedImageForSearchByImage(gfx_image).ToUIImage();
NSData* data = UIImageJPEGRepresentation(resized_image, 1.0);
return LoadParamsForResizedImageData(data, GURL(), template_url_service);
}
// This method does all the work of constructing the parameters. Internally,
// the class uses an empty GURL to signify that the url is not present, and
// shouldn't be added to the search arguments.
web::NavigationManager::WebLoadParams
ImageSearchParamGenerator::LoadParamsForResizedImageData(
NSData* data,
const GURL& url,
TemplateURLService* template_url_service) {
char const* bytes = reinterpret_cast<const char*>([data bytes]);
std::string byte_string(bytes, [data length]);
const TemplateURL* default_url =
template_url_service->GetDefaultSearchProvider();
DCHECK(!default_url->image_url().empty());
DCHECK(default_url->image_url_ref().IsValid(
template_url_service->search_terms_data()));
TemplateURLRef::SearchTermsArgs search_args(base::ASCIIToUTF16(""));
if (!url.is_empty()) {
search_args.image_url = url;
}
search_args.image_thumbnail_content = byte_string;
// Generate the URL and populate |post_content| with the content type and
// HTTP body for the request.
TemplateURLRef::PostContent post_content;
GURL result(default_url->image_url_ref().ReplaceSearchTerms(
search_args, template_url_service->search_terms_data(), &post_content));
web::NavigationManager::WebLoadParams web_load_params =
web_navigation_util::CreateWebLoadParams(
result, ui::PAGE_TRANSITION_TYPED, &post_content);
return web_load_params;
}
// Copyright 2019 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/url_loading/image_search_param_generator.h"
#include "base/test/scoped_task_environment.h"
#import "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
#include "ios/chrome/browser/search_engines/template_url_service_factory.h"
#include "testing/platform_test.h"
#include "third_party/ocmock/gtest_support.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
class ImageSearchParamGeneratorTest : public PlatformTest {
public:
ImageSearchParamGeneratorTest() {}
protected:
void SetUp() override {
// Set up a TestChromeBrowserState instance.
TestChromeBrowserState::Builder test_cbs_builder;
test_cbs_builder.AddTestingFactory(
ios::TemplateURLServiceFactory::GetInstance(),
ios::TemplateURLServiceFactory::GetDefaultFactory());
chrome_browser_state_ = test_cbs_builder.Build();
}
base::test::ScopedTaskEnvironment scoped_task_environment_;
std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
};
TEST_F(ImageSearchParamGeneratorTest, TestNilImage) {
TemplateURLService* template_url_service =
ios::TemplateURLServiceFactory::GetForBrowserState(
chrome_browser_state_.get());
web::NavigationManager::WebLoadParams load_params =
ImageSearchParamGenerator::LoadParamsForImageData(nil, GURL(),
template_url_service);
ASSERT_EQ(load_params.url,
GURL("https://www.google.com/searchbyimage/upload"));
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment