blob: 1fe52a09018e0a9b5622bae09cbf1bc80f8d8a9b [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/notifications/arc_application_notifier_controller.h"
#include <set>
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h"
#include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h"
#include "ui/base/layout.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/message_center/public/cpp/notifier_id.h"
namespace arc {
namespace {
constexpr int kArcAppIconSizeInDp = 48;
class ArcAppNotifierShutdownNotifierFactory
: public BrowserContextKeyedServiceShutdownNotifierFactory {
public:
static ArcAppNotifierShutdownNotifierFactory* GetInstance() {
return base::Singleton<ArcAppNotifierShutdownNotifierFactory>::get();
}
private:
friend struct base::DefaultSingletonTraits<
ArcAppNotifierShutdownNotifierFactory>;
ArcAppNotifierShutdownNotifierFactory()
: BrowserContextKeyedServiceShutdownNotifierFactory("ArcAppNotifier") {
DependsOn(ArcAppListPrefsFactory::GetInstance());
}
~ArcAppNotifierShutdownNotifierFactory() override {}
DISALLOW_COPY_AND_ASSIGN(ArcAppNotifierShutdownNotifierFactory);
};
} // namespace
ArcApplicationNotifierController::ArcApplicationNotifierController(
NotifierController::Observer* observer)
: observer_(observer), last_profile_(nullptr) {}
ArcApplicationNotifierController::~ArcApplicationNotifierController() {
StopObserving();
}
std::vector<ash::mojom::NotifierUiDataPtr>
ArcApplicationNotifierController::GetNotifierList(Profile* profile) {
// In Guest mode, it can be called but there's no ARC apps to return.
if (profile->IsOffTheRecord())
return std::vector<ash::mojom::NotifierUiDataPtr>();
package_to_app_ids_.clear();
icons_.clear();
StopObserving();
ArcAppListPrefs* const app_list = ArcAppListPrefs::Get(profile);
std::vector<ash::mojom::NotifierUiDataPtr> results;
// The app list can be null in unit tests.
if (!app_list)
return results;
const std::vector<std::string>& app_ids = app_list->GetAppIds();
last_profile_ = profile;
StartObserving();
for (const std::string& app_id : app_ids) {
const auto app = app_list->GetApp(app_id);
// Handle packages having multiple launcher activities.
if (!app || package_to_app_ids_.count(app->package_name))
continue;
const auto package = app_list->GetPackage(app->package_name);
if (!package || package->system)
continue;
// Load icons for notifier.
std::unique_ptr<ArcAppIcon> icon(
new ArcAppIcon(profile, app_id,
// ARC icon is available only for 48x48 dips.
kArcAppIconSizeInDp,
// The life time of icon must shorter than |this|.
this));
// Apply icon now to set the default image.
OnIconUpdated(icon.get());
// Add notifiers.
package_to_app_ids_.insert(std::make_pair(app->package_name, app_id));
message_center::NotifierId notifier_id(
message_center::NotifierId::ARC_APPLICATION, app_id);
auto ui_data = ash::mojom::NotifierUiData::New(
notifier_id, base::UTF8ToUTF16(app->name), app->notifications_enabled,
false /* enforced */, icon->image_skia());
icons_.push_back(std::move(icon));
results.push_back(std::move(ui_data));
}
return results;
}
void ArcApplicationNotifierController::SetNotifierEnabled(
Profile* profile,
const message_center::NotifierId& notifier_id,
bool enabled) {
ArcAppListPrefs::Get(profile)->SetNotificationsEnabled(notifier_id.id,
enabled);
// OnNotifierEnabledChanged will be invoked via ArcAppListPrefs::Observer.
}
void ArcApplicationNotifierController::OnIconUpdated(ArcAppIcon* icon) {
observer_->OnIconImageUpdated(
message_center::NotifierId(message_center::NotifierId::ARC_APPLICATION,
icon->app_id()),
icon->image_skia());
}
void ArcApplicationNotifierController::OnNotificationsEnabledChanged(
const std::string& package_name,
bool enabled) {
auto it = package_to_app_ids_.find(package_name);
if (it == package_to_app_ids_.end())
return;
observer_->OnNotifierEnabledChanged(
message_center::NotifierId(message_center::NotifierId::ARC_APPLICATION,
it->second),
enabled);
}
void ArcApplicationNotifierController::StartObserving() {
ArcAppListPrefs::Get(last_profile_)->AddObserver(this);
shutdown_notifier_ = ArcAppNotifierShutdownNotifierFactory::GetInstance()
->Get(last_profile_)
->Subscribe(base::BindRepeating(
&ArcApplicationNotifierController::StopObserving,
base::Unretained(this)));
}
void ArcApplicationNotifierController::StopObserving() {
if (!last_profile_)
return;
shutdown_notifier_.reset();
ArcAppListPrefs::Get(last_profile_)->RemoveObserver(this);
last_profile_ = nullptr;
}
} // namespace arc