blob: e483c3acd02a090e07fcbd33c90ce0f12c09221d [file] [log] [blame]
hironod36c21d2016-06-21 01:25:221// Copyright 2016 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
Evan Stadefdc58a82018-04-23 19:00:475#include "chrome/browser/notifications/arc_application_notifier_controller.h"
hironod36c21d2016-06-21 01:25:226
7#include <set>
8
Evan Stadeecfc48c2019-06-17 21:35:239#include "ash/public/cpp/notifier_metadata.h"
Sebastien Marchandf1349f52019-01-25 03:16:4110#include "base/bind.h"
hironod36c21d2016-06-21 01:25:2211#include "base/strings/utf_string_conversions.h"
12#include "chrome/browser/profiles/profile.h"
Evan Stadefdc58a82018-04-23 19:00:4713#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h"
14#include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h"
hirono0bed5da2016-06-22 01:35:4515#include "ui/base/layout.h"
16#include "ui/display/display.h"
17#include "ui/display/screen.h"
Evan Stade889ce4712018-01-28 15:26:2618#include "ui/message_center/public/cpp/notifier_id.h"
hironod36c21d2016-06-21 01:25:2219
20namespace arc {
21
22namespace {
hirono0bed5da2016-06-22 01:35:4523constexpr int kArcAppIconSizeInDp = 48;
Evan Stadefdc58a82018-04-23 19:00:4724
25class ArcAppNotifierShutdownNotifierFactory
26 : public BrowserContextKeyedServiceShutdownNotifierFactory {
27 public:
28 static ArcAppNotifierShutdownNotifierFactory* GetInstance() {
29 return base::Singleton<ArcAppNotifierShutdownNotifierFactory>::get();
30 }
31
32 private:
33 friend struct base::DefaultSingletonTraits<
34 ArcAppNotifierShutdownNotifierFactory>;
35
36 ArcAppNotifierShutdownNotifierFactory()
37 : BrowserContextKeyedServiceShutdownNotifierFactory("ArcAppNotifier") {
38 DependsOn(ArcAppListPrefsFactory::GetInstance());
39 }
40
41 ~ArcAppNotifierShutdownNotifierFactory() override {}
42
43 DISALLOW_COPY_AND_ASSIGN(ArcAppNotifierShutdownNotifierFactory);
44};
45
hironod36c21d2016-06-21 01:25:2246} // namespace
47
Evan Stadefdc58a82018-04-23 19:00:4748ArcApplicationNotifierController::ArcApplicationNotifierController(
49 NotifierController::Observer* observer)
hironoe39df252016-06-24 03:17:1450 : observer_(observer), last_profile_(nullptr) {}
hironod36c21d2016-06-21 01:25:2251
Evan Stadefdc58a82018-04-23 19:00:4752ArcApplicationNotifierController::~ArcApplicationNotifierController() {
hironoe39df252016-06-24 03:17:1453 StopObserving();
54}
hirono0bed5da2016-06-22 01:35:4555
Evan Stadeecfc48c2019-06-17 21:35:2356std::vector<ash::NotifierMetadata>
Evan Stadefdc58a82018-04-23 19:00:4757ArcApplicationNotifierController::GetNotifierList(Profile* profile) {
Tetsui Ohkubod91be842018-07-03 01:35:2258 // In Guest mode, it can be called but there's no ARC apps to return.
59 if (profile->IsOffTheRecord())
Evan Stadeecfc48c2019-06-17 21:35:2360 return std::vector<ash::NotifierMetadata>();
Tetsui Ohkubod91be842018-07-03 01:35:2261
hironoe39df252016-06-24 03:17:1462 package_to_app_ids_.clear();
63 icons_.clear();
64 StopObserving();
65
66 ArcAppListPrefs* const app_list = ArcAppListPrefs::Get(profile);
Evan Stadeecfc48c2019-06-17 21:35:2367 std::vector<ash::NotifierMetadata> notifiers;
Evan Stade51f736fc2017-10-25 05:26:1868 // The app list can be null in unit tests.
69 if (!app_list)
Evan Stadeecfc48c2019-06-17 21:35:2370 return notifiers;
hironod36c21d2016-06-21 01:25:2271 const std::vector<std::string>& app_ids = app_list->GetAppIds();
hironod36c21d2016-06-21 01:25:2272
hironoe39df252016-06-24 03:17:1473 last_profile_ = profile;
Evan Stadefdc58a82018-04-23 19:00:4774 StartObserving();
hironoe39df252016-06-24 03:17:1475
hironod36c21d2016-06-21 01:25:2276 for (const std::string& app_id : app_ids) {
77 const auto app = app_list->GetApp(app_id);
hironod36c21d2016-06-21 01:25:2278 // Handle packages having multiple launcher activities.
hirono1f918652016-07-05 09:54:5479 if (!app || package_to_app_ids_.count(app->package_name))
80 continue;
81
82 const auto package = app_list->GetPackage(app->package_name);
83 if (!package || package->system)
hironod36c21d2016-06-21 01:25:2284 continue;
85
hirono0bed5da2016-06-22 01:35:4586 // Load icons for notifier.
Vladislav Kaznacheevcea52b092018-07-25 22:37:2787 std::unique_ptr<ArcAppIcon> icon =
88 std::make_unique<ArcAppIcon>(profile, app_id,
hirono0bed5da2016-06-22 01:35:4589 // ARC icon is available only for 48x48 dips.
90 kArcAppIconSizeInDp,
91 // The life time of icon must shorter than |this|.
Vladislav Kaznacheevcea52b092018-07-25 22:37:2792 this);
khmel832d8b72017-05-08 18:38:1193 // Apply icon now to set the default image.
94 OnIconUpdated(icon.get());
hirono0bed5da2016-06-22 01:35:4595
96 // Add notifiers.
hironoe39df252016-06-24 03:17:1497 package_to_app_ids_.insert(std::make_pair(app->package_name, app_id));
hironod36c21d2016-06-21 01:25:2298 message_center::NotifierId notifier_id(
Daniel Chenga925cbb52018-11-06 21:52:3599 message_center::NotifierType::ARC_APPLICATION, app_id);
Evan Stadeecfc48c2019-06-17 21:35:23100 notifiers.emplace_back(notifier_id, base::UTF8ToUTF16(app->name),
101 app->notifications_enabled, false /* enforced */,
102 icon->image_skia());
hirono0bed5da2016-06-22 01:35:45103 icons_.push_back(std::move(icon));
hironod36c21d2016-06-21 01:25:22104 }
105
Evan Stadeecfc48c2019-06-17 21:35:23106 return notifiers;
hironod36c21d2016-06-21 01:25:22107}
108
Evan Stadefdc58a82018-04-23 19:00:47109void ArcApplicationNotifierController::SetNotifierEnabled(
hironod36c21d2016-06-21 01:25:22110 Profile* profile,
Evan Stade844ad7f2017-09-20 18:05:31111 const message_center::NotifierId& notifier_id,
hironod36c21d2016-06-21 01:25:22112 bool enabled) {
Evan Stadefdc58a82018-04-23 19:00:47113 ArcAppListPrefs::Get(profile)->SetNotificationsEnabled(notifier_id.id,
114 enabled);
hironoe39df252016-06-24 03:17:14115 // OnNotifierEnabledChanged will be invoked via ArcAppListPrefs::Observer.
116}
117
Evan Stadefdc58a82018-04-23 19:00:47118void ArcApplicationNotifierController::OnIconUpdated(ArcAppIcon* icon) {
119 observer_->OnIconImageUpdated(
Daniel Chenga925cbb52018-11-06 21:52:35120 message_center::NotifierId(message_center::NotifierType::ARC_APPLICATION,
Evan Stadefdc58a82018-04-23 19:00:47121 icon->app_id()),
122 icon->image_skia());
123}
124
125void ArcApplicationNotifierController::OnNotificationsEnabledChanged(
hironoe39df252016-06-24 03:17:14126 const std::string& package_name,
127 bool enabled) {
128 auto it = package_to_app_ids_.find(package_name);
129 if (it == package_to_app_ids_.end())
130 return;
131 observer_->OnNotifierEnabledChanged(
Daniel Chenga925cbb52018-11-06 21:52:35132 message_center::NotifierId(message_center::NotifierType::ARC_APPLICATION,
hironoe39df252016-06-24 03:17:14133 it->second),
134 enabled);
hironod36c21d2016-06-21 01:25:22135}
136
Evan Stadefdc58a82018-04-23 19:00:47137void ArcApplicationNotifierController::StartObserving() {
138 ArcAppListPrefs::Get(last_profile_)->AddObserver(this);
139 shutdown_notifier_ = ArcAppNotifierShutdownNotifierFactory::GetInstance()
140 ->Get(last_profile_)
141 ->Subscribe(base::BindRepeating(
142 &ArcApplicationNotifierController::StopObserving,
143 base::Unretained(this)));
hirono0bed5da2016-06-22 01:35:45144}
145
Evan Stadefdc58a82018-04-23 19:00:47146void ArcApplicationNotifierController::StopObserving() {
hironoe39df252016-06-24 03:17:14147 if (!last_profile_)
148 return;
Evan Stadefdc58a82018-04-23 19:00:47149 shutdown_notifier_.reset();
150 ArcAppListPrefs::Get(last_profile_)->RemoveObserver(this);
hironoe39df252016-06-24 03:17:14151 last_profile_ = nullptr;
152}
153
hironod36c21d2016-06-21 01:25:22154} // namespace arc