Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2013 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 #include "chrome/browser/ui/app_list/fast_show_pickler.h" | |
| 6 | |
|
benwells
2013/08/29 04:49:28
Nit: extra blank line.
koz (OOO until 15th September)
2013/08/30 00:44:50
Done.
| |
| 7 | |
| 8 namespace { | |
| 9 | |
| 10 using app_list::AppListItemModel; | |
| 11 using app_list::AppListModel; | |
| 12 | |
| 13 // These have the same meaning as SkBitmap::Config. Reproduced here to insure | |
| 14 // against their value changing in Skia. If the order of these changes kVersion | |
| 15 // should be incremented. | |
| 16 enum ImageFormat { | |
| 17 NONE, | |
| 18 A1, | |
| 19 A8, | |
| 20 INDEX_8, | |
| 21 RGB_565, | |
| 22 ARGB_4444, | |
| 23 ARGB_8888, | |
| 24 }; | |
| 25 | |
| 26 bool FormatToConfig(ImageFormat format, SkBitmap::Config* out) { | |
| 27 switch (format) { | |
| 28 case NONE: | |
| 29 *out = SkBitmap::kNo_Config; | |
| 30 break; | |
| 31 case A1: | |
| 32 *out = SkBitmap::kA1_Config; | |
| 33 break; | |
| 34 case A8: | |
| 35 *out = SkBitmap::kA8_Config; | |
| 36 break; | |
| 37 case INDEX_8: | |
| 38 *out = SkBitmap::kIndex8_Config; | |
| 39 break; | |
| 40 case RGB_565: | |
| 41 *out = SkBitmap::kRGB_565_Config; | |
| 42 break; | |
| 43 case ARGB_4444: | |
| 44 *out = SkBitmap::kARGB_4444_Config; | |
| 45 break; | |
| 46 case ARGB_8888: | |
| 47 *out = SkBitmap::kARGB_8888_Config; | |
| 48 break; | |
| 49 default: return false; | |
| 50 } | |
| 51 return true; | |
| 52 } | |
| 53 | |
| 54 bool ConfigToFormat(SkBitmap::Config config, ImageFormat* out) { | |
| 55 switch (config) { | |
| 56 case SkBitmap::kNo_Config: | |
| 57 *out = NONE; | |
| 58 break; | |
| 59 case SkBitmap::kA1_Config: | |
| 60 *out = A1; | |
| 61 break; | |
| 62 case SkBitmap::kA8_Config: | |
| 63 *out = A8; | |
| 64 break; | |
| 65 case SkBitmap::kIndex8_Config: | |
| 66 *out = INDEX_8; | |
| 67 break; | |
| 68 case SkBitmap::kRGB_565_Config: | |
| 69 *out = RGB_565; | |
| 70 break; | |
| 71 case SkBitmap::kARGB_4444_Config: | |
| 72 *out = ARGB_4444; | |
| 73 break; | |
| 74 case SkBitmap::kARGB_8888_Config: | |
| 75 *out = ARGB_8888; | |
| 76 break; | |
| 77 default: return false; | |
| 78 } | |
| 79 return true; | |
| 80 } | |
| 81 | |
| 82 bool PickleImage(Pickle* pickle, const gfx::ImageSkia& image) { | |
| 83 std::vector<gfx::ImageSkiaRep> reps(image.image_reps()); | |
|
xiyuan
2013/08/29 16:52:11
I just thought of potential problem. ExtensionAppI
koz (OOO until 15th September)
2013/08/30 00:44:50
I plan on handling that in a higher layer. There w
| |
| 84 pickle->WriteInt(static_cast<int>(reps.size())); | |
| 85 for (std::vector<gfx::ImageSkiaRep>::const_iterator it = reps.begin(); | |
| 86 it != reps.end(); ++it) { | |
| 87 pickle->WriteInt(static_cast<int>(it->scale_factor())); | |
| 88 pickle->WriteInt(it->pixel_width()); | |
| 89 pickle->WriteInt(it->pixel_height()); | |
| 90 ImageFormat format = NONE; | |
| 91 if (!ConfigToFormat(it->sk_bitmap().getConfig(), &format)) | |
| 92 return false; | |
| 93 pickle->WriteInt(static_cast<int>(format)); | |
| 94 int size = static_cast<int>(it->sk_bitmap().getSafeSize()); | |
| 95 pickle->WriteInt(size); | |
| 96 SkBitmap bitmap = it->sk_bitmap(); | |
| 97 SkAutoLockPixels lock(bitmap); | |
| 98 pickle->WriteBytes(bitmap.getPixels(), size); | |
| 99 } | |
| 100 return true; | |
| 101 } | |
| 102 | |
| 103 gfx::ImageSkia UnpickleImage(PickleIterator* it) { | |
| 104 int rep_count = 0; | |
| 105 if (!it->ReadInt(&rep_count)) | |
| 106 return gfx::ImageSkia(); | |
| 107 | |
| 108 gfx::ImageSkia result; | |
| 109 for (int i = 0; i < rep_count; ++i) { | |
| 110 int scale_factor = 0; | |
| 111 if (!it->ReadInt(&scale_factor)) | |
| 112 return gfx::ImageSkia(); | |
| 113 | |
| 114 int width = 0; | |
| 115 if (!it->ReadInt(&width)) | |
| 116 return gfx::ImageSkia(); | |
| 117 | |
| 118 int height = 0; | |
| 119 if (!it->ReadInt(&height)) | |
| 120 return gfx::ImageSkia(); | |
| 121 | |
| 122 int format_int = 0; | |
| 123 if (!it->ReadInt(&format_int)) | |
| 124 return gfx::ImageSkia(); | |
| 125 ImageFormat format = static_cast<ImageFormat>(format_int); | |
| 126 SkBitmap::Config config = SkBitmap::kNo_Config; | |
| 127 if (!FormatToConfig(format, &config)) | |
| 128 return gfx::ImageSkia(); | |
| 129 | |
| 130 int size = 0; | |
| 131 if (!it->ReadInt(&size)) | |
| 132 return gfx::ImageSkia(); | |
| 133 | |
| 134 const char* pixels = NULL; | |
| 135 if (!it->ReadBytes(&pixels, size)) | |
| 136 return gfx::ImageSkia(); | |
| 137 | |
| 138 SkBitmap bitmap; | |
| 139 bitmap.setConfig(static_cast<SkBitmap::Config>(config), width, height); | |
| 140 if (!bitmap.allocPixels()) | |
| 141 return gfx::ImageSkia(); | |
| 142 { | |
| 143 SkAutoLockPixels lock(bitmap); | |
| 144 memcpy(bitmap.getPixels(), pixels, bitmap.getSize()); | |
| 145 } | |
| 146 result.AddRepresentation( | |
| 147 gfx::ImageSkiaRep(bitmap, static_cast<ui::ScaleFactor>(scale_factor))); | |
| 148 } | |
| 149 | |
| 150 return result; | |
| 151 } | |
| 152 | |
| 153 scoped_ptr<AppListItemModel> UnpickleAppListItemModel(PickleIterator* it) { | |
| 154 scoped_ptr<AppListItemModel> result(new AppListItemModel); | |
| 155 std::string id; | |
| 156 if (!it->ReadString(&id)) | |
| 157 return scoped_ptr<AppListItemModel>(); | |
| 158 result->set_app_id(id); | |
| 159 std::string title; | |
| 160 if (!it->ReadString(&title)) | |
| 161 return scoped_ptr<AppListItemModel>(); | |
| 162 result->SetTitle(title); | |
| 163 bool has_shadow = false; | |
| 164 if (!it->ReadBool(&has_shadow)) | |
| 165 return scoped_ptr<AppListItemModel>(); | |
| 166 gfx::ImageSkia icon = UnpickleImage(it); | |
|
benwells
2013/08/29 04:49:28
Should you check icon.empty (or whatever the call
koz (OOO until 15th September)
2013/08/30 00:44:50
Ah, good point. gfx::ImageSkia() is a valid value
| |
| 167 result->SetIcon(icon, has_shadow); | |
| 168 return result.Pass(); | |
| 169 } | |
| 170 | |
| 171 | |
| 172 bool PickleAppListItemModel(Pickle* pickle, AppListItemModel* item) { | |
| 173 if (!pickle->WriteString(item->app_id())) | |
| 174 return false; | |
| 175 if (!pickle->WriteString(item->title())) | |
| 176 return false; | |
| 177 if (!pickle->WriteBool(item->has_shadow())) | |
| 178 return false; | |
| 179 if (!PickleImage(pickle, item->icon())) | |
| 180 return false; | |
| 181 return true; | |
| 182 } | |
| 183 | |
| 184 void CopyOverItem(AppListItemModel* src_item, AppListItemModel* dest_item) { | |
| 185 dest_item->set_app_id(src_item->app_id()); | |
| 186 dest_item->SetTitle(src_item->title()); | |
| 187 dest_item->SetIcon(src_item->icon(), src_item->has_shadow()); | |
| 188 } | |
| 189 | |
| 190 } // namespace | |
| 191 | |
| 192 // The version of the pickle format defined here. This needs to be incremented | |
| 193 // whenever this format is changed so new clients can invalidate old versions. | |
| 194 const int FastShowPickler::kVersion = 1; | |
| 195 | |
| 196 scoped_ptr<Pickle> FastShowPickler::PickleAppListModelForFastShow( | |
| 197 AppListModel* model) { | |
| 198 scoped_ptr<Pickle> result(new Pickle); | |
| 199 if (!result->WriteInt(kVersion)) | |
| 200 return scoped_ptr<Pickle>(); | |
| 201 if (!result->WriteInt((int) model->apps()->item_count())) | |
|
benwells
2013/08/29 04:49:28
Nit: If it was me I'd swap the item_count and sign
koz (OOO until 15th September)
2013/08/30 00:44:50
Done.
| |
| 202 return scoped_ptr<Pickle>(); | |
| 203 if (!result->WriteBool(model->signed_in())) | |
| 204 return scoped_ptr<Pickle>(); | |
| 205 for (size_t i = 0; i < model->apps()->item_count(); ++i) { | |
| 206 if (!PickleAppListItemModel(result.get(), model->apps()->GetItemAt(i))) | |
| 207 return scoped_ptr<Pickle>(); | |
| 208 } | |
| 209 return result.Pass(); | |
| 210 } | |
| 211 | |
| 212 void FastShowPickler::CopyOver(AppListModel* src, AppListModel* dest) { | |
| 213 dest->apps()->DeleteAll(); | |
| 214 for (size_t i = 0; i < src->apps()->item_count(); i++) { | |
| 215 AppListItemModel* src_item = src->apps()->GetItemAt(i); | |
| 216 AppListItemModel* dest_item = new AppListItemModel; | |
| 217 CopyOverItem(src_item, dest_item); | |
| 218 dest->apps()->Add(dest_item); | |
| 219 } | |
| 220 } | |
| 221 | |
| 222 scoped_ptr<AppListModel> | |
| 223 FastShowPickler::UnpickleAppListModelForFastShow(Pickle* pickle) { | |
| 224 PickleIterator it(*pickle); | |
| 225 int read_version = 0; | |
| 226 if (!it.ReadInt(&read_version)) | |
| 227 return scoped_ptr<AppListModel>(); | |
| 228 if (read_version != kVersion) | |
| 229 return scoped_ptr<AppListModel>(); | |
| 230 int app_count = 0; | |
| 231 if (!it.ReadInt(&app_count)) | |
| 232 return scoped_ptr<AppListModel>(); | |
| 233 bool signed_in = false; | |
| 234 if (!it.ReadBool(&signed_in)) | |
| 235 return scoped_ptr<AppListModel>(); | |
| 236 | |
| 237 scoped_ptr<AppListModel> model(new AppListModel); | |
| 238 for (int i = 0; i < app_count; ++i) { | |
| 239 scoped_ptr<AppListItemModel> item(UnpickleAppListItemModel(&it).Pass()); | |
| 240 if (!item) | |
| 241 return scoped_ptr<AppListModel>(); | |
| 242 model->apps()->Add(item.release()); | |
| 243 } | |
| 244 | |
| 245 return model.Pass(); | |
| 246 } | |
| OLD | NEW |