Skip to content

Commit

Permalink
feat(extensions): add support for some chrome.management APIs (#25098) (
Browse files Browse the repository at this point in the history
#25345)

* fix: initialize management policy

* fix(extensions): crash when using chrome.management

* test: add tests

* docs: add a note about chrome.management

* fix: lint errors

* fix: lint errors

* fix: remove favicon_service include

* fix: add missing management permission

* docs: more supported apis

* fix: extensions.md line endings
  • Loading branch information
sentialx committed Sep 8, 2020
1 parent 303b420 commit f99afa4
Show file tree
Hide file tree
Showing 11 changed files with 430 additions and 3 deletions.
12 changes: 12 additions & 0 deletions docs/api/extensions.md
Expand Up @@ -102,3 +102,15 @@ The following methods of `chrome.tabs` are supported:
> **Note:** In Chrome, passing `-1` as a tab ID signifies the "currently active
> tab". Since Electron has no such concept, passing `-1` as a tab ID is not
> supported and will raise an error.
### `chrome.management`

The following methods of `chrome.management` are supported:

- `chrome.management.getAll`
- `chrome.management.get`
- `chrome.management.getSelf`
- `chrome.management.getPermissionWarningsById`
- `chrome.management.getPermissionWarningsByManifest`
- `chrome.management.onEnabled`
- `chrome.management.onDisabled`
2 changes: 2 additions & 0 deletions filenames.gni
Expand Up @@ -626,6 +626,8 @@ filenames = {
"shell/browser/extensions/api/resources_private/resources_private_api.h",
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.cc",
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.h",
"shell/browser/extensions/api/management/electron_management_api_delegate.cc",
"shell/browser/extensions/api/management/electron_management_api_delegate.h",
"shell/browser/extensions/api/tabs/tabs_api.cc",
"shell/browser/extensions/api/tabs/tabs_api.h",
"shell/browser/extensions/api/streams_private/streams_private_api.cc",
Expand Down
@@ -0,0 +1,235 @@
// Copyright 2014 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.

// TODO(sentialx): emit relevant events in Electron's session?
#include "shell/browser/extensions/api/management/electron_management_api_delegate.h"

#include <memory>
#include <string>
#include <utility>

#include "base/bind.h"
#include "base/macros.h"
#include "base/strings/strcat.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "chrome/common/extensions/extension_metrics.h"
#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/web_application_info.h"
#include "chrome/common/webui_url_constants.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/api/management/management_api.h"
#include "extensions/browser/api/management/management_api_constants.h"
#include "extensions/browser/disable_reason.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/api/management.h"
#include "extensions/common/extension.h"
#include "services/data_decoder/public/cpp/data_decoder.h"
#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"

namespace {
class ManagementSetEnabledFunctionInstallPromptDelegate
: public extensions::InstallPromptDelegate {
public:
ManagementSetEnabledFunctionInstallPromptDelegate(
content::WebContents* web_contents,
content::BrowserContext* browser_context,
const extensions::Extension* extension,
const base::Callback<void(bool)>& callback) {
// TODO(sentialx): emit event
}
~ManagementSetEnabledFunctionInstallPromptDelegate() override {}

private:
base::WeakPtrFactory<ManagementSetEnabledFunctionInstallPromptDelegate>
weak_factory_{this};

DISALLOW_COPY_AND_ASSIGN(ManagementSetEnabledFunctionInstallPromptDelegate);
};

class ManagementUninstallFunctionUninstallDialogDelegate
: public extensions::UninstallDialogDelegate {
public:
ManagementUninstallFunctionUninstallDialogDelegate(
extensions::ManagementUninstallFunctionBase* function,
const extensions::Extension* target_extension,
bool show_programmatic_uninstall_ui) {
// TODO(sentialx): emit event
}

~ManagementUninstallFunctionUninstallDialogDelegate() override {}

private:
DISALLOW_COPY_AND_ASSIGN(ManagementUninstallFunctionUninstallDialogDelegate);
};

} // namespace

ElectronManagementAPIDelegate::ElectronManagementAPIDelegate() {}

ElectronManagementAPIDelegate::~ElectronManagementAPIDelegate() {}

void ElectronManagementAPIDelegate::LaunchAppFunctionDelegate(
const extensions::Extension* extension,
content::BrowserContext* context) const {
// TODO(sentialx): emit event
extensions::RecordAppLaunchType(extension_misc::APP_LAUNCH_EXTENSION_API,
extension->GetType());
}

GURL ElectronManagementAPIDelegate::GetFullLaunchURL(
const extensions::Extension* extension) const {
return extensions::AppLaunchInfo::GetFullLaunchURL(extension);
}

extensions::LaunchType ElectronManagementAPIDelegate::GetLaunchType(
const extensions::ExtensionPrefs* prefs,
const extensions::Extension* extension) const {
// TODO(sentialx)
return extensions::LAUNCH_TYPE_DEFAULT;
}

void ElectronManagementAPIDelegate::
GetPermissionWarningsByManifestFunctionDelegate(
extensions::ManagementGetPermissionWarningsByManifestFunction* function,
const std::string& manifest_str) const {
data_decoder::DataDecoder::ParseJsonIsolated(
manifest_str,
base::BindOnce(
&extensions::ManagementGetPermissionWarningsByManifestFunction::
OnParse,
function));
}

std::unique_ptr<extensions::InstallPromptDelegate>
ElectronManagementAPIDelegate::SetEnabledFunctionDelegate(
content::WebContents* web_contents,
content::BrowserContext* browser_context,
const extensions::Extension* extension,
const base::Callback<void(bool)>& callback) const {
return std::unique_ptr<ManagementSetEnabledFunctionInstallPromptDelegate>(
new ManagementSetEnabledFunctionInstallPromptDelegate(
web_contents, browser_context, extension, callback));
}

std::unique_ptr<extensions::UninstallDialogDelegate>
ElectronManagementAPIDelegate::UninstallFunctionDelegate(
extensions::ManagementUninstallFunctionBase* function,
const extensions::Extension* target_extension,
bool show_programmatic_uninstall_ui) const {
return std::unique_ptr<extensions::UninstallDialogDelegate>(
new ManagementUninstallFunctionUninstallDialogDelegate(
function, target_extension, show_programmatic_uninstall_ui));
}

bool ElectronManagementAPIDelegate::CreateAppShortcutFunctionDelegate(
extensions::ManagementCreateAppShortcutFunction* function,
const extensions::Extension* extension,
std::string* error) const {
return false; // TODO(sentialx): route event and return true
}

std::unique_ptr<extensions::AppForLinkDelegate>
ElectronManagementAPIDelegate::GenerateAppForLinkFunctionDelegate(
extensions::ManagementGenerateAppForLinkFunction* function,
content::BrowserContext* context,
const std::string& title,
const GURL& launch_url) const {
// TODO(sentialx)
return nullptr;
}

bool ElectronManagementAPIDelegate::CanContextInstallWebApps(
content::BrowserContext* context) const {
// TODO(sentialx)
return false;
}

void ElectronManagementAPIDelegate::InstallOrLaunchReplacementWebApp(
content::BrowserContext* context,
const GURL& web_app_url,
InstallOrLaunchWebAppCallback callback) const {
// TODO(sentialx)
}

bool ElectronManagementAPIDelegate::CanContextInstallAndroidApps(
content::BrowserContext* context) const {
return false;
}

void ElectronManagementAPIDelegate::CheckAndroidAppInstallStatus(
const std::string& package_name,
AndroidAppInstallStatusCallback callback) const {
std::move(callback).Run(false);
}

void ElectronManagementAPIDelegate::InstallReplacementAndroidApp(
const std::string& package_name,
InstallAndroidAppCallback callback) const {
std::move(callback).Run(false);
}

void ElectronManagementAPIDelegate::EnableExtension(
content::BrowserContext* context,
const std::string& extension_id) const {
// const extensions::Extension* extension =
// extensions::ExtensionRegistry::Get(context)->GetExtensionById(
// extension_id, extensions::ExtensionRegistry::EVERYTHING);

// TODO(sentialx): we don't have ExtensionService
// If the extension was disabled for a permissions increase, the Management
// API will have displayed a re-enable prompt to the user, so we know it's
// safe to grant permissions here.
// extensions::ExtensionSystem::Get(context)
// ->extension_service()
// ->GrantPermissionsAndEnableExtension(extension);
}

void ElectronManagementAPIDelegate::DisableExtension(
content::BrowserContext* context,
const extensions::Extension* source_extension,
const std::string& extension_id,
extensions::disable_reason::DisableReason disable_reason) const {
// TODO(sentialx): we don't have ExtensionService
// extensions::ExtensionSystem::Get(context)
// ->extension_service()
// ->DisableExtensionWithSource(source_extension, extension_id,
// disable_reason);
}

bool ElectronManagementAPIDelegate::UninstallExtension(
content::BrowserContext* context,
const std::string& transient_extension_id,
extensions::UninstallReason reason,
base::string16* error) const {
// TODO(sentialx): we don't have ExtensionService
// return extensions::ExtensionSystem::Get(context)
// ->extension_service()
// ->UninstallExtension(transient_extension_id, reason, error);
return false;
}

void ElectronManagementAPIDelegate::SetLaunchType(
content::BrowserContext* context,
const std::string& extension_id,
extensions::LaunchType launch_type) const {
// TODO(sentialx)
// extensions::SetLaunchType(context, extension_id, launch_type);
}

GURL ElectronManagementAPIDelegate::GetIconURL(
const extensions::Extension* extension,
int icon_size,
ExtensionIconSet::MatchType match,
bool grayscale) const {
GURL icon_url(base::StringPrintf("%s%s/%d/%d%s",
chrome::kChromeUIExtensionIconURL,
extension->id().c_str(), icon_size, match,
grayscale ? "?grayscale=true" : ""));
CHECK(icon_url.is_valid());
return icon_url;
}
@@ -0,0 +1,86 @@
// Copyright 2014 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_EXTENSIONS_API_MANAGEMENT_ELECTRON_MANAGEMENT_API_DELEGATE_H_
#define SHELL_BROWSER_EXTENSIONS_API_MANAGEMENT_ELECTRON_MANAGEMENT_API_DELEGATE_H_

#include <memory>
#include <string>

#include "base/task/cancelable_task_tracker.h"
#include "extensions/browser/api/management/management_api_delegate.h"

class ElectronManagementAPIDelegate : public extensions::ManagementAPIDelegate {
public:
ElectronManagementAPIDelegate();
~ElectronManagementAPIDelegate() override;

// ManagementAPIDelegate.
void LaunchAppFunctionDelegate(
const extensions::Extension* extension,
content::BrowserContext* context) const override;
GURL GetFullLaunchURL(const extensions::Extension* extension) const override;
extensions::LaunchType GetLaunchType(
const extensions::ExtensionPrefs* prefs,
const extensions::Extension* extension) const override;
void GetPermissionWarningsByManifestFunctionDelegate(
extensions::ManagementGetPermissionWarningsByManifestFunction* function,
const std::string& manifest_str) const override;
std::unique_ptr<extensions::InstallPromptDelegate> SetEnabledFunctionDelegate(
content::WebContents* web_contents,
content::BrowserContext* browser_context,
const extensions::Extension* extension,
const base::Callback<void(bool)>& callback) const override;
std::unique_ptr<extensions::UninstallDialogDelegate>
UninstallFunctionDelegate(
extensions::ManagementUninstallFunctionBase* function,
const extensions::Extension* target_extension,
bool show_programmatic_uninstall_ui) const override;
bool CreateAppShortcutFunctionDelegate(
extensions::ManagementCreateAppShortcutFunction* function,
const extensions::Extension* extension,
std::string* error) const override;
std::unique_ptr<extensions::AppForLinkDelegate>
GenerateAppForLinkFunctionDelegate(
extensions::ManagementGenerateAppForLinkFunction* function,
content::BrowserContext* context,
const std::string& title,
const GURL& launch_url) const override;
bool CanContextInstallWebApps(
content::BrowserContext* context) const override;
void InstallOrLaunchReplacementWebApp(
content::BrowserContext* context,
const GURL& web_app_url,
ManagementAPIDelegate::InstallOrLaunchWebAppCallback callback)
const override;
bool CanContextInstallAndroidApps(
content::BrowserContext* context) const override;
void CheckAndroidAppInstallStatus(
const std::string& package_name,
ManagementAPIDelegate::AndroidAppInstallStatusCallback callback)
const override;
void InstallReplacementAndroidApp(
const std::string& package_name,
ManagementAPIDelegate::InstallAndroidAppCallback callback) const override;
void EnableExtension(content::BrowserContext* context,
const std::string& extension_id) const override;
void DisableExtension(
content::BrowserContext* context,
const extensions::Extension* source_extension,
const std::string& extension_id,
extensions::disable_reason::DisableReason disable_reason) const override;
bool UninstallExtension(content::BrowserContext* context,
const std::string& transient_extension_id,
extensions::UninstallReason reason,
base::string16* error) const override;
void SetLaunchType(content::BrowserContext* context,
const std::string& extension_id,
extensions::LaunchType launch_type) const override;
GURL GetIconURL(const extensions::Extension* extension,
int icon_size,
ExtensionIconSet::MatchType match,
bool grayscale) const override;
};

#endif // SHELL_BROWSER_EXTENSIONS_API_MANAGEMENT_ELECTRON_MANAGEMENT_API_DELEGATE_H_
5 changes: 4 additions & 1 deletion shell/browser/extensions/electron_extension_system.cc
Expand Up @@ -25,6 +25,7 @@
#include "extensions/browser/api/app_runtime/app_runtime_api.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/info_map.h"
#include "extensions/browser/management_policy.h"
#include "extensions/browser/notification_types.h"
#include "extensions/browser/null_app_sorting.h"
#include "extensions/browser/quota_service.h"
Expand Down Expand Up @@ -91,6 +92,8 @@ void ElectronExtensionSystem::InitForRegularProfile(bool extensions_enabled) {

if (!browser_context_->IsOffTheRecord())
LoadComponentExtensions();

management_policy_.reset(new ManagementPolicy);
}

std::unique_ptr<base::DictionaryValue> ParseManifest(
Expand Down Expand Up @@ -130,7 +133,7 @@ RuntimeData* ElectronExtensionSystem::runtime_data() {
}

ManagementPolicy* ElectronExtensionSystem::management_policy() {
return nullptr;
return management_policy_.get();
}

ServiceWorkerManager* ElectronExtensionSystem::service_worker_manager() {
Expand Down
1 change: 1 addition & 0 deletions shell/browser/extensions/electron_extension_system.h
Expand Up @@ -104,6 +104,7 @@ class ElectronExtensionSystem : public ExtensionSystem {
std::unique_ptr<QuotaService> quota_service_;
std::unique_ptr<SharedUserScriptManager> shared_user_script_manager_;
std::unique_ptr<AppSorting> app_sorting_;
std::unique_ptr<ManagementPolicy> management_policy_;

std::unique_ptr<ElectronExtensionLoader> extension_loader_;

Expand Down

0 comments on commit f99afa4

Please sign in to comment.