fix: enable navigator.setAppBadge/clearAppBadge (#27067)

This commit is contained in:
John Kleinschmidt 2021-01-21 00:45:06 -05:00 committed by GitHub
parent 8b74361b0c
commit c5a41defbd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 481 additions and 41 deletions

View file

@ -0,0 +1,81 @@
// Copyright 2018 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 "shell/browser/badging/badge_manager.h"
#include <tuple>
#include <utility>
#include "base/i18n/number_formatting.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "shell/browser/badging/badge_manager_factory.h"
#include "shell/browser/browser.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/strings/grit/ui_strings.h"
namespace badging {
BadgeManager::BadgeManager() = default;
BadgeManager::~BadgeManager() = default;
// static
void BadgeManager::BindFrameReceiver(
content::RenderFrameHost* frame,
mojo::PendingReceiver<blink::mojom::BadgeService> receiver) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
auto* browser_context =
content::WebContents::FromRenderFrameHost(frame)->GetBrowserContext();
auto* badge_manager =
badging::BadgeManagerFactory::GetInstance()->GetForBrowserContext(
browser_context);
if (!badge_manager)
return;
auto context = std::make_unique<FrameBindingContext>(
frame->GetProcess()->GetID(), frame->GetRoutingID());
badge_manager->receivers_.Add(badge_manager, std::move(receiver),
std::move(context));
}
std::string BadgeManager::GetBadgeString(base::Optional<int> badge_content) {
if (!badge_content)
return "";
if (badge_content > kMaxBadgeContent) {
return base::UTF16ToUTF8(l10n_util::GetStringFUTF16(
IDS_SATURATED_BADGE_CONTENT, base::FormatNumber(kMaxBadgeContent)));
}
return base::UTF16ToUTF8(base::FormatNumber(badge_content.value()));
}
void BadgeManager::SetBadge(blink::mojom::BadgeValuePtr mojo_value) {
if (mojo_value->is_number() && mojo_value->get_number() == 0) {
mojo::ReportBadMessage(
"|value| should not be zero when it is |number| (ClearBadge should be "
"called instead)!");
return;
}
base::Optional<int> value =
mojo_value->is_flag() ? base::nullopt
: base::make_optional(mojo_value->get_number());
electron::Browser::Get()->SetBadgeCount(value);
}
void BadgeManager::ClearBadge() {
electron::Browser::Get()->SetBadgeCount(0);
}
} // namespace badging

View file

@ -0,0 +1,90 @@
// Copyright 2018 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.
#ifndef SHELL_BROWSER_BADGING_BADGE_MANAGER_H_
#define SHELL_BROWSER_BADGING_BADGE_MANAGER_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/macros.h"
#include "base/optional.h"
#include "components/keyed_service/core/keyed_service.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "third_party/blink/public/mojom/badging/badging.mojom.h"
#include "url/gurl.h"
namespace content {
class RenderFrameHost;
class RenderProcessHost;
} // namespace content
namespace badging {
// The maximum value of badge contents before saturation occurs.
constexpr int kMaxBadgeContent = 99;
// Maintains a record of badge contents and dispatches badge changes to a
// delegate.
class BadgeManager : public KeyedService, public blink::mojom::BadgeService {
public:
BadgeManager();
~BadgeManager() override;
static void BindFrameReceiver(
content::RenderFrameHost* frame,
mojo::PendingReceiver<blink::mojom::BadgeService> receiver);
// Determines the text to put on the badge based on some badge_content.
static std::string GetBadgeString(base::Optional<int> badge_content);
private:
// The BindingContext of a mojo request. Allows mojo calls to be tied back
// to the execution context they belong to without trusting the renderer for
// that information. This is an abstract base class that different types of
// execution contexts derive.
class BindingContext {
public:
virtual ~BindingContext() = default;
};
// The BindingContext for Window execution contexts.
class FrameBindingContext final : public BindingContext {
public:
FrameBindingContext(int process_id, int frame_id)
: process_id_(process_id), frame_id_(frame_id) {}
~FrameBindingContext() override = default;
int GetProcessId() { return process_id_; }
int GetFrameId() { return frame_id_; }
private:
int process_id_;
int frame_id_;
};
// blink::mojom::BadgeService:
// Note: These are private to stop them being called outside of mojo as they
// require a mojo binding context.
void SetBadge(blink::mojom::BadgeValuePtr value) override;
void ClearBadge() override;
// All the mojo receivers for the BadgeManager. Keeps track of the
// render_frame the binding is associated with, so as to not have to rely
// on the renderer passing it in.
mojo::ReceiverSet<blink::mojom::BadgeService, std::unique_ptr<BindingContext>>
receivers_;
// Delegate which handles actual setting and clearing of the badge.
// Note: This is currently only set on Windows and MacOS.
// std::unique_ptr<BadgeManagerDelegate> delegate_;
DISALLOW_COPY_AND_ASSIGN(BadgeManager);
};
} // namespace badging
#endif // SHELL_BROWSER_BADGING_BADGE_MANAGER_H_

View file

@ -0,0 +1,41 @@
// Copyright 2018 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 "shell/browser/badging/badge_manager_factory.h"
#include <memory>
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/memory/singleton.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "shell/browser/badging/badge_manager.h"
namespace badging {
// static
BadgeManager* BadgeManagerFactory::GetForBrowserContext(
content::BrowserContext* context) {
return static_cast<badging::BadgeManager*>(
GetInstance()->GetServiceForBrowserContext(context, true));
}
// static
BadgeManagerFactory* BadgeManagerFactory::GetInstance() {
return base::Singleton<BadgeManagerFactory>::get();
}
BadgeManagerFactory::BadgeManagerFactory()
: BrowserContextKeyedServiceFactory(
"BadgeManager",
BrowserContextDependencyManager::GetInstance()) {}
BadgeManagerFactory::~BadgeManagerFactory() {}
KeyedService* BadgeManagerFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
return new BadgeManager();
}
} // namespace badging

View file

@ -0,0 +1,44 @@
// Copyright 2018 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.
#ifndef SHELL_BROWSER_BADGING_BADGE_MANAGER_FACTORY_H_
#define SHELL_BROWSER_BADGING_BADGE_MANAGER_FACTORY_H_
#include "base/macros.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
namespace base {
template <typename T>
struct DefaultSingletonTraits;
}
namespace badging {
class BadgeManager;
// Singleton that provides access to context specific BadgeManagers.
class BadgeManagerFactory : public BrowserContextKeyedServiceFactory {
public:
// Gets the BadgeManager for the specified context
static BadgeManager* GetForBrowserContext(content::BrowserContext* context);
// Returns the BadgeManagerFactory singleton.
static BadgeManagerFactory* GetInstance();
private:
friend struct base::DefaultSingletonTraits<BadgeManagerFactory>;
BadgeManagerFactory();
~BadgeManagerFactory() override;
// BrowserContextKeyedServiceFactory
KeyedService* BuildServiceInstanceFor(
content::BrowserContext* context) const override;
DISALLOW_COPY_AND_ASSIGN(BadgeManagerFactory);
};
} // namespace badging
#endif // SHELL_BROWSER_BADGING_BADGE_MANAGER_FACTORY_H_