[CrOS Tether] Show tether dialog when connection is initiated.
When a connection to a Tether network is initiated but the current device has not yet connected to that tether host before, show the tether connection confirmation dialog.
The dialog is already shown if the connection attempt comes from the settings page (see [1]), but this will show the dialog when attempting a connection from other places (e.g., quick settings or a Tether notification from the message center).
[1] https://codereview.chromium.org/2855813002/
BUG=672263
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:closure_compilation
Review-Url: https://codereview.chromium.org/2855973002
Cr-Commit-Position: refs/heads/master@{#468830}
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.js b/chrome/browser/resources/settings/internet_page/internet_detail_page.js
index 451d0f5..a7761fa 100644
--- a/chrome/browser/resources/settings/internet_page/internet_detail_page.js
+++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.js
@@ -149,13 +149,14 @@
didSetFocus_: false,
/**
- * Set in currentRouteChanged() if the showTetherDialog URL query parameter is
- * set to true. The dialog cannot be shown until the network properties have
- * been fetched in networkPropertiesChanged_().
+ * Set in currentRouteChanged() if the showConfigure URL query
+ * parameter is set to true. The dialog cannot be shown until the
+ * network properties have been fetched in
+ * networkPropertiesChanged_().
* @type {boolean}
* @private
*/
- shouldShowTetherDialogWhenNetworkLoaded_: false,
+ shoudlShowConfigureWhenNetworkLoaded_: false,
/**
* Whether the previous route was also the network detail page.
@@ -190,14 +191,14 @@
console.error('No guid specified for page:' + route);
this.close_();
}
- this.shouldShowTetherDialogWhenNetworkLoaded_ =
- queryParams.get('showTetherDialog') == 'true';
- this.wasPreviousRouteNetworkDetailPage_ =
- oldRoute == settings.Route.NETWORK_DETAIL;
// Set basic networkProperties until they are loaded.
var type = /** @type {!chrome.networkingPrivate.NetworkType} */ (
queryParams.get('type')) ||
CrOnc.Type.WI_FI;
+ this.shoudlShowConfigureWhenNetworkLoaded_ =
+ queryParams.get('showConfigure') == 'true';
+ this.wasPreviousRouteNetworkDetailPage_ =
+ oldRoute == settings.Route.NETWORK_DETAIL;
var name = queryParams.get('name') || type;
this.networkProperties = {
GUID: this.guid,
@@ -253,7 +254,7 @@
button.focus();
}
- if (this.shouldShowTetherDialogWhenNetworkLoaded_
+ if (this.shoudlShowConfigureWhenNetworkLoaded_
&& this.networkProperties.Tether) {
this.showTetherDialog_();
}
@@ -580,11 +581,11 @@
/** @private */
onTetherDialogClose_: function() {
- // The tether dialog is opened by specifying "showTetherDialog=true" in the
- // query params. This may lead to the previous route also being the detail
- // page, in which case we should navigate back to the previous route here so
- // that when the user navigates back they will navigate to the previous
- // non-detail page.
+ // The tether dialog is opened by specifying "showConfigure=true"
+ // in the query params. This may lead to the previous route also
+ // being the detail page, in which case we should navigate back to
+ // the previous route here so that when the user navigates back
+ // they will navigate to the previous non-detail page.
if (this.wasPreviousRouteNetworkDetailPage_)
settings.navigateToPreviousRoute();
},
diff --git a/chrome/browser/resources/settings/internet_page/internet_page.js b/chrome/browser/resources/settings/internet_page/internet_page.js
index 44f3c18e..116f714 100644
--- a/chrome/browser/resources/settings/internet_page/internet_page.js
+++ b/chrome/browser/resources/settings/internet_page/internet_page.js
@@ -404,7 +404,7 @@
params.append('guid', properties.GUID);
params.append('type', properties.Type);
params.append('name', CrOnc.getNetworkName(properties));
- params.append('showTetherDialog', true.toString());
+ params.append('showConfigure', true.toString());
settings.navigateTo(settings.Route.NETWORK_DETAIL, params);
return;
diff --git a/chrome/browser/ui/ash/system_tray_client.cc b/chrome/browser/ui/ash/system_tray_client.cc
index f3cedfe..be329e6 100644
--- a/chrome/browser/ui/ash/system_tray_client.cc
+++ b/chrome/browser/ui/ash/system_tray_client.cc
@@ -39,6 +39,10 @@
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/session_manager_client.h"
#include "chromeos/login/login_state.h"
+#include "chromeos/network/network_handler.h"
+#include "chromeos/network/network_state.h"
+#include "chromeos/network/network_state_handler.h"
+#include "chromeos/network/tether_constants.h"
#include "components/session_manager/core/session_manager.h"
#include "components/user_manager/user_manager.h"
#include "content/public/browser/notification_service.h"
@@ -345,6 +349,17 @@
if (session_manager::SessionManager::Get()->IsScreenLocked())
return;
+ DCHECK(chromeos::NetworkHandler::IsInitialized());
+ const chromeos::NetworkState* network_state =
+ chromeos::NetworkHandler::Get()
+ ->network_state_handler()
+ ->GetNetworkStateFromGuid(network_id);
+ if (network_state && network_state->type() == chromeos::kTypeTether &&
+ !network_state->tether_has_connected_to_host()) {
+ ShowNetworkSettingsHelper(network_id, true /* show_configure */);
+ return;
+ }
+
// Dialog will default to the primary display.
chromeos::NetworkConfigView::ShowForNetworkId(network_id,
nullptr /* parent */);
@@ -377,6 +392,11 @@
}
void SystemTrayClient::ShowNetworkSettings(const std::string& network_id) {
+ ShowNetworkSettingsHelper(network_id, false /* show_configure */);
+}
+
+void SystemTrayClient::ShowNetworkSettingsHelper(const std::string& network_id,
+ bool show_configure) {
if (!LoginState::Get()->IsUserLoggedIn() ||
session_manager::SessionManager::Get()->IsInSecondaryLoginScreen()) {
return;
@@ -387,6 +407,8 @@
if (base::FeatureList::IsEnabled(features::kMaterialDesignSettings))
page = chrome::kNetworkDetailSubPage;
page += "?guid=" + net::EscapeUrlEncodedData(network_id, true);
+ if (show_configure)
+ page += "&showConfigure=true";
}
base::RecordAction(base::UserMetricsAction("OpenInternetOptionsDialog"));
ShowSettingsSubPageForActiveUser(page);
diff --git a/chrome/browser/ui/ash/system_tray_client.h b/chrome/browser/ui/ash/system_tray_client.h
index 06908c6..355d046 100644
--- a/chrome/browser/ui/ash/system_tray_client.h
+++ b/chrome/browser/ui/ash/system_tray_client.h
@@ -85,6 +85,10 @@
void RequestRestartForUpdate() override;
private:
+ // Helper function shared by ShowNetworkSettings() and ShowNetworkConfigure().
+ void ShowNetworkSettingsHelper(const std::string& network_id,
+ bool show_configure);
+
// Requests that ash show the update available icon.
void HandleUpdateAvailable();
diff --git a/chromeos/network/network_connect.cc b/chromeos/network/network_connect.cc
index b4b2b5ba3e..5778905 100644
--- a/chromeos/network/network_connect.cc
+++ b/chromeos/network/network_connect.cc
@@ -20,6 +20,7 @@
#include "chromeos/network/network_profile_handler.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_state_handler.h"
+#include "chromeos/network/tether_constants.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace chromeos {
@@ -244,8 +245,9 @@
}
NetworkHandler::Get()->network_connection_handler()->ConnectToNetwork(
- network->path(), base::Bind(&NetworkConnectImpl::OnConnectSucceeded,
- weak_factory_.GetWeakPtr(), network_id),
+ network->path(),
+ base::Bind(&NetworkConnectImpl::OnConnectSucceeded,
+ weak_factory_.GetWeakPtr(), network_id),
base::Bind(&NetworkConnectImpl::OnConnectFailed,
weak_factory_.GetWeakPtr(), network_id),
check_error_state);
@@ -387,6 +389,10 @@
} else if (network->RequiresActivation()) {
ActivateCellular(network_id);
return;
+ } else if (network->type() == kTypeTether &&
+ !network->tether_has_connected_to_host()) {
+ delegate_->ShowNetworkConfigure(network_id);
+ return;
}
}
const bool check_error_state = true;
diff --git a/chromeos/network/network_connect_unittest.cc b/chromeos/network/network_connect_unittest.cc
index 92e5c72..2d2d8b7 100644
--- a/chromeos/network/network_connect_unittest.cc
+++ b/chromeos/network/network_connect_unittest.cc
@@ -40,6 +40,8 @@
const char kCellular1ServicePath[] = "/service/cellular1";
const char kCellular1Guid[] = "cellular1_guid";
+const char kTetherGuid[] = "tether_guid";
+
class MockDelegate : public NetworkConnect::Delegate {
public:
MockDelegate() {}
@@ -56,6 +58,28 @@
MOCK_METHOD1(ShowMobileActivationError, void(const std::string& network_id));
};
+class FakeTetherDelegate : public NetworkConnectionHandler::TetherDelegate {
+ public:
+ FakeTetherDelegate() {}
+ ~FakeTetherDelegate() override {}
+
+ std::string last_connected_tether_network_guid() {
+ return last_connected_tether_network_guid_;
+ }
+
+ // NetworkConnectionHandler::TetherDelegate:
+ void ConnectToNetwork(
+ const std::string& tether_network_guid,
+ const base::Closure& success_callback,
+ const network_handler::StringResultCallback& error_callback) override {
+ last_connected_tether_network_guid_ = tether_network_guid;
+ success_callback.Run();
+ }
+
+ private:
+ std::string last_connected_tether_network_guid_;
+};
+
} // namespace
class NetworkConnectTest : public testing::Test {
@@ -74,6 +98,10 @@
mock_delegate_.reset(new MockDelegate());
ON_CALL(*mock_delegate_, ShowEnrollNetwork(_)).WillByDefault(Return(true));
+ fake_tether_delegate_.reset(new FakeTetherDelegate());
+ NetworkHandler::Get()->network_connection_handler()->SetTetherDelegate(
+ fake_tether_delegate_.get());
+
NetworkConnect::Initialize(mock_delegate_.get());
}
@@ -133,7 +161,19 @@
base::RunLoop().RunUntilIdle();
}
+ void AddTetherNetwork(bool has_connected_to_host) {
+ NetworkStateHandler* handler =
+ NetworkHandler::Get()->network_state_handler();
+ handler->SetTetherTechnologyState(
+ NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED);
+ handler->AddTetherNetworkState(kTetherGuid, "TetherName", "TetherCarrier",
+ 100 /* battery_percentage */,
+ 100 /* signal_strength */,
+ has_connected_to_host);
+ }
+
std::unique_ptr<MockDelegate> mock_delegate_;
+ std::unique_ptr<FakeTetherDelegate> fake_tether_delegate_;
base::test::ScopedTaskEnvironment scoped_task_environment_;
ShillDeviceClient::TestInterface* device_test_;
ShillServiceClient::TestInterface* service_test_;
@@ -227,6 +267,26 @@
EXPECT_FALSE(network->IsConnectingState());
}
+TEST_F(NetworkConnectTest, ConnectToTetherNetwork_HasConnectedToHost) {
+ EXPECT_CALL(*mock_delegate_, ShowNetworkConfigure(_)).Times(0);
+
+ AddTetherNetwork(true /* has_connected_to_host */);
+
+ NetworkConnect::Get()->ConnectToNetworkId(kTetherGuid);
+ EXPECT_EQ(kTetherGuid,
+ fake_tether_delegate_->last_connected_tether_network_guid());
+}
+
+TEST_F(NetworkConnectTest, ConnectToTetherNetwork_HasNotConnectedToHost) {
+ EXPECT_CALL(*mock_delegate_, ShowNetworkConfigure(_));
+
+ AddTetherNetwork(false /* has_connected_to_host */);
+
+ NetworkConnect::Get()->ConnectToNetworkId(kTetherGuid);
+ EXPECT_TRUE(
+ fake_tether_delegate_->last_connected_tether_network_guid().empty());
+}
+
// ShowNetworkSettings only applies to cellular networks.
TEST_F(NetworkConnectTest, ShowNetworkSettings) {
EXPECT_CALL(*mock_delegate_, ShowNetworkSettings(kCellular1Guid));