-
Notifications
You must be signed in to change notification settings - Fork 6.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[CrOS SLP] Trigger Managed SIM Lock Notification on policy change.
This CL adds the MSLN class which will manage the showing/hiding of the notification that guides managed users to PIN unlocking their SIM when the restrict SIM Lock global network configuration policy is set to true. Currently, the class only surfaces the notification when the policy changes. Other cases will be added in the next CLs. screenshot: http://go/tscreen/8fce7c8dc73c864e67e443d38abc6bff79b01533 Bug: b/228093904 Change-Id: I1d438ea17e0b26c917197d56b3243e93308bfa4f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3630569 Reviewed-by: Ahmed Mehfooz <amehfooz@chromium.org> Reviewed-by: Azeem Arshad <azeemarshad@chromium.org> Commit-Queue: Regan Hsu <hsuregan@chromium.org> Cr-Commit-Position: refs/heads/main@{#1001789}
- Loading branch information
Regan Hsu
authored and
Chromium LUCI CQ
committed
May 10, 2022
1 parent
c9d17d2
commit 7e1964a
Showing
9 changed files
with
377 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
ash/ash_strings_grd/IDS_ASH_NETWORK_MANAGED_SIM_LOCK_NOTIFICATION_MESSAGE.png.sha1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
8fce7c8dc73c864e67e443d38abc6bff79b01533 |
1 change: 1 addition & 0 deletions
1
ash/ash_strings_grd/IDS_ASH_NETWORK_MANAGED_SIM_LOCK_NOTIFICATION_TITLE.png.sha1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
8fce7c8dc73c864e67e443d38abc6bff79b01533 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
// Copyright 2022 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 "ash/system/network/managed_sim_lock_notifier.h" | ||
|
||
#include "ash/public/cpp/network_config_service.h" | ||
#include "ash/public/cpp/notification_utils.h" | ||
#include "ash/public/cpp/system_tray_client.h" | ||
#include "ash/shell.h" | ||
#include "ash/strings/grit/ash_strings.h" | ||
#include "ash/system/model/system_tray_model.h" | ||
#include "ash/system/tray/tray_popup_utils.h" | ||
#include "base/bind.h" | ||
#include "components/onc/onc_constants.h" | ||
#include "ui/base/l10n/l10n_util.h" | ||
#include "ui/message_center/message_center.h" | ||
#include "ui/message_center/public/cpp/message_center_constants.h" | ||
|
||
namespace ash { | ||
namespace { | ||
|
||
const char kNotifierManagedSimLock[] = "ash.managed-simlock"; | ||
|
||
} // namespace | ||
|
||
// static | ||
const char ManagedSimLockNotifier::kManagedSimLockNotificationId[] = | ||
"cros_managed_sim_lock_notifier_ids.pin_unlock_device"; | ||
|
||
ManagedSimLockNotifier::ManagedSimLockNotifier() { | ||
GetNetworkConfigService( | ||
remote_cros_network_config_.BindNewPipeAndPassReceiver()); | ||
remote_cros_network_config_->AddObserver( | ||
cros_network_config_observer_receiver_.BindNewPipeAndPassRemote()); | ||
} | ||
|
||
ManagedSimLockNotifier::~ManagedSimLockNotifier() {} | ||
|
||
void ManagedSimLockNotifier::OnPoliciesApplied(const std::string& userhash) { | ||
CheckGlobalNetworkConfiguarion(); | ||
} | ||
|
||
void ManagedSimLockNotifier::CheckGlobalNetworkConfiguarion() { | ||
remote_cros_network_config_->GetGlobalPolicy( | ||
base::BindOnce(&ManagedSimLockNotifier::OnGetGlobalPolicy, | ||
weak_ptr_factory_.GetWeakPtr())); | ||
} | ||
|
||
void ManagedSimLockNotifier::OnGetGlobalPolicy( | ||
chromeos::network_config::mojom::GlobalPolicyPtr global_policy) { | ||
if (!global_policy->allow_cellular_sim_lock) { | ||
MaybeShowNotification(); | ||
return; | ||
} | ||
|
||
RemoveNotification(); | ||
} | ||
|
||
void ManagedSimLockNotifier::MaybeShowNotification() { | ||
remote_cros_network_config_->GetNetworkStateList( | ||
chromeos::network_config::mojom::NetworkFilter::New( | ||
chromeos::network_config::mojom::FilterType::kAll, | ||
chromeos::network_config::mojom::NetworkType::kCellular, | ||
chromeos::network_config::mojom::kNoLimit), | ||
base::BindOnce(&ManagedSimLockNotifier::OnCellularNetworksList, | ||
weak_ptr_factory_.GetWeakPtr())); | ||
} | ||
|
||
void ManagedSimLockNotifier::OnCellularNetworksList( | ||
std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr> | ||
networks) { | ||
// Check if there are any PIN locked pSIM or eSIM networks. | ||
for (auto& network : networks) { | ||
if (network->type_state->get_cellular()->sim_locked) { | ||
ShowNotification(); | ||
return; | ||
} | ||
} | ||
|
||
RemoveNotification(); | ||
} | ||
|
||
void ManagedSimLockNotifier::ShowNotification() { | ||
scoped_refptr<message_center::NotificationDelegate> delegate = | ||
base::MakeRefCounted<message_center::HandleNotificationClickDelegate>( | ||
base::BindRepeating([](absl::optional<int> button_index) { | ||
// When clicked, open the SIM Unlock dialog in Cellular settings if | ||
// we can open WebUI settings, otherwise do nothing. | ||
if (TrayPopupUtils::CanOpenWebUISettings()) { | ||
Shell::Get() | ||
->system_tray_model() | ||
->client() | ||
->ShowSettingsSimUnlock(); | ||
} else { | ||
LOG(WARNING) << "Cannot open Cellular settings since it's not " | ||
"possible to open OS Settings"; | ||
} | ||
})); | ||
|
||
std::unique_ptr<message_center::Notification> notification = | ||
ash::CreateSystemNotification( | ||
message_center::NOTIFICATION_TYPE_SIMPLE, | ||
kManagedSimLockNotificationId, | ||
l10n_util::GetStringUTF16( | ||
IDS_ASH_NETWORK_MANAGED_SIM_LOCK_NOTIFICATION_TITLE), | ||
l10n_util::GetStringUTF16( | ||
IDS_ASH_NETWORK_MANAGED_SIM_LOCK_NOTIFICATION_MESSAGE), | ||
/*display_source=*/std::u16string(), GURL(), | ||
message_center::NotifierId( | ||
message_center::NotifierType::SYSTEM_COMPONENT, | ||
kNotifierManagedSimLock), | ||
message_center::RichNotificationData(), std::move(delegate), | ||
/*small_image=*/gfx::VectorIcon(), | ||
message_center::SystemNotificationWarningLevel::WARNING); | ||
|
||
message_center::MessageCenter* message_center = | ||
message_center::MessageCenter::Get(); | ||
message_center->AddNotification(std::move(notification)); | ||
} | ||
|
||
void ManagedSimLockNotifier::RemoveNotification() { | ||
message_center::MessageCenter* message_center = | ||
message_center::MessageCenter::Get(); | ||
message_center->RemoveNotification(kManagedSimLockNotificationId, false); | ||
} | ||
|
||
} // namespace ash |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// Copyright 2022 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 ASH_SYSTEM_NETWORK_MANAGED_SIM_LOCK_NOTIFIER_H_ | ||
#define ASH_SYSTEM_NETWORK_MANAGED_SIM_LOCK_NOTIFIER_H_ | ||
|
||
#include "ash/ash_export.h" | ||
#include "base/gtest_prod_util.h" | ||
#include "base/memory/weak_ptr.h" | ||
#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" | ||
#include "mojo/public/cpp/bindings/remote.h" | ||
|
||
namespace ash { | ||
|
||
// Notifies the user to unlock the currently active PIN locked SIM. | ||
// TODO(b/228093904): Surface notification during the start of each newly active | ||
// session if SIM is locked and policy is set to true. | ||
// TODO(b/228093904): Surface notification if active network changes to network | ||
// with SIM locked and policy is set to true. | ||
// TODO(b/228093904): Remove notification if user successfully unlocks SIM. | ||
// TODO(b/228093904): Remove notification if active network changes to network | ||
// without SIM locked and policy is set to true. | ||
class ASH_EXPORT ManagedSimLockNotifier | ||
: public chromeos::network_config::mojom::CrosNetworkConfigObserver { | ||
public: | ||
ManagedSimLockNotifier(); | ||
ManagedSimLockNotifier(const ManagedSimLockNotifier&) = delete; | ||
ManagedSimLockNotifier& operator=(const ManagedSimLockNotifier&) = delete; | ||
~ManagedSimLockNotifier() override; | ||
|
||
private: | ||
friend class ManagedSimLockNotifierTest; | ||
|
||
// CrosNetworkConfigObserver: | ||
void OnNetworkStateListChanged() override {} | ||
void OnActiveNetworksChanged( | ||
std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr> | ||
networks) override {} | ||
void OnNetworkStateChanged( | ||
chromeos::network_config::mojom::NetworkStatePropertiesPtr network) | ||
override {} | ||
void OnDeviceStateListChanged() override {} | ||
void OnVpnProvidersChanged() override {} | ||
void OnNetworkCertificatesChanged() override {} | ||
void OnPoliciesApplied(const std::string& userhash) override; | ||
|
||
void OnCellularNetworksList( | ||
std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr> | ||
networks); | ||
void OnGetGlobalPolicy( | ||
chromeos::network_config::mojom::GlobalPolicyPtr global_policy); | ||
|
||
void RemoveNotification(); | ||
void CheckGlobalNetworkConfiguarion(); | ||
void MaybeShowNotification(); | ||
void ShowNotification(); | ||
|
||
static const char kManagedSimLockNotificationId[]; | ||
|
||
mojo::Remote<chromeos::network_config::mojom::CrosNetworkConfig> | ||
remote_cros_network_config_; | ||
mojo::Receiver<chromeos::network_config::mojom::CrosNetworkConfigObserver> | ||
cros_network_config_observer_receiver_{this}; | ||
|
||
base::WeakPtrFactory<ManagedSimLockNotifier> weak_ptr_factory_{this}; | ||
}; | ||
|
||
} // namespace ash | ||
|
||
#endif // ASH_SYSTEM_NETWORK_MANAGED_SIM_LOCK_NOTIFIER_H_ |
157 changes: 157 additions & 0 deletions
157
ash/system/network/managed_sim_lock_notifier_unittest.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
// Copyright 2022 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 "ash/system/network/managed_sim_lock_notifier.h" | ||
|
||
#include "ash/constants/ash_features.h" | ||
#include "ash/system/system_notification_controller.h" | ||
#include "ash/test/ash_test_base.h" | ||
#include "base/bind.h" | ||
#include "base/run_loop.h" | ||
#include "base/test/scoped_feature_list.h" | ||
#include "chromeos/network/network_handler.h" | ||
#include "chromeos/network/network_handler_test_helper.h" | ||
#include "chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h" | ||
#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" | ||
#include "third_party/cros_system_api/dbus/shill/dbus-constants.h" | ||
#include "ui/message_center/message_center.h" | ||
#include "ui/message_center/public/cpp/notification.h" | ||
|
||
namespace ash { | ||
namespace { | ||
|
||
const char kTestCellularServicePath[] = "cellular_service_path"; | ||
const char kTestCellularDevicePath[] = "cellular_path"; | ||
const char kTestCellularDevicePathName[] = "stub_cellular_device"; | ||
const char kTestIccid[] = "1234567890123456789"; | ||
const char kTestCellularGuid[] = "cellular_guid"; | ||
const char kTestCellularName[] = "cellular_name"; | ||
const char kTestEid[] = "123456789012345678901234567890123"; | ||
|
||
} // namespace | ||
|
||
class ManagedSimLockNotifierTest : public NoSessionAshTestBase { | ||
protected: | ||
ManagedSimLockNotifierTest() { | ||
scoped_feature_list_.InitAndEnableFeature(features::kSimLockPolicy); | ||
} | ||
ManagedSimLockNotifierTest(const ManagedSimLockNotifierTest&) = delete; | ||
ManagedSimLockNotifierTest& operator=(const ManagedSimLockNotifierTest&) = | ||
delete; | ||
~ManagedSimLockNotifierTest() override = default; | ||
|
||
void SetUp() override { | ||
network_handler_test_helper_ = std::make_unique<NetworkHandlerTestHelper>(); | ||
|
||
network_config_helper_ = std::make_unique< | ||
chromeos::network_config::CrosNetworkConfigTestHelper>(); | ||
AshTestBase::SetUp(); | ||
base::RunLoop().RunUntilIdle(); | ||
|
||
// User must be logged in for notification to be visible. | ||
SimulateUserLogin("user1@test.com"); | ||
} | ||
|
||
void TearDown() override { | ||
AshTestBase::TearDown(); | ||
network_config_helper_.reset(); | ||
network_handler_test_helper_.reset(); | ||
} | ||
|
||
ManagedNetworkConfigurationHandler* managed_network_configuration_handler() { | ||
return NetworkHandler::Get()->managed_network_configuration_handler(); | ||
} | ||
|
||
void SetCellularSimLockState(bool should_lock_sim = true) { | ||
// Simulate a locked SIM. | ||
base::Value sim_lock_status(base::Value::Type::DICTIONARY); | ||
sim_lock_status.SetKey( | ||
shill::kSIMLockTypeProperty, | ||
base::Value(should_lock_sim ? shill::kSIMLockPin : "")); | ||
network_config_helper_->network_state_helper() | ||
.device_test() | ||
->SetDeviceProperty( | ||
kTestCellularDevicePath, shill::kSIMLockStatusProperty, | ||
std::move(sim_lock_status), /*notify_changed=*/true); | ||
|
||
// Set the cellular service to be the active profile. | ||
base::Value::ListStorage sim_slot_infos; | ||
base::Value slot_info_item(base::Value::Type::DICTIONARY); | ||
slot_info_item.SetKey(shill::kSIMSlotInfoICCID, base::Value(kTestIccid)); | ||
slot_info_item.SetBoolKey(shill::kSIMSlotInfoPrimary, true); | ||
sim_slot_infos.push_back(std::move(slot_info_item)); | ||
network_config_helper_->network_state_helper() | ||
.device_test() | ||
->SetDeviceProperty( | ||
kTestCellularDevicePath, shill::kSIMSlotInfoProperty, | ||
base::Value(sim_slot_infos), /*notify_changed=*/true); | ||
|
||
base::RunLoop().RunUntilIdle(); | ||
} | ||
|
||
void SetAllowCellularSimLock(bool allow_cellular_sim_lock) { | ||
base::DictionaryValue global_config; | ||
global_config.SetBoolKey( | ||
::onc::global_network_config::kAllowCellularSimLock, | ||
allow_cellular_sim_lock); | ||
managed_network_configuration_handler()->SetPolicy( | ||
::onc::ONC_SOURCE_DEVICE_POLICY, /*userhash=*/std::string(), | ||
base::ListValue(), global_config); | ||
base::RunLoop().RunUntilIdle(); | ||
} | ||
|
||
void AddCellularDevice() { | ||
network_config_helper_->network_state_helper().AddDevice( | ||
kTestCellularDevicePath, shill::kTypeCellular, | ||
kTestCellularDevicePathName); | ||
} | ||
|
||
void AddCellularService( | ||
const std::string& service_path = kTestCellularServicePath, | ||
const std::string& iccid = kTestIccid) { | ||
// Add idle, non-connectable network. | ||
network_config_helper_->network_state_helper().service_test()->AddService( | ||
service_path, kTestCellularGuid, kTestCellularName, | ||
shill::kTypeCellular, shill::kStateIdle, /*visible=*/true); | ||
|
||
network_config_helper_->network_state_helper() | ||
.service_test() | ||
->SetServiceProperty(service_path, shill::kEidProperty, | ||
base::Value(kTestEid)); | ||
|
||
network_config_helper_->network_state_helper() | ||
.service_test() | ||
->SetServiceProperty(service_path, shill::kIccidProperty, | ||
base::Value(iccid)); | ||
base::RunLoop().RunUntilIdle(); | ||
} | ||
|
||
// Returns the managed SIM lock notification if it is shown, and null if it is | ||
// not shown. | ||
message_center::Notification* GetManagedSimLockNotification() { | ||
return message_center::MessageCenter::Get()->FindVisibleNotificationById( | ||
ManagedSimLockNotifier::kManagedSimLockNotificationId); | ||
} | ||
|
||
base::test::ScopedFeatureList scoped_feature_list_; | ||
std::unique_ptr<chromeos::network_config::CrosNetworkConfigTestHelper> | ||
network_config_helper_; | ||
std::unique_ptr<NetworkHandlerTestHelper> network_handler_test_helper_; | ||
}; | ||
|
||
TEST_F(ManagedSimLockNotifierTest, PolicyChanged) { | ||
AddCellularDevice(); | ||
AddCellularService(); | ||
EXPECT_FALSE(GetManagedSimLockNotification()); | ||
|
||
SetCellularSimLockState(true); | ||
EXPECT_FALSE(GetManagedSimLockNotification()); | ||
|
||
SetAllowCellularSimLock(false); | ||
EXPECT_TRUE(GetManagedSimLockNotification()); | ||
|
||
SetAllowCellularSimLock(true); | ||
EXPECT_FALSE(GetManagedSimLockNotification()); | ||
} | ||
} // namespace ash |
Oops, something went wrong.