blob: 5df025a911b58b16ef6c80291de63f544c74c08e [file] [log] [blame]
// Copyright 2016 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 "chrome/browser/ui/app_list/arc/arc_app_dialog.h"
#include "base/command_line.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "chrome/browser/chromeos/arc/arc_session_manager.h"
#include "chrome/browser/chromeos/arc/arc_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
#include "chrome/browser/ui/app_list/app_list_service.h"
#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h"
#include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/arc/arc_util.h"
#include "components/arc/common/app.mojom.h"
#include "components/arc/test/connection_holder_util.h"
#include "components/arc/test/fake_app_instance.h"
#include "content/public/test/test_utils.h"
namespace arc {
class ArcAppUninstallDialogViewBrowserTest : public InProcessBrowserTest {
public:
ArcAppUninstallDialogViewBrowserTest() {}
// InProcessBrowserTest:
~ArcAppUninstallDialogViewBrowserTest() override {}
void SetUpCommandLine(base::CommandLine* command_line) override {
arc::SetArcAvailableCommandLineForTesting(command_line);
}
void SetUpInProcessBrowserTestFixture() override {
ArcSessionManager::DisableUIForTesting();
}
void SetUpOnMainThread() override {
profile_ = browser()->profile();
arc_app_list_pref_ = ArcAppListPrefs::Get(profile_);
if (!arc_app_list_pref_) {
ArcAppListPrefsFactory::GetInstance()->RecreateServiceInstanceForTesting(
profile_);
}
arc::SetArcPlayStoreEnabledForProfile(profile_, true);
arc_app_list_pref_ = ArcAppListPrefs::Get(profile_);
DCHECK(arc_app_list_pref_);
base::RunLoop run_loop;
arc_app_list_pref_->SetDefaltAppsReadyCallback(run_loop.QuitClosure());
run_loop.Run();
app_instance_.reset(new arc::FakeAppInstance(arc_app_list_pref_));
arc_app_list_pref_->app_connection_holder()->SetInstance(
app_instance_.get());
WaitForInstanceReady(arc_app_list_pref_->app_connection_holder());
// In this setup, we have one app and one shortcut which share one package.
mojom::AppInfo app;
app.name = base::StringPrintf("Fake App %d", 0);
app.package_name = base::StringPrintf("fake.package.%d", 0);
app.activity = base::StringPrintf("fake.app.%d.activity", 0);
app.sticky = false;
app_instance_->SendRefreshAppList(std::vector<mojom::AppInfo>(1, app));
mojom::ShortcutInfo shortcut;
shortcut.name = base::StringPrintf("Fake Shortcut %d", 0);
shortcut.package_name = base::StringPrintf("fake.package.%d", 0);
shortcut.intent_uri = base::StringPrintf("Fake Shortcut uri %d", 0);
app_instance_->SendInstallShortcut(shortcut);
mojom::ArcPackageInfo package;
package.package_name = base::StringPrintf("fake.package.%d", 0);
package.package_version = 0;
package.last_backup_android_id = 0;
package.last_backup_time = 0;
package.sync = false;
app_instance_->SendRefreshPackageList(
std::vector<mojom::ArcPackageInfo>(1, package));
}
void TearDownOnMainThread() override {
arc_app_list_pref_->app_connection_holder()->CloseInstance(
app_instance_.get());
app_instance_.reset();
ArcSessionManager::Get()->Shutdown();
}
// Ensures the ArcAppDialogView is destoryed.
void TearDown() override { ASSERT_FALSE(IsArcAppDialogViewAliveForTest()); }
ArcAppListPrefs* arc_app_list_pref() { return arc_app_list_pref_; }
FakeAppInstance* instance() { return app_instance_.get(); }
private:
ArcAppListPrefs* arc_app_list_pref_ = nullptr;
Profile* profile_ = nullptr;
std::unique_ptr<arc::FakeAppInstance> app_instance_;
DISALLOW_COPY_AND_ASSIGN(ArcAppUninstallDialogViewBrowserTest);
};
// User confirms/cancels ARC app uninstall. Note that the shortcut is removed
// when the app and the package are uninstalled since the shortcut and the app
// share same package.
IN_PROC_BROWSER_TEST_F(ArcAppUninstallDialogViewBrowserTest,
UserConfirmsUninstall) {
std::vector<std::string> app_ids = arc_app_list_pref()->GetAppIds();
EXPECT_EQ(app_ids.size(), 2u);
std::string package_name = base::StringPrintf("fake.package.%d", 0);
std::string app_activity = base::StringPrintf("fake.app.%d.activity", 0);
std::string app_id =
arc_app_list_pref()->GetAppId(package_name, app_activity);
AppListService* service = AppListService::Get();
ASSERT_TRUE(service);
AppListControllerDelegate* controller(service->GetControllerDelegate());
ASSERT_TRUE(controller);
// The dialog is only shown when AppList is visible, so we show AppList
// first.
service->ShowForProfile(browser()->profile());
ShowArcAppUninstallDialog(browser()->profile(), controller, app_id);
content::RunAllPendingInMessageLoop();
// When we show the dialog, AppList loses focus and gets dismissed.
EXPECT_FALSE(service->IsAppListVisible());
// Cancelling the dialog won't uninstall any app.
EXPECT_TRUE(CloseAppDialogViewAndConfirmForTest(false));
content::RunAllPendingInMessageLoop();
app_ids = arc_app_list_pref()->GetAppIds();
EXPECT_EQ(app_ids.size(), 2u);
// The app list is not showing, so the dialog won't show.
ShowArcAppUninstallDialog(browser()->profile(), controller, app_id);
content::RunAllPendingInMessageLoop();
EXPECT_FALSE(IsArcAppDialogViewAliveForTest());
// Acceptting the dialog won't work since it was not shown.
EXPECT_FALSE(CloseAppDialogViewAndConfirmForTest(true));
content::RunAllPendingInMessageLoop();
app_ids = arc_app_list_pref()->GetAppIds();
EXPECT_EQ(app_ids.size(), 2u);
controller->DismissView();
// Show the app list, and then the dialog.
service->ShowForProfile(browser()->profile());
ShowArcAppUninstallDialog(browser()->profile(), controller, app_id);
content::RunAllPendingInMessageLoop();
EXPECT_TRUE(IsArcAppDialogViewAliveForTest());
// Acceptting the dialog should work now.
EXPECT_TRUE(CloseAppDialogViewAndConfirmForTest(true));
content::RunAllPendingInMessageLoop();
app_ids = arc_app_list_pref()->GetAppIds();
EXPECT_EQ(app_ids.size(), 0u);
controller->DismissView();
}
// User confirms/cancels ARC app shortcut removal. Note that the app is not
// uninstalled when the shortcut is removed.
IN_PROC_BROWSER_TEST_F(ArcAppUninstallDialogViewBrowserTest,
UserConfirmsUninstallShortcut) {
std::vector<std::string> app_ids = arc_app_list_pref()->GetAppIds();
EXPECT_EQ(app_ids.size(), 2u);
std::string package_name = base::StringPrintf("fake.package.%d", 0);
std::string intent_uri = base::StringPrintf("Fake Shortcut uri %d", 0);
std::string app_id = arc_app_list_pref()->GetAppId(package_name, intent_uri);
AppListService* service = AppListService::Get();
ASSERT_TRUE(service);
AppListControllerDelegate* controller(service->GetControllerDelegate());
ASSERT_TRUE(controller);
// The dialog is only shown when AppList is visible, so we show AppList
// first.
service->ShowForProfile(browser()->profile());
ShowArcAppUninstallDialog(browser()->profile(), controller, app_id);
content::RunAllPendingInMessageLoop();
// When we show the dialog, AppList loses focus and gets dismissed.
EXPECT_FALSE(service->IsAppListVisible());
// Cancelling the dialog won't uninstall any app.
EXPECT_TRUE(CloseAppDialogViewAndConfirmForTest(false));
content::RunAllPendingInMessageLoop();
app_ids = arc_app_list_pref()->GetAppIds();
EXPECT_EQ(app_ids.size(), 2u);
// The app list is not showing, so the dialog won't show.
ShowArcAppUninstallDialog(browser()->profile(), controller, app_id);
content::RunAllPendingInMessageLoop();
EXPECT_FALSE(IsArcAppDialogViewAliveForTest());
// Acceptting the dialog won't work since it was not shown.
EXPECT_FALSE(CloseAppDialogViewAndConfirmForTest(true));
content::RunAllPendingInMessageLoop();
app_ids = arc_app_list_pref()->GetAppIds();
EXPECT_EQ(app_ids.size(), 2u);
// Show the app list, and then the dialog.
service->ShowForProfile(browser()->profile());
ShowArcAppUninstallDialog(browser()->profile(), controller, app_id);
content::RunAllPendingInMessageLoop();
EXPECT_TRUE(IsArcAppDialogViewAliveForTest());
// Acceptting the dialog should work now.
EXPECT_TRUE(CloseAppDialogViewAndConfirmForTest(true));
content::RunAllPendingInMessageLoop();
app_ids = arc_app_list_pref()->GetAppIds();
EXPECT_EQ(app_ids.size(), 1u);
controller->DismissView();
}
} // namespace arc