Commit 086ed1b6 authored by danielng's avatar danielng Committed by Commit Bot

crostini: Integrate Crostini mic settings into CrostiniManager

Integrating the UI for Crostini mic settings (cl:2079718) into
CrostiniManager. When mic sharing is enabled in the settings
UI, CrostiniManager will hence forth allow Crostini to access
the mic (this takes effect when Termina is restarted). This is all
behind a flag currently, and the UI is based on PM mock-ups (see
PRD here go/guestos-mic).

Bug: 1016193
Change-Id: I3e0ac16032d1a8b88d91b829703ca166348759c4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2086359
Commit-Queue: Daniel Ng <danielng@google.com>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Reviewed-by: default avatarJulian Watson <juwa@google.com>
Cr-Commit-Position: refs/heads/master@{#750872}
parent fb9e596e
...@@ -979,6 +979,12 @@ ...@@ -979,6 +979,12 @@
<message name="IDS_SETTINGS_CROSTINI_MIC_TITLE" desc="Title for sharing mic with Crostini."> <message name="IDS_SETTINGS_CROSTINI_MIC_TITLE" desc="Title for sharing mic with Crostini.">
Give access to microphone Give access to microphone
</message> </message>
<message name="IDS_SETTINGS_CROSTINI_MIC_DIALOG_TITLE" desc="Dialog title for sharing mic with Crostini.">
Linux restart required
</message>
<message name="IDS_SETTINGS_CROSTINI_MIC_DIALOG_LABEL" desc="Dialog label for sharing mic with Crostini.">
Changes to microphone will take effect when Linux is next restarted.
</message>
<!-- Android apps page (OS settings) --> <!-- Android apps page (OS settings) -->
<message name="IDS_SETTINGS_ANDROID_APPS_LABEL" desc="The text associated with the primary section setting."> <message name="IDS_SETTINGS_ANDROID_APPS_LABEL" desc="The text associated with the primary section setting.">
......
c6f8ddc644804630785198b6fd04fd480f1915e9
\ No newline at end of file
c6f8ddc644804630785198b6fd04fd480f1915e9
\ No newline at end of file
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_features.h"
#include "chromeos/dbus/anomaly_detector_client.h" #include "chromeos/dbus/anomaly_detector_client.h"
#include "chromeos/dbus/concierge_client.h" #include "chromeos/dbus/concierge_client.h"
...@@ -120,6 +121,16 @@ void InvokeAndErasePendingContainerCallbacks( ...@@ -120,6 +121,16 @@ void InvokeAndErasePendingContainerCallbacks(
container_callbacks->erase(range.first, range.second); container_callbacks->erase(range.first, range.second);
} }
bool IsMicSharingEnabled(Profile* profile) {
if (base::FeatureList::IsEnabled(
chromeos::features::kCrostiniShowMicSetting) &&
profile->GetPrefs()->GetBoolean(::prefs::kAudioCaptureAllowed) &&
profile->GetPrefs()->GetBoolean(crostini::prefs::kCrostiniMicSharing)) {
return true;
}
return false;
}
} // namespace } // namespace
CrostiniManager::RestartOptions::RestartOptions() = default; CrostiniManager::RestartOptions::RestartOptions() = default;
...@@ -1253,6 +1264,9 @@ void CrostiniManager::StartTerminaVm(std::string name, ...@@ -1253,6 +1264,9 @@ void CrostiniManager::StartTerminaVm(std::string name,
request.set_owner_id(owner_id_); request.set_owner_id(owner_id_);
if (base::FeatureList::IsEnabled(chromeos::features::kCrostiniGpuSupport)) if (base::FeatureList::IsEnabled(chromeos::features::kCrostiniGpuSupport))
request.set_enable_gpu(true); request.set_enable_gpu(true);
if (IsMicSharingEnabled(profile_)) {
request.set_enable_audio_capture(true);
}
const int32_t cpus = base::SysInfo::NumberOfProcessors() - num_cores_disabled; const int32_t cpus = base::SysInfo::NumberOfProcessors() - num_cores_disabled;
DCHECK_LT(0, cpus); DCHECK_LT(0, cpus);
request.set_cpus(cpus); request.set_cpus(cpus);
......
<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="crostini_browser_proxy.html">
<link rel="import" href="../../settings_shared_css.html">
<dom-module id="settings-crostini-mic-sharing-dialog">
<template>
<style include="settings-shared"></style>
<cr-dialog id="dialog" close-text="$i18n{close}">
<div slot="title">$i18n{crostiniMicDialogTitle}</div>
<div slot="body">$i18n{crostiniMicDialogLabel}</div>
<div slot="button-container">
<cr-button class="action-button" on-click="onOkTap_">
$i18n{ok}
</cr-button>
</div>
</cr-dialog>
</template>
<script src="crostini_mic_sharing_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 'settings-crostini-mic-sharing-dialog' is a component that
* alerts the user when Crostini needs to be restarted in order for changes to
* the mic sharing settings to take effect.
*/
Polymer({
is: 'settings-crostini-mic-sharing-dialog',
/** @override */
attached() {
this.$.dialog.showModal();
},
/** @private */
onOkTap_() {
this.$.dialog.close();
},
});
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html"> <link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html">
<link rel="import" href="crostini_browser_proxy.html"> <link rel="import" href="crostini_browser_proxy.html">
<link rel="import" href="crostini_mic_sharing_dialog.html">
<link rel="import" href="../../controls/settings_toggle_button.html"> <link rel="import" href="../../controls/settings_toggle_button.html">
<link rel="import" href="../../i18n_setup.html"> <link rel="import" href="../../i18n_setup.html">
<link rel="import" href="../../prefs/prefs_behavior.html"> <link rel="import" href="../../prefs/prefs_behavior.html">
...@@ -95,8 +96,9 @@ ...@@ -95,8 +96,9 @@
</template> </template>
<template is="dom-if" if="[[showCrostiniMic_]]"> <template is="dom-if" if="[[showCrostiniMic_]]">
<settings-toggle-button id="crostini-mic-sharing" <settings-toggle-button id="crostini-mic-sharing"
pref="{{prefs.crostini.mic_sharing}}" on-change="onMicSharingChange_"
label="$i18n{enableCrostiniMicTitle}"> pref="{{prefs.crostini.mic_sharing}}"
label="$i18n{crostiniMicTitle}">
</settings-toggle-button> </settings-toggle-button>
</template> </template>
<template is="dom-if" if="[[!hideCrostiniUninstall_]]"> <template is="dom-if" if="[[!hideCrostiniUninstall_]]">
...@@ -108,6 +110,12 @@ ...@@ -108,6 +110,12 @@
</cr-button> </cr-button>
</div> </div>
</template> </template>
<template is="dom-if" if="[[showCrostiniMicSharingDialog_]]" restamp>
<settings-crostini-mic-sharing-dialog
on-close="onCrostiniMicSharingDialogClose_">
</settings-crostini-mic-sharing-dialog>
</template>
</template> </template>
<script src="crostini_subpage.js"></script> <script src="crostini_subpage.js"></script>
</dom-module> </dom-module>
...@@ -135,6 +135,12 @@ Polymer({ ...@@ -135,6 +135,12 @@ Polymer({
type: Boolean, type: Boolean,
value: false, value: false,
}, },
/** @private {boolean} */
showCrostiniMicSharingDialog_: {
type: Boolean,
value: false,
},
}, },
/** settings.RouteOriginBehavior override */ /** settings.RouteOriginBehavior override */
...@@ -247,6 +253,21 @@ Polymer({ ...@@ -247,6 +253,21 @@ Polymer({
settings.routes.CROSTINI_PORT_FORWARDING); settings.routes.CROSTINI_PORT_FORWARDING);
}, },
/**
* Shows a dialog when adjusting mic settings.
* TODO(danielng): We should only show the dialog if termina is running and
* the settings change to be different to the current state of termina.
* @private
*/
onMicSharingChange_: function() {
this.showCrostiniMicSharingDialog_ = true;
},
/** @private */
onCrostiniMicSharingDialogClose_: function() {
this.showCrostiniMicSharingDialog_ = false;
},
/** /**
* @private * @private
* @param {boolean} a * @param {boolean} a
......
...@@ -893,6 +893,12 @@ ...@@ -893,6 +893,12 @@
<structure name="IDR_OS_SETTINGS_CROSTINI_PORT_FORWARDING_JS" <structure name="IDR_OS_SETTINGS_CROSTINI_PORT_FORWARDING_JS"
file="chromeos/crostini_page/crostini_port_forwarding.js" file="chromeos/crostini_page/crostini_port_forwarding.js"
type="chrome_html" /> type="chrome_html" />
<structure name="IDR_OS_SETTINGS_CROSTINI_MIC_SHARING_DIALOG_HTML"
file="chromeos/crostini_page/crostini_mic_sharing_dialog.html"
type="chrome_html" />
<structure name="IDR_OS_SETTINGS_CROSTINI_MIC_SHARING_DIALOG_JS"
file="chromeos/crostini_page/crostini_mic_sharing_dialog.js"
type="chrome_html" />
<structure name="IDR_OS_SETTINGS_CROSTINI_SHARED_PATHS_HTML" <structure name="IDR_OS_SETTINGS_CROSTINI_SHARED_PATHS_HTML"
file="chromeos/crostini_page/crostini_shared_paths.html" file="chromeos/crostini_page/crostini_shared_paths.html"
type="chrome_html" /> type="chrome_html" />
......
...@@ -694,7 +694,9 @@ void AddCrostiniStrings(content::WebUIDataSource* html_source, ...@@ -694,7 +694,9 @@ void AddCrostiniStrings(content::WebUIDataSource* html_source,
{"crostiniDiskResizeResizingError", {"crostiniDiskResizeResizingError",
IDS_SETTINGS_CROSTINI_DISK_RESIZE_RESIZING_ERROR}, IDS_SETTINGS_CROSTINI_DISK_RESIZE_RESIZING_ERROR},
{"crostiniDiskResizeDone", IDS_SETTINGS_CROSTINI_DISK_RESIZE_DONE}, {"crostiniDiskResizeDone", IDS_SETTINGS_CROSTINI_DISK_RESIZE_DONE},
{"enableCrostiniMicTitle", IDS_SETTINGS_CROSTINI_MIC_TITLE}, {"crostiniMicTitle", IDS_SETTINGS_CROSTINI_MIC_TITLE},
{"crostiniMicDialogTitle", IDS_SETTINGS_CROSTINI_MIC_DIALOG_TITLE},
{"crostiniMicDialogLabel", IDS_SETTINGS_CROSTINI_MIC_DIALOG_LABEL},
}; };
AddLocalizedStringsBulk(html_source, kLocalizedStrings); AddLocalizedStringsBulk(html_source, kLocalizedStrings);
html_source->AddString( html_source->AddString(
......
...@@ -266,13 +266,19 @@ suite('CrostiniPageTests', function() { ...@@ -266,13 +266,19 @@ suite('CrostiniPageTests', function() {
assertFalse(subpage.$$('#import cr-button').disabled); assertFalse(subpage.$$('#import cr-button').disabled);
}); });
test('TogglecCrostiniMicSharing', function() { test('ToggleCrostiniMicSharing', async function() {
assertTrue(!!subpage.$$('#crostini-mic-sharing')); assertTrue(!!subpage.$$('#crostini-mic-sharing'));
assertFalse(!!subpage.$$('settings-crostini-mic-sharing-dialog'));
setCrostiniPrefs(true, {micSharing: true}); setCrostiniPrefs(true, {micSharing: true});
assertTrue(subpage.$$('#crostini-mic-sharing').checked); assertTrue(subpage.$$('#crostini-mic-sharing').checked);
assertTrue(subpage.$$('#crostini-mic-sharing').pref.value); assertTrue(subpage.$$('#crostini-mic-sharing').pref.value);
subpage.$$('#crostini-mic-sharing').click(); subpage.$$('#crostini-mic-sharing').click();
await flushAsync();
assertTrue(!!subpage.$$('settings-crostini-mic-sharing-dialog'));
const dialog = subpage.$$('settings-crostini-mic-sharing-dialog');
dialog.$$('cr-dialog cr-button').click();
await flushAsync();
assertFalse(subpage.$$('#crostini-mic-sharing').checked); assertFalse(subpage.$$('#crostini-mic-sharing').checked);
assertFalse(subpage.$$('#crostini-mic-sharing').pref.value); assertFalse(subpage.$$('#crostini-mic-sharing').pref.value);
......
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