Commit 215be9c2 authored by Jason Lin's avatar Jason Lin Committed by Commit Bot

Store PluginVM camera/mic permissions in auto-reset prefs

We are making the permissions persistent across chrome restarts, so we
have to change the way the permissions are stored (currently, they are
stored as member variables initialized to false). Note that this CL
still resets the prefs values to false in
`PluginVmManagerImpl::OnPrimaryUserProfilePrepared()` because the
required permission indicators/notifications are not ready yet, so the
behavior for now is actually going to be the same.

This CL also fixes the bug that pressing <esc> key on the relaunch
dialog does not recover the toggle state.

This CL also simplfies the code by:
* removing <plugin-vm-permission-dialog> --- it is simpler to use
  <cr-dialog> directly.
* replacing `wouldPermissionChangeRequireRelaunch()` with
  `isRelaunchNeededForNewPermissions()` --- The toggle is the only way
  the user can change the value, so there is no need for the c++ code to
  check whether the values are actually different.

Bug: b/167491603
Change-Id: I423e1d03db6e4d2b52fefc052c22eb4f27733425
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2488262
Commit-Queue: Jason Lin <lxj@google.com>
Reviewed-by: default avatarJeevan Shikaram <jshikaram@chromium.org>
Reviewed-by: default avatarcalamity <calamity@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarJoel Hockey <joelhockey@chromium.org>
Reviewed-by: default avatarDaniel Ng <danielng@google.com>
Cr-Commit-Position: refs/heads/master@{#821080}
parent ac8cc2c7
......@@ -35,21 +35,13 @@ struct PermissionInfo {
const char* pref_name;
};
struct PluginVmHandledPermissionInfo {
app_management::mojom::PluginVmPermissionType permission;
plugin_vm::PermissionType permission_type;
};
constexpr PermissionInfo permission_infos[] = {
{app_management::mojom::PluginVmPermissionType::PRINTING,
plugin_vm::prefs::kPluginVmPrintersAllowed},
};
constexpr PluginVmHandledPermissionInfo plugin_vm_handled_permission_infos[] = {
{app_management::mojom::PluginVmPermissionType::CAMERA,
plugin_vm::PermissionType::kCamera},
plugin_vm::prefs::kPluginVmCameraAllowed},
{app_management::mojom::PluginVmPermissionType::MICROPHONE,
plugin_vm::PermissionType::kMicrophone},
plugin_vm::prefs::kPluginVmMicAllowed},
};
const char* PermissionToPrefName(
......@@ -84,9 +76,7 @@ void SetShowInAppManagement(apps::mojom::App* app, bool installed) {
: apps::mojom::OptionalBool::kFalse;
}
void PopulatePermissions(apps::mojom::App* app,
Profile* profile,
bool allowed) {
void PopulatePermissions(apps::mojom::App* app, Profile* profile) {
for (const PermissionInfo& info : permission_infos) {
auto permission = apps::mojom::Permission::New();
permission->permission_id = static_cast<uint32_t>(info.permission);
......@@ -96,21 +86,6 @@ void PopulatePermissions(apps::mojom::App* app,
permission->is_managed = false;
app->permissions.push_back(std::move(permission));
}
for (const PluginVmHandledPermissionInfo& info :
plugin_vm_handled_permission_infos) {
auto permission = apps::mojom::Permission::New();
permission->permission_id = static_cast<uint32_t>(info.permission);
permission->value_type = apps::mojom::PermissionValueType::kBool;
if (allowed) {
permission->value = static_cast<uint32_t>(
plugin_vm::PluginVmManagerFactory::GetForProfile(profile)
->GetPermission(info.permission_type));
} else {
permission->value = static_cast<uint32_t>(false);
}
permission->is_managed = false;
app->permissions.push_back(std::move(permission));
}
}
apps::mojom::AppPtr GetPluginVmApp(Profile* profile, bool allowed) {
......@@ -127,7 +102,7 @@ apps::mojom::AppPtr GetPluginVmApp(Profile* profile, bool allowed) {
SetShowInAppManagement(
app.get(), plugin_vm::PluginVmFeatures::Get()->IsConfigured(profile));
PopulatePermissions(app.get(), profile, allowed);
PopulatePermissions(app.get(), profile);
SetAppAllowed(app.get(), allowed);
return app;
......@@ -140,7 +115,7 @@ namespace apps {
PluginVmApps::PluginVmApps(
const mojo::Remote<apps::mojom::AppService>& app_service,
Profile* profile)
: profile_(profile), registry_(nullptr), permissions_observer_(this) {
: profile_(profile), registry_(nullptr) {
// Don't show anything for non-primary profiles. We can't use
// `PluginVmFeatures::Get()->IsAllowed()` here because we still let the user
// uninstall Plugin VM when it isn't allowed for some other reasons (e.g.
......@@ -171,10 +146,6 @@ PluginVmApps::PluginVmApps(
base::Unretained(this)));
is_allowed_ = plugin_vm::PluginVmFeatures::Get()->IsAllowed(profile_);
if (is_allowed_) {
permissions_observer_.Add(
plugin_vm::PluginVmManagerFactory::GetForProfile(profile_));
}
}
PluginVmApps::~PluginVmApps() {
......@@ -242,7 +213,7 @@ void PluginVmApps::SetPermission(const std::string& app_id,
apps::mojom::AppPtr app = apps::mojom::App::New();
app->app_type = apps::mojom::AppType::kPluginVm;
app->app_id = plugin_vm::kPluginVmShelfAppId;
PopulatePermissions(app.get(), profile_, is_allowed_);
PopulatePermissions(app.get(), profile_);
Publish(std::move(app), subscribers_);
}
......@@ -364,14 +335,4 @@ void PluginVmApps::OnPluginVmConfiguredChanged() {
Publish(std::move(app), subscribers_);
}
void PluginVmApps::OnPluginVmPermissionsChanged(
plugin_vm::PermissionType permission_type,
bool allowed) {
apps::mojom::AppPtr app = apps::mojom::App::New();
app->app_type = apps::mojom::AppType::kPluginVm;
app->app_id = plugin_vm::kPluginVmShelfAppId;
PopulatePermissions(app.get(), profile_, is_allowed_);
Publish(std::move(app), subscribers_);
}
} // namespace apps
......@@ -29,7 +29,6 @@ namespace apps {
//
// See components/services/app_service/README.md.
class PluginVmApps : public apps::PublisherBase,
public plugin_vm::PluginVmPermissionsObserver,
public guest_os::GuestOsRegistryService::Observer {
public:
PluginVmApps(const mojo::Remote<apps::mojom::AppService>& app_service,
......@@ -77,9 +76,6 @@ class PluginVmApps : public apps::PublisherBase,
bool new_icon_key);
void OnPluginVmAllowedChanged(bool is_allowed);
void OnPluginVmConfiguredChanged();
// plugin_vm::PluginVmPermissionsObserver
void OnPluginVmPermissionsChanged(plugin_vm::PermissionType permission_type,
bool allowed) override;
mojo::RemoteSet<apps::mojom::Subscriber> subscribers_;
......@@ -91,12 +87,6 @@ class PluginVmApps : public apps::PublisherBase,
// Whether the Plugin VM app is allowed by policy.
bool is_allowed_;
ScopedObserver<plugin_vm::PluginVmManager,
plugin_vm::PluginVmPermissionsObserver,
&plugin_vm::PluginVmManager::AddPluginVmPermissionsObserver,
&plugin_vm::PluginVmManager::RemovePluginVmPermissionsObserver>
permissions_observer_;
std::unique_ptr<plugin_vm::PluginVmPolicySubscription> policy_subscription_;
PrefChangeRegistrar pref_registrar_;
};
......
......@@ -2064,7 +2064,6 @@ source_set("chromeos") {
"plugin_vm/plugin_vm_installer_factory.h",
"plugin_vm/plugin_vm_license_checker.cc",
"plugin_vm/plugin_vm_license_checker.h",
"plugin_vm/plugin_vm_manager.cc",
"plugin_vm/plugin_vm_manager.h",
"plugin_vm/plugin_vm_manager_factory.cc",
"plugin_vm/plugin_vm_manager_factory.h",
......
......@@ -12,8 +12,7 @@
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/plugin_vm/plugin_vm_manager.h"
#include "chrome/browser/chromeos/plugin_vm/plugin_vm_manager_factory.h"
#include "chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
......@@ -327,20 +326,18 @@ void VmPermissionServiceProvider::UpdatePluginVmPermissions(VmInfo* vm) {
}
const PrefService* prefs = profile->GetPrefs();
auto* PluginVmManager =
plugin_vm::PluginVmManagerFactory::GetForProfile(profile);
if (base::FeatureList::IsEnabled(
chromeos::features::kPluginVmShowCameraPermissions) &&
prefs->GetBoolean(prefs::kVideoCaptureAllowed)) {
vm->permission_to_enabled_map[VmInfo::PermissionCamera] =
PluginVmManager->GetPermission(plugin_vm::PermissionType::kCamera);
prefs->GetBoolean(plugin_vm::prefs::kPluginVmCameraAllowed);
}
if (base::FeatureList::IsEnabled(
chromeos::features::kPluginVmShowMicrophonePermissions) &&
prefs->GetBoolean(prefs::kAudioCaptureAllowed)) {
vm->permission_to_enabled_map[VmInfo::PermissionMicrophone] =
PluginVmManager->GetPermission(plugin_vm::PermissionType::kMicrophone);
prefs->GetBoolean(plugin_vm::prefs::kPluginVmMicAllowed);
}
}
......
// Copyright 2019 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/chromeos/plugin_vm/plugin_vm_manager.h"
namespace plugin_vm {
PluginVmManager::PluginVmManager() = default;
PluginVmManager::~PluginVmManager() = default;
bool PluginVmManager::GetPermission(PermissionType permission_type) {
auto it = permissions_.find(permission_type);
DCHECK(it != permissions_.end());
return it->second;
}
void PluginVmManager::SetPermission(PermissionType permission_type,
bool value) {
auto it = permissions_.find(permission_type);
DCHECK(it != permissions_.end());
if (it->second == value) {
return;
}
it->second = value;
for (auto& observer : plugin_vm_permissions_observers_) {
observer.OnPluginVmPermissionsChanged(permission_type, value);
}
}
void PluginVmManager::AddPluginVmPermissionsObserver(
PluginVmPermissionsObserver* observer) {
plugin_vm_permissions_observers_.AddObserver(observer);
}
void PluginVmManager::RemovePluginVmPermissionsObserver(
PluginVmPermissionsObserver* observer) {
plugin_vm_permissions_observers_.RemoveObserver(observer);
}
} // namespace plugin_vm
......@@ -19,21 +19,10 @@ class VmStartingObserver;
namespace plugin_vm {
enum class PermissionType { kCamera = 0, kMicrophone = 1 };
class PluginVmPermissionsObserver : public base::CheckedObserver {
public:
virtual void OnPluginVmPermissionsChanged(
plugin_vm::PermissionType permission_type,
bool allowed) = 0;
};
class PluginVmManager : public KeyedService {
public:
using LaunchPluginVmCallback = base::OnceCallback<void(bool success)>;
~PluginVmManager() override;
virtual void OnPrimaryUserProfilePrepared() = 0;
virtual void LaunchPluginVm(LaunchPluginVmCallback callback) = 0;
......@@ -63,28 +52,11 @@ class PluginVmManager : public KeyedService {
virtual void RemoveVmStartingObserver(
chromeos::VmStartingObserver* observer) = 0;
// Add/remove permissions observers
void AddPluginVmPermissionsObserver(PluginVmPermissionsObserver* observer);
void RemovePluginVmPermissionsObserver(PluginVmPermissionsObserver* observer);
virtual vm_tools::plugin_dispatcher::VmState vm_state() const = 0;
bool GetPermission(PermissionType permission_type);
void SetPermission(PermissionType permission_type, bool value);
// Indicates whether relaunch (suspend + start) is needed for the new
// permissions to go into effect.
// camera/mic permissions to go into effect.
virtual bool IsRelaunchNeededForNewPermissions() const = 0;
protected:
PluginVmManager();
private:
base::flat_map<PermissionType, bool> permissions_ = {
{PermissionType::kCamera, false},
{PermissionType::kMicrophone, false}};
base::ObserverList<PluginVmPermissionsObserver>
plugin_vm_permissions_observers_;
};
} // namespace plugin_vm
......
......@@ -119,6 +119,11 @@ void PluginVmManagerImpl::OnPrimaryUserProfilePrepared() {
request.set_owner_id(owner_id_);
request.set_vm_name_uuid(kPluginVmName);
// TODO(b/167491603): We need to reset these permissions until we have
// permission indicators/notifications working.
profile_->GetPrefs()->SetBoolean(prefs::kPluginVmCameraAllowed, false);
profile_->GetPrefs()->SetBoolean(prefs::kPluginVmMicAllowed, false);
// Probe the dispatcher.
chromeos::DBusThreadManager::Get()->GetVmPluginDispatcherClient()->ListVms(
std::move(request),
......
......@@ -26,8 +26,11 @@ const char kPluginVmImage[] = "plugin_vm.image";
// this user on this device.
const char kPluginVmImageExists[] = "plugin_vm.image_exists";
// A boolean preference indicating whether Plugin VM is allowed to use printers.
// Boolean preferences indicating whether Plugin VM is allowed to use certain
// devices.
const char kPluginVmPrintersAllowed[] = "plugin_vm.printers_allowed";
const char kPluginVmCameraAllowed[] = "plugin_vm.camera_allowed";
const char kPluginVmMicAllowed[] = "plugin_vm.mic_allowed";
// A string preference that specifies PluginVm licensing user id.
const char kPluginVmUserId[] = "plugin_vm.user_id";
......@@ -54,6 +57,8 @@ void RegisterProfilePrefs(PrefRegistrySimple* registry) {
// TODO(crbug.com/1066760): For convenience this currently defaults to true,
// but we'll need to revisit before launch.
registry->RegisterBooleanPref(kPluginVmPrintersAllowed, true);
registry->RegisterBooleanPref(kPluginVmCameraAllowed, false);
registry->RegisterBooleanPref(kPluginVmMicAllowed, false);
registry->RegisterStringPref(kPluginVmUserId, std::string());
registry->RegisterBooleanPref(kPluginVmDataCollectionAllowed, false);
registry->RegisterIntegerPref(kPluginVmRequiredFreeDiskSpaceGB,
......
......@@ -14,6 +14,8 @@ extern const char kPluginVmAllowed[];
extern const char kPluginVmImage[];
extern const char kPluginVmImageExists[];
extern const char kPluginVmPrintersAllowed[];
extern const char kPluginVmCameraAllowed[];
extern const char kPluginVmMicAllowed[];
extern const char kPluginVmUserId[];
extern const char kEngagementPrefsPrefix[];
extern const char kPluginVmDataCollectionAllowed[];
......
......@@ -555,8 +555,6 @@ if (optimize_webui) {
"chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_browser_proxy.js",
"chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.html",
"chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.js",
"chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_permission_dialog.html",
"chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_permission_dialog.js",
"chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_shared_paths.html",
"chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_shared_paths.js",
"chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_shared_usb_devices.html",
......
......@@ -20,7 +20,6 @@ js_library("plugin_vm_browser_proxy") {
js_library("plugin_vm_detail_view") {
deps = [
":plugin_vm_browser_proxy",
":plugin_vm_permission_dialog",
"../:constants",
"../:permission_item",
"../:store_client",
......@@ -45,10 +44,6 @@ js_library("plugin_vm_shared_usb_devices") {
]
}
js_library("plugin_vm_permission_dialog") {
deps = [ ":plugin_vm_browser_proxy" ]
}
# TODO: Uncomment as the Polymer3 migration makes progress.
#js_type_check("closure_compile_module") {
# is_polymer3 = true
......@@ -98,7 +93,6 @@ group("polymer3_elements") {
public_deps = [
":modulize",
":plugin_vm_detail_view_module",
":plugin_vm_permission_dialog_module",
":plugin_vm_shared_paths_module",
":plugin_vm_shared_usb_devices_module",
]
......@@ -110,12 +104,6 @@ polymer_modulizer("plugin_vm_detail_view") {
html_type = "dom-module"
}
polymer_modulizer("plugin_vm_permission_dialog") {
js_file = "plugin_vm_permission_dialog.js"
html_file = "plugin_vm_permission_dialog.html"
html_type = "dom-module"
}
polymer_modulizer("plugin_vm_shared_paths") {
js_file = "plugin_vm_shared_paths.js"
html_file = "plugin_vm_shared_paths.html"
......
......@@ -56,18 +56,10 @@ cr.define('settings', function() {
setPluginVmUsbDeviceShared(guid, shared) {}
/**
* @param {!PermissionSetting} permissionSetting The proposed change to
* permissions
* @return {!Promise<boolean>} Whether Plugin VM needs to be relaunched for
* permissions to take effect.
*/
wouldPermissionChangeRequireRelaunch(permissionSetting) {}
/**
* @param {!PermissionSetting} permissionSetting The change to make to the
* permissions
*/
setPluginVmPermission(permissionSetting) {}
isRelaunchNeededForNewPermissions() {}
/**
* Relaunches Plugin VM.
......@@ -98,17 +90,8 @@ cr.define('settings', function() {
}
/** @override */
wouldPermissionChangeRequireRelaunch(permissionSetting) {
return cr.sendWithPromise(
'wouldPermissionChangeRequireRelaunch',
permissionSetting.permissionType, permissionSetting.proposedValue);
}
/** @override */
setPluginVmPermission(permissionSetting) {
chrome.send(
'setPluginVmPermission',
[permissionSetting.permissionType, permissionSetting.proposedValue]);
isRelaunchNeededForNewPermissions() {
return cr.sendWithPromise('isRelaunchNeededForNewPermissions');
}
/** @override */
......
......@@ -8,7 +8,6 @@
<link rel="import" href="../store_client.html">
<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
<link rel="import" href="chrome://resources/cr_elements/icons.html">
<link rel="import" href="plugin_vm_permission_dialog.html">
<dom-module id="app-management-plugin-vm-detail-view">
<template>
......@@ -78,12 +77,18 @@
</div>
</div>
<template is="dom-if" if="[[showPluginVmPermissionDialog_]]" restamp>
<app-management-plugin-vm-permission-dialog
on-close="onPluginVmPermissionDialogClose_"
pending-permission-change="[[pendingPermissionChange_]]"
reset-permission-change="{{resetPermissionChange}}">
</app-management-plugin-vm-permission-dialog>
<template is="dom-if" if="[[showDialog_]]" restamp>
<cr-dialog close-text="$i18n{close}" show-on-attach on-cancel="onCancel_">
<div slot="body">[[dialogText_]]</div>
<div slot="button-container">
<cr-button class="cancel-button" on-click="onCancel_">
$i18n{cancel}
</cr-button>
<cr-button class="action-button" on-click="onRelaunchTap_">
$i18n{pluginVmPermissionDialogRelaunchButton}
</cr-button>
</div>
</cr-dialog>
</template>
</template>
<script src="plugin_vm_detail_view.js"></script>
......
......@@ -39,29 +39,16 @@ Polymer({
},
/** @private {boolean} */
showPluginVmPermissionDialog_: {
showDialog_: {
type: Boolean,
value: false,
},
/**
* The current permssion type that is being changed
* and its proposed value.
* @private {?PermissionSetting}
*/
pendingPermissionChange_: {
type: Object,
value: null,
},
/** @private {string} */
dialogText_: String,
/**
* If the last permission change should be reset.
* {boolean}
*/
resetPermissionChange: {
type: Boolean,
value: false,
},
/** @private {Element} */
pendingPermissionItem_: Object,
},
attached() {
......@@ -89,58 +76,39 @@ Polymer({
* @param {!Event} e
* @private
*/
onPermissionChanged_: function(e) {
const permissionTypeString =
/** @type {{permissionType:string}} */ (e.target).permissionType;
let permissionType;
switch (permissionTypeString) {
onPermissionChanged_: async function(e) {
this.pendingPermissionItem_ = /** @type {Element} */ (e.target);
switch (e.target.permissionType) {
case 'CAMERA':
permissionType = PermissionType.CAMERA;
this.dialogText_ =
loadTimeData.getString('pluginVmPermissionDialogCameraLabel');
break;
case 'MICROPHONE':
permissionType = PermissionType.MICROPHONE;
this.dialogText_ =
loadTimeData.getString('pluginVmPermissionDialogMicrophoneLabel');
break;
default:
assertNotReached();
}
const permissionSetting = /** @type {!PermissionSetting} */ ({
permissionType: permissionType,
proposedValue: !app_management.util.getPermissionValueBool(
this.app_, permissionTypeString)
});
settings.PluginVmBrowserProxyImpl.getInstance()
.wouldPermissionChangeRequireRelaunch(permissionSetting)
.then(requiresRestart => {
if (requiresRestart) {
this.pendingPermissionChange_ = permissionSetting;
this.showPluginVmPermissionDialog_ = true;
} else {
settings.PluginVmBrowserProxyImpl.getInstance()
.setPluginVmPermission(permissionSetting);
}
});
},
/** @private */
onPluginVmPermissionDialogClose_: function() {
if (this.resetPermissionChange) {
switch (this.pendingPermissionChange_.permissionType) {
case PermissionType.CAMERA:
/* @type {!AppManagementPermissionItem} */ (
this.$$('#camera-permission'))
.resetToggle();
break;
case PermissionType.MICROPHONE:
/* @type @{!AppManagementPermissionItem} */ (
this.$$('#microphone-permission'))
.resetToggle();
break;
default:
assertNotReached();
}
const requiresRelaunch =
await settings.PluginVmBrowserProxyImpl.getInstance()
.isRelaunchNeededForNewPermissions();
if (requiresRelaunch) {
this.showDialog_ = true;
} else {
this.pendingPermissionItem_.syncPermission();
}
this.resetPermissionChange = false;
this.showPluginVmPermissionDialog_ = false;
this.pendingPermissionChange_ = null;
},
onRelaunchTap_: function() {
this.pendingPermissionItem_.syncPermission();
settings.PluginVmBrowserProxyImpl.getInstance().relaunchPluginVm();
this.showDialog_ = false;
},
onCancel_: function() {
this.pendingPermissionItem_.resetToggle();
this.showDialog_ = false;
},
});
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
<link rel="import" href="../browser_proxy.html">
<link rel="import" href="../../../../settings_shared_css.html">
<dom-module id="app-management-plugin-vm-permission-dialog">
<template>
<style include="settings-shared"></style>
<cr-dialog id="dialog" close-text="$i18n{close}">
<div id="dialog-text" slot="body">[[dialogText_]]</div>
<div slot="button-container">
<cr-button id="dialogCancelButton" class="cancel-button"
on-click="onCancelTap_">
$i18n{cancel}
</cr-button>
<cr-button id="dialogRelaunchButton" class="action-button"
on-click="onRelaunchTap_">
$i18n{pluginVmPermissionDialogRelaunchButton}
</cr-button>
</div>
</cr-dialog>
</template>
<script src="plugin_vm_permission_dialog.js"></script>
</dom-module>
// Copyright 2020 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.
/**
* @fileoverview 'app-management-plugin-vm-permission-dialog' is a component
* that alerts the user when Plugin Vm needs to be relaunched in order for
* changes to the permission settings to take effect.
*/
Polymer({
is: 'app-management-plugin-vm-permission-dialog',
properties: {
/**
* An attribute indicating the type of permission that is being
* changed and what value to change it to.
* {!PermissionSetting}
*/
pendingPermissionChange: Object,
/**
* If the last permission change should be reset.
* {boolean}
*/
resetPermissionChange: {
type: Boolean,
notify: true,
},
/** @private {string} */
dialogText_: {
type: String,
computed: 'getDialogText_()',
},
},
/** @override */
attached() {
this.$.dialog.showModal();
},
/** @private */
onCancelTap_() {
this.resetPermissionChange = true;
this.$.dialog.close();
},
/** @private */
onRelaunchTap_() {
const proxy = settings.PluginVmBrowserProxyImpl.getInstance();
// Reinitializing PermissionSetting Object to keep the closure compiler
// happy.
proxy.setPluginVmPermission({
permissionType: this.pendingPermissionChange.permissionType,
proposedValue: this.pendingPermissionChange.proposedValue
});
proxy.relaunchPluginVm();
this.$.dialog.close();
},
/** @private */
getDialogText_() {
switch (this.pendingPermissionChange.permissionType) {
case PermissionType.CAMERA:
return loadTimeData.getString('pluginVmPermissionDialogCameraLabel');
case PermissionType.MICROPHONE:
return loadTimeData.getString(
'pluginVmPermissionDialogMicrophoneLabel');
default:
assertNotReached();
}
},
});
......@@ -288,12 +288,6 @@
<structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PLUGIN_VM_BROWSER_PROXY_HTML"
file="chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_browser_proxy.html"
compress="false" type="chrome_html" />
<structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PLUGIN_VM_PERMISSION_DIALOG_JS"
file="chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_permission_dialog.js"
compress="false" type="chrome_html" />
<structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PLUGIN_VM_PERMISSION_DIALOG_HTML"
file="chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_permission_dialog.html"
compress="false" type="chrome_html" />
<structure name="IDR_OS_SETTINGS_CAPTIONS_SUBPAGE_JS"
file="a11y_page/captions_subpage.js"
compress="false" type="chrome_html" />
......
......@@ -64,14 +64,10 @@ void PluginVmHandler::RegisterMessages() {
base::BindRepeating(&PluginVmHandler::HandleSetPluginVmUsbDeviceShared,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"wouldPermissionChangeRequireRelaunch",
"isRelaunchNeededForNewPermissions",
base::BindRepeating(
&PluginVmHandler::HandleWouldPermissionChangeRequireRelaunch,
&PluginVmHandler::HandleIsRelaunchNeededForNewPermissions,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"setPluginVmPermission",
base::BindRepeating(&PluginVmHandler::HandleSetPluginVmPermission,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"relaunchPluginVm",
base::BindRepeating(&PluginVmHandler::HandleRelaunchPluginVm,
......@@ -163,35 +159,17 @@ void PluginVmHandler::OnUsbDevicesChanged() {
UsbDevicesToListValue(detector->GetDevicesSharableWithCrostini()));
}
void PluginVmHandler::HandleWouldPermissionChangeRequireRelaunch(
void PluginVmHandler::HandleIsRelaunchNeededForNewPermissions(
const base::ListValue* args) {
AllowJavascript();
CHECK_EQ(3U, args->GetSize());
std::string callback_id = args->GetList()[0].GetString();
plugin_vm::PermissionType permission_type =
static_cast<plugin_vm::PermissionType>(args->GetList()[1].GetInt());
DCHECK(permission_type == plugin_vm::PermissionType::kCamera ||
permission_type == plugin_vm::PermissionType::kMicrophone);
plugin_vm::PluginVmManager* manager =
plugin_vm::PluginVmManagerFactory::GetForProfile(profile_);
bool current_value = manager->GetPermission(permission_type);
bool proposed_value = args->GetList()[2].GetBool();
bool requires_relaunch = proposed_value != current_value &&
manager->IsRelaunchNeededForNewPermissions();
ResolveJavascriptCallback(base::Value(callback_id),
base::Value(requires_relaunch));
}
void PluginVmHandler::HandleSetPluginVmPermission(const base::ListValue* args) {
CHECK_EQ(2U, args->GetSize());
plugin_vm::PermissionType permission_type =
static_cast<plugin_vm::PermissionType>(args->GetList()[0].GetInt());
bool proposed_value = args->GetList()[1].GetBool();
DCHECK(permission_type == plugin_vm::PermissionType::kCamera ||
permission_type == plugin_vm::PermissionType::kMicrophone);
plugin_vm::PluginVmManagerFactory::GetForProfile(profile_)->SetPermission(
permission_type, proposed_value);
CHECK_EQ(1U, args->GetList().size());
bool requires_relaunch =
plugin_vm::PluginVmManagerFactory::GetForProfile(profile_)
->IsRelaunchNeededForNewPermissions();
ResolveJavascriptCallback(
/*callback_id=*/base::Value(args->GetList()[0].GetString()),
base::Value(requires_relaunch));
}
void PluginVmHandler::HandleRelaunchPluginVm(const base::ListValue* args) {
......
......@@ -47,9 +47,7 @@ class PluginVmHandler : public ::settings::SettingsPageUIHandler,
void HandleSetPluginVmUsbDeviceShared(const base::ListValue* args);
// Checks if Plugin VM would need to be relaunched if the proposed changes are
// made.
void HandleWouldPermissionChangeRequireRelaunch(const base::ListValue* args);
// Sets the specified permission to the value proposed.
void HandleSetPluginVmPermission(const base::ListValue* args);
void HandleIsRelaunchNeededForNewPermissions(const base::ListValue* args);
// Relaunches Plugin VM.
void HandleRelaunchPluginVm(const base::ListValue* args);
......
......@@ -8,13 +8,12 @@ class TestPluginVmBrowserProxy extends TestBrowserProxy {
super([
'getPluginVmSharedPathsDisplayText',
'removePluginVmSharedPath',
'wouldPermissionChangeRequireRelaunch',
'isRelaunchNeededForNewPermissions',
'setPluginVmPermission',
'relaunchPluginVm',
]);
this.removeSharedPathResult = true;
this.pluginVmRunning = false;
this.permissions = [true, true]; // [0]Camera, [1]Microphone
}
/** @override */
......@@ -30,20 +29,9 @@ class TestPluginVmBrowserProxy extends TestBrowserProxy {
}
/** @override */
wouldPermissionChangeRequireRelaunch(permissionSetting) {
this.methodCalled(
'wouldPermissionChangeRequireRelaunch', permissionSetting);
return Promise.resolve(
permissionSetting.proposedValue !==
this.permissions[permissionSetting.permissionType] &&
this.pluginVmRunning);
}
/** @override */
setPluginVmPermission(permissionSetting) {
this.methodCalled('setPluginVmPermission', permissionSetting);
this.permissions[permissionSetting.permissionType] =
permissionSetting.proposedValue;
isRelaunchNeededForNewPermissions() {
this.methodCalled('isRelaunchNeededForNewPermissions');
return Promise.resolve(this.pluginVmRunning);
}
/** @override */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment