notification.cc 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. // Copyright 2020 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/notification.h"
  5. #include <tuple>
  6. #include "base/base64.h"
  7. #include "base/containers/flat_map.h"
  8. #include "base/logging.h"
  9. #include "base/memory/ref_counted_memory.h"
  10. #include "base/strings/utf_string_conversions.h"
  11. #include "third_party/skia/include/core/SkColor.h"
  12. namespace ash {
  13. namespace phonehub {
  14. const char kVisibleAppName[] = "visible_app_name";
  15. const char kPackageName[] = "package_name";
  16. const char kUserId[] = "user_id";
  17. const char kIcon[] = "icon";
  18. const char kIconColorR[] = "icon_color_r";
  19. const char kIconColorG[] = "icon_color_g";
  20. const char kIconColorB[] = "icon_color_b";
  21. const char kIconIsMonochrome[] = "icon_is_monochrome";
  22. Notification::AppMetadata::AppMetadata(const std::u16string& visible_app_name,
  23. const std::string& package_name,
  24. const gfx::Image& icon,
  25. const absl::optional<SkColor> icon_color,
  26. bool icon_is_monochrome,
  27. int64_t user_id)
  28. : visible_app_name(visible_app_name),
  29. package_name(package_name),
  30. icon(icon),
  31. icon_color(icon_color),
  32. icon_is_monochrome(icon_is_monochrome),
  33. user_id(user_id) {}
  34. Notification::AppMetadata::AppMetadata(const AppMetadata& other) = default;
  35. Notification::AppMetadata& Notification::AppMetadata::operator=(
  36. const AppMetadata& other) = default;
  37. bool Notification::AppMetadata::operator==(const AppMetadata& other) const {
  38. return visible_app_name == other.visible_app_name &&
  39. package_name == other.package_name && icon == other.icon &&
  40. user_id == other.user_id;
  41. }
  42. bool Notification::AppMetadata::operator!=(const AppMetadata& other) const {
  43. return !(*this == other);
  44. }
  45. base::Value Notification::AppMetadata::ToValue() const {
  46. scoped_refptr<base::RefCountedMemory> png_data = icon.As1xPNGBytes();
  47. base::Value val(base::Value::Type::DICTIONARY);
  48. val.SetKey(kVisibleAppName, base::Value(visible_app_name));
  49. val.SetKey(kPackageName, base::Value(package_name));
  50. val.SetDoubleKey(kUserId, user_id);
  51. val.SetKey(kIcon, base::Value(base::Base64Encode(*png_data)));
  52. val.SetBoolKey(kIconIsMonochrome, icon_is_monochrome);
  53. if (icon_color.has_value()) {
  54. val.SetIntKey(kIconColorR, SkColorGetR(*icon_color));
  55. val.SetIntKey(kIconColorG, SkColorGetG(*icon_color));
  56. val.SetIntKey(kIconColorB, SkColorGetB(*icon_color));
  57. }
  58. return val;
  59. }
  60. // static
  61. Notification::AppMetadata Notification::AppMetadata::FromValue(
  62. const base::Value& value) {
  63. DCHECK(value.is_dict());
  64. DCHECK(value.FindKey(kVisibleAppName));
  65. DCHECK(value.FindKey(kVisibleAppName)->is_string());
  66. DCHECK(value.FindKey(kPackageName));
  67. DCHECK(value.FindKey(kPackageName)->is_string());
  68. DCHECK(value.FindKey(kUserId));
  69. DCHECK(value.FindKey(kUserId)->is_double());
  70. DCHECK(value.FindKey(kIcon));
  71. DCHECK(value.FindKey(kIcon)->is_string());
  72. if (value.FindKey(kIconIsMonochrome)) {
  73. DCHECK(value.FindKey(kIconIsMonochrome)->is_bool());
  74. }
  75. bool icon_is_monochrome =
  76. value.FindBoolPath(kIconIsMonochrome).value_or(false);
  77. absl::optional<SkColor> icon_color = absl::nullopt;
  78. if (value.FindKey(kIconColorR)) {
  79. DCHECK(value.FindKey(kIconColorR)->is_int());
  80. DCHECK(value.FindKey(kIconColorG));
  81. DCHECK(value.FindKey(kIconColorG)->is_int());
  82. DCHECK(value.FindKey(kIconColorB));
  83. DCHECK(value.FindKey(kIconColorB)->is_int());
  84. icon_color = SkColorSetRGB(*(value.FindIntPath(kIconColorR)),
  85. *(value.FindIntPath(kIconColorG)),
  86. *(value.FindIntPath(kIconColorB)));
  87. }
  88. const base::Value* visible_app_name_value = value.FindPath(kVisibleAppName);
  89. std::u16string visible_app_name_string_value;
  90. if (visible_app_name_value->is_string()) {
  91. visible_app_name_string_value =
  92. base::UTF8ToUTF16(visible_app_name_value->GetString());
  93. }
  94. std::string icon_str;
  95. base::Base64Decode(*(value.FindStringPath(kIcon)), &icon_str);
  96. gfx::Image decode_icon = gfx::Image::CreateFrom1xPNGBytes(
  97. base::RefCountedString::TakeString(&icon_str));
  98. return Notification::AppMetadata(visible_app_name_string_value,
  99. *(value.FindStringPath(kPackageName)),
  100. decode_icon, icon_color, icon_is_monochrome,
  101. *(value.FindDoublePath(kUserId)));
  102. }
  103. Notification::Notification(
  104. int64_t id,
  105. const AppMetadata& app_metadata,
  106. const base::Time& timestamp,
  107. Importance importance,
  108. Notification::Category category,
  109. const base::flat_map<Notification::ActionType, int64_t>& action_id_map,
  110. InteractionBehavior interaction_behavior,
  111. const absl::optional<std::u16string>& title,
  112. const absl::optional<std::u16string>& text_content,
  113. const absl::optional<gfx::Image>& shared_image,
  114. const absl::optional<gfx::Image>& contact_image)
  115. : id_(id),
  116. app_metadata_(app_metadata),
  117. timestamp_(timestamp),
  118. importance_(importance),
  119. category_(category),
  120. action_id_map_(action_id_map),
  121. interaction_behavior_(interaction_behavior),
  122. title_(title),
  123. text_content_(text_content),
  124. shared_image_(shared_image),
  125. contact_image_(contact_image) {}
  126. Notification::Notification(const Notification& other) = default;
  127. Notification::~Notification() = default;
  128. bool Notification::operator<(const Notification& other) const {
  129. return std::tie(timestamp_, id_) < std::tie(other.timestamp_, other.id_);
  130. }
  131. bool Notification::operator==(const Notification& other) const {
  132. return id_ == other.id_ && app_metadata_ == other.app_metadata_ &&
  133. timestamp_ == other.timestamp_ && importance_ == other.importance_ &&
  134. category_ == other.category_ &&
  135. action_id_map_ == other.action_id_map_ &&
  136. interaction_behavior_ == other.interaction_behavior_ &&
  137. title_ == other.title_ && text_content_ == other.text_content_ &&
  138. shared_image_ == other.shared_image_ &&
  139. contact_image_ == other.contact_image_;
  140. }
  141. bool Notification::operator!=(const Notification& other) const {
  142. return !(*this == other);
  143. }
  144. std::ostream& operator<<(std::ostream& stream,
  145. const Notification::AppMetadata& app_metadata) {
  146. stream << "{VisibleAppName: \"" << app_metadata.visible_app_name << "\", "
  147. << "PackageName: \"" << app_metadata.package_name << "\"}";
  148. return stream;
  149. }
  150. std::ostream& operator<<(std::ostream& stream,
  151. Notification::Importance importance) {
  152. switch (importance) {
  153. case Notification::Importance::kUnspecified:
  154. stream << "[Unspecified]";
  155. break;
  156. case Notification::Importance::kNone:
  157. stream << "[None]";
  158. break;
  159. case Notification::Importance::kMin:
  160. stream << "[Min]";
  161. break;
  162. case Notification::Importance::kLow:
  163. stream << "[Low]";
  164. break;
  165. case Notification::Importance::kDefault:
  166. stream << "[Default]";
  167. break;
  168. case Notification::Importance::kHigh:
  169. stream << "[High]";
  170. break;
  171. }
  172. return stream;
  173. }
  174. std::ostream& operator<<(std::ostream& stream,
  175. Notification::InteractionBehavior behavior) {
  176. switch (behavior) {
  177. case Notification::InteractionBehavior::kNone:
  178. stream << "[None]";
  179. break;
  180. case Notification::InteractionBehavior::kOpenable:
  181. stream << "[Openable]";
  182. break;
  183. }
  184. return stream;
  185. }
  186. std::ostream& operator<<(std::ostream& stream,
  187. Notification::Category catetory) {
  188. switch (catetory) {
  189. case Notification::Category::kNone:
  190. stream << "[None]";
  191. break;
  192. case Notification::Category::kConversation:
  193. stream << "[Conversation]";
  194. break;
  195. case Notification::Category::kIncomingCall:
  196. stream << "[IncomingCall]";
  197. break;
  198. case Notification::Category::kOngoingCall:
  199. stream << "[OngoingCall]";
  200. break;
  201. case Notification::Category::kScreenCall:
  202. stream << "[ScreenCall]";
  203. break;
  204. }
  205. return stream;
  206. }
  207. std::ostream& operator<<(std::ostream& stream,
  208. const Notification& notification) {
  209. stream << "{Id: " << notification.id() << ", "
  210. << "App: " << notification.app_metadata() << ", "
  211. << "Timestamp: " << notification.timestamp() << ", "
  212. << "Importance: " << notification.importance() << ", "
  213. << "Category: " << notification.category() << ", "
  214. << "InteractionBehavior: " << notification.interaction_behavior()
  215. << "}";
  216. return stream;
  217. }
  218. } // namespace phonehub
  219. } // namespace ash