Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Unified Diff: ios/chrome/app/spotlight/base_spotlight_manager.mm

Issue 2580363002: Upstream Chrome on iOS source code [1/11]. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ios/chrome/app/spotlight/base_spotlight_manager.mm
diff --git a/ios/chrome/app/spotlight/base_spotlight_manager.mm b/ios/chrome/app/spotlight/base_spotlight_manager.mm
new file mode 100644
index 0000000000000000000000000000000000000000..4d497c1b1d9a2a1d21c614816576a63a5260d1ca
--- /dev/null
+++ b/ios/chrome/app/spotlight/base_spotlight_manager.mm
@@ -0,0 +1,272 @@
+// Copyright 2015 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/app/spotlight/base_spotlight_manager.h"
+
+#import <CommonCrypto/CommonCrypto.h>
+#import <MobileCoreServices/MobileCoreServices.h>
+
+#include "base/ios/weak_nsobject.h"
+#include "base/mac/bind_objc_block.h"
+#include "base/strings/sys_string_conversions.h"
+#include "base/task/cancelable_task_tracker.h"
+#include "components/favicon/core/fallback_url_util.h"
+#include "components/favicon/core/large_icon_service.h"
+#include "components/favicon_base/fallback_icon_style.h"
+#include "components/favicon_base/favicon_types.h"
+#include "ios/chrome/grit/ios_strings.h"
+#include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
+#include "ios/public/provider/chrome/browser/spotlight/spotlight_provider.h"
+#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
+#import "net/base/mac/url_conversions.h"
+#include "skia/ext/skia_utils_ios.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace {
+// Minimum size of the icon to be used in Spotlight.
+const NSInteger kMinIconSize = 32;
+
+// Preferred size of the icon to be used in Spotlight.
+const NSInteger kIconSize = 64;
+
+// Size of the fallback icon.
+const CGFloat kFallbackIconSize = 180;
+
+// Radius of the rounded corner of the fallback icon.
+const CGFloat kFallbackRoundedCorner = 8;
+}
+
+@interface BaseSpotlightManager () {
+ // Domain of the spotlight manager.
+ spotlight::Domain _spotlightDomain;
+
+ // Service to retrieve large favicon or colors for a fallback icon.
+ favicon::LargeIconService* _largeIconService; // weak
+
+ // Queue to query large icons.
+ base::CancelableTaskTracker _largeIconTaskTracker;
+
+ // Dictionary to track the tasks querying the large icons.
+ base::scoped_nsobject<NSMutableDictionary> _pendingTasks;
+}
+
+// Compute a hash consisting of the first 8 bytes of the MD5 hash of a string
+// containing |URL| and |title|.
+- (int64_t)getHashForURL:(const GURL&)URL title:(NSString*)title;
+
+// Create an image with a rounded square with color |backgroundColor| and
+// |string| centered in color |textColor|.
+UIImage* GetFallbackImageWithStringAndColor(NSString* string,
+ UIColor* backgroundColor,
+ UIColor* textColor);
+
+// Returns an array of Keywords for Spotlight search.
+- (NSArray*)keywordsForSpotlightItems;
+
+@end
+
+@implementation BaseSpotlightManager
+
+- (instancetype)initWithLargeIconService:
+ (favicon::LargeIconService*)largeIconService
+ domain:(spotlight::Domain)domain {
+ self = [super init];
+ if (self) {
+ _spotlightDomain = domain;
+ _largeIconService = largeIconService;
+ _pendingTasks.reset([[NSMutableDictionary alloc] init]);
+ }
+ return self;
+}
+
+- (instancetype)init {
+ NOTREACHED();
+ return nil;
+}
+
+- (int64_t)getHashForURL:(const GURL&)URL title:(NSString*)title {
+ NSString* key = [NSString
+ stringWithFormat:@"%@ %@", base::SysUTF8ToNSString(URL.spec()), title];
+ unsigned char hash[CC_MD5_DIGEST_LENGTH];
+ const std::string clipboard = base::SysNSStringToUTF8(key);
+ const char* c_string = clipboard.c_str();
+ CC_MD5(c_string, strlen(c_string), hash);
+ uint64_t md5 = *(reinterpret_cast<uint64_t*>(hash));
+ return md5;
+}
+
+- (NSString*)spotlightIDForURL:(const GURL&)URL title:(NSString*)title {
+ NSString* spotlightID = [NSString
+ stringWithFormat:@"%@.%016llx",
+ spotlight::StringFromSpotlightDomain(_spotlightDomain),
+ [self getHashForURL:URL title:title]];
+ return spotlightID;
+}
+
+- (void)cancelAllLargeIconPendingTasks {
+ _largeIconTaskTracker.TryCancelAll();
+ [_pendingTasks removeAllObjects];
+}
+
+- (void)clearAllSpotlightItems:(BlockWithError)callback {
+ [self cancelAllLargeIconPendingTasks];
+ spotlight::DeleteSearchableDomainItems(_spotlightDomain, callback);
+}
+
+- (CSSearchableItem*)spotlightItemWithItemID:(NSString*)itemID
+ attributeSet:(CSSearchableItemAttributeSet*)
+ attributeSet {
+ CSCustomAttributeKey* key = [[[CSCustomAttributeKey alloc]
+ initWithKeyName:spotlight::GetSpotlightCustomAttributeItemID()
+ searchable:YES
+ searchableByDefault:YES
+ unique:YES
+ multiValued:NO] autorelease];
+ [attributeSet setValue:itemID forCustomKey:key];
+ attributeSet.keywords = [self keywordsForSpotlightItems];
+
+ NSString* domainID = spotlight::StringFromSpotlightDomain(_spotlightDomain);
+
+ return [[[CSSearchableItem alloc] initWithUniqueIdentifier:itemID
+ domainIdentifier:domainID
+ attributeSet:attributeSet]
+ autorelease];
+}
+
+- (NSArray*)spotlightItemsWithURL:(const GURL&)indexedURL
+ favicon:(UIImage*)favicon
+ defaultTitle:(NSString*)defaultTitle {
+ DCHECK(defaultTitle);
+ NSURL* nsURL = net::NSURLWithGURL(indexedURL);
+ std::string description = indexedURL.SchemeIsCryptographic()
+ ? indexedURL.GetOrigin().spec()
+ : indexedURL.spec();
+
+ base::scoped_nsobject<CSSearchableItemAttributeSet> attributeSet(
+ [[CSSearchableItemAttributeSet alloc]
+ initWithItemContentType:(NSString*)kUTTypeURL]);
+ [attributeSet setTitle:defaultTitle];
+ [attributeSet setDisplayName:defaultTitle];
+ [attributeSet setURL:nsURL];
+ [attributeSet setContentURL:nsURL];
+ [attributeSet setContentDescription:base::SysUTF8ToNSString(description)];
+ [attributeSet setThumbnailData:UIImagePNGRepresentation(favicon)];
+
+ NSString* itemID = [self spotlightIDForURL:indexedURL title:defaultTitle];
+ return [NSArray arrayWithObject:[self spotlightItemWithItemID:itemID
+ attributeSet:attributeSet]];
+}
+
+UIImage* GetFallbackImageWithStringAndColor(NSString* string,
+ UIColor* backgroundColor,
+ UIColor* textColor) {
+ CGRect rect = CGRectMake(0, 0, kFallbackIconSize, kFallbackIconSize);
+ UIGraphicsBeginImageContext(rect.size);
+ CGContextRef context = UIGraphicsGetCurrentContext();
+ CGContextSetFillColorWithColor(context, [backgroundColor CGColor]);
+ CGContextSetStrokeColorWithColor(context, [textColor CGColor]);
+ UIBezierPath* rounded =
+ [UIBezierPath bezierPathWithRoundedRect:rect
+ cornerRadius:kFallbackRoundedCorner];
+ [rounded fill];
+ UIFont* font = [MDCTypography headlineFont];
+ font = [font fontWithSize:(kFallbackIconSize / 2)];
+ CGRect textRect = CGRectMake(0, (kFallbackIconSize - [font lineHeight]) / 2,
+ kFallbackIconSize, [font lineHeight]);
+ base::scoped_nsobject<NSMutableParagraphStyle> paragraphStyle(
+ [[NSMutableParagraphStyle alloc] init]);
+ [paragraphStyle setAlignment:NSTextAlignmentCenter];
+ base::scoped_nsobject<NSMutableDictionary> attributes(
+ [[NSMutableDictionary alloc] init]);
+ [attributes setValue:font forKey:NSFontAttributeName];
+ [attributes setValue:textColor forKey:NSForegroundColorAttributeName];
+ [attributes setValue:paragraphStyle forKey:NSParagraphStyleAttributeName];
+
+ [string drawInRect:textRect withAttributes:attributes];
+ UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
+ UIGraphicsEndImageContext();
+ return image;
+}
+
+- (void)refreshItemsWithURL:(const GURL&)URLToRefresh title:(NSString*)title {
+ NSURL* NSURL = net::NSURLWithGURL(URLToRefresh);
+
+ if (!NSURL || [_pendingTasks objectForKey:NSURL]) {
+ return;
+ }
+
+ base::WeakNSObject<BaseSpotlightManager> weakSelf(self);
+ GURL URL = URLToRefresh;
+ void (^faviconBlock)(const favicon_base::LargeIconResult&) = ^(
+ const favicon_base::LargeIconResult& result) {
+ base::scoped_nsobject<BaseSpotlightManager> strongSelf([weakSelf retain]);
+ if (!strongSelf) {
+ return;
+ }
+ [strongSelf.get()->_pendingTasks removeObjectForKey:NSURL];
+ UIImage* favicon;
+ if (result.bitmap.is_valid()) {
+ scoped_refptr<base::RefCountedMemory> data =
+ result.bitmap.bitmap_data.get();
+ favicon = [UIImage
+ imageWithData:[NSData dataWithBytes:data->front() length:data->size()]
+ scale:[UIScreen mainScreen].scale];
+ } else {
+ NSString* iconText =
+ base::SysUTF16ToNSString(favicon::GetFallbackIconText(URL));
+ UIColor* backgroundColor = skia::UIColorFromSkColor(
+ result.fallback_icon_style->background_color);
+ UIColor* textColor =
+ skia::UIColorFromSkColor(result.fallback_icon_style->text_color);
+ favicon = GetFallbackImageWithStringAndColor(iconText, backgroundColor,
+ textColor);
+ }
+ NSArray* spotlightItems = [strongSelf spotlightItemsWithURL:URL
+ favicon:favicon
+ defaultTitle:title];
+
+ if ([spotlightItems count]) {
+ [[CSSearchableIndex defaultSearchableIndex]
+ indexSearchableItems:spotlightItems
+ completionHandler:nil];
+ }
+ };
+
+ base::CancelableTaskTracker::TaskId taskID =
+ _largeIconService->GetLargeIconOrFallbackStyle(
+ URL, kMinIconSize * [UIScreen mainScreen].scale,
+ kIconSize * [UIScreen mainScreen].scale,
+ base::BindBlock(faviconBlock), &_largeIconTaskTracker);
+ [_pendingTasks setObject:[NSNumber numberWithLongLong:taskID] forKey:NSURL];
+}
+
+- (NSUInteger)pendingLargeIconTasksCount {
+ return [_pendingTasks count];
+}
+
+#pragma mark private methods
+
+- (NSArray*)keywordsForSpotlightItems {
+ NSMutableArray* keywordsArray = [NSMutableArray arrayWithArray:@[
+ l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_ONE),
+ l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_TWO),
+ l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_THREE),
+ l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_FOUR),
+ l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_FIVE),
+ l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_SIX),
+ l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_SEVEN),
+ l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_EIGHT),
+ l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_NINE),
+ l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_TEN)
+ ]];
+ NSArray* additionalArray = ios::GetChromeBrowserProvider()
+ ->GetSpotlightProvider()
+ ->GetAdditionalKeywords();
+ if (additionalArray) {
+ [keywordsArray addObjectsFromArray:additionalArray];
+ }
+ return keywordsArray;
+}
+
+@end
« no previous file with comments | « ios/chrome/app/spotlight/base_spotlight_manager.h ('k') | ios/chrome/app/spotlight/bookmarks_spotlight_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698