0

[Exo] Add provider to store last connection status and entry point

Create an AppsLaunchInfoProvider to store last connection check
result and the entry point that app streaming started from. This
will be used to check which histogram we should log the app streaming
result.

Bug: b/274477247
Change-Id: I8802d3bc5bb22cb6c936e08e64475c7ac681da3f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4347923
Reviewed-by: Crisrael Lucero <crisrael@google.com>
Reviewed-by: Jon Mann <jonmann@chromium.org>
Commit-Queue: Pu Shi <pushi@google.com>
Cr-Commit-Position: refs/heads/main@{#1120830}
This commit is contained in:
Pu Shi
2023-03-22 22:25:45 +00:00
committed by Chromium LUCI CQ
parent b9e97aedfc
commit 5b13c56c35
12 changed files with 251 additions and 17 deletions

@ -54,6 +54,8 @@ static_library("eche_app_ui") {
"apps_access_manager_impl.h",
"apps_access_setup_operation.cc",
"apps_access_setup_operation.h",
"apps_launch_info_provider.cc",
"apps_launch_info_provider.h",
"eche_alert_generator.cc",
"eche_alert_generator.h",
"eche_app_manager.cc",
@ -163,6 +165,7 @@ source_set("unit_tests") {
sources = [
"apps_access_manager_impl_unittest.cc",
"apps_access_setup_operation_unittest.cc",
"apps_launch_info_provider_unittest.cc",
"eche_alert_generator_unittest.cc",
"eche_app_manager_unittest.cc",
"eche_connection_scheduler_impl_unittest.cc",

@ -0,0 +1,33 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/webui/eche_app_ui/apps_launch_info_provider.h"
#include "ash/webui/eche_app_ui/mojom/eche_app.mojom-shared.h"
namespace ash {
namespace eche_app {
AppsLaunchInfoProvider::AppsLaunchInfoProvider(
EcheConnectionStatusHandler* connection_handler)
: eche_connection_status_handler_(connection_handler) {
eche_connection_status_handler_->AddObserver(this);
}
AppsLaunchInfoProvider::~AppsLaunchInfoProvider() {
eche_connection_status_handler_->RemoveObserver(this);
}
void AppsLaunchInfoProvider::OnConnectionStatusForUiChanged(
mojom::ConnectionStatus connection_status) {
last_connection_ = connection_status;
}
void AppsLaunchInfoProvider::SetEntryPoint(
mojom::AppStreamLaunchEntryPoint entry_point) {
entry_point_ = entry_point;
}
} // namespace eche_app
} // namespace ash

@ -0,0 +1,48 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_WEBUI_ECHE_APP_UI_APPS_LAUNCH_INFO_PROVIDER_H_
#define ASH_WEBUI_ECHE_APP_UI_APPS_LAUNCH_INFO_PROVIDER_H_
#include <cstdint>
#include "ash/webui/eche_app_ui/eche_connection_status_handler.h"
#include "ash/webui/eche_app_ui/mojom/eche_app.mojom-shared.h"
#include "ash/webui/eche_app_ui/mojom/eche_app.mojom.h"
namespace ash {
namespace eche_app {
// A class to store app stream entry point and last connection status.
class AppsLaunchInfoProvider : public EcheConnectionStatusHandler::Observer {
public:
explicit AppsLaunchInfoProvider(EcheConnectionStatusHandler*);
~AppsLaunchInfoProvider() override;
AppsLaunchInfoProvider(const AppsLaunchInfoProvider&) = delete;
AppsLaunchInfoProvider& operator=(const AppsLaunchInfoProvider&) = delete;
// EcheConnectionStatusHandler::Observer:
void OnConnectionStatusForUiChanged(
mojom::ConnectionStatus connection_status) override;
void SetEntryPoint(mojom::AppStreamLaunchEntryPoint entry_point);
mojom::ConnectionStatus GetConnectionStatusForUi() {
return last_connection_;
}
mojom::AppStreamLaunchEntryPoint entry_point() { return entry_point_; }
private:
EcheConnectionStatusHandler* eche_connection_status_handler_;
mojom::AppStreamLaunchEntryPoint entry_point_ =
mojom::AppStreamLaunchEntryPoint::UNKNOWN;
mojom::ConnectionStatus last_connection_ =
mojom::ConnectionStatus::kConnectionStatusDisconnected;
};
} // namespace eche_app
} // namespace ash
#endif // ASH_WEBUI_ECHE_APP_UI_APPS_LAUNCH_INFO_PROVIDER_H_

@ -0,0 +1,101 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/webui/eche_app_ui/apps_launch_info_provider.h"
#include <memory>
#include "ash/webui/eche_app_ui/eche_connection_status_handler.h"
#include "ash/constants/ash_features.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace ash::eche_app {
class AppsLaunchInfoProviderTest : public testing::Test {
public:
AppsLaunchInfoProviderTest() = default;
AppsLaunchInfoProviderTest(const AppsLaunchInfoProviderTest&) = delete;
AppsLaunchInfoProviderTest& operator=(const AppsLaunchInfoProviderTest&) =
delete;
~AppsLaunchInfoProviderTest() override = default;
// testing::Test:
void SetUp() override {
scoped_feature_list_.InitWithFeatures(
/*enabled_features=*/{features::kEcheSWA,
features::kEcheNetworkConnectionState},
/*disabled_features=*/{});
handler_ = std::make_unique<EcheConnectionStatusHandler>();
provider_ = std::make_unique<AppsLaunchInfoProvider>(handler_.get());
}
void TearDown() override {
provider_.reset();
handler_.reset();
}
void NotifyConnectionStatusForUiChanged(mojom::ConnectionStatus status) {
handler_->SetConnectionStatusForUi(status);
}
mojom::ConnectionStatus GetLastConnectionStatus() {
return provider_->GetConnectionStatusForUi();
}
void SetEntryPoint(mojom::AppStreamLaunchEntryPoint entry_point) {
provider_->SetEntryPoint(entry_point);
}
mojom::AppStreamLaunchEntryPoint GetEntryPoint() {
return provider_->entry_point();
}
base::test::ScopedFeatureList scoped_feature_list_;
private:
std::unique_ptr<EcheConnectionStatusHandler> handler_;
std::unique_ptr<AppsLaunchInfoProvider> provider_;
};
TEST_F(AppsLaunchInfoProviderTest, OnConnectionStatusForUiChanged) {
EXPECT_EQ(GetLastConnectionStatus(),
mojom::ConnectionStatus::kConnectionStatusDisconnected);
NotifyConnectionStatusForUiChanged(
mojom::ConnectionStatus::kConnectionStatusConnecting);
EXPECT_EQ(GetLastConnectionStatus(),
mojom::ConnectionStatus::kConnectionStatusConnecting);
NotifyConnectionStatusForUiChanged(
mojom::ConnectionStatus::kConnectionStatusConnected);
EXPECT_EQ(GetLastConnectionStatus(),
mojom::ConnectionStatus::kConnectionStatusConnected);
NotifyConnectionStatusForUiChanged(
mojom::ConnectionStatus::kConnectionStatusFailed);
EXPECT_EQ(GetLastConnectionStatus(),
mojom::ConnectionStatus::kConnectionStatusFailed);
NotifyConnectionStatusForUiChanged(
mojom::ConnectionStatus::kConnectionStatusDisconnected);
EXPECT_EQ(GetLastConnectionStatus(),
mojom::ConnectionStatus::kConnectionStatusDisconnected);
}
TEST_F(AppsLaunchInfoProviderTest, SetEntryPoint) {
EXPECT_EQ(GetEntryPoint(), mojom::AppStreamLaunchEntryPoint::UNKNOWN);
SetEntryPoint(mojom::AppStreamLaunchEntryPoint::NOTIFICATION);
EXPECT_EQ(GetEntryPoint(), mojom::AppStreamLaunchEntryPoint::NOTIFICATION);
SetEntryPoint(mojom::AppStreamLaunchEntryPoint::APPS_LIST);
EXPECT_EQ(GetEntryPoint(), mojom::AppStreamLaunchEntryPoint::APPS_LIST);
SetEntryPoint(mojom::AppStreamLaunchEntryPoint::RECENT_APPS);
EXPECT_EQ(GetEntryPoint(), mojom::AppStreamLaunchEntryPoint::RECENT_APPS);
}
} // namespace ash::eche_app

@ -9,6 +9,7 @@
#include "ash/constants/ash_features.h"
#include "ash/public/cpp/network_config_service.h"
#include "ash/webui/eche_app_ui/apps_access_manager_impl.h"
#include "ash/webui/eche_app_ui/apps_launch_info_provider.h"
#include "ash/webui/eche_app_ui/eche_alert_generator.h"
#include "ash/webui/eche_app_ui/eche_connection_metrics_recorder.h"
#include "ash/webui/eche_app_ui/eche_connection_scheduler_impl.h"
@ -59,18 +60,23 @@ EcheAppManager::EcheAppManager(
device_sync_client,
multidevice_setup_client,
connection_manager_.get())),
eche_connection_status_handler_(
std::make_unique<EcheConnectionStatusHandler>()),
launch_app_helper_(
std::make_unique<LaunchAppHelper>(phone_hub_manager,
launch_eche_app_function,
launch_notification_function,
close_notification_function)),
apps_launch_info_provider_(std::make_unique<AppsLaunchInfoProvider>(
eche_connection_status_handler_.get())),
stream_status_change_handler_(
std::make_unique<EcheStreamStatusChangeHandler>()),
eche_notification_click_handler_(
std::make_unique<EcheNotificationClickHandler>(
phone_hub_manager,
feature_status_provider_.get(),
launch_app_helper_.get())),
launch_app_helper_.get(),
apps_launch_info_provider_.get())),
connection_scheduler_(std::make_unique<EcheConnectionSchedulerImpl>(
connection_manager_.get(),
feature_status_provider_.get())),
@ -95,7 +101,8 @@ EcheAppManager::EcheAppManager(
phone_hub_manager,
feature_status_provider_.get(),
launch_app_helper_.get(),
stream_status_change_handler_.get())),
stream_status_change_handler_.get(),
apps_launch_info_provider_.get())),
alert_generator_(
std::make_unique<EcheAlertGenerator>(launch_app_helper_.get(),
pref_service)),
@ -111,9 +118,7 @@ EcheAppManager::EcheAppManager(
stream_status_change_handler_.get(),
feature_status_provider_.get())),
eche_stream_orientation_observer_(
std::make_unique<EcheStreamOrientationObserver>()),
eche_connection_status_handler_(
std::make_unique<EcheConnectionStatusHandler>()) {
std::make_unique<EcheStreamOrientationObserver>()) {
ash::GetNetworkConfigService(
remote_cros_network_config_.BindNewPipeAndPassReceiver());
system_info_provider_ = std::make_unique<SystemInfoProvider>(
@ -179,7 +184,6 @@ void EcheAppManager::StreamGoBack() {
// NOTE: These should be destroyed in the opposite order of how these objects
// are initialized in the constructor.
void EcheAppManager::Shutdown() {
eche_connection_status_handler_.reset();
eche_stream_orientation_observer_.reset();
system_info_provider_.reset();
eche_tray_stream_status_observer_.reset();
@ -194,7 +198,9 @@ void EcheAppManager::Shutdown() {
connection_scheduler_.reset();
eche_notification_click_handler_.reset();
stream_status_change_handler_.reset();
apps_launch_info_provider_.reset();
launch_app_helper_.reset();
eche_connection_status_handler_.reset();
feature_status_provider_.reset();
connection_manager_.reset();
}

@ -9,6 +9,7 @@
#include <memory>
#include "ash/webui/eche_app_ui/apps_launch_info_provider.h"
#include "ash/webui/eche_app_ui/eche_feature_status_provider.h"
#include "ash/webui/eche_app_ui/eche_notification_click_handler.h"
#include "ash/webui/eche_app_ui/eche_recent_app_click_handler.h"
@ -42,6 +43,7 @@ class SecureChannelClient;
namespace eche_app {
class AppsLaunchInfoProvider;
class EcheConnector;
class EcheMessageReceiver;
class EcheAlertGenerator;
@ -113,7 +115,9 @@ class EcheAppManager : public KeyedService {
private:
std::unique_ptr<secure_channel::ConnectionManager> connection_manager_;
std::unique_ptr<EcheFeatureStatusProvider> feature_status_provider_;
std::unique_ptr<EcheConnectionStatusHandler> eche_connection_status_handler_;
std::unique_ptr<LaunchAppHelper> launch_app_helper_;
std::unique_ptr<AppsLaunchInfoProvider> apps_launch_info_provider_;
std::unique_ptr<EcheStreamStatusChangeHandler> stream_status_change_handler_;
std::unique_ptr<EcheNotificationClickHandler>
eche_notification_click_handler_;
@ -133,7 +137,6 @@ class EcheAppManager : public KeyedService {
eche_tray_stream_status_observer_;
std::unique_ptr<EcheStreamOrientationObserver>
eche_stream_orientation_observer_;
std::unique_ptr<EcheConnectionStatusHandler> eche_connection_status_handler_;
};
} // namespace eche_app

@ -6,6 +6,7 @@
#include "ash/root_window_controller.h"
#include "ash/shell.h"
#include "ash/webui/eche_app_ui/apps_launch_info_provider.h"
#include "ash/webui/eche_app_ui/launch_app_helper.h"
#include "base/metrics/histogram_functions.h"
#include "chromeos/ash/components/multidevice/logging/logging.h"
@ -17,9 +18,11 @@ namespace eche_app {
EcheNotificationClickHandler::EcheNotificationClickHandler(
phonehub::PhoneHubManager* phone_hub_manager,
FeatureStatusProvider* feature_status_provider,
LaunchAppHelper* launch_app_helper)
LaunchAppHelper* launch_app_helper,
AppsLaunchInfoProvider* apps_launch_info_provider)
: feature_status_provider_(feature_status_provider),
launch_app_helper_(launch_app_helper) {
launch_app_helper_(launch_app_helper),
apps_launch_info_provider_(apps_launch_info_provider) {
handler_ = phone_hub_manager->GetNotificationInteractionHandler();
phone_model_ = phone_hub_manager->GetPhoneModel();
feature_status_provider_->AddObserver(this);
@ -49,6 +52,8 @@ void EcheNotificationClickHandler::HandleNotificationClick(
base::UmaHistogramEnumeration(
"Eche.AppStream.LaunchAttempt",
mojom::AppStreamLaunchEntryPoint::NOTIFICATION);
apps_launch_info_provider_->SetEntryPoint(
mojom::AppStreamLaunchEntryPoint::NOTIFICATION);
launch_app_helper_->LaunchEcheApp(
notification_id, app_metadata.package_name,
app_metadata.visible_app_name, app_metadata.user_id,

@ -22,14 +22,17 @@ class PhoneHubManager;
namespace eche_app {
class LaunchAppHelper;
class AppsLaunchInfoProvider;
// Handles notification clicks originating from Phone Hub notifications.
class EcheNotificationClickHandler : public phonehub::NotificationClickHandler,
public FeatureStatusProvider::Observer {
public:
EcheNotificationClickHandler(phonehub::PhoneHubManager* phone_hub_manager,
FeatureStatusProvider* feature_status_provider,
LaunchAppHelper* launch_app_helper);
EcheNotificationClickHandler(
phonehub::PhoneHubManager* phone_hub_manager,
FeatureStatusProvider* feature_status_provider,
LaunchAppHelper* launch_app_helper,
AppsLaunchInfoProvider* apps_launch_info_provider);
~EcheNotificationClickHandler() override;
EcheNotificationClickHandler(const EcheNotificationClickHandler&) = delete;
@ -51,6 +54,7 @@ class EcheNotificationClickHandler : public phonehub::NotificationClickHandler,
phonehub::PhoneModel* phone_model_;
FeatureStatusProvider* feature_status_provider_;
LaunchAppHelper* launch_app_helper_;
AppsLaunchInfoProvider* apps_launch_info_provider_;
bool is_click_handler_set_ = false;
};

@ -7,6 +7,8 @@
#include <string>
#include "ash/constants/ash_features.h"
#include "ash/webui/eche_app_ui/apps_launch_info_provider.h"
#include "ash/webui/eche_app_ui/eche_connection_status_handler.h"
#include "ash/webui/eche_app_ui/fake_feature_status_provider.h"
#include "ash/webui/eche_app_ui/fake_launch_app_helper.h"
#include "ash/webui/eche_app_ui/launch_app_helper.h"
@ -50,12 +52,18 @@ class EcheNotificationClickHandlerTest : public testing::Test {
base::BindRepeating(
&EcheNotificationClickHandlerTest::FakeCloseNotificationFunction,
base::Unretained(this)));
connection_status_handler_ =
std::make_unique<eche_app::EcheConnectionStatusHandler>();
apps_launch_info_provider_ = std::make_unique<AppsLaunchInfoProvider>(
connection_status_handler_.get());
handler_ = std::make_unique<EcheNotificationClickHandler>(
&fake_phone_hub_manager_, &fake_feature_status_provider_,
launch_app_helper_.get());
launch_app_helper_.get(), apps_launch_info_provider_.get());
}
void TearDown() override {
connection_status_handler_.reset();
apps_launch_info_provider_.reset();
launch_app_helper_.reset();
handler_.reset();
}
@ -116,6 +124,9 @@ class EcheNotificationClickHandlerTest : public testing::Test {
base::test::ScopedFeatureList scoped_feature_list_;
FakeFeatureStatusProvider fake_feature_status_provider_;
std::unique_ptr<FakeLaunchAppHelper> launch_app_helper_;
std::unique_ptr<eche_app::EcheConnectionStatusHandler>
connection_status_handler_;
std::unique_ptr<AppsLaunchInfoProvider> apps_launch_info_provider_;
size_t num_notifications_shown_ = 0;
size_t num_app_launch_ = 0;
};

@ -8,6 +8,7 @@
#include "ash/shell.h"
#include "ash/system/eche/eche_tray.h"
#include "ash/system/phonehub/phone_hub_ui_controller.h"
#include "ash/webui/eche_app_ui/apps_launch_info_provider.h"
#include "ash/webui/eche_app_ui/launch_app_helper.h"
#include "base/metrics/histogram_functions.h"
#include "chromeos/ash/components/phonehub/phone_hub_manager.h"
@ -19,11 +20,13 @@ EcheRecentAppClickHandler::EcheRecentAppClickHandler(
phonehub::PhoneHubManager* phone_hub_manager,
FeatureStatusProvider* feature_status_provider,
LaunchAppHelper* launch_app_helper,
EcheStreamStatusChangeHandler* stream_status_change_handler)
EcheStreamStatusChangeHandler* stream_status_change_handler,
AppsLaunchInfoProvider* apps_launch_info_provider)
: phone_hub_manager_(phone_hub_manager),
feature_status_provider_(feature_status_provider),
launch_app_helper_(launch_app_helper),
stream_status_change_handler_(stream_status_change_handler) {
stream_status_change_handler_(stream_status_change_handler),
apps_launch_info_provider_(apps_launch_info_provider) {
notification_handler_ =
phone_hub_manager->GetNotificationInteractionHandler();
recent_apps_handler_ = phone_hub_manager->GetRecentAppsInteractionHandler();
@ -84,6 +87,7 @@ void EcheRecentAppClickHandler::OnRecentAppClicked(
base::UmaHistogramEnumeration("Eche.AppStream.LaunchAttempt", entrypoint);
to_stream_apps_.emplace_back(app_metadata);
apps_launch_info_provider_->SetEntryPoint(entrypoint);
launch_app_helper_->LaunchEcheApp(
/*notification_id=*/absl::nullopt, app_metadata.package_name,
app_metadata.visible_app_name, app_metadata.user_id,

@ -24,6 +24,7 @@ class PhoneHubManager;
namespace eche_app {
class LaunchAppHelper;
class AppsLaunchInfoProvider;
// Handles recent app clicks originating from Phone Hub recent apps.
class EcheRecentAppClickHandler
@ -36,7 +37,8 @@ class EcheRecentAppClickHandler
phonehub::PhoneHubManager* phone_hub_manager,
FeatureStatusProvider* feature_status_provider,
LaunchAppHelper* launch_app_helper,
EcheStreamStatusChangeHandler* stream_status_change_handler);
EcheStreamStatusChangeHandler* stream_status_change_handler,
AppsLaunchInfoProvider* apps_launch_info_provider);
~EcheRecentAppClickHandler() override;
EcheRecentAppClickHandler(const EcheRecentAppClickHandler&) = delete;
@ -70,6 +72,7 @@ class EcheRecentAppClickHandler
LaunchAppHelper* launch_app_helper_;
EcheStreamStatusChangeHandler* stream_status_change_handler_;
std::vector<phonehub::Notification::AppMetadata> to_stream_apps_;
AppsLaunchInfoProvider* apps_launch_info_provider_;
bool is_click_handler_set_ = false;
bool is_stream_started_ = false;
};

@ -4,9 +4,12 @@
#include "ash/webui/eche_app_ui/eche_recent_app_click_handler.h"
#include <memory>
#include <string>
#include "ash/constants/ash_features.h"
#include "ash/webui/eche_app_ui/apps_launch_info_provider.h"
#include "ash/webui/eche_app_ui/eche_connection_status_handler.h"
#include "ash/webui/eche_app_ui/eche_stream_status_change_handler.h"
#include "ash/webui/eche_app_ui/fake_feature_status_provider.h"
#include "ash/webui/eche_app_ui/fake_launch_app_helper.h"
@ -50,14 +53,21 @@ class EcheRecentAppClickHandlerTest : public testing::Test {
base::BindRepeating(
&EcheRecentAppClickHandlerTest::FakeCloseNotificationFunction,
base::Unretained(this)));
connection_status_handler_ =
std::make_unique<eche_app::EcheConnectionStatusHandler>();
apps_launch_info_provider_ = std::make_unique<AppsLaunchInfoProvider>(
connection_status_handler_.get());
stream_status_change_handler_ =
std::make_unique<EcheStreamStatusChangeHandler>();
handler_ = std::make_unique<EcheRecentAppClickHandler>(
&fake_phone_hub_manager_, &fake_feature_status_provider_,
launch_app_helper_.get(), stream_status_change_handler_.get());
launch_app_helper_.get(), stream_status_change_handler_.get(),
apps_launch_info_provider_.get());
}
void TearDown() override {
apps_launch_info_provider_.reset();
connection_status_handler_.reset();
launch_app_helper_.reset();
handler_.reset();
stream_status_change_handler_.reset();
@ -137,6 +147,9 @@ class EcheRecentAppClickHandlerTest : public testing::Test {
std::unique_ptr<FakeLaunchAppHelper> launch_app_helper_;
std::unique_ptr<EcheStreamStatusChangeHandler> stream_status_change_handler_;
std::unique_ptr<EcheRecentAppClickHandler> handler_;
std::unique_ptr<eche_app::EcheConnectionStatusHandler>
connection_status_handler_;
std::unique_ptr<AppsLaunchInfoProvider> apps_launch_info_provider_;
std::string package_name_;
std::u16string visible_name_;
int64_t user_id_;