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

Side by Side Diff: ios/chrome/app/spotlight/spotlight_util.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/spotlight_util.h"
6
7 #import <CoreSpotlight/CoreSpotlight.h>
8
9 #include "base/metrics/histogram.h"
10 #include "base/strings/sys_string_conversions.h"
11 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
12 #include "ios/public/provider/chrome/browser/spotlight/spotlight_provider.h"
13 #include "url/gurl.h"
14
15 namespace {
16 // This enum is used for Histogram. Items should not be removed or reordered and
17 // this enum should be kept synced with histograms.xml.
18 // The three states correspond to:
19 // - SPOTLIGHT_UNSUPPORTED: Framework CoreSpotlight is not found and
20 // [CSSearchableIndex class] returns nil.
21 // - SPOTLIGHT_UNAVAILABLE: Framework is loaded but [CSSearchableIndex
22 // isIndexingAvailable] return NO. Note: It is unclear if this state is
23 // reachable (I could not find configuration where CoreSpotlight was loaded but
24 // [CSSearchableIndex isIndexingAvailable] returned NO.
25 // - SPOTLIGHT_AVAILABLE: Framework is loaded and [CSSearchableIndex
26 // isIndexingAvailable] returns YES. Note: This does not mean the actual
27 // indexing will happen. If the user disables Spotlight in the system settings,
28 // [CSSearchableIndex isIndexingAvailable] still returns YES.
29 enum Availability {
30 SPOTLIGHT_UNSUPPORTED = 0,
31 SPOTLIGHT_UNAVAILABLE,
32 SPOTLIGHT_AVAILABLE,
33 SPOTLIGHT_AVAILABILITY_COUNT
34 };
35
36 // Documentation says that failed deletion should be retried. Set a maximum
37 // value to avoid infinite loop.
38 const int kMaxDeletionAttempts = 5;
39
40 // Execute blockName block with up to retryCount retries on error. Execute
41 // callback when done.
42 void DoWithRetry(BlockWithError callback,
43 NSUInteger retryCount,
44 void (^blockName)(BlockWithError error)) {
45 BlockWithError retryCallback = ^(NSError* error) {
46 if (error && retryCount > 0) {
47 DoWithRetry(callback, retryCount - 1, blockName);
48 } else {
49 if (callback) {
50 callback(error);
51 }
52 }
53 };
54 blockName(retryCallback);
55 }
56
57 // Execute blockName block with up to kMaxDeletionAttempts retries on error.
58 // Execute callback when done.
59 void DoWithRetry(BlockWithError completion,
60 void (^blockName)(BlockWithError error)) {
61 DoWithRetry(completion, kMaxDeletionAttempts, blockName);
62 }
63
64 } // namespace
65
66 namespace spotlight {
67
68 // NSUserDefaults key of entry containing date of the latest bookmarks indexing.
69 const char kSpotlightLastIndexingDateKey[] = "SpotlightLastIndexingDate";
70
71 // NSUserDefault key of entry containing Chrome version of the latest bookmarks
72 // indexing.
73 const char kSpotlightLastIndexingVersionKey[] = "SpotlightLastIndexingVersion";
74
75 // The current version of the Spotlight index format.
76 // Change this value if there are change int the information indexed in
77 // Spotlight. This will force reindexation on next startup.
78 // Value is stored in |kSpotlightLastIndexingVersionKey|.
79 const int kCurrentSpotlightIndexVersion = 2;
80
81 Domain SpotlightDomainFromString(NSString* domain) {
82 SpotlightProvider* provider =
83 ios::GetChromeBrowserProvider()->GetSpotlightProvider();
84 if ([domain hasPrefix:[provider->GetBookmarkDomain()
85 stringByAppendingString:@"."]]) {
86 return DOMAIN_BOOKMARKS;
87 } else if ([domain hasPrefix:[provider->GetTopSitesDomain()
88 stringByAppendingString:@"."]]) {
89 return DOMAIN_TOPSITES;
90 } else if ([domain hasPrefix:[provider->GetActionsDomain()
91 stringByAppendingString:@"."]]) {
92 return DOMAIN_ACTIONS;
93 }
94 // On normal flow, it is not possible to reach this point. When testing the
95 // app, it may be possible though if the app is downgraded.
96 NOTREACHED();
97 return DOMAIN_UNKNOWN;
98 }
99
100 NSString* StringFromSpotlightDomain(Domain domain) {
101 SpotlightProvider* provider =
102 ios::GetChromeBrowserProvider()->GetSpotlightProvider();
103 switch (domain) {
104 case DOMAIN_BOOKMARKS:
105 return provider->GetBookmarkDomain();
106 case DOMAIN_TOPSITES:
107 return provider->GetTopSitesDomain();
108 case DOMAIN_ACTIONS:
109 return provider->GetActionsDomain();
110 default:
111 // On normal flow, it is not possible to reach this point. When testing
112 // the app, it may be possible though if the app is downgraded.
113 NOTREACHED();
114 return nil;
115 }
116 }
117
118 void DeleteItemsWithIdentifiers(NSArray* items, BlockWithError callback) {
119 void (^deleteItems)(BlockWithError) = ^(BlockWithError errorBlock) {
120 [[CSSearchableIndex defaultSearchableIndex]
121 deleteSearchableItemsWithIdentifiers:items
122 completionHandler:errorBlock];
123 };
124
125 DoWithRetry(callback, deleteItems);
126 }
127
128 void DeleteSearchableDomainItems(Domain domain, BlockWithError callback) {
129 void (^deleteItems)(BlockWithError) = ^(BlockWithError errorBlock) {
130 [[CSSearchableIndex defaultSearchableIndex]
131 deleteSearchableItemsWithDomainIdentifiers:@[ StringFromSpotlightDomain(
132 domain) ]
133 completionHandler:errorBlock];
134 };
135
136 DoWithRetry(callback, deleteItems);
137 }
138
139 void ClearAllSpotlightEntries(BlockWithError callback) {
140 BlockWithError augmentedCallback = ^(NSError* error) {
141 [[NSUserDefaults standardUserDefaults]
142 removeObjectForKey:@(kSpotlightLastIndexingDateKey)];
143 if (callback) {
144 callback(error);
145 }
146 };
147
148 void (^deleteItems)(BlockWithError) = ^(BlockWithError errorBlock) {
149 [[CSSearchableIndex defaultSearchableIndex]
150 deleteAllSearchableItemsWithCompletionHandler:errorBlock];
151 };
152
153 DoWithRetry(augmentedCallback, deleteItems);
154 }
155
156 bool IsSpotlightAvailable() {
157 bool provided = ios::GetChromeBrowserProvider()
158 ->GetSpotlightProvider()
159 ->IsSpotlightEnabled();
160 if (!provided) {
161 // The product does not support Spotlight, do not go further.
162 return false;
163 }
164 bool loaded = !![CSSearchableIndex class];
165 bool available = loaded && [CSSearchableIndex isIndexingAvailable];
166 static dispatch_once_t once;
167 dispatch_once(&once, ^{
168 Availability availability = SPOTLIGHT_UNSUPPORTED;
169 if (loaded) {
170 availability = SPOTLIGHT_UNAVAILABLE;
171 }
172 if (available) {
173 availability = SPOTLIGHT_AVAILABLE;
174 }
175 UMA_HISTOGRAM_ENUMERATION("IOS.Spotlight.Availability", availability,
176 SPOTLIGHT_AVAILABILITY_COUNT);
177 });
178 return loaded && available;
179 }
180
181 void ClearSpotlightIndexWithCompletion(BlockWithError completion) {
182 DCHECK(IsSpotlightAvailable());
183 ClearAllSpotlightEntries(completion);
184 }
185
186 NSString* GetSpotlightCustomAttributeItemID() {
187 return ios::GetChromeBrowserProvider()
188 ->GetSpotlightProvider()
189 ->GetCustomAttributeItemID();
190 }
191
192 void GetURLForSpotlightItemID(NSString* itemID, BlockWithNSURL completion) {
193 NSString* queryString =
194 [NSString stringWithFormat:@"%@ == \"%@\"",
195 GetSpotlightCustomAttributeItemID(), itemID];
196
197 CSSearchQuery* query =
198 [[CSSearchQuery alloc] initWithQueryString:queryString
199 attributes:@[ @"contentURL" ]];
200
201 [query setFoundItemsHandler:^(NSArray<CSSearchableItem*>* items) {
202 if ([items count] == 1) {
203 CSSearchableItem* searchableItem = [items objectAtIndex:0];
204 if (searchableItem) {
205 completion([[searchableItem attributeSet] contentURL]);
206 return;
207 }
208 }
209 completion(nil);
210
211 }];
212
213 [query start];
214 }
215
216 } // namespace spotlight
OLDNEW
« no previous file with comments | « ios/chrome/app/spotlight/spotlight_util.h ('k') | ios/chrome/app/spotlight/topsites_spotlight_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698