blob: 66bf268833090a184cc14d419d3ec6efabb1de3a [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/permissions/permission_update_message_controller_android.h"
#include "base/android/jni_android.h"
#include "base/memory/raw_ptr.h"
#include "base/test/mock_callback.h"
#include "chrome/browser/android/android_theme_resources.h"
#include "chrome/grit/branded_strings.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "components/messages/android/mock_message_dispatcher_bridge.h"
#include "components/strings/grit/components_strings.h"
class PermissionUpdateMessageControllerAndroidTest
: public ChromeRenderViewHostTestHarness {
public:
PermissionUpdateMessageControllerAndroidTest() = default;
~PermissionUpdateMessageControllerAndroidTest() override = default;
void SetUp() override;
void TearDown() override;
PermissionUpdateMessageController* GetController() { return controller_; }
void ShowLocation(base::OnceCallback<void(bool)> callback) {
EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage);
GetController()->ShowMessageInternal(
{}, {}, {}, IDR_ANDROID_INFOBAR_GEOLOCATION,
IDS_MESSAGE_MISSING_LOCATION_PERMISSION_TITLE,
IDS_MESSAGE_MISSING_LOCATION_PERMISSION_TEXT, std::move(callback));
}
void ShowMedia(base::OnceCallback<void(bool)> callback) {
EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage);
GetController()->ShowMessageInternal(
{}, {}, {}, IDR_ANDROID_INFOBAR_GEOLOCATION,
IDS_MESSAGE_MISSING_MICROPHONE_CAMERA_PERMISSION_TITLE,
IDS_MESSAGE_MISSING_MICROPHONE_CAMERA_PERMISSIONS_TEXT,
std::move(callback));
}
void ShowDownload(base::OnceCallback<void(bool)> callback,
bool expected_enqueue) {
if (expected_enqueue)
EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage);
GetController()->ShowMessageInternal(
{}, {}, {}, IDR_ANDORID_MESSAGE_PERMISSION_STORAGE,
IDS_MESSAGE_MISSING_STORAGE_ACCESS_PERMISSION_TITLE,
IDS_MESSAGE_STORAGE_ACCESS_PERMISSION_TEXT, std::move(callback));
}
size_t GetMessageDelegatesSize() {
return GetController()->message_delegates_.size();
}
void OnPermissionGranted(bool granted) {
GetController()->message_delegates_.front()->OnPermissionResult(granted);
}
void SetPermissionResultTriggeredSynchronously() {
GetController()->message_delegates_.front()->message_->SetActionClick(
base::BindOnce(
&PermissionUpdateMessageControllerAndroidTest::OnPermissionGranted,
base::Unretained(this), false));
}
void DismissedByPrimaryAction() {
messages::MessageDispatcherBridge::Get()->DismissMessage(
GetController()->message_delegates_.front()->message_.get(),
messages::DismissReason::PRIMARY_ACTION);
}
void ExpectDismiss(messages::DismissReason expected_reason) {
EXPECT_CALL(message_dispatcher_bridge_, DismissMessage)
.WillOnce([expected_reason](messages::MessageWrapper* message,
messages::DismissReason dismiss_reason) {
EXPECT_EQ(static_cast<int>(expected_reason),
static_cast<int>(dismiss_reason));
message->HandleDismissCallback(base::android::AttachCurrentThread(),
static_cast<int>(dismiss_reason));
});
}
private:
raw_ptr<PermissionUpdateMessageController> controller_;
messages::MockMessageDispatcherBridge message_dispatcher_bridge_;
};
void PermissionUpdateMessageControllerAndroidTest::SetUp() {
ChromeRenderViewHostTestHarness::SetUp();
messages::MessageDispatcherBridge::SetInstanceForTesting(
&message_dispatcher_bridge_);
PermissionUpdateMessageController::CreateForWebContents(web_contents());
controller_ =
PermissionUpdateMessageController::FromWebContents(web_contents());
}
void PermissionUpdateMessageControllerAndroidTest::TearDown() {
messages::MessageDispatcherBridge::SetInstanceForTesting(nullptr);
ChromeRenderViewHostTestHarness::TearDown();
}
TEST_F(PermissionUpdateMessageControllerAndroidTest,
OnMessageDismissedByPrimaryAction) {
base::MockOnceCallback<void(bool)> mock_permission_update_callback1;
base::MockOnceCallback<void(bool)> mock_permission_update_callback2;
ShowLocation(mock_permission_update_callback1.Get());
EXPECT_EQ(1u, GetMessageDelegatesSize());
ShowMedia(mock_permission_update_callback2.Get());
EXPECT_EQ(2u, GetMessageDelegatesSize());
EXPECT_CALL(mock_permission_update_callback1, Run(false));
// Message is dismissed first by primary action, and then permission update
// callback is invoked. In this case, the dismiss reason should be
// PRIMARY_ACTION.
ExpectDismiss(messages::DismissReason::PRIMARY_ACTION);
DismissedByPrimaryAction();
OnPermissionGranted(false);
EXPECT_EQ(1u, GetMessageDelegatesSize());
EXPECT_CALL(mock_permission_update_callback2, Run(true));
ExpectDismiss(messages::DismissReason::PRIMARY_ACTION);
DismissedByPrimaryAction();
OnPermissionGranted(true);
EXPECT_EQ(0u, GetMessageDelegatesSize());
}
TEST_F(PermissionUpdateMessageControllerAndroidTest, OnPermissionResult) {
// Permission update callback is invoked before dismiss callback is triggered.
// In this case, dismiss callback is invoked when the controller is trying
// to delete the message delegate. The dismiss reason should be UNKNOWN.
base::MockOnceCallback<void(bool)> mock_permission_update_callback1;
ShowLocation(mock_permission_update_callback1.Get());
EXPECT_EQ(1u, GetMessageDelegatesSize());
SetPermissionResultTriggeredSynchronously();
EXPECT_CALL(mock_permission_update_callback1, Run(true));
ExpectDismiss(messages::DismissReason::UNKNOWN);
OnPermissionGranted(true);
EXPECT_EQ(0u, GetMessageDelegatesSize());
base::MockOnceCallback<void(bool)> mock_permission_update_callback2;
ShowMedia(mock_permission_update_callback2.Get());
EXPECT_EQ(1u, GetMessageDelegatesSize());
SetPermissionResultTriggeredSynchronously();
EXPECT_CALL(mock_permission_update_callback2, Run(false));
ExpectDismiss(messages::DismissReason::UNKNOWN);
OnPermissionGranted(false);
EXPECT_EQ(0u, GetMessageDelegatesSize());
}
TEST_F(PermissionUpdateMessageControllerAndroidTest,
OnEnqueuingDuplciatedMessage) {
base::MockOnceCallback<void(bool)> mock_permission_update_callback1;
base::MockOnceCallback<void(bool)> mock_permission_update_callback2;
ShowDownload(mock_permission_update_callback1.Get(), true);
EXPECT_EQ(1u, GetMessageDelegatesSize());
ShowDownload(mock_permission_update_callback2.Get(), false);
EXPECT_EQ(1u, GetMessageDelegatesSize());
EXPECT_CALL(mock_permission_update_callback1, Run(false));
EXPECT_CALL(mock_permission_update_callback2, Run(false));
// Message is dismissed first by primary action, and then permission update
// callback is invoked. In this case, the dismiss reason should be
// PRIMARY_ACTION.
ExpectDismiss(messages::DismissReason::PRIMARY_ACTION);
DismissedByPrimaryAction();
OnPermissionGranted(false);
EXPECT_EQ(0u, GetMessageDelegatesSize());
}