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

Side by Side Diff: ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.mm

Issue 2588733002: Upstream Chrome on iOS source code [9/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/browser/ui/tab_switcher/tab_switcher_utils.h"
6
7 #import <UIKit/UIKit.h>
8
9 #include "base/logging.h"
10 #include "base/mac/scoped_nsobject.h"
11 #include "components/browser_sync/profile_sync_service.h"
12 #include "components/sync/driver/sync_service.h"
13 #include "components/sync_sessions/open_tabs_ui_delegate.h"
14 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
15 #import "ios/chrome/browser/favicon/favicon_loader.h"
16 #include "ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.h"
17 #include "ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.h"
18 #include "ios/chrome/grit/ios_theme_resources.h"
19 #include "ui/base/resource/resource_bundle.h"
20
21 namespace ios_internal {
22
23 UIImage* DefaultFaviconImage() {
24 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
25 return rb.GetNativeImageNamed(IDR_IOS_OMNIBOX_HTTP).ToUIImage();
26 }
27
28 void GetFavicon(GURL const& url,
29 ios::ChromeBrowserState* browser_state,
30 ios_internal::FaviconGetterCompletionBlock block) {
31 DCHECK(browser_state);
32 syncer::SyncService* sync_service =
33 IOSChromeProfileSyncServiceFactory::GetForBrowserState(browser_state);
34 sync_sessions::OpenTabsUIDelegate* open_tabs =
35 sync_service ? sync_service->GetOpenTabsUIDelegate() : NULL;
36 scoped_refptr<base::RefCountedMemory> favicon;
37 if (open_tabs &&
38 open_tabs->GetSyncedFaviconForPageURL(url.spec(), &favicon)) {
39 dispatch_queue_t queue =
40 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
41 dispatch_async(queue, ^{
42 NSData* pngData =
43 [NSData dataWithBytes:favicon->front() length:favicon->size()];
44 base::scoped_nsobject<UIImage> image(
45 [[UIImage alloc] initWithData:pngData]);
46 dispatch_async(dispatch_get_main_queue(), ^{
47 // |UIImage initWithData:| may return nil.
48 if (image) {
49 block(image);
50 } else {
51 block(DefaultFaviconImage());
52 }
53 });
54 });
55 block(DefaultFaviconImage());
56 return;
57 }
58
59 // Use the FaviconCache if there is no synced favicon.
60 FaviconLoader* loader =
61 IOSChromeFaviconLoaderFactory::GetForBrowserState(browser_state);
62 if (loader) {
63 int types = favicon_base::FAVICON | favicon_base::TOUCH_ICON |
64 favicon_base::TOUCH_PRECOMPOSED_ICON;
65 UIImage* image = loader->ImageForURL(url, types, block);
66 DCHECK(image);
67 block(image);
68 return;
69 }
70 // Finally returns a default image.
71 block(DefaultFaviconImage());
72 }
73
74 enum BacktrackOperation { NOTHING, SUBSTITUTION, DELETION, INSERTION };
75
76 BacktrackOperation BacktrackOperationInCostMatrix(
77 std::vector<std::vector<int>> const& costMatrix,
78 size_t finalIndex,
79 size_t initialIndex) {
80 DCHECK(finalIndex || initialIndex);
81 DCHECK(initialIndex < costMatrix.size());
82 DCHECK(finalIndex < costMatrix[initialIndex].size());
83
84 if (finalIndex == 0)
85 return DELETION;
86 if (initialIndex == 0)
87 return INSERTION;
88
89 int currentCost = costMatrix[initialIndex][finalIndex];
90
91 int costBeforeInsertion = costMatrix[initialIndex][finalIndex - 1];
92 if (costBeforeInsertion + 1 == currentCost)
93 return INSERTION;
94
95 int costBeforeDeletion = costMatrix[initialIndex - 1][finalIndex];
96 if (costBeforeDeletion + 1 == currentCost)
97 return DELETION;
98
99 int costBeforeSubstitution = costMatrix[initialIndex - 1][finalIndex - 1];
100 if (costBeforeSubstitution == currentCost)
101 return NOTHING;
102
103 return SUBSTITUTION;
104 }
105
106 void MinimalReplacementOperations(std::vector<size_t> const& initial,
107 std::vector<size_t> const& final,
108 std::vector<size_t>* substitutions,
109 std::vector<size_t>* deletions,
110 std::vector<size_t>* insertions) {
111 DCHECK(substitutions);
112 DCHECK(deletions);
113 DCHECK(insertions);
114 DCHECK_EQ(substitutions->size(), 0UL);
115 DCHECK_EQ(deletions->size(), 0UL);
116 DCHECK_EQ(insertions->size(), 0UL);
117
118 // The substitutions/deletions/insertions are computed using the Levenshtein
119 // algorithm.
120 // https://en.wikipedia.org/wiki/Levenshtein_distance
121
122 const size_t initialSize = initial.size() + 1;
123 const size_t finalSize = final.size() + 1;
124
125 std::vector<std::vector<int>> costMatrix(initialSize,
126 std::vector<int>(finalSize));
127
128 for (size_t i = 1; i < initialSize; i++)
129 costMatrix[i][0] = i;
130 for (size_t i = 1; i < finalSize; i++)
131 costMatrix[0][i] = i;
132
133 // Step 1: Generate cost matrix.
134 for (size_t initialIndex = 1; initialIndex < initialSize; initialIndex++) {
135 for (size_t finalIndex = 1; finalIndex < finalSize; finalIndex++) {
136 if (initial[initialIndex - 1] == final[finalIndex - 1]) {
137 costMatrix[initialIndex][finalIndex] =
138 costMatrix[initialIndex - 1][finalIndex - 1];
139 } else {
140 int costAfterSubstitution =
141 costMatrix[initialIndex - 1][finalIndex - 1] + 1;
142 int costAfterInsertion = costMatrix[initialIndex][finalIndex - 1] + 1;
143 int costAfterDeletion = costMatrix[initialIndex - 1][finalIndex] + 1;
144 costMatrix[initialIndex][finalIndex] =
145 std::min(std::min(costAfterDeletion, costAfterInsertion),
146 costAfterSubstitution);
147 }
148 }
149 }
150
151 // Step 2: Backtrack to find the operations (deletion, insertion,
152 // substitution).
153 size_t initialIndex = initialSize - 1;
154 size_t finalIndex = finalSize - 1;
155 while (initialIndex != 0 || finalIndex != 0) {
156 BacktrackOperation op =
157 BacktrackOperationInCostMatrix(costMatrix, finalIndex, initialIndex);
158 switch (op) {
159 case SUBSTITUTION:
160 finalIndex--;
161 initialIndex--;
162 // The substitution is relative to |initial|.
163 substitutions->push_back(initialIndex);
164 break;
165 case DELETION:
166 initialIndex--;
167 // The deletion is relative to |initial|.
168 deletions->push_back(initialIndex);
169 break;
170 case INSERTION:
171 finalIndex--;
172 // The insertion is relative to |final|.
173 insertions->push_back(finalIndex);
174 break;
175 case NOTHING:
176 finalIndex--;
177 initialIndex--;
178 break;
179 }
180 }
181
182 // The backtracking results in the indexes of the operations being stored in
183 // decreasing order.
184 // For readability, order them in ascending value.
185 std::reverse(std::begin(*substitutions), std::end(*substitutions));
186 std::reverse(std::begin(*deletions), std::end(*deletions));
187 std::reverse(std::begin(*insertions), std::end(*insertions));
188 }
189
190 } // namespace ios_internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698