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

Side by Side Diff: components/arc/intent_helper/activity_icon_loader.cc

Issue 2655233007: Get rid of RefCounted for ActivityIconLoader. (Closed)
Patch Set: Created 3 years, 10 months 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/arc/intent_helper/activity_icon_loader.h" 5 #include "components/arc/intent_helper/activity_icon_loader.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <tuple> 9 #include <tuple>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/base64.h" 12 #include "base/base64.h"
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/memory/ptr_util.h" 14 #include "base/memory/ptr_util.h"
15 #include "base/memory/ref_counted.h"
15 #include "base/task_runner_util.h" 16 #include "base/task_runner_util.h"
16 #include "components/arc/arc_bridge_service.h" 17 #include "components/arc/arc_bridge_service.h"
17 #include "components/arc/arc_service_manager.h" 18 #include "components/arc/arc_service_manager.h"
19 #include "components/arc/intent_helper/arc_intent_helper_bridge.h"
18 #include "ui/base/layout.h" 20 #include "ui/base/layout.h"
19 #include "ui/gfx/image/image_skia.h" 21 #include "ui/gfx/image/image_skia.h"
20 #include "ui/gfx/image/image_skia_operations.h" 22 #include "ui/gfx/image/image_skia_operations.h"
21 23
22 namespace arc { 24 namespace arc {
23 25
24 namespace { 26 namespace {
25 27
26 constexpr size_t kSmallIconSizeInDip = 16; 28 constexpr size_t kSmallIconSizeInDip = 16;
27 constexpr size_t kLargeIconSizeInDip = 20; 29 constexpr size_t kLargeIconSizeInDip = 20;
(...skipping 14 matching lines...) Expand all
42 auto* instance = ARC_GET_INSTANCE_FOR_METHOD( 44 auto* instance = ARC_GET_INSTANCE_FOR_METHOD(
43 ArcServiceManager::Get()->arc_bridge_service()->intent_helper(), 45 ArcServiceManager::Get()->arc_bridge_service()->intent_helper(),
44 RequestActivityIcons); 46 RequestActivityIcons);
45 if (!instance && out_error_code) { 47 if (!instance && out_error_code) {
46 *out_error_code = 48 *out_error_code =
47 ArcIntentHelperBridge::GetResult::FAILED_ARC_NOT_SUPPORTED; 49 ArcIntentHelperBridge::GetResult::FAILED_ARC_NOT_SUPPORTED;
48 } 50 }
49 return instance; 51 return instance;
50 } 52 }
51 53
54 // static
Yusuke Sato 2017/01/27 18:21:17 remove
hidehiko 2017/01/30 17:04:03 Done.
55 std::unique_ptr<ActivityIconLoader::ActivityToIconsMap> ResizeAndEncodeIcons(
56 std::vector<mojom::ActivityIconPtr> icons) {
57 auto result = base::MakeUnique<ActivityIconLoader::ActivityToIconsMap>();
58 for (size_t i = 0; i < icons.size(); ++i) {
59 static const size_t kBytesPerPixel = 4;
60 const mojom::ActivityIconPtr& icon = icons.at(i);
61 if (icon->width > kMaxIconSizeInPx || icon->height > kMaxIconSizeInPx ||
62 icon->width == 0 || icon->height == 0 ||
63 icon->icon.size() != (icon->width * icon->height * kBytesPerPixel)) {
64 continue;
65 }
66
67 SkBitmap bitmap;
68 bitmap.allocPixels(SkImageInfo::MakeN32Premul(icon->width, icon->height));
69 if (!bitmap.getPixels())
70 continue;
71 DCHECK_GE(bitmap.getSafeSize(), icon->icon.size());
72 memcpy(bitmap.getPixels(), &icon->icon.front(), icon->icon.size());
73
74 gfx::ImageSkia original(gfx::ImageSkia::CreateFrom1xBitmap(bitmap));
75
76 // Resize the original icon to the sizes intent_helper needs.
77 gfx::ImageSkia icon_large(gfx::ImageSkiaOperations::CreateResizedImage(
78 original, skia::ImageOperations::RESIZE_BEST,
79 gfx::Size(kLargeIconSizeInDip, kLargeIconSizeInDip)));
80 gfx::ImageSkia icon_small(gfx::ImageSkiaOperations::CreateResizedImage(
81 original, skia::ImageOperations::RESIZE_BEST,
82 gfx::Size(kSmallIconSizeInDip, kSmallIconSizeInDip)));
83 gfx::Image icon16(icon_small);
84 gfx::Image icon20(icon_large);
85
86 // Encode the icon as PNG data, and then as data: URL.
87 scoped_refptr<base::RefCountedMemory> img = icon16.As1xPNGBytes();
88 if (!img)
89 continue;
90 std::string encoded;
91 base::Base64Encode(base::StringPiece(img->front_as<char>(), img->size()),
92 &encoded);
93 scoped_refptr<base::RefCountedData<GURL>> dataurl(
94 new base::RefCountedData<GURL>(GURL(kPngDataUrlPrefix + encoded)));
95
96 const std::string activity_name = icon->activity->activity_name.has_value()
97 ? (*icon->activity->activity_name)
98 : std::string();
99 result->insert(
100 std::make_pair(ActivityIconLoader::ActivityName(
101 icon->activity->package_name, activity_name),
102 ActivityIconLoader::Icons(icon16, icon20, dataurl)));
103 }
104
105 return result;
106 }
107
52 } // namespace 108 } // namespace
53 109
54 ActivityIconLoader::Icons::Icons( 110 ActivityIconLoader::Icons::Icons(
55 const gfx::Image& icon16, 111 const gfx::Image& icon16,
56 const gfx::Image& icon20, 112 const gfx::Image& icon20,
57 const scoped_refptr<base::RefCountedData<GURL>>& icon16_dataurl) 113 const scoped_refptr<base::RefCountedData<GURL>>& icon16_dataurl)
58 : icon16(icon16), icon20(icon20), icon16_dataurl(icon16_dataurl) {} 114 : icon16(icon16), icon20(icon20), icon16_dataurl(icon16_dataurl) {}
59 115
60 ActivityIconLoader::Icons::Icons(const Icons& other) = default; 116 ActivityIconLoader::Icons::Icons(const Icons& other) = default;
61 117
62 ActivityIconLoader::Icons::~Icons() = default; 118 ActivityIconLoader::Icons::~Icons() = default;
63 119
64 ActivityIconLoader::ActivityName::ActivityName(const std::string& package_name, 120 ActivityIconLoader::ActivityName::ActivityName(const std::string& package_name,
65 const std::string& activity_name) 121 const std::string& activity_name)
66 : package_name(package_name), activity_name(activity_name) {} 122 : package_name(package_name), activity_name(activity_name) {}
67 123
68 bool ActivityIconLoader::ActivityName::operator<( 124 bool ActivityIconLoader::ActivityName::operator<(
69 const ActivityName& other) const { 125 const ActivityName& other) const {
70 return std::tie(package_name, activity_name) < 126 return std::tie(package_name, activity_name) <
71 std::tie(other.package_name, other.activity_name); 127 std::tie(other.package_name, other.activity_name);
72 } 128 }
73 129
74 ActivityIconLoader::ActivityIconLoader() 130 ActivityIconLoader::ActivityIconLoader()
75 : scale_factor_(GetSupportedScaleFactor()) {} 131 : scale_factor_(GetSupportedScaleFactor()), weak_ptr_factory_(this) {}
76 132
77 ActivityIconLoader::~ActivityIconLoader() {} 133 ActivityIconLoader::~ActivityIconLoader() = default;
78 134
79 void ActivityIconLoader::InvalidateIcons(const std::string& package_name) { 135 void ActivityIconLoader::InvalidateIcons(const std::string& package_name) {
80 DCHECK(thread_checker_.CalledOnValidThread()); 136 DCHECK(thread_checker_.CalledOnValidThread());
81 for (auto it = cached_icons_.begin(); it != cached_icons_.end();) { 137 for (auto it = cached_icons_.begin(); it != cached_icons_.end();) {
82 if (it->first.package_name == package_name) 138 if (it->first.package_name == package_name)
83 it = cached_icons_.erase(it); 139 it = cached_icons_.erase(it);
84 else 140 else
85 ++it; 141 ++it;
86 } 142 }
87 } 143 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 return GetResult(GetResult::FAILED_ARC_NOT_READY); 178 return GetResult(GetResult::FAILED_ARC_NOT_READY);
123 case ArcIntentHelperBridge::GetResult::FAILED_ARC_NOT_SUPPORTED: 179 case ArcIntentHelperBridge::GetResult::FAILED_ARC_NOT_SUPPORTED:
124 return GetResult(GetResult::FAILED_ARC_NOT_SUPPORTED); 180 return GetResult(GetResult::FAILED_ARC_NOT_SUPPORTED);
125 } 181 }
126 NOTREACHED(); 182 NOTREACHED();
127 } 183 }
128 184
129 // Fetch icons from ARC. 185 // Fetch icons from ARC.
130 instance->RequestActivityIcons( 186 instance->RequestActivityIcons(
131 std::move(activities_to_fetch), mojom::ScaleFactor(scale_factor_), 187 std::move(activities_to_fetch), mojom::ScaleFactor(scale_factor_),
132 base::Bind(&ActivityIconLoader::OnIconsReady, this, base::Passed(&result), 188 base::Bind(&ActivityIconLoader::OnIconsReady,
133 cb)); 189 weak_ptr_factory_.GetWeakPtr(), base::Passed(&result), cb));
134 return GetResult::SUCCEEDED_ASYNC; 190 return GetResult::SUCCEEDED_ASYNC;
135 } 191 }
136 192
137 void ActivityIconLoader::OnIconsResizedForTesting( 193 void ActivityIconLoader::OnIconsResizedForTesting(
138 const OnIconsReadyCallback& cb, 194 const OnIconsReadyCallback& cb,
139 std::unique_ptr<ActivityToIconsMap> result) { 195 std::unique_ptr<ActivityToIconsMap> result) {
140 OnIconsResized(base::MakeUnique<ActivityToIconsMap>(), cb, std::move(result)); 196 OnIconsResized(base::MakeUnique<ActivityToIconsMap>(), cb, std::move(result));
141 } 197 }
142 198
143 void ActivityIconLoader::AddCacheEntryForTesting(const ActivityName& activity) { 199 void ActivityIconLoader::AddCacheEntryForTesting(const ActivityName& activity) {
(...skipping 15 matching lines...) Expand all
159 } 215 }
160 216
161 void ActivityIconLoader::OnIconsReady( 217 void ActivityIconLoader::OnIconsReady(
162 std::unique_ptr<ActivityToIconsMap> cached_result, 218 std::unique_ptr<ActivityToIconsMap> cached_result,
163 const OnIconsReadyCallback& cb, 219 const OnIconsReadyCallback& cb,
164 std::vector<mojom::ActivityIconPtr> icons) { 220 std::vector<mojom::ActivityIconPtr> icons) {
165 DCHECK(thread_checker_.CalledOnValidThread()); 221 DCHECK(thread_checker_.CalledOnValidThread());
166 ArcServiceManager* manager = ArcServiceManager::Get(); 222 ArcServiceManager* manager = ArcServiceManager::Get();
167 base::PostTaskAndReplyWithResult( 223 base::PostTaskAndReplyWithResult(
168 manager->blocking_task_runner().get(), FROM_HERE, 224 manager->blocking_task_runner().get(), FROM_HERE,
169 base::Bind(&ActivityIconLoader::ResizeAndEncodeIcons, 225 base::Bind(&ResizeAndEncodeIcons, base::Passed(&icons)),
170 base::Passed(&icons)), 226 base::Bind(&ActivityIconLoader::OnIconsResized,
171 base::Bind(&ActivityIconLoader::OnIconsResized, this, 227 weak_ptr_factory_.GetWeakPtr(), base::Passed(&cached_result),
172 base::Passed(&cached_result), cb)); 228 cb));
173 }
174
175 // static
176 std::unique_ptr<ActivityIconLoader::ActivityToIconsMap>
177 ActivityIconLoader::ResizeAndEncodeIcons(
178 std::vector<mojom::ActivityIconPtr> icons) {
179 std::unique_ptr<ActivityToIconsMap> result(new ActivityToIconsMap);
180
181 for (size_t i = 0; i < icons.size(); ++i) {
182 static const size_t kBytesPerPixel = 4;
183 const mojom::ActivityIconPtr& icon = icons.at(i);
184 if (icon->width > kMaxIconSizeInPx || icon->height > kMaxIconSizeInPx ||
185 icon->width == 0 || icon->height == 0 ||
186 icon->icon.size() != (icon->width * icon->height * kBytesPerPixel)) {
187 continue;
188 }
189
190 SkBitmap bitmap;
191 bitmap.allocPixels(SkImageInfo::MakeN32Premul(icon->width, icon->height));
192 if (!bitmap.getPixels())
193 continue;
194 DCHECK_GE(bitmap.getSafeSize(), icon->icon.size());
195 memcpy(bitmap.getPixels(), &icon->icon.front(), icon->icon.size());
196
197 gfx::ImageSkia original(gfx::ImageSkia::CreateFrom1xBitmap(bitmap));
198
199 // Resize the original icon to the sizes intent_helper needs.
200 gfx::ImageSkia icon_large(gfx::ImageSkiaOperations::CreateResizedImage(
201 original, skia::ImageOperations::RESIZE_BEST,
202 gfx::Size(kLargeIconSizeInDip, kLargeIconSizeInDip)));
203 gfx::ImageSkia icon_small(gfx::ImageSkiaOperations::CreateResizedImage(
204 original, skia::ImageOperations::RESIZE_BEST,
205 gfx::Size(kSmallIconSizeInDip, kSmallIconSizeInDip)));
206 gfx::Image icon16(icon_small);
207 gfx::Image icon20(icon_large);
208
209 // Encode the icon as PNG data, and then as data: URL.
210 scoped_refptr<base::RefCountedMemory> img = icon16.As1xPNGBytes();
211 if (!img)
212 continue;
213 std::string encoded;
214 base::Base64Encode(base::StringPiece(img->front_as<char>(), img->size()),
215 &encoded);
216 scoped_refptr<base::RefCountedData<GURL>> dataurl(
217 new base::RefCountedData<GURL>(GURL(kPngDataUrlPrefix + encoded)));
218
219 const std::string activity_name = icon->activity->activity_name.has_value()
220 ? (*icon->activity->activity_name)
221 : std::string();
222 result->insert(std::make_pair(
223 ActivityName(icon->activity->package_name, activity_name),
224 Icons(icon16, icon20, dataurl)));
225 }
226
227 return result;
228 } 229 }
229 230
230 void ActivityIconLoader::OnIconsResized( 231 void ActivityIconLoader::OnIconsResized(
231 std::unique_ptr<ActivityToIconsMap> cached_result, 232 std::unique_ptr<ActivityToIconsMap> cached_result,
232 const OnIconsReadyCallback& cb, 233 const OnIconsReadyCallback& cb,
233 std::unique_ptr<ActivityToIconsMap> result) { 234 std::unique_ptr<ActivityToIconsMap> result) {
234 DCHECK(thread_checker_.CalledOnValidThread()); 235 DCHECK(thread_checker_.CalledOnValidThread());
235 // Update |cached_icons_|. 236 // Update |cached_icons_|.
236 for (const auto& kv : *result) { 237 for (const auto& kv : *result) {
237 cached_icons_.erase(kv.first); 238 cached_icons_.erase(kv.first);
238 cached_icons_.insert(std::make_pair(kv.first, kv.second)); 239 cached_icons_.insert(std::make_pair(kv.first, kv.second));
239 } 240 }
240 241
241 // Merge the results that were obtained from cache before doing IPC. 242 // Merge the results that were obtained from cache before doing IPC.
242 result->insert(cached_result->begin(), cached_result->end()); 243 result->insert(cached_result->begin(), cached_result->end());
243 cb.Run(std::move(result)); 244 cb.Run(std::move(result));
244 } 245 }
245 246
246 } // namespace arc 247 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698