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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 #import "ios/chrome/app/spotlight/base_spotlight_manager.h"
6
7 #import <CommonCrypto/CommonCrypto.h>
8 #import <MobileCoreServices/MobileCoreServices.h>
9
10 #include "base/ios/weak_nsobject.h"
11 #include "base/mac/bind_objc_block.h"
12 #include "base/strings/sys_string_conversions.h"
13 #include "base/task/cancelable_task_tracker.h"
14 #include "components/favicon/core/fallback_url_util.h"
15 #include "components/favicon/core/large_icon_service.h"
16 #include "components/favicon_base/fallback_icon_style.h"
17 #include "components/favicon_base/favicon_types.h"
18 #include "ios/chrome/grit/ios_strings.h"
19 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
20 #include "ios/public/provider/chrome/browser/spotlight/spotlight_provider.h"
21 #import "ios/third_party/material_components_ios/src/components/Typography/src/M aterialTypography.h"
22 #import "net/base/mac/url_conversions.h"
23 #include "skia/ext/skia_utils_ios.h"
24 #include "ui/base/l10n/l10n_util.h"
25
26 namespace {
27 // Minimum size of the icon to be used in Spotlight.
28 const NSInteger kMinIconSize = 32;
29
30 // Preferred size of the icon to be used in Spotlight.
31 const NSInteger kIconSize = 64;
32
33 // Size of the fallback icon.
34 const CGFloat kFallbackIconSize = 180;
35
36 // Radius of the rounded corner of the fallback icon.
37 const CGFloat kFallbackRoundedCorner = 8;
38 }
39
40 @interface BaseSpotlightManager () {
41 // Domain of the spotlight manager.
42 spotlight::Domain _spotlightDomain;
43
44 // Service to retrieve large favicon or colors for a fallback icon.
45 favicon::LargeIconService* _largeIconService; // weak
46
47 // Queue to query large icons.
48 base::CancelableTaskTracker _largeIconTaskTracker;
49
50 // Dictionary to track the tasks querying the large icons.
51 base::scoped_nsobject<NSMutableDictionary> _pendingTasks;
52 }
53
54 // Compute a hash consisting of the first 8 bytes of the MD5 hash of a string
55 // containing |URL| and |title|.
56 - (int64_t)getHashForURL:(const GURL&)URL title:(NSString*)title;
57
58 // Create an image with a rounded square with color |backgroundColor| and
59 // |string| centered in color |textColor|.
60 UIImage* GetFallbackImageWithStringAndColor(NSString* string,
61 UIColor* backgroundColor,
62 UIColor* textColor);
63
64 // Returns an array of Keywords for Spotlight search.
65 - (NSArray*)keywordsForSpotlightItems;
66
67 @end
68
69 @implementation BaseSpotlightManager
70
71 - (instancetype)initWithLargeIconService:
72 (favicon::LargeIconService*)largeIconService
73 domain:(spotlight::Domain)domain {
74 self = [super init];
75 if (self) {
76 _spotlightDomain = domain;
77 _largeIconService = largeIconService;
78 _pendingTasks.reset([[NSMutableDictionary alloc] init]);
79 }
80 return self;
81 }
82
83 - (instancetype)init {
84 NOTREACHED();
85 return nil;
86 }
87
88 - (int64_t)getHashForURL:(const GURL&)URL title:(NSString*)title {
89 NSString* key = [NSString
90 stringWithFormat:@"%@ %@", base::SysUTF8ToNSString(URL.spec()), title];
91 unsigned char hash[CC_MD5_DIGEST_LENGTH];
92 const std::string clipboard = base::SysNSStringToUTF8(key);
93 const char* c_string = clipboard.c_str();
94 CC_MD5(c_string, strlen(c_string), hash);
95 uint64_t md5 = *(reinterpret_cast<uint64_t*>(hash));
96 return md5;
97 }
98
99 - (NSString*)spotlightIDForURL:(const GURL&)URL title:(NSString*)title {
100 NSString* spotlightID = [NSString
101 stringWithFormat:@"%@.%016llx",
102 spotlight::StringFromSpotlightDomain(_spotlightDomain),
103 [self getHashForURL:URL title:title]];
104 return spotlightID;
105 }
106
107 - (void)cancelAllLargeIconPendingTasks {
108 _largeIconTaskTracker.TryCancelAll();
109 [_pendingTasks removeAllObjects];
110 }
111
112 - (void)clearAllSpotlightItems:(BlockWithError)callback {
113 [self cancelAllLargeIconPendingTasks];
114 spotlight::DeleteSearchableDomainItems(_spotlightDomain, callback);
115 }
116
117 - (CSSearchableItem*)spotlightItemWithItemID:(NSString*)itemID
118 attributeSet:(CSSearchableItemAttributeSet*)
119 attributeSet {
120 CSCustomAttributeKey* key = [[[CSCustomAttributeKey alloc]
121 initWithKeyName:spotlight::GetSpotlightCustomAttributeItemID()
122 searchable:YES
123 searchableByDefault:YES
124 unique:YES
125 multiValued:NO] autorelease];
126 [attributeSet setValue:itemID forCustomKey:key];
127 attributeSet.keywords = [self keywordsForSpotlightItems];
128
129 NSString* domainID = spotlight::StringFromSpotlightDomain(_spotlightDomain);
130
131 return [[[CSSearchableItem alloc] initWithUniqueIdentifier:itemID
132 domainIdentifier:domainID
133 attributeSet:attributeSet]
134 autorelease];
135 }
136
137 - (NSArray*)spotlightItemsWithURL:(const GURL&)indexedURL
138 favicon:(UIImage*)favicon
139 defaultTitle:(NSString*)defaultTitle {
140 DCHECK(defaultTitle);
141 NSURL* nsURL = net::NSURLWithGURL(indexedURL);
142 std::string description = indexedURL.SchemeIsCryptographic()
143 ? indexedURL.GetOrigin().spec()
144 : indexedURL.spec();
145
146 base::scoped_nsobject<CSSearchableItemAttributeSet> attributeSet(
147 [[CSSearchableItemAttributeSet alloc]
148 initWithItemContentType:(NSString*)kUTTypeURL]);
149 [attributeSet setTitle:defaultTitle];
150 [attributeSet setDisplayName:defaultTitle];
151 [attributeSet setURL:nsURL];
152 [attributeSet setContentURL:nsURL];
153 [attributeSet setContentDescription:base::SysUTF8ToNSString(description)];
154 [attributeSet setThumbnailData:UIImagePNGRepresentation(favicon)];
155
156 NSString* itemID = [self spotlightIDForURL:indexedURL title:defaultTitle];
157 return [NSArray arrayWithObject:[self spotlightItemWithItemID:itemID
158 attributeSet:attributeSet]];
159 }
160
161 UIImage* GetFallbackImageWithStringAndColor(NSString* string,
162 UIColor* backgroundColor,
163 UIColor* textColor) {
164 CGRect rect = CGRectMake(0, 0, kFallbackIconSize, kFallbackIconSize);
165 UIGraphicsBeginImageContext(rect.size);
166 CGContextRef context = UIGraphicsGetCurrentContext();
167 CGContextSetFillColorWithColor(context, [backgroundColor CGColor]);
168 CGContextSetStrokeColorWithColor(context, [textColor CGColor]);
169 UIBezierPath* rounded =
170 [UIBezierPath bezierPathWithRoundedRect:rect
171 cornerRadius:kFallbackRoundedCorner];
172 [rounded fill];
173 UIFont* font = [MDCTypography headlineFont];
174 font = [font fontWithSize:(kFallbackIconSize / 2)];
175 CGRect textRect = CGRectMake(0, (kFallbackIconSize - [font lineHeight]) / 2,
176 kFallbackIconSize, [font lineHeight]);
177 base::scoped_nsobject<NSMutableParagraphStyle> paragraphStyle(
178 [[NSMutableParagraphStyle alloc] init]);
179 [paragraphStyle setAlignment:NSTextAlignmentCenter];
180 base::scoped_nsobject<NSMutableDictionary> attributes(
181 [[NSMutableDictionary alloc] init]);
182 [attributes setValue:font forKey:NSFontAttributeName];
183 [attributes setValue:textColor forKey:NSForegroundColorAttributeName];
184 [attributes setValue:paragraphStyle forKey:NSParagraphStyleAttributeName];
185
186 [string drawInRect:textRect withAttributes:attributes];
187 UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
188 UIGraphicsEndImageContext();
189 return image;
190 }
191
192 - (void)refreshItemsWithURL:(const GURL&)URLToRefresh title:(NSString*)title {
193 NSURL* NSURL = net::NSURLWithGURL(URLToRefresh);
194
195 if (!NSURL || [_pendingTasks objectForKey:NSURL]) {
196 return;
197 }
198
199 base::WeakNSObject<BaseSpotlightManager> weakSelf(self);
200 GURL URL = URLToRefresh;
201 void (^faviconBlock)(const favicon_base::LargeIconResult&) = ^(
202 const favicon_base::LargeIconResult& result) {
203 base::scoped_nsobject<BaseSpotlightManager> strongSelf([weakSelf retain]);
204 if (!strongSelf) {
205 return;
206 }
207 [strongSelf.get()->_pendingTasks removeObjectForKey:NSURL];
208 UIImage* favicon;
209 if (result.bitmap.is_valid()) {
210 scoped_refptr<base::RefCountedMemory> data =
211 result.bitmap.bitmap_data.get();
212 favicon = [UIImage
213 imageWithData:[NSData dataWithBytes:data->front() length:data->size()]
214 scale:[UIScreen mainScreen].scale];
215 } else {
216 NSString* iconText =
217 base::SysUTF16ToNSString(favicon::GetFallbackIconText(URL));
218 UIColor* backgroundColor = skia::UIColorFromSkColor(
219 result.fallback_icon_style->background_color);
220 UIColor* textColor =
221 skia::UIColorFromSkColor(result.fallback_icon_style->text_color);
222 favicon = GetFallbackImageWithStringAndColor(iconText, backgroundColor,
223 textColor);
224 }
225 NSArray* spotlightItems = [strongSelf spotlightItemsWithURL:URL
226 favicon:favicon
227 defaultTitle:title];
228
229 if ([spotlightItems count]) {
230 [[CSSearchableIndex defaultSearchableIndex]
231 indexSearchableItems:spotlightItems
232 completionHandler:nil];
233 }
234 };
235
236 base::CancelableTaskTracker::TaskId taskID =
237 _largeIconService->GetLargeIconOrFallbackStyle(
238 URL, kMinIconSize * [UIScreen mainScreen].scale,
239 kIconSize * [UIScreen mainScreen].scale,
240 base::BindBlock(faviconBlock), &_largeIconTaskTracker);
241 [_pendingTasks setObject:[NSNumber numberWithLongLong:taskID] forKey:NSURL];
242 }
243
244 - (NSUInteger)pendingLargeIconTasksCount {
245 return [_pendingTasks count];
246 }
247
248 #pragma mark private methods
249
250 - (NSArray*)keywordsForSpotlightItems {
251 NSMutableArray* keywordsArray = [NSMutableArray arrayWithArray:@[
252 l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_ONE),
253 l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_TWO),
254 l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_THREE),
255 l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_FOUR),
256 l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_FIVE),
257 l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_SIX),
258 l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_SEVEN),
259 l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_EIGHT),
260 l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_NINE),
261 l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_TEN)
262 ]];
263 NSArray* additionalArray = ios::GetChromeBrowserProvider()
264 ->GetSpotlightProvider()
265 ->GetAdditionalKeywords();
266 if (additionalArray) {
267 [keywordsArray addObjectsFromArray:additionalArray];
268 }
269 return keywordsArray;
270 }
271
272 @end
OLDNEW
« 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