icon_decoder_impl_unittest.cc 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. // Copyright 2022 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. #include "ash/components/phonehub/icon_decoder_impl.h"
  5. #include <memory>
  6. #include "ash/components/phonehub/icon_decoder.h"
  7. #include "ash/components/phonehub/proto/phonehub_api.pb.h"
  8. #include "base/bind.h"
  9. #include "testing/gtest/include/gtest/gtest.h"
  10. #include "ui/gfx/image/image.h"
  11. #include "ui/gfx/image/image_skia.h"
  12. namespace ash {
  13. namespace phonehub {
  14. namespace {
  15. // Verifies the bitmaps in the decoded items match the id of the requests.
  16. // As the id % 10 is used as the width of the bitmaps, it checks to see if
  17. // the ids and bitmap sizes match ort not.
  18. void VerifyDecodedItem(IconDecoder::DecodingData& item) {
  19. EXPECT_EQ((int)(item.id % 10), item.result.Width());
  20. }
  21. void VerifyDecodedItems(std::vector<IconDecoder::DecodingData>* items) {
  22. for (IconDecoder::DecodingData& item : *items)
  23. VerifyDecodedItem(item);
  24. }
  25. } // namespace
  26. class TestDecoderDelegate : public IconDecoderImpl::DecoderDelegate {
  27. public:
  28. TestDecoderDelegate() = default;
  29. ~TestDecoderDelegate() override = default;
  30. void Decode(const IconDecoder::DecodingData& data,
  31. data_decoder::DecodeImageCallback callback) override {
  32. pending_callbacks_[data.id] = std::move(callback);
  33. }
  34. void CompleteRequest(const unsigned long id) {
  35. SkBitmap test_bitmap;
  36. test_bitmap.allocN32Pixels(id % 10, 1);
  37. std::move(pending_callbacks_.at(id)).Run(test_bitmap);
  38. pending_callbacks_.erase(id);
  39. }
  40. void FailRequest(const unsigned long id) {
  41. SkBitmap test_bitmap;
  42. std::move(pending_callbacks_.at(id)).Run(test_bitmap);
  43. pending_callbacks_.erase(id);
  44. }
  45. void CompleteAllRequests() {
  46. for (auto& it : pending_callbacks_)
  47. CompleteRequest(it.first);
  48. pending_callbacks_.clear();
  49. }
  50. private:
  51. base::flat_map<unsigned long, data_decoder::DecodeImageCallback>
  52. pending_callbacks_;
  53. };
  54. class IconDecoderImplTest : public testing::Test {
  55. protected:
  56. IconDecoderImplTest() = default;
  57. IconDecoderImplTest(const IconDecoderImplTest&) = delete;
  58. IconDecoderImplTest& operator=(const IconDecoderImplTest&) = delete;
  59. ~IconDecoderImplTest() override = default;
  60. void SetUp() override {
  61. decoder_.decoder_delegate_ = std::make_unique<TestDecoderDelegate>();
  62. }
  63. void BatchDecode(
  64. std::unique_ptr<std::vector<IconDecoder::DecodingData>> decode_items) {
  65. decoder_.BatchDecode(std::move(decode_items),
  66. base::BindOnce(&IconDecoderImplTest::OnItemsDecoded,
  67. weak_ptr_factory_.GetWeakPtr()));
  68. }
  69. void CompleteDecodeRequest(const unsigned long id) {
  70. static_cast<TestDecoderDelegate*>(decoder_.decoder_delegate_.get())
  71. ->CompleteRequest(id);
  72. }
  73. void FailDecodeRequest(const unsigned long id) {
  74. static_cast<TestDecoderDelegate*>(decoder_.decoder_delegate_.get())
  75. ->FailRequest(id);
  76. }
  77. void CompleteAllDecodeRequests() {
  78. static_cast<TestDecoderDelegate*>(decoder_.decoder_delegate_.get())
  79. ->CompleteAllRequests();
  80. }
  81. int completed_batch_count() const { return completed_batch_count_; }
  82. std::vector<IconDecoder::DecodingData>* last_decoded_batch() const {
  83. return last_decoded_batch_.get();
  84. }
  85. void OnItemsDecoded(
  86. std::unique_ptr<std::vector<IconDecoder::DecodingData>> decode_items) {
  87. completed_batch_count_++;
  88. last_decoded_batch_ = std::move(decode_items);
  89. }
  90. private:
  91. IconDecoderImpl decoder_;
  92. int completed_batch_count_ = 0;
  93. std::unique_ptr<std::vector<IconDecoder::DecodingData>> last_decoded_batch_;
  94. base::WeakPtrFactory<IconDecoderImplTest> weak_ptr_factory_{this};
  95. };
  96. TEST_F(IconDecoderImplTest, BatchDecodeWithNoExistingItems) {
  97. auto decode_items =
  98. std::make_unique<std::vector<IconDecoder::DecodingData>>();
  99. decode_items->push_back(IconDecoder::DecodingData(1, "input1"));
  100. decode_items->push_back(IconDecoder::DecodingData(2, "input2"));
  101. decode_items->push_back(IconDecoder::DecodingData(3, "input3"));
  102. BatchDecode(std::move(decode_items));
  103. CompleteDecodeRequest(3);
  104. CompleteDecodeRequest(2);
  105. EXPECT_EQ(0, completed_batch_count());
  106. // The batch of items won't be added until decode request are completed for
  107. // all items.
  108. CompleteDecodeRequest(1);
  109. EXPECT_EQ(1, completed_batch_count());
  110. auto* result = last_decoded_batch();
  111. EXPECT_EQ(3UL, result->size());
  112. }
  113. TEST_F(IconDecoderImplTest, BatchDecodeWithOutOfOrderCompletions) {
  114. auto decode_items =
  115. std::make_unique<std::vector<IconDecoder::DecodingData>>();
  116. decode_items->push_back(IconDecoder::DecodingData(1, "input1"));
  117. decode_items->push_back(IconDecoder::DecodingData(2, "input2"));
  118. decode_items->push_back(IconDecoder::DecodingData(3, "input3"));
  119. BatchDecode(std::move(decode_items));
  120. CompleteDecodeRequest(2);
  121. CompleteDecodeRequest(1);
  122. CompleteDecodeRequest(3);
  123. EXPECT_EQ(1, completed_batch_count());
  124. auto* result = last_decoded_batch();
  125. EXPECT_EQ(3UL, result->size());
  126. VerifyDecodedItems(result);
  127. }
  128. TEST_F(IconDecoderImplTest, BatchDecodeWithErrors) {
  129. auto decode_items =
  130. std::make_unique<std::vector<IconDecoder::DecodingData>>();
  131. decode_items->push_back(IconDecoder::DecodingData(1, "input1"));
  132. decode_items->push_back(IconDecoder::DecodingData(2, "input2"));
  133. decode_items->push_back(IconDecoder::DecodingData(3, "input3"));
  134. BatchDecode(std::move(decode_items));
  135. FailDecodeRequest(2);
  136. CompleteDecodeRequest(1);
  137. CompleteDecodeRequest(3);
  138. EXPECT_EQ(1, completed_batch_count());
  139. auto* result = last_decoded_batch();
  140. EXPECT_EQ(3UL, result->size());
  141. VerifyDecodedItem((*result)[0]);
  142. VerifyDecodedItem((*result)[2]);
  143. EXPECT_EQ(0, (*result)[1].result.Width());
  144. }
  145. TEST_F(IconDecoderImplTest, BatchDecodeWithInProgresRequests) {
  146. auto decode_items1 =
  147. std::make_unique<std::vector<IconDecoder::DecodingData>>();
  148. decode_items1->push_back(IconDecoder::DecodingData(2, "input2"));
  149. decode_items1->push_back(IconDecoder::DecodingData(1, "input1"));
  150. BatchDecode(std::move(decode_items1));
  151. CompleteDecodeRequest(1);
  152. auto decode_items2 =
  153. std::make_unique<std::vector<IconDecoder::DecodingData>>();
  154. decode_items2->push_back(IconDecoder::DecodingData(3, "input3"));
  155. decode_items2->push_back(IconDecoder::DecodingData(2, "input2"));
  156. BatchDecode(std::move(decode_items2)); // This will cancel the previous call.
  157. CompleteDecodeRequest(2);
  158. CompleteDecodeRequest(3);
  159. EXPECT_EQ(1, completed_batch_count());
  160. auto* result = last_decoded_batch();
  161. EXPECT_EQ(2UL, result->size());
  162. VerifyDecodedItems(result);
  163. }
  164. } // namespace phonehub
  165. } // namespace ash